From 5a367a5221633a3ada42d34083b28aabddba6ef1 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 14 Aug 2021 07:53:20 +0200 Subject: [PATCH] Bin to Yaml conversions --- radio/src/CMakeLists.txt | 5 +- radio/src/myeeprom.h | 6 +- radio/src/storage/conversions/conversions.cpp | 30 ++++++-- radio/src/storage/modelslist.cpp | 75 ++++++++++++------- radio/src/storage/modelslist.h | 5 ++ radio/src/storage/sdcard_common.cpp | 1 + radio/src/storage/sdcard_raw.cpp | 4 +- radio/src/storage/sdcard_raw.h | 15 +++- radio/src/storage/sdcard_yaml.cpp | 43 +++++++++-- radio/src/storage/sdcard_yaml.h | 24 ++++++ 10 files changed, 162 insertions(+), 46 deletions(-) create mode 100644 radio/src/storage/sdcard_yaml.h diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 532e28b32..6423d3575 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -57,7 +57,7 @@ option(TBS_RELEASE "Used to build TBS released firmware" OFF) option(IMRC_RELEASE "Used to build IMRC released firmware" OFF) option(HARDWARE_TRAINER_MULTI "Allow multi trainer" OFF) option(BOOTLOADER "Include Bootloader" ON) -option(YAML_STORAGE "Enable YAML storage" NO) +option(YAML_STORAGE "Enable YAML storage" OFF) # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -160,12 +160,9 @@ if(${STORAGE} STREQUAL SDCARD) set(SRC ${SRC} storage/sdcard_raw.cpp) add_definitions(-DSDCARD_RAW) elseif(${STORAGE_FORMAT} STREQUAL YAML) - # TODO: how do we check if the conversions - # should be done from SD card or EEPROM? set(SRC ${SRC} storage/sdcard_yaml.cpp storage/sdcard_raw.cpp) add_definitions(-DSDCARD_YAML) include(storage/yaml/CMakeLists.txt) - #add_subdirectory(storage/yaml) endif() elseif(${STORAGE} STREQUAL EEPROM) set(SRC ${SRC} storage/eeprom_common.cpp) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 56ab0a560..47b36c773 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -25,7 +25,11 @@ #include "datastructs.h" #include "libopenui/src/bitfield.h" -#define EEPROM_VER 220 +#if defined(SDCARD_YAML) + #define EEPROM_VER 255 +#else + #define EEPROM_VER 220 +#endif #define FIRST_CONV_EEPROM_VER 219 #define GET_MODULE_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol diff --git a/radio/src/storage/conversions/conversions.cpp b/radio/src/storage/conversions/conversions.cpp index b638f9898..456420c38 100644 --- a/radio/src/storage/conversions/conversions.cpp +++ b/radio/src/storage/conversions/conversions.cpp @@ -25,6 +25,8 @@ #if defined(COLORLCD) #include "storage/modelslist.h" #include "storage/sdcard_common.h" +#include "storage/sdcard_raw.h" +#include "storage/sdcard_yaml.h" static void drawProgressScreen(const char* filename, int progress, int total) { @@ -73,9 +75,11 @@ void convertRadioData(int version) if (version == 219) { convertRadioData_219_to_220(g_eeGeneral); storageDirty(EE_GENERAL); - storageCheck(true); } #endif + g_eeGeneral.version = EEPROM_VER; + storageDirty(EE_GENERAL); + storageCheck(true); converted++; #if defined(SIMU) @@ -87,22 +91,32 @@ void convertRadioData(int version) for (auto model_ptr : *category_ptr) { uint8_t model_version; - const char* filename = model_ptr->modelFilename; + char* filename = model_ptr->modelFilename; TRACE("converting '%s' (%d/%d)", filename, converted, to_convert); drawProgressScreen(filename, converted, to_convert); - error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model), &model_version); + error = readModelBin(filename, (uint8_t *)&g_model, sizeof(g_model), &model_version); if (!error) { convertModelData(model_version); +#if defined(SDCARD_YAML) + //TODO: convert filename & output to YAML directly + const char* ext = strrchr(filename, '.'); + if ((ext != nullptr) && !strncmp(ext, MODELS_EXT, 4)) { + memcpy((void*)ext, (void*)YAML_EXT, sizeof(YAML_EXT) - 1); + } + if (!strncmp(filename, g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME)) { + strncpy(g_eeGeneral.currModelFilename, filename, LEN_MODEL_FILENAME+1); + } + error = writeModelYaml(filename); +#else char path[256]; getModelPath(path, filename); - //TODO: if YAML is used, output to YAML directly error = writeFileBin(path, (uint8_t *)&g_model, sizeof(g_model)); - +#endif //TODO: what should be done with this error? } @@ -114,6 +128,12 @@ void convertRadioData(int version) } } +#if defined(SDCARD_YAML) + modelslist.save(); + storageDirty(EE_GENERAL); + storageCheck(true); +#endif + // reload models list modelslist.clear(); modelslist.load(); diff --git a/radio/src/storage/modelslist.cpp b/radio/src/storage/modelslist.cpp index 4430d2104..b2010d07d 100644 --- a/radio/src/storage/modelslist.cpp +++ b/radio/src/storage/modelslist.cpp @@ -136,7 +136,7 @@ bool ModelCell::fetchRfData() uint16_t size; uint8_t version; - const char * err = openFile(buf, &file, &size, &version); + const char * err = openFileBin(buf, &file, &size, &version); if (err || version != EEPROM_VER) return false; FSIZE_t start_offset = f_tell(&file); @@ -299,23 +299,15 @@ void ModelsList::clear() init(); } -bool ModelsList::load() +bool ModelsList::loadTxt() { char line[LEN_MODELS_IDX_LINE+1]; ModelsCategory * category = nullptr; ModelCell * model = nullptr; - if (loaded) - return true; - -#if !defined(SDCARD_YAML) FRESULT result = f_open(&file, RADIO_MODELSLIST_PATH, FA_OPEN_EXISTING | FA_READ); -#else - FRESULT result = f_open(&file, RADIO_MODELSLIST_YAML_PATH, FA_OPEN_EXISTING | FA_READ); -#endif if (result == FR_OK) { -#if !defined(SDCARD_YAML) // TXT reader while (readNextLine(line, LEN_MODELS_IDX_LINE)) { int len = strlen(line); // TODO could be returned by readNextLine @@ -339,7 +331,20 @@ bool ModelsList::load() modelsCount += 1; } } -#else + + f_close(&file); + return true; + } + + return false; +} + +#if defined(SDCARD_YAML) +bool ModelsList::loadYaml() +{ + char line[LEN_MODELS_IDX_LINE+1]; + FRESULT result = f_open(&file, RADIO_MODELSLIST_YAML_PATH, FA_OPEN_EXISTING | FA_READ); + if (result == FR_OK) { // YAML reader TRACE("YAML modelslist reader"); @@ -357,26 +362,45 @@ bool ModelsList::load() break; } - // debug output - //modelslist.dump(); -#endif - f_close(&file); + return true; } + return false; +} +#endif + +bool ModelsList::load() +{ + if (loaded) + return true; + + bool res = false; +#if !defined(SDCARD_YAML) + res = loadTxt(); +#else + FILINFO fno; + if (f_stat(RADIO_MODELSLIST_YAML_PATH, &fno) != FR_OK) { + res = loadTxt(); + } else { + res = loadYaml(); + } +#endif + if (!currentModel) { - if (model) { - currentModel = model; + if (categories.empty()) { + currentCategory = new ModelsCategory("Models"); + categories.push_back(currentCategory); + } else { + currentCategory = *categories.begin(); + if (!currentCategory->empty()) { + currentModel = *currentCategory->begin(); + } } - else { - category = new ModelsCategory("Models"); - categories.push_back(category); - } - currentCategory = category; } loaded = true; - return true; + return res; } void ModelsList::save() @@ -386,10 +410,7 @@ void ModelsList::save() #else FRESULT result = f_open(&file, RADIO_MODELSLIST_YAML_PATH, FA_CREATE_ALWAYS | FA_WRITE); #endif - - if (result != FR_OK) { - return; - } + if (result != FR_OK) return; for (list::iterator it = categories.begin(); it != categories.end(); ++it) { diff --git a/radio/src/storage/modelslist.h b/radio/src/storage/modelslist.h index 3551f73c5..42c16c400 100644 --- a/radio/src/storage/modelslist.h +++ b/radio/src/storage/modelslist.h @@ -157,6 +157,11 @@ public: protected: FIL file; + + bool loadTxt(); +#if defined(SDCARD_YAML) + bool loadYaml(); +#endif }; extern ModelsList modelslist; diff --git a/radio/src/storage/sdcard_common.cpp b/radio/src/storage/sdcard_common.cpp index 0ffb78699..b0c0de252 100644 --- a/radio/src/storage/sdcard_common.cpp +++ b/radio/src/storage/sdcard_common.cpp @@ -158,6 +158,7 @@ void storageReadAll() if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) { currentLanguagePackIdx = i; currentLanguagePack = languagePacks[i]; + break; } } diff --git a/radio/src/storage/sdcard_raw.cpp b/radio/src/storage/sdcard_raw.cpp index ff5a2c8e8..dcb5c24dc 100644 --- a/radio/src/storage/sdcard_raw.cpp +++ b/radio/src/storage/sdcard_raw.cpp @@ -170,7 +170,8 @@ const char * writeGeneralSettingsBin() return writeFileBin(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral)); } -void storageCreateModelsListBin() +#if !defined(SDCARD_YAML) +void storageCreateModelsList() { FIL file; @@ -180,3 +181,4 @@ void storageCreateModelsListBin() f_close(&file); } } +#endif diff --git a/radio/src/storage/sdcard_raw.h b/radio/src/storage/sdcard_raw.h index 7ac88873b..09d904a45 100644 --- a/radio/src/storage/sdcard_raw.h +++ b/radio/src/storage/sdcard_raw.h @@ -24,6 +24,19 @@ #include "FatFs/ff.h" -//const char * openFileBin(const char * fullpath, FIL* file, uint16_t* size); +#if !defined(SDCARD_YAML) +#define writeModel writeModelBin +#define loadRadioSettings loadRadioSettingsBin +#define writeGeneralSettings writeGeneralSettingsBin +#define readModel readModelBin +#endif + +const char* loadRadioSettingsBin(); +const char * writeGeneralSettingsBin(); + +const char* openFileBin(const char * fullpath, FIL * file, uint16_t * size, uint8_t * version); +const char* readModelBin(const char* filename, uint8_t* buffer, uint32_t size, + uint8_t* version); +const char * writeModelBin(); #endif diff --git a/radio/src/storage/sdcard_yaml.cpp b/radio/src/storage/sdcard_yaml.cpp index a6cc1c7a3..add78d309 100644 --- a/radio/src/storage/sdcard_yaml.cpp +++ b/radio/src/storage/sdcard_yaml.cpp @@ -22,6 +22,7 @@ #include "opentx.h" #include "storage.h" #include "sdcard_common.h" +#include "sdcard_raw.h" #include "modelslist.h" @@ -74,8 +75,7 @@ void storageCreateModelsList() // SDCARD storage interface // - -const char * loadRadioSettings() +const char * loadRadioSettingsYaml() { // YAML reader TRACE("YAML radio settings reader"); @@ -86,6 +86,16 @@ const char * loadRadioSettings() return readYamlFile(RADIO_SETTINGS_YAML_PATH, YamlTreeWalker::get_parser_calls(), &tree); } +const char * loadRadioSettings() +{ + FILINFO fno; + if (f_stat(RADIO_SETTINGS_YAML_PATH, &fno) != FR_OK) { + return loadRadioSettingsBin(); + } + + return loadRadioSettingsYaml(); +} + struct yaml_writer_ctx { FIL* file; FRESULT result; @@ -133,7 +143,7 @@ const char * writeGeneralSettings() } -const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, uint8_t * version) +const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t size, uint8_t * version) { // YAML reader TRACE("YAML model reader"); @@ -159,7 +169,7 @@ const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, u // wipe memory before reading YAML memset(buffer,0,size); - //#if defined(FLIGHT_MODES) && defined(GVARS) +#if defined(FLIGHT_MODES) && defined(GVARS) // reset GVars to default values // Note: taken from opentx.cpp::modelDefault() //TODO: new func in gvars @@ -168,19 +178,33 @@ const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, u g_model.flightModeData[p].gvars[i] = GVAR_MAX+1; } } - //#endif +#endif *version = 255; // max version number return readYamlFile(path, YamlTreeWalker::get_parser_calls(), &tree); } -const char * writeModel() +const char* readModel(const char* filename, uint8_t* buffer, uint32_t size, + uint8_t* version) +{ + const char* ext = strrchr(filename, '.'); + if (ext != nullptr) { + if (!strncmp(ext, YAML_EXT, 4)) { + return readModelYaml(filename, buffer, size, version); + } + + return readModelBin(filename, buffer, size, version); + } + return nullptr; +} + +const char * writeModelYaml(const char* filename) { // YAML reader TRACE("YAML model writer"); char path[256]; - getModelPath(path, g_eeGeneral.currModelFilename); + getModelPath(path, filename); FIL file; @@ -206,3 +230,8 @@ const char * writeModel() f_close(&file); return NULL; } + +const char * writeModel() +{ + return writeModelYaml(g_eeGeneral.currModelFilename); +} diff --git a/radio/src/storage/sdcard_yaml.h b/radio/src/storage/sdcard_yaml.h new file mode 100644 index 000000000..9b39edb7e --- /dev/null +++ b/radio/src/storage/sdcard_yaml.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * 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. + */ + +#pragma once + +const char * writeModelYaml(const char* filename);