From 50bbea48bddca2789acc77612b2daf428fa23d32 Mon Sep 17 00:00:00 2001 From: Peter Feerick Date: Wed, 16 Aug 2023 10:11:31 +1000 Subject: [PATCH] fix(cpn): Radio settings yaml for adc refactor (#3862) * Remove commented lines * Restrict calibration to sticks, pots and sliders * Fix pots and sliders config to support pre and post adc refactor * fix: pfeerick sucks at rebases * chore: Add more bits missed during rebase * chore(cpn): use adc version constant * fix(cpn): calibration encode mapping --------- Co-authored-by: elecpower --- companion/src/constants.h | 2 + companion/src/firmwares/boards.cpp | 264 +++++++++++++----- companion/src/firmwares/boards.h | 6 +- companion/src/firmwares/datahelpers.cpp | 23 ++ companion/src/firmwares/datahelpers.h | 59 ++-- .../src/firmwares/edgetx/yaml_calibdata.cpp | 44 ++- .../firmwares/edgetx/yaml_generalsettings.cpp | 78 ++++-- .../src/firmwares/edgetx/yaml_modeldata.cpp | 17 +- companion/src/firmwares/edgetx/yaml_ops.cpp | 7 +- companion/src/firmwares/edgetx/yaml_ops.h | 4 + .../firmwares/edgetx/yaml_switchconfig.cpp | 26 +- .../src/firmwares/edgetx/yaml_switchconfig.h | 2 +- companion/src/firmwares/eeprominterface.h | 9 +- companion/src/helpers.cpp | 14 + companion/src/helpers.h | 2 + 15 files changed, 421 insertions(+), 136 deletions(-) diff --git a/companion/src/constants.h b/companion/src/constants.h index 77a4dd45e..85c4da333 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -85,3 +85,5 @@ #define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator. #define EDGETX_HOME_PAGE_URL "https://edgetx.org" + +#define CPN_ADC_REFACTOR_VERSION "2.10.0" diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 0a6926f47..87baaaa6a 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -22,6 +22,7 @@ #include "macros.h" #include "compounditemmodels.h" #include "moduledata.h" +#include "helpers.h" // TODO remove all those constants // Update: These are now all only used within this class. @@ -594,17 +595,29 @@ QString Boards::getAxisName(int index) return CPN_STR_UNKNOWN_ITEM; } -StringTagMappingTable Boards::getAnalogNamesLookupTable(Board::Type board) +StringTagMappingTable Boards::getAnalogNamesLookupTable(Board::Type board, const QString strVersion) { + SemanticVersion version(strVersion); + SemanticVersion adcVersion(QString(CPN_ADC_REFACTOR_VERSION)); + StringTagMappingTable tbl; if (getBoardCapability(board, Board::Sticks)) { - tbl.insert(tbl.end(), { - {tr("Rud").toStdString(), "Rud"}, - {tr("Ele").toStdString(), "Ele"}, - {tr("Thr").toStdString(), "Thr"}, - {tr("Ail").toStdString(), "Ail"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("Rud").toStdString(), "Rud"}, + {tr("Ele").toStdString(), "Ele"}, + {tr("Thr").toStdString(), "Thr"}, + {tr("Ail").toStdString(), "Ail"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("Rud").toStdString(), "LH", 0}, + {tr("Ele").toStdString(), "LV", 1}, + {tr("Thr").toStdString(), "RH", 2}, + {tr("Ail").toStdString(), "RV", 3}, + }); + } } if (IS_SKY9X(board)) { @@ -614,77 +627,162 @@ StringTagMappingTable Boards::getAnalogNamesLookupTable(Board::Type board) {tr("P3").toStdString(), "P3"}, }); } else if (IS_TARANIS_X9LITE(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "S1"}, - {tr("POT1").toStdString(), "POT1"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "S1"}, + {tr("POT1").toStdString(), "POT1"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + }); + } } else if (IS_TARANIS_X9E(board)) { - tbl.insert(tbl.end(), { - {tr("F1").toStdString(), "POT1"}, - {tr("F2").toStdString(), "POT2"}, - {tr("F3").toStdString(), "POT3"}, - {tr("F4").toStdString(), "POT4"}, - {tr("S1").toStdString(), "SLIDER1"}, - {tr("S2").toStdString(), "SLIDER2"}, - {tr("LS").toStdString(), "SLIDER3"}, - {tr("RS").toStdString(), "SLIDER4"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("F1").toStdString(), "POT1"}, + {tr("F2").toStdString(), "POT2"}, + {tr("F3").toStdString(), "POT3"}, + {tr("F4").toStdString(), "POT4"}, + {tr("S1").toStdString(), "SLIDER1"}, + {tr("S2").toStdString(), "SLIDER2"}, + {tr("LS").toStdString(), "SLIDER3"}, + {tr("RS").toStdString(), "SLIDER4"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("F1").toStdString(), "P1", 4}, + {tr("F2").toStdString(), "P2", 5}, + {tr("S1").toStdString(), "SL3", 8}, + {tr("S2").toStdString(), "SL4", 9}, + {tr("LS").toStdString(), "SL1", 6}, + {tr("RS").toStdString(), "SL2", 7}, + }); + } } else if (IS_TARANIS_XLITES(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "POT1"}, - {tr("S2").toStdString(), "POT2"}, - {tr("TltX").toStdString(), "TILT_X"}, - {tr("TltY").toStdString(), "TILT_Y"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "POT1"}, + {tr("S2").toStdString(), "POT2"}, + {tr("TltX").toStdString(), "TILT_X"}, + {tr("TltY").toStdString(), "TILT_Y"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("S2").toStdString(), "P2", 5}, + {tr("TltX").toStdString(), "TILT_X", 6}, + {tr("TltY").toStdString(), "TILT_Y", 7}, + }); + } } else if (IS_RADIOMASTER_BOXER(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "POT1"}, - {tr("S2").toStdString(), "POT2"}, - {tr("S3").toStdString(), "POT3"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "POT1"}, + {tr("S2").toStdString(), "POT2"}, + {tr("S3").toStdString(), "POT3"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("S2").toStdString(), "P2", 5}, + {tr("S3").toStdString(), "P3", 6}, + }); + } } else if ((IS_TARANIS_SMALL(board) && !IS_JUMPER_TLITE(board)) || IS_FLYSKY_NV14(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "POT1"}, - {tr("S2").toStdString(), "POT2"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "POT1"}, + {tr("S2").toStdString(), "POT2"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("S2").toStdString(), "P2", 5}, + }); + } } else if (IS_TARANIS_X9(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "POT1"}, - {tr("S2").toStdString(), "POT2"}, - {tr("S3").toStdString(), "POT3"}, - {tr("LS").toStdString(), "SLIDER1"}, - {tr("RS").toStdString(), "SLIDER2"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "POT1"}, + {tr("S2").toStdString(), "POT2"}, + {tr("S3").toStdString(), "POT3"}, + {tr("LS").toStdString(), "SLIDER1"}, + {tr("RS").toStdString(), "SLIDER2"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("S2").toStdString(), "P2", 5}, + {tr("S3").toStdString(), "P3", 6}, + {tr("LS").toStdString(), "SL1", 7}, + {tr("RS").toStdString(), "SL2", 8}, + }); + } } else if (IS_HORUS_X12S(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "S1"}, - {tr("6P").toStdString(), "6POS"}, - {tr("S2").toStdString(), "S2"}, - {tr("L1").toStdString(), "S3"}, - {tr("L2").toStdString(), "S4"}, - {tr("LS").toStdString(), "LS"}, - {tr("RS").toStdString(), "RS"}, - {tr("JSx").toStdString(), "MOUSE1"}, - {tr("JSy").toStdString(), "MOUSE2"}, - {tr("TltX").toStdString(), "TILT_X"}, - {tr("TltY").toStdString(), "TILT_Y"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "S1"}, + {tr("6P").toStdString(), "6POS"}, + {tr("S2").toStdString(), "S2"}, + {tr("L1").toStdString(), "S3"}, + {tr("L2").toStdString(), "S4"}, + {tr("LS").toStdString(), "LS"}, + {tr("RS").toStdString(), "RS"}, + {tr("JSx").toStdString(), "MOUSE1"}, + {tr("JSy").toStdString(), "MOUSE2"}, + {tr("TltX").toStdString(), "TILT_X"}, + {tr("TltY").toStdString(), "TILT_Y"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("6POS").toStdString(), "P2", 5}, + {tr("S2").toStdString(), "P3", 6}, + {tr("L1").toStdString(), "SL3", 9}, + {tr("L2").toStdString(), "SL4", 10}, + {tr("LS").toStdString(), "SL1", 7}, + {tr("RS").toStdString(), "SL2", 8}, + {tr("JSx").toStdString(), "JSx", 11}, + {tr("JSy").toStdString(), "JSy", 12}, + {tr("TltX").toStdString(), "TILT_X", 13}, + {tr("TltY").toStdString(), "TILT_Y", 14}, + }); + } } else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) { - tbl.insert(tbl.end(), { - {tr("S1").toStdString(), "S1"}, - {tr("6P").toStdString(), "6POS"}, - {tr("S2").toStdString(), "S2"}, - {tr("EX1").toStdString(), "EXT1"}, - {tr("EX2").toStdString(), "EXT2"}, - {tr("EX3").toStdString(), "EXT3"}, - {tr("EX4").toStdString(), "EXT4"}, - {tr("LS").toStdString(), "LS"}, - {tr("RS").toStdString(), "RS"}, - {tr("JSx").toStdString(), "MOUSE1"}, - {tr("JSy").toStdString(), "MOUSE2"}, - {tr("TltX").toStdString(), "TILT_X"}, - {tr("TltY").toStdString(), "TILT_Y"}, - }); + if (version < adcVersion) { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "S1"}, + {tr("6P").toStdString(), "6POS"}, + {tr("S2").toStdString(), "S2"}, + {tr("EX1").toStdString(), "EXT1"}, + {tr("EX2").toStdString(), "EXT2"}, + {tr("EX3").toStdString(), "EXT3"}, + {tr("EX4").toStdString(), "EXT4"}, + {tr("LS").toStdString(), "LS"}, + {tr("RS").toStdString(), "RS"}, + {tr("JSx").toStdString(), "MOUSE1"}, + {tr("JSy").toStdString(), "MOUSE2"}, + {tr("TltX").toStdString(), "TILT_X"}, + {tr("TltY").toStdString(), "TILT_Y"}, + }); + } else { + tbl.insert(tbl.end(), { + {tr("S1").toStdString(), "P1", 4}, + {tr("6POS").toStdString(), "P2", 5}, + {tr("S2").toStdString(), "P3", 6}, + {tr("EXT1").toStdString(), "EXT1", 9}, + {tr("EXT2").toStdString(), "EXT2", 10}, + {tr("EXT3").toStdString(), "EXT3", 11}, + {tr("EXT4").toStdString(), "EXT4", 12}, + {tr("LS").toStdString(), "SL1", 7}, + {tr("RS").toStdString(), "SL2", 8}, + {tr("JSx").toStdString(), "JSx", 13}, + {tr("JSy").toStdString(), "JSy", 14}, + {tr("TltX").toStdString(), "TILT_X", 15}, + {tr("TltY").toStdString(), "TILT_Y", 16}, + }); + } } return tbl; @@ -1051,3 +1149,27 @@ AbstractStaticItemModel * Boards::externalModuleSizeItemModel() mdl->loadItemList(); return mdl; } + +// EdgeTX 2.10.0 ADC refactor changed order of pots and sliders that affected interpretation of model warnings +// This conversion needs to be revisited when Companion is refactored to use ADC radio defns +// Make ADC orders backwards compatible + +// the values below are based on radio\src\util\hw_defns\pots_config.py + +// static +int Boards::adcPotsBeforeSliders(Board::Type board, SemanticVersion version) +{ + if (version >= SemanticVersion(CPN_ADC_REFACTOR_VERSION)) { + if (IS_TARANIS_X9(board) || IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board) || IS_RADIOMASTER_BOXER(board)) + return 3; + else if (IS_TARANIS_X9LITE(board)) + return 1; + else if (IS_JUMPER_TLITE(board) || IS_BETAFPV_LR3PRO(board) || IS_IFLIGHT_COMMANDO8(board)) + return 0; + else + return 2; + } + else { + return getCapability(board, Board::Pots); + } +} diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index c2ec9e94d..c38b10601 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -26,6 +26,7 @@ #include class AbstractStaticItemModel; +class SemanticVersion; // identiying names of static abstract item models constexpr char AIM_BOARDS_POT_TYPE[] {"boards.pottype"}; @@ -224,7 +225,7 @@ class Boards static StringTagMappingTable getSwitchesLookupTable(Board::Type board); static int getCapability(Board::Type board, Board::Capability capability); static QString getAxisName(int index); - static StringTagMappingTable getAnalogNamesLookupTable(Board::Type board); + static StringTagMappingTable getAnalogNamesLookupTable(Board::Type board, const QString strVersion = "0.0.0"); static QString getAnalogInputName(Board::Type board, int index); static bool isBoardCompatible(Board::Type board1, Board::Type board2); static QString getBoardName(Board::Type board); @@ -243,6 +244,9 @@ class Boards static QString externalModuleSizeToString(int value); static AbstractStaticItemModel * externalModuleSizeItemModel(); + // TODO replace when refactored to support json defns + static int adcPotsBeforeSliders(Board::Type board, SemanticVersion version); + protected: Board::Type m_boardType; diff --git a/companion/src/firmwares/datahelpers.cpp b/companion/src/firmwares/datahelpers.cpp index a7003d75b..8dc6237e2 100644 --- a/companion/src/firmwares/datahelpers.cpp +++ b/companion/src/firmwares/datahelpers.cpp @@ -91,3 +91,26 @@ std::string DataHelpers::getStringTagMappingTag(const StringTagMappingTable& lut return std::string(); } + +int DataHelpers::getStringTagMappingSeq(const StringTagMappingTable& lut, unsigned int index) +{ + if (index < lut.size()) + return lut[index].seq; + + return -1; +} + +std::string DataHelpers::getStringSeqMappingTag(const StringTagMappingTable& lut, unsigned int seq) +{ + const auto it = + find_if(lut.begin(), lut.end(), [=](const StringTagMapping& elmt) { + if (elmt.seq == seq) return true; + return false; + }); + + if (it != lut.end()) { + return it->tag; + } + + return std::string(); +} diff --git a/companion/src/firmwares/datahelpers.h b/companion/src/firmwares/datahelpers.h index 07d7609e0..b4512b7cc 100644 --- a/companion/src/firmwares/datahelpers.h +++ b/companion/src/firmwares/datahelpers.h @@ -27,40 +27,65 @@ struct StringTagMapping { std::string name; std::string tag; + unsigned int seq; StringTagMapping() = default; StringTagMapping(const char* name) : - name(name), tag(name) + name(name), tag(name), seq(0) { } StringTagMapping(const std::string& name) : - name(name), tag(name) + name(name), tag(name), seq(0) { } - StringTagMapping(const char* name, const char* tag) : - name(name), tag(tag) + StringTagMapping(const char* name, const char* tag, const unsigned int seq = 0) : + name(name), tag(tag), seq(seq) { } - StringTagMapping(const std::string& name, const std::string& tag) : - name(name), tag(tag) + StringTagMapping(const std::string& name, const std::string& tag, const unsigned int seq = 0) : + name(name), tag(tag), seq(seq) { } }; typedef std::vector StringTagMappingTable; -#define STRINGTAGMAPPINGFUNCS_HELPER(tbl, name, index, tag) \ - inline int name##index (const char * tag) \ - { \ - return DataHelpers::getStringTagMappingIndex(tbl, tag); \ - } \ - \ - inline std::string name##tag (unsigned int index) \ - { \ - return DataHelpers::getStringTagMappingTag(tbl, index); \ +#define STRINGTAGMAPPINGFUNCS_HELPER(tbl, name) \ + inline int name##Index (const char * tag) \ + { \ + return DataHelpers::getStringTagMappingIndex(tbl, tag); \ + } \ + \ + inline std::string name##Tag (unsigned int index) \ + { \ + return DataHelpers::getStringTagMappingTag(tbl, index); \ } -#define STRINGTAGMAPPINGFUNCS(tbl, name) STRINGTAGMAPPINGFUNCS_HELPER(tbl, get##name, Index, Tag) +#define STRINGTAGMAPPINGFUNCS_ADC_HELPER(tbl, tbladc, name) \ + STRINGTAGMAPPINGFUNCS_HELPER(tbl, name) \ + \ + inline int name##IndexADC (const char * tag) \ + { \ + return DataHelpers::getStringTagMappingIndex(tbladc, tag); \ + } \ + \ + inline std::string name##TagADC (unsigned int index) \ + { \ + return DataHelpers::getStringTagMappingTag(tbladc, index); \ + } \ + \ + inline int name##SeqADC (unsigned int index) \ + { \ + return DataHelpers::getStringTagMappingSeq(tbladc, index); \ + } \ + \ + inline std::string name##SeqTagADC (unsigned int seq) \ + { \ + return DataHelpers::getStringSeqMappingTag(tbladc, seq); \ + } + +#define STRINGTAGMAPPINGFUNCS(tbl, name) STRINGTAGMAPPINGFUNCS_HELPER(tbl, get##name) +#define STRINGTAGMAPPINGFUNCS_ADC(tbl, tbladc, name) STRINGTAGMAPPINGFUNCS_ADC_HELPER(tbl, tbladc, get##name) class FieldRange { @@ -107,4 +132,6 @@ namespace DataHelpers QString timeToString(const int value, const unsigned int mask); int getStringTagMappingIndex(const StringTagMappingTable& lut, const char * tag); std::string getStringTagMappingTag(const StringTagMappingTable& lut, unsigned int index); + int getStringTagMappingSeq(const StringTagMappingTable& lut, unsigned int index); + std::string getStringSeqMappingTag(const StringTagMappingTable& lut, unsigned int seq); } diff --git a/companion/src/firmwares/edgetx/yaml_calibdata.cpp b/companion/src/firmwares/edgetx/yaml_calibdata.cpp index 32f0b2000..44519e7a0 100644 --- a/companion/src/firmwares/edgetx/yaml_calibdata.cpp +++ b/companion/src/firmwares/edgetx/yaml_calibdata.cpp @@ -21,15 +21,21 @@ #include "yaml_calibdata.h" #include "eeprominterface.h" -YamlCalibData::YamlCalibData() { memset(calib, 0, sizeof(calib)); } +YamlCalibData::YamlCalibData() +{ + memset(calib, 0, sizeof(calib)); +} YamlCalibData::YamlCalibData(const int* calibMid, const int* calibSpanNeg, const int* calibSpanPos) { for (int i = 0; i < CPN_MAX_ANALOGS; i++) { - calib[i].mid = calibMid[i]; - calib[i].spanNeg = calibSpanNeg[i]; - calib[i].spanPos = calibSpanPos[i]; + int seq = getCurrentFirmware()->getAnalogInputSeqADC(i); + if (seq >= 0 && seq < CPN_MAX_ANALOGS) { + calib[seq].mid = calibMid[i]; + calib[seq].spanNeg = calibSpanNeg[i]; + calib[seq].spanPos = calibSpanPos[i]; + } } } @@ -67,10 +73,21 @@ bool convert::decode(const Node& node, CalibData& rhs) Node convert::encode(const YamlCalibData& rhs) { Node node; - int idx = 0; - const auto* calibIdxLut = getCurrentFirmware()->getAnalogIndexNamesLookupTable(); - for (const auto& kv : *calibIdxLut) { - node[kv.tag] = rhs.calib[idx++]; + auto fw = getCurrentFirmware(); + auto board = fw->getBoard(); + const auto* calibIdxLut = fw->getAnalogIndexNamesLookupTableADC(); + const int calibs = Boards::getCapability(board, Board::Sticks) + + Boards::getCapability(board, Board::Pots) + + Boards::getCapability(board, Board::Sliders); + for (int i = 0; i < calibs; i++) { + for (int j = 0; j < (int)calibIdxLut->size(); j++) { + int seq = getCurrentFirmware()->getAnalogInputSeqADC(j); + if (seq == i) { + std::string tag = getCurrentFirmware()->getAnalogInputTagADC(j); + node[tag] = rhs.calib[seq]; + break; + } + } } return node; } @@ -82,10 +99,15 @@ bool convert::decode(const Node& node, YamlCalibData& rhs) for (const auto& kv : node) { std::string tag; kv.first >> tag; - int idx = getCurrentFirmware()->getAnalogInputIndex(tag.c_str()); - if (idx >= 0) { + int idx = 0; + + if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) + idx = getCurrentFirmware()->getAnalogInputIndex(tag.c_str()); + else + idx = getCurrentFirmware()->getAnalogInputIndexADC(tag.c_str()); + + if (idx >= 0) kv.second >> rhs.calib[idx]; - } } return true; } diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index a14ea419c..748d91c85 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -32,8 +32,6 @@ #include -SemanticVersion radioSettingsVersion; - const YamlLookupTable beeperModeLut = { { GeneralSettings::BEEPER_QUIET, "mode_quiet" }, { GeneralSettings::BEEPER_ALARMS_ONLY, "mode_alarms" }, @@ -150,13 +148,14 @@ Node convert::encode(const GeneralSettings& rhs) Node node; auto fw = getCurrentFirmware(); + auto board = fw->getBoard(); - bool hasColorLcd = Boards::getCapability(fw->getBoard(), Board::HasColorLcd); + bool hasColorLcd = Boards::getCapability(board, Board::HasColorLcd); node["semver"] = VERSION; - std::string board = fw->getFlavour().toStdString(); - node["board"] = board; + std::string strboard = fw->getFlavour().toStdString(); + node["board"] = strboard; YamlCalibData calib(rhs.calibMid, rhs.calibSpanNeg, rhs.calibSpanPos); node["calib"] = calib; @@ -264,17 +263,38 @@ Node convert::encode(const GeneralSettings& rhs) node["switchConfig"] = switchConfig; } - // combine pots and sliders into potsConfig - Node potsConfig; - potsConfig = YamlPotConfig(rhs.potName, rhs.potConfig); - if (potsConfig && potsConfig.IsMap()) { - node["potsConfig"] = potsConfig; + // TODO revisit when Companion refactored for adc + // adc encoding requires pots and sliders to be merged in a prescribed sequence as defined in radio json + int maxPots = CPN_MAX_POTS + CPN_MAX_SLIDERS; + char potName[maxPots][HARDWARE_NAME_LEN + 1]; + unsigned int potConfig[maxPots]; + + const int sticks = Boards::getCapability(board, Board::Sticks); + int adcoffset = sticks; + int seq = 0; + + for (int i = 0; i < Boards::getCapability(board, Board::Pots); i++) { + seq = getCurrentFirmware()->getAnalogInputSeqADC(adcoffset + i) - sticks; + if (seq >= 0 && seq < maxPots) { + strcpy(potName[seq], rhs.potName[i]); + potConfig[seq] = rhs.potConfig[i]; + } } - Node slidersConfig; - slidersConfig = YamlSliderConfig(rhs.sliderName, rhs.sliderConfig); - if (slidersConfig && slidersConfig.IsMap()) { - node["slidersConfig"] = slidersConfig; + adcoffset += Boards::getCapability(board, Board::Pots); + + for (int i = 0; i < Boards::getCapability(board, Board::Sliders); i++) { + seq = getCurrentFirmware()->getAnalogInputSeqADC(adcoffset + i) - sticks; + if (seq >= 0 && seq < maxPots) { + strcpy(potName[seq], rhs.sliderName[i]); + potConfig[seq] = rhs.sliderConfig[i]; + } + } + + Node potsConfig; + potsConfig = YamlPotConfig(potName, potConfig); + if (potsConfig && potsConfig.IsMap()) { + node["potsConfig"] = potsConfig; } // Color lcd theme settings are not used in EdgeTx @@ -361,6 +381,7 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) node["board"] >> flavour; auto fw = getCurrentFirmware(); + auto board = fw->getBoard(); qDebug() << "Settings version:" << rhs.semver << "File flavour:" << flavour.c_str() << "Firmware flavour:" << fw->getFlavour(); @@ -521,13 +542,34 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) node["switchConfig"] >> switchConfig; switchConfig.copy(rhs.switchName, rhs.switchConfig); + // TODO: revisit when Companion refactored to support adc + // adc pots and sliders decoded into a single array but Compapanion has separate arrays + int maxPots = CPN_MAX_POTS + CPN_MAX_SLIDERS; // must match YamlPotConfig declaration + char potName[maxPots][HARDWARE_NAME_LEN + 1]; + unsigned int potConfig[maxPots]; + YamlPotConfig potsConfig; node["potsConfig"] >> potsConfig; - potsConfig.copy(rhs.potName, rhs.potConfig); + potsConfig.copy(potName, potConfig); - YamlSliderConfig slidersConfig; - node["slidersConfig"] >> slidersConfig; - slidersConfig.copy(rhs.sliderName, rhs.sliderConfig); + int numPots = Boards::getCapability(board, Board::Pots); + + for (int i = 0; i < numPots; i++) { + strcpy(rhs.potName[i], potName[i]); + rhs.potConfig[i] = potConfig[i]; + } + + if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) { + YamlSliderConfig slidersConfig; + node["slidersConfig"] >> slidersConfig; + slidersConfig.copy(rhs.sliderName, rhs.sliderConfig); + } + else { + for (int i = 0; i < Boards::getCapability(board, Board::Sliders); i++) { + strcpy(rhs.sliderName[i], potName[numPots + i]); + rhs.sliderConfig[i] = potConfig[numPots + i]; + } + } // Color lcd theme settings are not used in EdgeTx // RadioTheme::ThemeData themeData; diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index aba2bd42f..1da4e3520 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -177,10 +177,9 @@ struct YamlPotsWarnEnabled { unsigned int value; const Board::Type board = getCurrentBoard(); - // modeldata potwarnen_t potsWarnEnabled const int maxradio = 8 * (int)(Boards::getCapability(board, Board::HasColorLcd) ? sizeof(uint16_t) : sizeof(uint8_t)); const int maxcpn = CPN_MAX_POTS + CPN_MAX_SLIDERS; - const int slidersStart = adcPotsBeforeSliders(); + const int slidersStart = Boards::adcPotsBeforeSliders(board, modelSettingsVersion); const int numpots = Boards::getCapability(board, Board::Pots); const int offset = numpots - slidersStart; @@ -229,11 +228,10 @@ struct YamlBeepANACenter { unsigned int value; const Board::Type board = getCurrentBoard(); - // modeldata BeepANACenter beepANACenter const int maxradio = 8 * (int)sizeof(uint16_t); const int numstickspots = CPN_MAX_STICKS + Boards::getCapability(board, Board::Pots); const int maxcpn = numstickspots + getBoardCapability(board, Board::Sliders); - const int slidersStart = CPN_MAX_STICKS + adcPotsBeforeSliders(); + const int slidersStart = CPN_MAX_STICKS + Boards::adcPotsBeforeSliders(board, modelSettingsVersion); const int offset = numstickspots - slidersStart; YamlBeepANACenter() = default; @@ -1154,12 +1152,12 @@ bool convert::decode(const Node& node, ModelData& rhs) unsigned int modelIds[CPN_MAX_MODULES]; memset(modelIds, 0, sizeof(modelIds)); - version = SemanticVersion(); + modelSettingsVersion = SemanticVersion(); if (node["semver"]) { node["semver"] >> rhs.semver; if (SemanticVersion().isValid(rhs.semver)) { - version = SemanticVersion(QString(rhs.semver)); + modelSettingsVersion = SemanticVersion(QString(rhs.semver)); } else { qDebug() << "Invalid settings version:" << rhs.semver; @@ -1167,9 +1165,9 @@ bool convert::decode(const Node& node, ModelData& rhs) } } - qDebug() << "Settings version:" << version.toString(); + qDebug() << "Settings version:" << modelSettingsVersion.toString(); - if (version > SemanticVersion(VERSION)) + if (modelSettingsVersion > SemanticVersion(VERSION)) qDebug() << "Warning: version not supported by Companion!"; if (node["header"]) { @@ -1371,7 +1369,8 @@ bool convert::decode(const Node& node, ModelData& rhs) // preferably perform conversions here to avoid cluttering the field decodes - if (version < SemanticVersion("2.8.0")) { + if (modelSettingsVersion < SemanticVersion("2.8.0")) + { // Cells 7 and 8 introduced requiring Highest and Delta to be shifted + 2 for (int i = 0; i < CPN_MAX_SENSORS; i++) { SensorData &sd = rhs.sensorData[i]; diff --git a/companion/src/firmwares/edgetx/yaml_ops.cpp b/companion/src/firmwares/edgetx/yaml_ops.cpp index c89aaea89..4d1302c03 100644 --- a/companion/src/firmwares/edgetx/yaml_ops.cpp +++ b/companion/src/firmwares/edgetx/yaml_ops.cpp @@ -20,6 +20,9 @@ #include "yaml_ops.h" +SemanticVersion radioSettingsVersion; +SemanticVersion modelSettingsVersion; + YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut) { if (node && node.IsScalar()) { @@ -32,7 +35,7 @@ YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut) if (it != lut.end()) { return YAML::Node(it->first); - } + } return YAML::Node(); } @@ -63,7 +66,7 @@ std::string LookupValue(const YamlLookupTable& lut, const int& value) if (elmt.first == value) return true; return false; }); - + if (it != lut.end()) { return it->second; } diff --git a/companion/src/firmwares/edgetx/yaml_ops.h b/companion/src/firmwares/edgetx/yaml_ops.h index 539db8b96..3b58b919e 100644 --- a/companion/src/firmwares/edgetx/yaml_ops.h +++ b/companion/src/firmwares/edgetx/yaml_ops.h @@ -23,6 +23,7 @@ #include #include #include +#include "helpers.h" typedef std::pair YamlLookupTableElmt; typedef std::vector YamlLookupTable; @@ -171,3 +172,6 @@ struct convert_enum return convert_enum::decode(node, lut, rhs); \ } \ } + +extern SemanticVersion radioSettingsVersion; +extern SemanticVersion modelSettingsVersion; diff --git a/companion/src/firmwares/edgetx/yaml_switchconfig.cpp b/companion/src/firmwares/edgetx/yaml_switchconfig.cpp index 7ab997c55..94b2b3e9b 100644 --- a/companion/src/firmwares/edgetx/yaml_switchconfig.cpp +++ b/companion/src/firmwares/edgetx/yaml_switchconfig.cpp @@ -90,7 +90,13 @@ std::string YamlSwitchLookup::idx2name(unsigned int idx) int YamlPotLookup::name2idx(const std::string& name) { auto fw = getCurrentFirmware(); - int idx = fw->getAnalogInputIndex(name.c_str()); + int idx = 0; + + if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) + idx = fw->getAnalogInputIndex(name.c_str()); + else + idx = fw->getAnalogInputIndexADC(name.c_str()); + if (idx < 0) return idx; int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks); @@ -98,7 +104,8 @@ int YamlPotLookup::name2idx(const std::string& name) idx -= sticks; int pots = Boards::getCapability(fw->getBoard(), Board::Pots); - if (idx >= pots) return -1; + int sliders = Boards::getCapability(fw->getBoard(), Board::Sliders); + if (idx >= pots + sliders) return -1; return idx; } @@ -106,17 +113,24 @@ int YamlPotLookup::name2idx(const std::string& name) std::string YamlPotLookup::idx2name(unsigned int idx) { auto fw = getCurrentFirmware(); - unsigned int pots = Boards::getCapability(fw->getBoard(), Board::Pots); + auto board = fw->getBoard(); + unsigned int pots = Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders); if (idx >= pots) return std::string(); - unsigned int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks); - return fw->getAnalogInputTag(idx + sticks); + unsigned int sticks = Boards::getCapability(board, Board::Sticks); + return fw->getAnalogInputSeqTagADC(idx + sticks); } int YamlSliderLookup::name2idx(const std::string& name) { auto fw = getCurrentFirmware(); - int idx = fw->getAnalogInputIndex(name.c_str()); + int idx = 0; + + if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) + idx = fw->getAnalogInputIndex(name.c_str()); + else + idx = fw->getAnalogInputIndexADC(name.c_str()); + if (idx < 0) return idx; int sticks = Boards::getCapability(fw->getBoard(), Board::Sticks); diff --git a/companion/src/firmwares/edgetx/yaml_switchconfig.h b/companion/src/firmwares/edgetx/yaml_switchconfig.h index cdd57ad9b..50d2765ff 100644 --- a/companion/src/firmwares/edgetx/yaml_switchconfig.h +++ b/companion/src/firmwares/edgetx/yaml_switchconfig.h @@ -88,7 +88,7 @@ struct YamlPotLookup { static std::string idx2name(unsigned int idx); }; extern const YamlLookupTable potConfigLut; -typedef YamlKnobConfig YamlPotConfig; +typedef YamlKnobConfig YamlPotConfig; // S1: // type: with_detent diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index 0aacb422a..710ee259f 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -300,6 +300,7 @@ class Firmware downloadId(downloadId), simulatorId(simulatorId), analogInputNamesLookupTable(Boards::getAnalogNamesLookupTable(board)), + analogInputNamesLookupTableADC(Boards::getAnalogNamesLookupTable(board, QString(CPN_ADC_REFACTOR_VERSION))), switchesLookupTable(Boards::getSwitchesLookupTable(board)), trimSwitchesLookupTable(Boards::getTrimSwitchesLookupTable(board)), trimSourcesLookupTable(Boards::getTrimSourcesLookupTable(board)), @@ -426,7 +427,12 @@ class Firmware return &analogInputNamesLookupTable; } - STRINGTAGMAPPINGFUNCS(analogInputNamesLookupTable, AnalogInput); + const StringTagMappingTable* getAnalogIndexNamesLookupTableADC() + { + return &analogInputNamesLookupTableADC; + } + + STRINGTAGMAPPINGFUNCS_ADC(analogInputNamesLookupTable, analogInputNamesLookupTableADC, AnalogInput); STRINGTAGMAPPINGFUNCS(switchesLookupTable, Switches); STRINGTAGMAPPINGFUNCS(trimSwitchesLookupTable, TrimSwitches); STRINGTAGMAPPINGFUNCS(trimSourcesLookupTable, TrimSources); @@ -449,6 +455,7 @@ class Firmware // used by YAML encode and decode const StringTagMappingTable analogInputNamesLookupTable; + const StringTagMappingTable analogInputNamesLookupTableADC; const StringTagMappingTable switchesLookupTable; const StringTagMappingTable trimSwitchesLookupTable; const StringTagMappingTable trimSourcesLookupTable; diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 178762554..faa57c7c5 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -884,6 +884,20 @@ QString SemanticVersion::toString() const return ret; } +bool SemanticVersion::isEmpty(const QString vers) +{ + fromString(vers); + return isEmpty(); +} + +bool SemanticVersion::isEmpty() +{ + if (toInt() == SemanticVersion().toInt() ) + return true; + else + return false; +} + int SemanticVersion::compare(const SemanticVersion& other) { if (version.major != other.version.major) { diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 4b1758174..6795918e3 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -260,6 +260,8 @@ class SemanticVersion QString toString() const; unsigned int toInt() const; bool fromInt(const unsigned int val); + bool isEmpty(const QString vers); + bool isEmpty(); SemanticVersion& operator=(const SemanticVersion& rhs);