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 <neilh713@tpg.com.au>
This commit is contained in:
Peter Feerick
2023-08-16 10:11:31 +10:00
committed by GitHub
co-authored by elecpower
parent 1177891750
commit 50bbea48bd
15 changed files with 421 additions and 136 deletions
+2
View File
@@ -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"
+193 -71
View File
@@ -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);
}
}
+5 -1
View File
@@ -26,6 +26,7 @@
#include <QString>
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;
+23
View File
@@ -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();
}
+43 -16
View File
@@ -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<StringTagMapping> 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);
}
@@ -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<CalibData>::decode(const Node& node, CalibData& rhs)
Node convert<YamlCalibData>::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<YamlCalibData>::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;
}
@@ -32,8 +32,6 @@
#include <QMessageBox>
SemanticVersion radioSettingsVersion;
const YamlLookupTable beeperModeLut = {
{ GeneralSettings::BEEPER_QUIET, "mode_quiet" },
{ GeneralSettings::BEEPER_ALARMS_ONLY, "mode_alarms" },
@@ -150,13 +148,14 @@ Node convert<GeneralSettings>::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<GeneralSettings>::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<GeneralSettings>::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<GeneralSettings>::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;
@@ -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<ModelData>::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<ModelData>::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<ModelData>::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];
+5 -2
View File
@@ -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;
}
@@ -23,6 +23,7 @@
#include <yaml-cpp/yaml.h>
#include <algorithm>
#include <QString>
#include "helpers.h"
typedef std::pair<int, std::string> YamlLookupTableElmt;
typedef std::vector<YamlLookupTableElmt> YamlLookupTable;
@@ -171,3 +172,6 @@ struct convert_enum
return convert_enum<enum_type>::decode(node, lut, rhs); \
} \
}
extern SemanticVersion radioSettingsVersion;
extern SemanticVersion modelSettingsVersion;
@@ -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);
@@ -88,7 +88,7 @@ struct YamlPotLookup {
static std::string idx2name(unsigned int idx);
};
extern const YamlLookupTable potConfigLut;
typedef YamlKnobConfig<CPN_MAX_POTS, YamlPotLookup, potConfigLut> YamlPotConfig;
typedef YamlKnobConfig<CPN_MAX_POTS + CPN_MAX_SLIDERS, YamlPotLookup, potConfigLut> YamlPotConfig;
// S1:
// type: with_detent
+8 -1
View File
@@ -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;
+14
View File
@@ -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) {
+2
View File
@@ -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);