diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 00810590b..314dde10c 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -154,10 +154,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/bitmaps/${BITMAPS_DIR}) include(gui/CMakeLists.txt) set(SRC ${SRC} storage/storage_common.cpp) + if(${STORAGE} STREQUAL SDCARD) - set(SRC ${SRC} storage/modelslist.cpp storage/sdcard_common.cpp) - if(${STORAGE_FORMAT} STREQUAL BIN) - set(SRC ${SRC} storage/sdcard_raw.cpp) + set(SRC ${SRC} storage/sdcard_common.cpp) + if(${STORAGE_FORMAT} STREQUAL RAW) + set(SRC ${SRC} storage/modelslist.cpp storage/sdcard_raw.cpp) add_definitions(-DSDCARD_RAW) elseif(${STORAGE_FORMAT} STREQUAL YAML) set(SRC ${SRC} storage/sdcard_yaml.cpp) @@ -166,10 +167,14 @@ if(${STORAGE} STREQUAL SDCARD) if (${STORAGE_CONVERT} STREQUAL EEPROM_RLC) set(SRC ${SRC} storage/eeprom_rlc.cpp) add_definitions(-DEEPROM_RLC) - else() + else(${STORAGE_CONVERT} STREQUAL RAW) set(SRC ${SRC} storage/sdcard_raw.cpp) endif() endif() + if(STORAGE_MODELSLIST) + set(SRC ${SRC} storage/modelslist.cpp) + add_definitions(-DSTORAGE_MODELSLIST) + endif() elseif(${STORAGE} STREQUAL EEPROM) set(SRC ${SRC} storage/eeprom_common.cpp) add_definitions(-DEEPROM) @@ -185,6 +190,7 @@ elseif(${STORAGE} STREQUAL EEPROM) endif() endif() + include(storage/conversions/CMakeLists.txt) if(RTC_BACKUP_RAM) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 38232478c..21304de7e 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -759,7 +759,6 @@ PACK(struct TrainerData { NOBACKUP(uint8_t spare5:1 SKIP); \ NOBACKUP(uint8_t blOffBright:7); \ NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]); - #define CURR_MODEL_FILENAME #elif defined(PCBTARANIS) #if defined(STORAGE_BLUETOOTH) #define BLUETOOTH_FIELDS \ @@ -778,14 +777,8 @@ PACK(struct TrainerData { char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME]; \ char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME]; \ BLUETOOTH_FIELDS - #if defined(SDCARD_YAML) - #define CURR_MODEL_FILENAME char currModelFilename[LEN_MODEL_FILENAME+1] - #else - #define CURR_MODEL_FILENAME - #endif #else #define EXTRA_GENERAL_FIELDS - #define CURR_MODEL_FILENAME #endif #if defined(COLORLCD) && !defined(BACKUP) @@ -881,9 +874,6 @@ PACK(struct RadioData { GYRO_FIELDS NOBACKUP(int8_t uartSampleMode:2); // See UartSampleModes -#if defined(PCBTARANIS) - CURR_MODEL_FILENAME; -#endif }); #undef SWITCHES_WARNING_DATA @@ -990,39 +980,19 @@ static inline void check_struct() CHKSIZE(TrainerData, 16); #if defined(PCBXLITES) - #if !defined(SDCARD_YAML) - CHKSIZE(RadioData, 861); - #else - CHKSIZE(RadioData, 878); - #endif + CHKSIZE(RadioData, 861); CHKSIZE(ModelData, 6157); #elif defined(PCBXLITE) - #if !defined(SDCARD_YAML) - CHKSIZE(RadioData, 859); - #else - CHKSIZE(RadioData, 876); - #endif + CHKSIZE(RadioData, 859); CHKSIZE(ModelData, 6157); #elif defined(PCBX7) - #if !defined(SDCARD_YAML) - CHKSIZE(RadioData, 865); - #else - CHKSIZE(RadioData, 882); - #endif + CHKSIZE(RadioData, 865); CHKSIZE(ModelData, 6157); #elif defined(PCBX9E) - #if !defined(SDCARD_YAML) - CHKSIZE(RadioData, 961); - #else - CHKSIZE(RadioData, 978); - #endif + CHKSIZE(RadioData, 961); CHKSIZE(ModelData, 6614); #elif defined(PCBX9D) || defined(PCBX9DP) - #if !defined(SDCARD_YAML) - CHKSIZE(RadioData, 899); - #else - CHKSIZE(RadioData, 916); - #endif + CHKSIZE(RadioData, 899); CHKSIZE(ModelData, 6604); #elif defined(PCBHORUS) CHKSIZE(RadioData, 902); diff --git a/radio/src/gui/128x64/CMakeLists.txt b/radio/src/gui/128x64/CMakeLists.txt index 1fe1b2fca..9cbd14165 100644 --- a/radio/src/gui/128x64/CMakeLists.txt +++ b/radio/src/gui/128x64/CMakeLists.txt @@ -1,9 +1,3 @@ -if(${STORAGE} STREQUAL SDCARD) - set(MODEL_SELECT_SRC model_select_sd.cpp) -else() - set(MODEL_SELECT_SRC model_select.cpp) -endif() - set(GUI_SRC ${GUI_SRC} lcd.cpp @@ -11,7 +5,7 @@ set(GUI_SRC popups.cpp widgets.cpp startup_shutdown.cpp - ${MODEL_SELECT_SRC} + model_select.cpp menu_model.cpp model_setup.cpp model_failsafe.cpp diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp index 351e41f35..38fcbb12f 100644 --- a/radio/src/gui/128x64/model_select.cpp +++ b/radio/src/gui/128x64/model_select.cpp @@ -27,7 +27,7 @@ void onDeleteModelConfirm(const char * result) { if (result == STR_OK) { storageCheck(true); - eeDeleteModel(menuVerticalPosition); // delete file + deleteModel(menuVerticalPosition); // delete file s_copyMode = 0; } } @@ -56,7 +56,8 @@ void onModelSelectMenu(const char * result) #if defined(SDCARD) else if (result == STR_BACKUP_MODEL) { storageCheck(true); // force writing of current model data before this is changed - POPUP_WARNING(eeBackupModel(sub)); + // TODO + //POPUP_WARNING(eeBackupModel(sub)); } else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { if (sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, nullptr)) @@ -73,10 +74,11 @@ void onModelSelectMenu(const char * result) else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); - POPUP_WARNING(eeRestoreModel(sub, (char *)result)); - if (!warningText && g_eeGeneral.currModel == sub) { - eeLoadModel(sub); - } + // TODO + //POPUP_WARNING(eeRestoreModel(sub, (char *)result)); + //if (!warningText && g_eeGeneral.currModel == sub) { + // eeLoadModel(sub); + //} } #endif } @@ -108,7 +110,7 @@ void menuModelSelect(event_t event) case EVT_KEY_LONG(KEY_EXIT): killEvents(event); - if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { + if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && modelExists(sub)) { POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), 0); } @@ -135,7 +137,7 @@ void menuModelSelect(event_t event) case EVT_KEY_BREAK(KEY_ENTER): s_editMode = 0; if (READ_ONLY()) { - if (g_eeGeneral.currModel != sub && eeModelExists(sub)) { + if (g_eeGeneral.currModel != sub && modelExists(sub)) { selectModel(sub); } } @@ -146,7 +148,7 @@ void menuModelSelect(event_t event) uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; if (s_copyMode == COPY_MODE) { - if (!eeCopyModel(cur, s_copySrcRow)) { + if (!copyModel(cur, s_copySrcRow)) { cur = sub; } } @@ -155,7 +157,7 @@ void menuModelSelect(event_t event) while (sub != cur) { uint8_t src = cur; cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; - eeSwapModels(src, cur); + swapModels(src, cur); if (src == s_copySrcRow) s_copySrcRow = cur; else if (cur == s_copySrcRow) @@ -174,7 +176,7 @@ void menuModelSelect(event_t event) s_copyMode = 0; killEvents(event); if (g_eeGeneral.currModel != sub) { - if (eeModelExists(sub)) { + if (modelExists(sub)) { POPUP_MENU_ADD_ITEM(STR_SELECT_MODEL); POPUP_MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); POPUP_MENU_ADD_ITEM(STR_COPY_MODEL); @@ -197,7 +199,7 @@ void menuModelSelect(event_t event) } POPUP_MENU_START(onModelSelectMenu); } - else if (eeModelExists(sub)) { + else if (modelExists(sub)) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copyTgtOfs = 0; s_copySrcRow = -1; @@ -261,7 +263,7 @@ void menuModelSelect(event_t event) if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) { s_copySrcRow = oldSub; // find a hole (in the first empty slot above / below) - sub = eeFindEmptyModel(s_copySrcRow, IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_DOWN)); + sub = findEmptyModel(s_copySrcRow, IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_DOWN)); if (sub < 0) { // no free room for duplicating the model AUDIO_ERROR(); @@ -276,14 +278,10 @@ void menuModelSelect(event_t event) break; } -#if defined(EEPROM_RLC) +#if defined(EEPROM) lcdDrawText(9*FW-(LEN_FREE-4)*FW-4, 0, STR_FREE); if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); lcdDrawNumber(lcdLastRightPos+3, 0, reusableBuffer.modelsel.eepromfree, LEFT); -#elif defined(EEPROM_RLC) - lcdDrawText(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE); - if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); - lcdDrawNumber(17*FW, 0, reusableBuffer.modelsel.eepromfree, RIGHT); #endif #if defined(NAVIGATION_X7) @@ -320,7 +318,7 @@ void menuModelSelect(event_t event) k %= MAX_MODELS; - if (eeModelExists(k)) { + if (modelExists(k)) { drawModelName(4*FW, y, modelHeaders[k].name, k, 0); if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+menuVerticalOffset!=(vertpos_t)sub)) { lcdDrawChar(1, y, '*'); diff --git a/radio/src/gui/128x64/model_select_sd.cpp b/radio/src/gui/128x64/model_select_sd.cpp deleted file mode 100644 index 3659509b9..000000000 --- a/radio/src/gui/128x64/model_select_sd.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include "opentx.h" -#include "storage/modelslist.h" - - -#define CATEGORIES_WIDTH 62 -#define MODELSEL_W 62 -#define PHASE_ONE_FIRST_LINE (1 + 1 * FH) - -enum ModelSelectMode { - MODE_SELECT_MODEL, - MODE_RENAME_CATEGORY, - MODE_MOVE_MODEL, -}; - -enum ModelDeleteMode { - MODE_DELETE_MODEL, - MODE_DELETE_CATEGORY, -}; - -struct { - uint8_t selectMode, deleteMode; - ModelsCategory * currentCategory = nullptr; - int currentCategoryIndex; - int16_t subModelIndex = -1; - bool modelSelected = false; - ModelCell * currentModel = nullptr; - ModelCell * selectedModel = nullptr; - tmr10ms_t preEnterTime; - bool preEnterValid = false; - bool categorySelectMode = false; - uint16_t categoriesVerticalOffset = 0; - uint16_t categoriesVerticalPosition = 0; -} modelSelect; - -bool eeModelExists(uint8_t id) -{ - int index = 0; - - for (ModelsCategory::iterator it = modelSelect.currentCategory->begin(); - it != modelSelect.currentCategory->end(); ++it, ++index) { - if (id == index) { - return true; - } - } - - return false; -} - -void setCurrentModel(unsigned int index) -{ - std::list::iterator it = modelSelect.currentCategory->begin(); - std::advance(it, index); - modelSelect.currentModel = *it; -} - -void getSelectedModel(unsigned int index) -{ - std::list::iterator it = modelSelect.currentCategory->begin(); - std::advance(it, index); - modelSelect.selectedModel = *it; -} - -void setCurrentCategory(unsigned int index) -{ - modelSelect.currentCategoryIndex = index; - const std::list& cats = modelslist.getCategories(); - std::list::const_iterator it = cats.begin(); - std::advance(it, index); - modelSelect.currentCategory = *it; - modelSelect.categoriesVerticalPosition = index; - modelSelect.categoriesVerticalOffset = limit(modelSelect.categoriesVerticalPosition - 4, modelSelect.categoriesVerticalOffset, min(modelSelect.categoriesVerticalPosition, max(0, cats.size() - 5))); -} - -void initModelsList() -{ - modelslist.load(); - - modelSelect.categoriesVerticalOffset = 0; - bool found = false; - int index = 0; - const std::list& cats = modelslist.getCategories(); - for (std::list::const_iterator it = cats.begin(); it != cats.end(); ++it, ++index) { - if (*it == modelslist.getCurrentCategory()) { - setCurrentCategory(index); - found = true; - break; - } - } - if (!found) { - setCurrentCategory(0); - } - - menuVerticalOffset = 0; - found = false; - index = 0; - for (ModelsCategory::iterator it = modelSelect.currentCategory->begin(); it != modelSelect.currentCategory->end(); ++it, ++index) { - if (*it == modelslist.getCurrentModel()) { - setCurrentModel(index); - menuVerticalPosition = index; - found = true; - break; - } - } - if (!found) { - modelslist.addModel(modelSelect.currentCategory, g_eeGeneral.currModelFilename); - setCurrentModel(0); - modelslist.setCurrentModel(modelSelect.currentModel); - modelslist.save(); - storageDirty(EE_GENERAL); - storageDirty(EE_MODEL); - storageCheck(true); - } -} - - -void onModelSelectMenu(const char * result) -{ - if (result == STR_SELECT_MODEL) { - setCurrentModel(menuVerticalPosition); - storageFlushCurrentModel(); - storageCheck(true); - memcpy(g_eeGeneral.currModelFilename, modelSelect.currentModel->modelFilename, LEN_MODEL_FILENAME); - modelslist.setCurrentModel(modelSelect.currentModel); - loadModel(g_eeGeneral.currModelFilename, true); - modelslist.setCurrentCategory(modelSelect.currentCategory); - modelslist.save(); -#if defined(INTERNAL_MODULE_CRSF) - if (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_CROSSFIRE) { - crossfireTurnOnRf(); - bkregSetStatusFlag(CRSF_SET_MODEL_ID_PENDING); - } - else { - crossfireTurnOffRf(false); - } -#endif - storageDirty(EE_GENERAL); - storageCheck(true); - } - else if (result == STR_DELETE_MODEL) { - getSelectedModel(menuVerticalPosition); - POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); - SET_WARNING_INFO(modelSelect.selectedModel->modelName, LEN_MODEL_NAME, 0); - modelSelect.deleteMode = MODE_DELETE_MODEL; - } - else if (result == STR_CREATE_MODEL) { - storageCheck(true); - modelslist.addModel(modelSelect.currentCategory, createModel()); - modelSelect.selectMode = MODE_SELECT_MODEL; - setCurrentModel(modelSelect.currentCategory->size() - 1 ); - modelslist.setCurrentModel(modelSelect.currentModel); - modelslist.onNewModelCreated(modelSelect.currentModel, &g_model); - modelslist.setCurrentCategory(modelSelect.currentCategory); - modelslist.save(); -#if defined(INTERNAL_MODULE_CRSF) - if (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_CROSSFIRE) { - crossfireTurnOnRf(); - bkregSetStatusFlag(CRSF_SET_MODEL_ID_PENDING); - } - else { - crossfireTurnOffRf(false); - } -#endif - storageDirty(EE_GENERAL); - storageCheck(true); - menuVerticalPosition = modelSelect.currentCategory->size() - 1; - } - else if (result == STR_DUPLICATE_MODEL) { - char duplicatedFilename[LEN_MODEL_FILENAME + 1]; - setCurrentModel(menuVerticalPosition); - memcpy(duplicatedFilename, modelSelect.currentModel->modelFilename, sizeof(duplicatedFilename)); - if (findNextFileIndex(duplicatedFilename, LEN_MODEL_FILENAME, MODELS_PATH)) { - sdCopyFile(modelSelect.currentModel->modelFilename, MODELS_PATH, duplicatedFilename, MODELS_PATH); - ModelCell* dup_model = modelslist.addModel(modelSelect.currentCategory, duplicatedFilename); - dup_model->fetchRfData(); - menuVerticalPosition = modelSelect.currentCategory->size() - 1; - } - else { - POPUP_WARNING("Invalid File"); - } - } - else if (result == STR_MOVE_MODEL) { - setCurrentModel(menuVerticalPosition); - modelSelect.selectMode = MODE_MOVE_MODEL; - modelSelect.categorySelectMode = true; - } - else if (result == STR_CREATE_CATEGORY) { - modelSelect.currentCategory = modelslist.createCategory(); - setCurrentCategory(modelslist.getCategories().size() - 1); - modelslist.save(); - storageDirty(EE_GENERAL); - storageCheck(true); - } - else if (result == STR_RENAME_CATEGORY) { - modelSelect.selectMode = MODE_RENAME_CATEGORY; - s_editMode = EDIT_MODIFY_STRING; - editNameCursorPos = 0; - } - else if (result == STR_DELETE_CATEGORY) { - if (modelSelect.currentCategory->size() > 0){ - POPUP_WARNING(STR_DELETE_ERROR); - SET_WARNING_INFO(STR_CAT_NOT_EMPTY, sizeof(TR_CAT_NOT_EMPTY), 0); - } - else { - POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); - SET_WARNING_INFO(modelSelect.currentCategory->name, LEN_MODEL_FILENAME, 0); - modelSelect.deleteMode = MODE_DELETE_CATEGORY; - } - } -} - -void menuModelSelect(event_t event) -{ - int8_t old_editMode = s_editMode; - - if (warningResult) { - warningResult = 0; - - if (modelSelect.deleteMode == MODE_DELETE_CATEGORY) { - TRACE("DELETE CATEGORY"); - modelslist.removeCategory(modelSelect.currentCategory); - modelslist.save(); - setCurrentCategory(modelSelect.currentCategoryIndex > 0 ? modelSelect.currentCategoryIndex-1 : modelSelect.currentCategoryIndex); - } - else if (modelSelect.deleteMode == MODE_DELETE_MODEL) { - int modelIndex = menuVerticalPosition; - setCurrentModel(modelIndex); - modelslist.removeModel(modelSelect.currentCategory, modelSelect.currentModel); - modelSelect.selectMode = 0; - menuVerticalPosition = modelSelect.currentCategory->size()-1; - } - } - - const std::list& cats = modelslist.getCategories(); - - title(STR_MENUMODELSEL); - drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), 0); - - event_t _event_ = ((event==EVT_KEY_BREAK(KEY_ENTER) || event==EVT_KEY_LONG(KEY_ENTER)) ? 0 : event); - check_submenu_simple(_event_, modelSelect.currentCategory ? modelSelect.currentCategory->size() : 30); - - switch (event) { - case EVT_ENTRY: - modelSelect.selectMode = MODE_SELECT_MODEL; - initModelsList(); - modelSelect.preEnterValid = false; - modelSelect.categorySelectMode = false; - break; - case EVT_KEY_BREAK(KEY_ENTER): - if (modelSelect.selectMode == MODE_MOVE_MODEL) { - modelSelect.selectMode = MODE_SELECT_MODEL; - modelSelect.categorySelectMode = false; - } - killEvents(event); - break; - case EVT_KEY_FIRST(KEY_EXIT): - switch (modelSelect.selectMode) { - case MODE_MOVE_MODEL: - modelSelect.selectMode = MODE_SELECT_MODEL; - break; - } - break; - case EVT_KEY_FIRST(KEY_ENTER): - if (!modelSelect.preEnterValid) { - modelSelect.preEnterValid = true; - modelSelect.preEnterTime = get_tmr10ms(); - } - else { - modelSelect.preEnterValid = false; - modelSelect.categorySelectMode = !modelSelect.categorySelectMode; - // if (modelSelect.categorySelectMode) - // AUDIO_CATEGORY_ENABLE(); - // else - // AUDIO_CATEGORY_DISABLE(); - } - break; - -#if defined(KEYS_GPIO_REG_PAGE) - case EVT_KEY_BREAK(KEY_PAGE): - { - if (modelSelect.categorySelectMode) { - if (modelSelect.categoriesVerticalPosition >= cats.size() - 1) - modelSelect.categoriesVerticalPosition = 0; - else - modelSelect.categoriesVerticalPosition += 1; - - if (modelSelect.selectMode == MODE_SELECT_MODEL) { - setCurrentCategory(modelSelect.categoriesVerticalPosition); - menuVerticalPosition = 0; - } - if (modelSelect.selectMode == MODE_MOVE_MODEL) { - ModelsCategory * previous_category = modelSelect.currentCategory; - ModelCell * model = modelSelect.currentModel; - setCurrentCategory(modelSelect.categoriesVerticalPosition); - modelslist.moveModel(model, previous_category, modelSelect.currentCategory); - menuVerticalPosition = modelSelect.currentCategory->size()-1; - } - - modelSelect.subModelIndex = -1; - modelSelect.modelSelected = false; - killEvents(event); - } - else { - chainMenu(menuModelSetup); - } - break; - } - - case EVT_KEY_LONG(KEY_PAGE): - { - if (modelSelect.categorySelectMode) { - if (modelSelect.categoriesVerticalPosition == 0) - modelSelect.categoriesVerticalPosition = cats.size() - 1; - else - modelSelect.categoriesVerticalPosition -= 1; - - if (modelSelect.selectMode == MODE_SELECT_MODEL) { - setCurrentCategory(modelSelect.categoriesVerticalPosition); - menuVerticalPosition = 0; - } - if (modelSelect.selectMode == MODE_MOVE_MODEL) { - ModelsCategory * previous_category = modelSelect.currentCategory; - ModelCell * model = modelSelect.currentModel; - setCurrentCategory(modelSelect.categoriesVerticalPosition); - modelslist.moveModel(model, previous_category, modelSelect.currentCategory); - } - - modelSelect.subModelIndex = -1; - modelSelect.modelSelected = false; - killEvents(event); - } - else { - chainMenu(menuTabModel[DIM(menuTabModel)-1]); - killEvents(event); - } - break; - } -#endif - case EVT_KEY_LONG(KEY_ENTER): - if (modelSelect.selectMode == MODE_SELECT_MODEL) { - killEvents(event); - if (!modelSelect.modelSelected && !modelSelect.currentCategory->empty()) { - POPUP_MENU_ADD_ITEM(STR_SELECT_MODEL); - } - POPUP_MENU_ADD_ITEM(STR_CREATE_MODEL); - if (!modelSelect.currentCategory->empty()) { - if (modelSelect.currentModel) { - POPUP_MENU_ADD_ITEM(STR_DUPLICATE_MODEL); - POPUP_MENU_ADD_ITEM(STR_MOVE_MODEL); - } - if (!modelSelect.modelSelected) { - POPUP_MENU_ADD_ITEM(STR_DELETE_MODEL); - } - } - POPUP_MENU_ADD_ITEM(STR_CREATE_CATEGORY); - POPUP_MENU_ADD_ITEM(STR_RENAME_CATEGORY); - if (cats.size() > 1) { - POPUP_MENU_ADD_ITEM(STR_DELETE_CATEGORY); - } - POPUP_MENU_START(onModelSelectMenu); - } - killEvents(event); - break; - default: - break; - } - - if (modelSelect.preEnterValid && (get_tmr10ms() - modelSelect.preEnterTime) > 50) { - modelSelect.preEnterValid = false; - } - - int index = 0; - coord_t y = 18; - - drawVerticalScrollbar(CATEGORIES_WIDTH - 1, y - 1, 4 * (FH + 7) - 5, modelSelect.categoriesVerticalOffset, cats.size(), 5); - - // Categories - for (std::list::const_iterator it = cats.begin(); it != cats.end(); ++it, ++index) { - if (index >= modelSelect.categoriesVerticalOffset && index < modelSelect.categoriesVerticalOffset + 5) { - coord_t y = MENU_HEADER_HEIGHT * 2 + 1 + (index - modelSelect.categoriesVerticalOffset) * FH * 4 / 3; - uint8_t k = index ; - - if (modelSelect.selectMode == MODE_RENAME_CATEGORY && modelSelect.currentCategory == *it) { - lcdDrawSolidFilledRect(9, y, MODELSEL_W - 1 - 9, 7); - lcdDrawRect(8, y - 1, MODELSEL_W - 1 - 7, 9, DOTTED); - editName(4, y, modelSelect.currentCategory->name, sizeof(modelSelect.currentCategory->name), event, 1, 0, old_editMode); - if (s_editMode == 0 || event == EVT_KEY_BREAK(KEY_EXIT)) { - modelslist.save(); - modelSelect.selectMode = MODE_SELECT_MODEL; - } - } - else { - lcdDrawSizedText(2, y, (*it)->name, strlen((*it)->name), ((modelSelect.categoriesVerticalPosition == k) ? INVERS : 0)); - } - if (modelSelect.selectMode == MODE_MOVE_MODEL && modelSelect.categoriesVerticalPosition == k) { - lcdDrawSolidFilledRect(9, y, MODELSEL_W - 1 - 9, 7); - lcdDrawRect(8, y - 1, MODELSEL_W - 1 - 7, 9, modelSelect.selectMode == COPY_MODE ? SOLID : DOTTED); - } - } - } - - // Models - index = 0; - bool selected = false; - bool current = false; - - for (uint8_t i = 0; i < modelSelect.currentCategory->size(); i++) { - coord_t y = MENU_HEADER_HEIGHT*2 + 1 + i*FH; - uint8_t k = i+menuVerticalOffset; - - if (k >= modelSelect.currentCategory->size()) - break; - - std::list::iterator it = modelSelect.currentCategory->begin(); - std::advance(it, k); - - selected = ((modelSelect.selectMode == MODE_SELECT_MODEL || modelSelect.selectMode == MODE_MOVE_MODEL) && k == menuVerticalPosition); - current = !strncmp((*it)->modelFilename, g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME); - - if (current) { - lcdDrawChar(9 * FW + 11, y, '*'); - lcdDrawText(9 * FW + 18, y, g_model.header.name, LEADING0 | ((selected) ? INVERS : 0)); - modelSelect.subModelIndex = k; - } - else { - lcdDrawText(9 * FW + 18, y, (*it)->modelName, LEADING0 | ((selected) ? INVERS : 0)); - } - - y += 16; - - if (selected) { - lcdDrawText(5, LCD_H - FH - 1, (*it)->modelFilename, SMLSIZE); - } - } - - if (modelSelect.subModelIndex == menuVerticalPosition) { - modelSelect.modelSelected = true; - } - else { - modelSelect.modelSelected = false; - } -} - diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 4373bf497..76b243894 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1419,10 +1419,11 @@ void menuModelSetup(event_t event) } else if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); -#if defined(EEPROM) - uint8_t newVal = findNextUnusedModelId(g_eeGeneral.currModel, moduleIdx); + uint8_t newVal = 0; +#if defined(STORAGE_MODELSLIST) + newVal = modelslist.findNextUnusedModelId(moduleIdx); #else - uint8_t newVal = modelslist.findNextUnusedModelId(moduleIdx); + newVal = findNextUnusedModelId(g_eeGeneral.currModel, moduleIdx); #endif if (newVal != g_model.header.modelId[moduleIdx]) { modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx] = newVal; diff --git a/radio/src/gui/212x64/model_select.cpp b/radio/src/gui/212x64/model_select.cpp index 990d4aa5f..8b48001a0 100644 --- a/radio/src/gui/212x64/model_select.cpp +++ b/radio/src/gui/212x64/model_select.cpp @@ -46,7 +46,8 @@ void onModelSelectMenu(const char * result) } else if (result == STR_BACKUP_MODEL) { storageCheck(true); // force writing of current model data before this is changed - POPUP_WARNING(eeBackupModel(sub)); + //TODO + //POPUP_WARNING(eeBackupModel(sub)); } else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { if (sdListFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, nullptr)) @@ -63,10 +64,11 @@ void onModelSelectMenu(const char * result) else if (result != STR_EXIT) { // The user choosed a file on SD to restore storageCheck(true); - POPUP_WARNING(eeRestoreModel(sub, (char *)result)); - if (!warningText && g_eeGeneral.currModel == sub) { - eeLoadModel(sub); - } + // TODO + // POPUP_WARNING(eeRestoreModel(sub, (char *)result)); + // if (!warningText && g_eeGeneral.currModel == sub) { + // eeLoadModel(sub); + // } } } @@ -75,7 +77,7 @@ void menuModelSelect(event_t event) if (warningResult) { warningResult = 0; storageCheck(true); - eeDeleteModel(menuVerticalPosition); // delete file + deleteModel(menuVerticalPosition); // delete file s_copyMode = 0; event = EVT_ENTRY_UP; } @@ -104,7 +106,7 @@ void menuModelSelect(event_t event) break; case EVT_KEY_LONG(KEY_EXIT): - if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { + if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && modelExists(sub)) { char * nametmp = reusableBuffer.modelsel.mainname; strcat_modelname (nametmp, sub); POPUP_CONFIRMATION(STR_DELETEMODEL, nullptr); @@ -132,7 +134,7 @@ void menuModelSelect(event_t event) case EVT_KEY_BREAK(KEY_ENTER): s_editMode = 0; if (READ_ONLY()) { - if (g_eeGeneral.currModel != sub && eeModelExists(sub)) { + if (g_eeGeneral.currModel != sub && modelExists(sub)) { selectModel(sub); } } @@ -143,7 +145,7 @@ void menuModelSelect(event_t event) uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; if (s_copyMode == COPY_MODE) { - if (!eeCopyModel(cur, s_copySrcRow)) { + if (!copyModel(cur, s_copySrcRow)) { cur = sub; } } @@ -152,7 +154,7 @@ void menuModelSelect(event_t event) while (sub != cur) { uint8_t src = cur; cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; - eeSwapModels(src, cur); + swapModels(src, cur); if (src == s_copySrcRow) s_copySrcRow = cur; else if (cur == s_copySrcRow) @@ -171,7 +173,7 @@ void menuModelSelect(event_t event) s_copyMode = 0; killEvents(event); if (g_eeGeneral.currModel != sub) { - if (eeModelExists(sub)) { + if (modelExists(sub)) { POPUP_MENU_ADD_ITEM(STR_SELECT_MODEL); POPUP_MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); POPUP_MENU_ADD_ITEM(STR_COPY_MODEL); @@ -190,7 +192,7 @@ void menuModelSelect(event_t event) } POPUP_MENU_START(onModelSelectMenu); } - else if (eeModelExists(sub)) { + else if (modelExists(sub)) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copyTgtOfs = 0; s_copySrcRow = -1; @@ -219,7 +221,7 @@ void menuModelSelect(event_t event) if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) { s_copySrcRow = oldSub; // find a hole (in the first empty slot above / below) - sub = eeFindEmptyModel(s_copySrcRow, event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)); + sub = findEmptyModel(s_copySrcRow, event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)); if (sub < 0) { // no free room for duplicating the model AUDIO_ERROR(); @@ -234,9 +236,11 @@ void menuModelSelect(event_t event) break; } +#if defined(EEPROM) lcdDrawNumber(19*FW, 0, EeFsGetFree(), RIGHT); lcdDrawText(19*FW + 3, 0, STR_BYTES); lcdDrawText(lcdLastRightPos + 3, 0, STR_FREE); +#endif drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), 0); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); @@ -267,9 +271,11 @@ void menuModelSelect(event_t event) k %= MAX_MODELS; - if (eeModelExists(k)) { + if (modelExists(k)) { drawModelName(4*FW, y, modelHeaders[k].name, k, 0); +#if defined(EEPROM) lcdDrawNumber(20*FW, y, eeModelSize(k), RIGHT); +#endif if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+menuVerticalOffset!=(vertpos_t)sub)) lcdDrawChar(1, y, '*'); } diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 55a265b37..05b5527aa 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -843,8 +843,9 @@ bool modelHasNotes() return true; } -#if !defined(EEPROM) - buf = strAppendFilename(&filename[sizeof(MODELS_PATH)], g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME); +#if defined(STORAGE_MODELSLIST) + buf = strAppendFilename(&filename[sizeof(MODELS_PATH)], + g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME); strcpy(buf, TEXT_EXT); if (isFileAvailable(filename)) { return true; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 5e6c2c64b..3b917919d 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -335,7 +335,7 @@ void generalDefault() memcpy(g_eeGeneral.bluetoothName, defaultName, sizeof(defaultName)); #endif -#if !defined(EEPROM) +#if defined(STORAGE_MODELSLIST) strcpy(g_eeGeneral.currModelFilename, DEFAULT_MODEL_FILENAME); #endif diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 58d8219a6..7b824087a 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1188,12 +1188,23 @@ bool zexist(const char *str, uint8_t size); unsigned int effectiveLen(const char * str, unsigned int size); char * strcat_zchar(char *dest, const char *name, uint8_t size, const char spaceSym = 0, const char *defaultName=nullptr, uint8_t defaultNameSize=0, uint8_t defaultIdx=0); #define strcatFlightmodeName(dest, idx) strcat_zchar(dest, g_model.flightModeData[idx].name, LEN_FLIGHT_MODE_NAME, 0, STR_FM, PSIZE(TR_FM), idx+1) -#if defined(EEPROM) -#define strcat_modelname(dest, idx) strcat_zchar(dest, modelHeaders[idx].name, LEN_MODEL_NAME, 0, STR_MODEL, PSIZE(TR_MODEL), idx+1) -#define strcat_currentmodelname(dest, foo) strcat_modelname(dest, g_eeGeneral.currModel) + +#if !defined(STORAGE_MODELSLIST) + +#define strcat_modelname(dest, idx) \ + strcat_zchar(dest, modelHeaders[idx].name, LEN_MODEL_NAME, 0, STR_MODEL, \ + PSIZE(TR_MODEL), idx + 1) + +#define strcat_currentmodelname(dest, foo) \ + strcat_modelname(dest, g_eeGeneral.currModel) + #else -#define strcat_currentmodelname(dest, spaceSym) strcat_zchar(dest, g_model.header.name, LEN_MODEL_NAME, spaceSym) + +#define strcat_currentmodelname(dest, spaceSym) \ + strcat_zchar(dest, g_model.header.name, LEN_MODEL_NAME, spaceSym) + #endif + #define ZLEN(s) zlen(s, sizeof(s)) #define ZEXIST(s) zexist(s, sizeof(s)) diff --git a/radio/src/storage/conversions/conversions.cpp b/radio/src/storage/conversions/conversions.cpp index 2888f6ba2..a07feeb6c 100644 --- a/radio/src/storage/conversions/conversions.cpp +++ b/radio/src/storage/conversions/conversions.cpp @@ -170,23 +170,6 @@ void eeConvertModel(int id, int version) uint8_t currModel = g_eeGeneral.currModel; g_eeGeneral.currModel = id; -#if !defined(EEPROM) - char filename[LEN_MODEL_FILENAME+1]; - memset(filename, 0, sizeof(filename)); - char* s = strAppend(filename, MODEL_FILENAME_PREFIX); - s = strAppendUnsigned(s, id + 1, 2); - s = strAppend(s, MODEL_FILENAME_SUFFIX); - memcpy(g_eeGeneral.currModelFilename, filename, sizeof(g_eeGeneral.currModelFilename)); - - if (!modelslist.getCurrentCategory()) { - ModelsCategory* cat = modelslist.createCategory("Models", false); - modelslist.setCurrentCategory(cat); - } - ModelCell* model = modelslist.addModel(modelslist.getCurrentCategory(), - filename, false); - model->setModelName(g_model.header.name); -#endif - storageDirty(EE_MODEL); storageCheck(true); @@ -233,7 +216,7 @@ bool eeConvert() storageDirty(EE_GENERAL); storageCheck(true); -#if !defined(EEPROM) +#if defined(STORAGE_MODELSLIST) modelslist.clear(); #endif @@ -265,7 +248,7 @@ bool eeConvert() } } -#if !defined(EEPROM) +#if defined(STORAGE_MODELSLIST) modelslist.save(); #endif diff --git a/radio/src/storage/eeprom_common.cpp b/radio/src/storage/eeprom_common.cpp index d9458ac32..bcadc9dec 100644 --- a/radio/src/storage/eeprom_common.cpp +++ b/radio/src/storage/eeprom_common.cpp @@ -56,37 +56,6 @@ void eeLoadModel(uint8_t index) } } -uint8_t eeFindEmptyModel(uint8_t id, bool down) -{ - uint8_t i = id; - for (;;) { - i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS; - if (!eeModelExists(i)) break; - if (i == id) return 0xff; // no free space in directory left - } - return i; -} - -void selectModel(uint8_t sub) -{ -#if !defined(COLORLCD) - showMessageBox(STR_LOADINGMODEL); -#endif - storageFlushCurrentModel(); - storageCheck(true); // force writing of current model data before this is changed - g_eeGeneral.currModel = sub; - storageDirty(EE_GENERAL); - eeLoadModel(sub); -} - -ModelHeader modelHeaders[MAX_MODELS]; -void eeLoadModelHeaders() -{ - for (uint32_t i=0; i> 3u] |= mask; - } - - for (uint8_t id = 1; id <= getMaxRxNum(module); id++) { - uint8_t mask = 1u << (id & 7u); - if (!(usedModelIds[id >> 3u] & mask)) { - // found free ID - return id; - } - } - - // failed finding something... - return 0; -} diff --git a/radio/src/storage/eeprom_common.h b/radio/src/storage/eeprom_common.h index 09b75e04e..af7071373 100644 --- a/radio/src/storage/eeprom_common.h +++ b/radio/src/storage/eeprom_common.h @@ -32,16 +32,11 @@ void eeLoadModel(uint8_t id); uint8_t eeFindEmptyModel(uint8_t id, bool down); void selectModel(uint8_t sub); -extern ModelHeader modelHeaders[MAX_MODELS]; -void eeLoadModelHeader(uint8_t id, ModelHeader *header); -void eeLoadModelHeaders(); - void storageClearRadioSettings(); bool storageReadRadioSettings(bool allowFixes = true); void storageReadCurrentModel(); void checkModelIdUnique(uint8_t index, uint8_t module); -uint8_t findNextUnusedModelId(uint8_t index, uint8_t module); #if defined(EEPROM_RLC) #include "eeprom_rlc.h" diff --git a/radio/src/storage/sdcard_common.cpp b/radio/src/storage/sdcard_common.cpp index d53fa9ef6..ec7a32375 100644 --- a/radio/src/storage/sdcard_common.cpp +++ b/radio/src/storage/sdcard_common.cpp @@ -26,10 +26,6 @@ #include "conversions/conversions.h" #include "model_init.h" -//#if !defined(EEPROM_SDCARD) -ModelHeader modelHeaders[MAX_MODELS]; -//#endif - // defined either in sdcard_raw.cpp or sdcard_yaml.cpp void storageCreateModelsList(); @@ -71,7 +67,9 @@ void storageFormat() { sdCheckAndCreateDirectory(RADIO_PATH); sdCheckAndCreateDirectory(MODELS_PATH); +#if defined(STORAGE_MODELSLIST) storageCreateModelsList(); +#endif generalDefault(); } @@ -96,6 +94,7 @@ void storageCheck(bool immediately) } } +#if defined(STORAGE_MODELSLIST) const char * createModel() { preModelLoad(); @@ -108,6 +107,7 @@ const char * createModel() if (index > 0) { setModelDefaults(index); memcpy(g_eeGeneral.currModelFilename, filename, sizeof(g_eeGeneral.currModelFilename)); + storageDirty(EE_GENERAL); storageDirty(EE_MODEL); storageCheck(true); @@ -116,6 +116,7 @@ const char * createModel() return g_eeGeneral.currModelFilename; } +#endif const char * loadModel(const char * filename, bool alarms) { @@ -150,13 +151,20 @@ void storageReadAll() { TRACE("storageReadAll"); +#if defined(STORAGE_MODELSLIST) // Wipe models list in case // it's being reloaded after USB connection modelslist.clear(); +#endif if (loadRadioSettings() != nullptr) { storageEraseAll(true); } +#if !defined(STORAGE_MODELSLIST) + else { + loadModelHeaders(); + } +#endif for (uint8_t i = 0; languagePacks[i] != nullptr; i++) { if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) { @@ -166,6 +174,7 @@ void storageReadAll() } } +#if defined(STORAGE_MODELSLIST) // and reload the list modelslist.load(); @@ -185,24 +194,17 @@ void storageReadAll() if (loadModel(g_eeGeneral.currModelFilename, false) != nullptr) { TRACE("No current model or SD card error"); } +#else + if (loadModel(g_eeGeneral.currModel, false) != nullptr) { + TRACE("No current model or SD card error"); + } +#endif } #if !defined(COLORLCD) void checkModelIdUnique(uint8_t index, uint8_t module) { - if (isModuleXJTD8(module)) - return; - - char * warn_buf = reusableBuffer.moduleSetup.msg; - - // cannot rely exactly on WARNING_LINE_LEN so using WARNING_LINE_LEN-2 - size_t warn_buf_len = sizeof(reusableBuffer.moduleSetup.msg) - WARNING_LINE_LEN - 2; - if (!modelslist.isModelIdUnique(module,warn_buf,warn_buf_len)) { - if (warn_buf[0] != 0) { - POPUP_WARNING(STR_MODELIDUSED); - SET_WARNING_INFO(warn_buf, sizeof(reusableBuffer.moduleSetup.msg), 0); - } - } + //TODO } #endif diff --git a/radio/src/storage/sdcard_common.h b/radio/src/storage/sdcard_common.h index 80e6f9895..f5bd06052 100644 --- a/radio/src/storage/sdcard_common.h +++ b/radio/src/storage/sdcard_common.h @@ -53,6 +53,19 @@ const char * loadModel(const char * filename, bool alarms=true); const char * createModel(); const char * writeModel(); +#if !defined(STORAGE_MODELSLIST) + +// index storage vs modelslist +void selectModel(uint8_t idx); +const char* loadModel(uint8_t idx, bool alarms=true); +bool modelExists(uint8_t idx); +bool copyModel(uint8_t dst, uint8_t src); +void swapModels(uint8_t id1, uint8_t id2); +int8_t deleteModel(uint8_t idx); +uint8_t findEmptyModel(uint8_t id, bool down); + +#endif + const char * loadRadioSettings(); const char * writeGeneralSettings(); diff --git a/radio/src/storage/sdcard_yaml.cpp b/radio/src/storage/sdcard_yaml.cpp index 1fb3906aa..478c4144b 100644 --- a/radio/src/storage/sdcard_yaml.cpp +++ b/radio/src/storage/sdcard_yaml.cpp @@ -20,6 +20,7 @@ */ #include "opentx.h" +#include "opentx_helpers.h" #include "storage.h" #include "sdcard_common.h" #include "sdcard_raw.h" @@ -67,6 +68,7 @@ const char * readYamlFile(const char* fullpath, const YamlParserCalls* calls, vo // Generic storage interface // +#if !defined(EEPROM_RLC) void storageCreateModelsList() { modelslist.clear(); @@ -74,6 +76,7 @@ void storageCreateModelsList() cat->addModel(DEFAULT_MODEL_FILENAME); modelslist.save(); } +#endif // // SDCARD storage interface @@ -244,7 +247,94 @@ const char * writeModelYaml(const char* filename) return NULL; } +#if !defined(STORAGE_MODELSLIST) +// EEPROM slot simulation based on file names: +// - /MODELS/model[00-99].yml + +constexpr uint8_t MODELIDX_STRLEN = sizeof(MODEL_FILENAME_PREFIX "00"); + +static void getModelNumberStr(uint8_t idx, char* model_idx) +{ + memcpy(model_idx, MODEL_FILENAME_PREFIX, sizeof(MODEL_FILENAME_PREFIX)); + model_idx[sizeof(MODEL_FILENAME_PREFIX)-1] = '0' + idx / 10; + model_idx[sizeof(MODEL_FILENAME_PREFIX)] = '0' + idx % 10; + model_idx[sizeof(MODEL_FILENAME_PREFIX)+1] = '\0'; +} +#endif + const char * writeModel() { - return writeModelYaml(g_eeGeneral.currModelFilename); +#if defined(STORAGE_MODELSLIST) + return writeModelYaml(g_eeGeneral.currModelFilename); +#else + char fname[MODELIDX_STRLEN + sizeof(YAML_EXT)]; + getModelNumberStr(g_eeGeneral.currModel, fname); + strcat(fname, YAML_EXT); + return writeModelYaml(fname); +#endif } + +#if !defined(STORAGE_MODELSLIST) +void loadModelHeader(uint8_t id, ModelHeader* header) +{ + PartialModel partial; + memclear(&partial, sizeof(PartialModel)); + + if (modelExists(id)) { + uint8_t dummy; + char fname[MODELIDX_STRLEN + sizeof(YAML_EXT)]; + getModelNumberStr(id, fname); + strcat(fname, YAML_EXT); + readModelYaml(fname, reinterpret_cast(&partial), sizeof(partial), &dummy); + memcpy(header, &partial, sizeof(ModelHeader)); + } +} + +const char * loadModel(uint8_t idx, bool alarms) +{ + char fname[MODELIDX_STRLEN + sizeof(YAML_EXT)]; + getModelNumberStr(idx, fname); + strcat(fname, YAML_EXT); + return loadModel(fname, alarms); +} + +bool modelExists(uint8_t idx) +{ + char model_idx[MODELIDX_STRLEN]; + getModelNumberStr(idx, model_idx); + GET_FILENAME(fname, MODELS_PATH, model_idx, YAML_EXT); + + FILINFO fno; + return f_stat(fname, &fno) == FR_OK; +} + +bool copyModel(uint8_t dst, uint8_t src) +{ + // TODO: overwrite possible? + char model_idx_src[MODELIDX_STRLEN]; + char model_idx_dst[MODELIDX_STRLEN]; + getModelNumberStr(src, model_idx_src); + getModelNumberStr(dst, model_idx_dst); + + GET_FILENAME(fname_src, MODELS_PATH, model_idx_src, YAML_EXT); + GET_FILENAME(fname_dst, MODELS_PATH, model_idx_dst, YAML_EXT); + + return sdCopyFile(fname_src, fname_dst); +} + +void swapModels(uint8_t id1, uint8_t id2) +{ + //TODO +} + +int8_t deleteModel(uint8_t idx) +{ + char model_idx[MODELIDX_STRLEN]; + getModelNumberStr(idx, model_idx); + + GET_FILENAME(fname, MODELS_PATH PATH_SEPARATOR MODEL_FILENAME_PREFIX, + model_idx, YAML_EXT); + + return f_unlink(fname) == FR_OK ? 0 : -1; +} +#endif diff --git a/radio/src/storage/storage.h b/radio/src/storage/storage.h index 061dedafd..9c3be9dc3 100644 --- a/radio/src/storage/storage.h +++ b/radio/src/storage/storage.h @@ -63,6 +63,15 @@ void preModelLoad(); void postModelLoad(bool alarms); void checkExternalAntenna(); +#if !defined(STORAGE_MODELSLIST) +extern ModelHeader modelHeaders[MAX_MODELS]; + +void loadModelHeader(uint8_t id, ModelHeader *header); +void loadModelHeaders(); + +uint8_t findNextUnusedModelId(uint8_t index, uint8_t module); +#endif + #if defined(EEPROM) #include "eeprom_common.h" #endif diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 8d80875fe..5b791974e 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -237,3 +237,66 @@ void storageFlushCurrentModel() storageDirty(EE_MODEL); } } + +#if !defined(STORAGE_MODELSLIST) +void selectModel(uint8_t idx) +{ +#if !defined(COLORLCD) + showMessageBox(STR_LOADINGMODEL); +#endif + storageFlushCurrentModel(); + storageCheck(true); // force writing of current model data before this is changed + g_eeGeneral.currModel = idx; + storageDirty(EE_GENERAL); + loadModel(idx); +} + +uint8_t findEmptyModel(uint8_t id, bool down) +{ + uint8_t i = id; + for (;;) { + i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS; + if (!modelExists(i)) break; + if (i == id) return 0xff; // no free space in directory left + } + return i; +} + +ModelHeader modelHeaders[MAX_MODELS]; + +void loadModelHeaders() +{ + for (uint32_t i=0; i> 3u] |= mask; + } + + for (uint8_t id = 1; id <= getMaxRxNum(module); id++) { + uint8_t mask = 1u << (id & 7u); + if (!(usedModelIds[id >> 3u] & mask)) { + // found free ID + return id; + } + } + + // failed finding something... + return 0; +} +#endif diff --git a/radio/src/storage/yaml/CMakeLists.txt b/radio/src/storage/yaml/CMakeLists.txt index 386a1e2f4..646e1137e 100644 --- a/radio/src/storage/yaml/CMakeLists.txt +++ b/radio/src/storage/yaml/CMakeLists.txt @@ -3,9 +3,12 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(SRC ${SRC} storage/yaml/yaml_tree_walker.cpp storage/yaml/yaml_parser.cpp storage/yaml/yaml_bits.cpp - storage/yaml/yaml_modelslist.cpp storage/yaml/yaml_datastructs.cpp) +if(STORAGE_MODELSLIST) + set(SRC ${SRC} storage/yaml/yaml_modelslist.cpp) +endif() + # Warning: this file must be kept in sync with 'yaml_datastructs.cpp' # in the same directory. diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index de680a60b..a99063b70 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -14,7 +14,8 @@ set(CPU_TYPE STM32F4) set(HSE_VALUE 12000000) set(SDCARD YES) set(STORAGE SDCARD) -set(STORAGE_FORMAT BIN) +set(STORAGE_FORMAT RAW) +set(STORAGE_MODELSLIST YES) set(HAPTIC YES) set(GUI_DIR colorlcd) set(BITMAPS_DIR 480x272) @@ -34,8 +35,8 @@ else() endif() if(YAML_STORAGE) + set(STORAGE_CONVERT RAW) set(STORAGE_FORMAT YAML) - set(STORAGE_CONVERT SDCARD_RAW) endif() # for size report script diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 737b5bacb..619ea6867 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -15,7 +15,7 @@ add_definitions(-DPCBFRSKY) if(PCB STREQUAL X9E) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) - set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) + #set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(STICKS "STANDARD" CACHE STRING "Sticks type (STANDARD/HORUS)") set(CPU_TYPE STM32F4) @@ -49,7 +49,7 @@ if(PCB STREQUAL X9E) set(ROTARY_ENCODER YES) add_definitions(-DMANUFACTURER_FRSKY) elseif(PCB STREQUAL X9D+) - set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) + #set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) set(HAPTIC YES) set(LUA_EXPORT lua_export_x9d) add_definitions(-DPCBX9DP -DPCBX9) @@ -98,7 +98,7 @@ elseif(PCB STREQUAL X9D+) set(STATUS_LEDS NO) endif() elseif(PCB STREQUAL X9D) - set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) + #set(YAML_STORAGE OFF CACHE BOOL "Enable YAML storage" FORCE) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(FLAVOUR x9d)