diff --git a/companion/src/firmwares/customfunctiondata.h b/companion/src/firmwares/customfunctiondata.h index d4f824e8898..11ab8cb23ff 100644 --- a/companion/src/firmwares/customfunctiondata.h +++ b/companion/src/firmwares/customfunctiondata.h @@ -28,6 +28,8 @@ #include #include +#define CF_CUSTNAME_LEN 10 + class Firmware; class ModelData; class GeneralSettings; @@ -109,6 +111,7 @@ class CustomFunctionData { unsigned int enabled; // TODO perhaps not any more the right name unsigned int adjustMode; int repeatParam; + char custName[CF_CUSTNAME_LEN + 1]; void convert(RadioDataConversionState & cstate); diff --git a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp index f902e13bb5a..02be227efa1 100644 --- a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp +++ b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp @@ -257,6 +257,8 @@ Node convert::encode(const CustomFunctionData& rhs) node["def"] = def; } + node["custName"] = rhs.custName; + return node; } @@ -265,6 +267,8 @@ bool convert::decode(const Node& node, { node["swtch"] >> rhs.swtch; + node["custName"] >> rhs.custName; + int func = 0; node["func"] >> customFnLut >> func; rhs.func = (AssignFunc)func; diff --git a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp index b3f5eff5f31..bea44ef4de9 100644 --- a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp +++ b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp @@ -42,6 +42,7 @@ static const YamlLookupTable funcLut = { {LS_FN_DAPOS, "FUNC_ADIFFEGREATER"}, {LS_FN_TIMER, "FUNC_TIMER"}, {LS_FN_STICKY, "FUNC_STICKY"}, + {LS_FN_SAFE, "FUNC_SAFE"}, }; static int timerValue2lsw(uint32_t t) @@ -80,6 +81,12 @@ Node convert::encode(const LogicalSwitchData& rhs) def += YamlRawSwitchEncode(RawSwitch(rhs.val2)); } break; + case LS_FAMILY_SAFE: { + def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); + def += ","; + def += YamlRawSwitchEncode(RawSwitch(rhs.val2)); + } break; + case LS_FAMILY_EDGE: { def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); def += ","; @@ -119,7 +126,7 @@ Node convert::encode(const LogicalSwitchData& rhs) node["andsw"] = YamlRawSwitchEncode(RawSwitch(rhs.andsw)); node["lsPersist"] = (int)rhs.lsPersist; node["lsState"] = (int)rhs.lsState; - + node["custName"] = rhs.custName; return node; } @@ -127,6 +134,7 @@ bool convert::decode(const Node& node, LogicalSwitchData& rhs) { node["func"] >> funcLut >> rhs.func; + node["custName"] >> rhs.custName; std::string def_str; node["def"] >> def_str; @@ -142,6 +150,14 @@ bool convert::decode(const Node& node, rhs.val2 = YamlRawSwitchDecode(sw_str).toValue(); } break; +case LS_FAMILY_SAFE: { + std::string sw_str; + getline(def, sw_str, ','); + rhs.val1 = YamlRawSwitchDecode(sw_str).toValue(); + getline(def, sw_str); + rhs.val2 = YamlRawSwitchDecode(sw_str).toValue(); + } break; + case LS_FAMILY_EDGE: { std::string sw_str; getline(def, sw_str, ','); diff --git a/companion/src/firmwares/logicalswitchdata.cpp b/companion/src/firmwares/logicalswitchdata.cpp index 527b475f7f4..e5e26ee0527 100644 --- a/companion/src/firmwares/logicalswitchdata.cpp +++ b/companion/src/firmwares/logicalswitchdata.cpp @@ -28,7 +28,7 @@ bool LogicalSwitchData::isEmpty() const { - return (func == 0); + return (func == LS_FN_OFF); } CSFunctionFamily LogicalSwitchData::getFunctionFamily() const @@ -39,6 +39,8 @@ CSFunctionFamily LogicalSwitchData::getFunctionFamily() const return LS_FAMILY_TIMER; else if (func == LS_FN_STICKY) return LS_FAMILY_STICKY; + else if (func == LS_FN_SAFE) + return LS_FAMILY_SAFE; else if (func < LS_FN_AND || func > LS_FN_ELESS) return LS_FAMILY_VOFS; else if (func < LS_FN_EQUAL) @@ -103,6 +105,8 @@ QString LogicalSwitchData::funcToString() const return tr("Timer"); case LS_FN_STICKY: return tr("Sticky"); + case LS_FN_SAFE: + return tr("Safe"); case LS_FN_EDGE: return tr("Edge"); default: @@ -112,7 +116,7 @@ QString LogicalSwitchData::funcToString() const QString LogicalSwitchData::nameToString(int index) const { - return RadioData::getElementName(tr("L"), index + 1, NULL, true); + return RadioData::getElementName(tr("L"), index + 1, custName, true); } void LogicalSwitchData::convert(RadioDataConversionState & cstate) @@ -125,6 +129,10 @@ void LogicalSwitchData::convert(RadioDataConversionState & cstate) val1 = RawSource(val1).convert(cstate.withComponentField("V1")).toValue(); break; case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: + val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue(); + val2 = RawSwitch(val2).convert(cstate.withComponentField("V2")).toValue(); + break; case LS_FAMILY_VBOOL: val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue(); val2 = RawSwitch(val2).convert(cstate.withComponentField("V2")).toValue(); diff --git a/companion/src/firmwares/logicalswitchdata.h b/companion/src/firmwares/logicalswitchdata.h index f915d4ee179..cd01adc0b56 100644 --- a/companion/src/firmwares/logicalswitchdata.h +++ b/companion/src/firmwares/logicalswitchdata.h @@ -24,6 +24,8 @@ #include +#define LS_CUSTNAME_LEN 10 + class RadioDataConversionState; enum CSFunction { @@ -48,8 +50,9 @@ enum CSFunction { LS_FN_TIMER, LS_FN_STICKY, LS_FN_EDGE, + LS_FN_SAFE, // later ... LS_FN_RANGE, - LS_FN_MAX + LS_FN_MAX }; enum CSFunctionFamily { @@ -59,6 +62,7 @@ enum CSFunctionFamily { LS_FAMILY_TIMER, LS_FAMILY_STICKY, LS_FAMILY_EDGE, + LS_FAMILY_SAFE }; class LogicalSwitchData { @@ -79,6 +83,7 @@ class LogicalSwitchData { int andsw; bool lsState; bool lsPersist; + char custName[LS_CUSTNAME_LEN + 1]; void clear() { memset(this, 0, sizeof(LogicalSwitchData)); } bool isEmpty() const; diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 85dae1b7b03..9b17227b68d 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -719,6 +719,12 @@ int ModelData::updateReference() } break; case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: + if (lsd->val1 != 0) + updateSwitchIntRef(lsd->val1); + if (lsd->val2 != 0) + updateSwitchIntRef(lsd->val2); + break; case LS_FAMILY_VBOOL: oldval1 = lsd->val1; oldval2 = lsd->val2; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 6c3193012e8..1ca42ccc69c 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -1515,6 +1515,7 @@ class LogicalSwitchesFunctionsTable: public ConversionTable { addConversion(LS_FN_DAPOS, val++); addConversion(LS_FN_TIMER, val++); addConversion(LS_FN_STICKY, val++); + addConversion(LS_FN_SAFE, val++); } }; @@ -1570,7 +1571,7 @@ class LogicalSwitchField: public TransformedField { v2 = csw.val2; v3 = csw.val3; } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { + else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY || csw.func == LS_FN_SAFE) { switchesConversionTable->exportValue(csw.val1, v1); switchesConversionTable->exportValue(csw.val2, v2); } @@ -1595,7 +1596,7 @@ class LogicalSwitchField: public TransformedField { csw.val2 = v2; csw.val3 = v3; } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { + else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY || csw.func == LS_FN_SAFE) { switchesConversionTable->importValue(v1, csw.val1); switchesConversionTable->importValue(v2, csw.val2); } diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp index 14979d446c3..1a36d32db3a 100644 --- a/companion/src/firmwares/rawsource.cpp +++ b/companion/src/firmwares/rawsource.cpp @@ -215,7 +215,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con return DataHelpers::getCompositeName(dfltName, custName, prefixCustomName); case SOURCE_TYPE_CUSTOM_SWITCH: - return RawSwitch(SWITCH_TYPE_VIRTUAL, index).toString(); // RawSwitch uses 1 based index + return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1) .toString(board, generalSettings, model); // RawSwitch uses 1 based index case SOURCE_TYPE_CYC: return tr("CYC%1").arg(index); diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 70da6be2fd5..dd2b2d6471c 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -110,10 +110,20 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen case SWITCH_TYPE_VIRTUAL: if (modelData) - return modelData->logicalSw[index].nameToString(index - 1); + return modelData->logicalSw[index - 1].nameToString(index - 1); else return LogicalSwitchData().nameToString(index - 1); + case SWITCH_TYPE_FUNCTIONSWITCH: + if (!Boards::getCapability(board, Board::FunctionSwitches)) + return CPN_STR_UNKNOWN_ITEM; + qr = div(index - 1, 3); + if (modelData) + swName = QString(modelData->functionSwitchNames[qr.quot]).trimmed(); + if (swName.isEmpty()) + swName = tr("SW%1").arg(qr.quot + 1); + return swName + directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1); + case SWITCH_TYPE_MULTIPOS_POT: if (!Boards::getCapability(board, Board::MultiposPotsPositions)) return CPN_STR_UNKNOWN_ITEM; diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 1d27330ce6e..9bca8ff8d52 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -22,6 +22,7 @@ #include "customfunctions.h" #include "helpers.h" #include "appdata.h" +#include "namevalidator.h" #include @@ -33,6 +34,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, mediaPlayer(nullptr), modelsUpdateCnt(0) { + Board::Type board = firmware->getBoard(); lock = true; fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); @@ -86,7 +88,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, } } - if (IS_STM32(firmware->getBoard())) { + if (IS_STM32(board)) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); for (int i = 0; i < fswCapability; i++) { if (functions[i].func == FuncPlayScript) { @@ -98,7 +100,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, } } - if (IS_STM32(firmware->getBoard())) { + if (IS_STM32(board)) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/RGBLED", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); for (int i = 0; i < fswCapability; i++) { if (functions[i].func == FuncRGBLed) { @@ -114,7 +116,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, playIcon.addImage("stop.png", QIcon::Normal, QIcon::On); QStringList headerLabels; - headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Repeat") << tr("Enable"); + headerLabels << "#" << tr("Name") << tr("Switch") << tr("Action") << tr("Parameters") << tr("Repeat") << tr("Enable"); TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels); for (int i = 0; i < fswCapability; i++) { @@ -132,6 +134,15 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); + // The Custom Name + name[i] = new QLineEdit(this); + name[i]->setProperty("index", i); + name[i]->setMaxLength(CF_CUSTNAME_LEN); + name[i]->setValidator(new NameValidator(board, this)); + name[i]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + connect(name[i], SIGNAL(editingFinished()), this, SLOT(onNameEdited())); + tableLayout->addWidget(i, 1, name[i]); + // The switch fswtchSwtch[i] = new QComboBox(this); fswtchSwtch[i]->setProperty("index", i); @@ -141,7 +152,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchSwtch[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); fswtchSwtch[i]->setMaxVisibleItems(10); connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); - tableLayout->addWidget(i, 1, fswtchSwtch[i]); + tableLayout->addWidget(i, 2, fswtchSwtch[i]); // The function fswtchFunc[i] = new QComboBox(this); @@ -150,11 +161,11 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); fswtchFunc[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited())); - tableLayout->addWidget(i, 2, fswtchFunc[i]); + tableLayout->addWidget(i, 3, fswtchFunc[i]); // The parameters QHBoxLayout * paramLayout = new QHBoxLayout(); - tableLayout->addLayout(i, 3, paramLayout); + tableLayout->addLayout(i, 4, paramLayout); fswtchGVmode[i] = new QComboBox(this); fswtchGVmode[i]->setProperty("index", i); @@ -205,7 +216,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, connect(playBT[i], &QToolButton::clicked, this, &CustomFunctionsPanel::toggleSound); QHBoxLayout * repeatLayout = new QHBoxLayout(); - tableLayout->addLayout(i, 4, repeatLayout); + tableLayout->addLayout(i, 5, repeatLayout); fswtchRepeat[i] = new QComboBox(this); fswtchRepeat[i]->setProperty("index", i); if (functions[i].func == FuncPlayScript || functions[i].func == FuncRGBLed) @@ -230,7 +241,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, disableMouseScrolling(); tableLayout->resizeColumnsToContents(); - tableLayout->setColumnWidth(3, 300); + tableLayout->setColumnWidth(5, 300); tableLayout->pushRowsUp(fswCapability + 1); update(); @@ -353,18 +364,34 @@ void CustomFunctionsPanel::functionEdited() lock = true; int index = sender()->property("index").toInt(); RawSwitch swtch = functions[index].swtch; + int paramTemp =functions[index].param; + functions[index].clear(); functions[index].swtch = swtch; functions[index].func = (AssignFunc)fswtchFunc[index]->currentData().toInt(); functions[index].enabled = true; if (functions[index].func == FuncLogs) functions[index].param = 10; // 1 sec + functions[index].param = paramTemp; + strcpy(functions[index].custName, name[index]->text().toLatin1()); + refreshCustomFunction(index); emit modified(); lock = false; } } +void CustomFunctionsPanel::onNameEdited() +{ + QLineEdit *le = qobject_cast(sender()); + int index = le->property("index").toInt(); + CustomFunctionData & cfn = functions[index]; + if (cfn.custName != le->text()) { + strcpy(cfn.custName, le->text().toLatin1()); + emit modified(); + } +} + void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { CustomFunctionData & cfn = functions[i]; @@ -377,6 +404,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) cfn.enabled = fswtchEnable[i]->isChecked(); } else { + name[i]->setText(cfn.custName); fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue())); fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func)); fswtchEnable[i]->setChecked(cfn.enabled); @@ -385,6 +413,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (!cfn.isEmpty()) { widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC | CUSTOM_FUNCTION_ENABLE; + name[i]->setText(cfn.custName); + if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) { if (model) { int channelsMax = model->getChannelsMax(true); @@ -392,8 +422,11 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setMinimum(-channelsMax); fswtchParam[i]->setMaximum(channelsMax); + name[i]->setText(cfn.custName); + if (modified) { cfn.param = fswtchParam[i]->value(); + strcpy(cfn.custName, name[i]->text().toLatin1()); } fswtchParam[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; @@ -801,6 +834,7 @@ void CustomFunctionsPanel::swapData(int idx1, int idx2) void CustomFunctionsPanel::resetCBsAndRefresh(int idx) { lock = true; + name[idx]->clear(); fswtchSwtch[idx]->setCurrentIndex(fswtchSwtch[idx]->findData(functions[idx].swtch.toValue())); fswtchFunc[idx]->setCurrentIndex(fswtchFunc[idx]->findData(functions[idx].func)); fswtchGVmode[idx]->setCurrentIndex(functions[idx].adjustMode); diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index c64ef860cf6..dbc76a1a7b5 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -47,6 +47,7 @@ class CustomFunctionsPanel : public GenericPanel private slots: void customFunctionEdited(); + void onNameEdited(); void functionEdited(); void onCustomContextMenuRequested(QPoint pos); void refreshCustomFunction(int index, bool modified=false); @@ -95,6 +96,7 @@ class CustomFunctionsPanel : public GenericPanel QSet tracksSet; QSet scriptsSet; int mediaPlayerCurrent; + QLineEdit * name[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchSwtch[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchFunc[CPN_MAX_SPECIAL_FUNCTIONS]; QCheckBox * fswtchParamGV[CPN_MAX_SPECIAL_FUNCTIONS]; diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index b628fcd0d1a..afb6d44e23d 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -22,6 +22,7 @@ #include "logicalswitches.h" #include "filtereditemmodels.h" #include "helpers.h" +#include "namevalidator.h" #include @@ -32,6 +33,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, selectedIndex(0), modelsUpdateCnt(0) { + Board::Type board = firmware->getBoard(); rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::LogicalSwitchesContext); connectItemModelEvents(rawSwitchFilteredModel); @@ -44,7 +46,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt); QStringList headerLabels; - headerLabels << "#" << tr("Function") << tr("V1") << tr("V2") << tr("AND Switch"); + headerLabels << "#" << tr("Name") << tr("Function") << tr("V1") << tr("V2") << tr("AND Switch"); if (lsCapabilityExt) { headerLabels << tr("Duration") << tr("Delay"); } @@ -65,12 +67,21 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); + // The Custom Name + name[i] = new QLineEdit(this); + name[i]->setProperty("index", i); + name[i]->setMaxLength(LS_CUSTNAME_LEN); + name[i]->setValidator(new NameValidator(board, this)); + name[i]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + connect(name[i], SIGNAL(editingFinished()), this, SLOT(onNameEdited())); + tableLayout->addWidget(i, 1, name[i]); + // The function cbFunction[i] = new QComboBox(this); cbFunction[i]->setProperty("index", i); populateFunctionCB(cbFunction[i]); connect(cbFunction[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onFunctionChanged())); - tableLayout->addWidget(i, 1, cbFunction[i]); + tableLayout->addWidget(i, 2, cbFunction[i]); // V1 QHBoxLayout *v1Layout = new QHBoxLayout(); @@ -88,7 +99,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(dsbValue[i], SIGNAL(editingFinished()), this, SLOT(onOffsetChanged())); v1Layout->addWidget(dsbValue[i]); dsbValue[i]->setVisible(false); - tableLayout->addLayout(i, 2, v1Layout); + tableLayout->addLayout(i, 3, v1Layout); // V2 QHBoxLayout *v2Layout = new QHBoxLayout(); @@ -121,7 +132,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, connect(teOffset[i],SIGNAL(editingFinished()),this,SLOT(onOffsetChanged())); v2Layout->addWidget(teOffset[i]); teOffset[i]->setVisible(false); - tableLayout->addLayout(i, 3, v2Layout); + tableLayout->addLayout(i, 4, v2Layout); // AND cbAndSwitch[i] = new QComboBox(this); @@ -129,7 +140,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, cbAndSwitch[i]->setModel(rawSwitchFilteredModel); cbAndSwitch[i]->setVisible(true); connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int))); - tableLayout->addWidget(i, 4, cbAndSwitch[i]); + tableLayout->addWidget(i, 5, cbAndSwitch[i]); if (lsCapabilityExt) { // Duration @@ -141,7 +152,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, dsbDuration[i]->setAccelerated(true); dsbDuration[i]->setDecimals(1); connect(dsbDuration[i], SIGNAL(valueChanged(double)), this, SLOT(onDurationChanged(double))); - tableLayout->addWidget(i, 5, dsbDuration[i]); + tableLayout->addWidget(i, 6, dsbDuration[i]); // Delay dsbDelay[i] = new QDoubleSpinBox(this); @@ -152,7 +163,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, dsbDelay[i]->setAccelerated(true); dsbDelay[i]->setDecimals(1); connect(dsbDelay[i], SIGNAL(valueChanged(double)), this, SLOT(onDelayChanged(double))); - tableLayout->addWidget(i, 6, dsbDelay[i]); + tableLayout->addWidget(i, 7, dsbDelay[i]); } cbPersist[i] = new QCheckBox(this); @@ -174,6 +185,19 @@ LogicalSwitchesPanel::~LogicalSwitchesPanel() delete rawSwitchFilteredModel; } +void LogicalSwitchesPanel::onNameEdited() +{ + QLineEdit *le = qobject_cast(sender()); + int index = le->property("index").toInt(); + + if (model->logicalSw[index].custName != le->text()) { + strcpy(model->logicalSw[index].custName, le->text().toLatin1()); + if (model->logicalSw[index].func != LS_FN_OFF) + updateItemModels(); + emit modified(); + } +} + void LogicalSwitchesPanel::onFunctionChanged() { if (!lock) { @@ -377,6 +401,8 @@ void LogicalSwitchesPanel::updateLine(int i) if (!model->logicalSw[i].isEmpty()) { mask = LINE_ENABLED | DELAY_ENABLED | DURATION_ENABLED; + name[i]->setText(model->logicalSw[i].custName); + switch (model->logicalSw[i].getFunctionFamily()) { case LS_FAMILY_VOFS: @@ -412,6 +438,7 @@ void LogicalSwitchesPanel::updateLine(int i) case LS_FAMILY_STICKY: // no break mask |= PERSIST_ENABLED; cbPersist[i]->setChecked(model->logicalSw[i].lsPersist); + case LS_FAMILY_SAFE: // no break case LS_FAMILY_VBOOL: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; cbSource1[i]->setModel(rawSwitchFilteredModel); @@ -490,7 +517,8 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) LS_FN_DPOS, LS_FN_DAPOS, LS_FN_TIMER, - LS_FN_STICKY + LS_FN_STICKY, + LS_FN_SAFE }; b->clear(); @@ -620,6 +648,7 @@ void LogicalSwitchesPanel::cmClear(bool prompt) model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); + name[selectedIndex]->clear(); updateLine(selectedIndex); updateItemModels(); emit modified(); @@ -632,6 +661,7 @@ void LogicalSwitchesPanel::cmClearAll() for (int i = 0; i < lsCapability; i++) { model->logicalSw[i].clear(); + name[i]->clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i); } update(); diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h index 3b0fb4a9ac6..33ac8f341a4 100644 --- a/companion/src/modeledit/logicalswitches.h +++ b/companion/src/modeledit/logicalswitches.h @@ -43,6 +43,7 @@ class LogicalSwitchesPanel : public ModelPanel private slots: void onFunctionChanged(); + void onNameEdited(); void onV1Changed(int value); void onV2Changed(int value); void onAndSwitchChanged(int value); @@ -66,6 +67,7 @@ class LogicalSwitchesPanel : public ModelPanel void onItemModelUpdateComplete(); private: + QLineEdit *name[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES]; QDoubleSpinBox * dsbValue[CPN_MAX_LOGICAL_SWITCHES]; QDoubleSpinBox * dsbOffset[CPN_MAX_LOGICAL_SWITCHES]; diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index f17d09d4947..ae41406b2ee 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -399,6 +399,18 @@ QString ModelPrinter::printMixerLine(const MixData & mix, bool showMultiplex, in { QString str = " "; + if (firmware->getCapability(HasMixerNames) && mix.name[0]){ + std::string strMixName(mix.name); + str += QString(" [%1]").arg(mix.name).toHtmlEscaped(); + for (int i = 0; i < (6- strMixName.length()); i++) { + str += " "; + } + } + else { + str += "       "; + } + str += "     "; + if (showMultiplex) { switch(mix.mltpx) { case (1): str += "*="; break; @@ -538,6 +550,9 @@ QString ModelPrinter::printLogicalSwitchLine(int idx) if (ls.lsPersist) result += tr(" Persistent"); break; + case LS_FAMILY_SAFE: + result += tr("Safe") + QString("(%1, %2)").arg(sw1Name).arg(sw2Name); + break; case LS_FAMILY_TIMER: result += tr("Timer") + QString("(%1, %2)").arg(ValToTim(ls.val1)).arg(ValToTim(ls.val2)); break; diff --git a/companion/src/simulation/radiooutputswidget.cpp b/companion/src/simulation/radiooutputswidget.cpp index 1a4b2977168..f0974fe591c 100644 --- a/companion/src/simulation/radiooutputswidget.cpp +++ b/companion/src/simulation/radiooutputswidget.cpp @@ -284,6 +284,11 @@ void RadioOutputsWidget::setupLsDisplay() QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo) { + //TODO: place logicSwitch friendly name on radio output window. + //int modelindex = RadioData().generalSettings.currModelIndex; + //ModelData &model = RadioData().models[modelindex]; + //QString namestring = model.logicalSw[switchNo].custName; + QLabel * swtch = new QLabel(parent); swtch->setAutoFillBackground(true); swtch->setFrameStyle(QFrame::Panel | QFrame::Raised); @@ -300,6 +305,7 @@ QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo font.setBold(false); swtch->setFont(font); swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0'))); + //swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0')) + ": " + namestring); swtch->setAlignment(Qt::AlignCenter); m_logicSwitchMap.insert(switchNo, swtch); return swtch; diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 20057eeb9d7..fc57d94ee62 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -137,6 +137,9 @@ enum CurveType { #define MAX_CURVE_POINTS 512 #endif +#define LEN_SPEC_FN_NAME 10 +#define LEN_LOGICSW_NAME 10 + #define NUM_MODULES 2 #define XPOTS_MULTIPOS_COUNT 6 diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index f20d1f0318c..988f7444bdb 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -45,14 +45,14 @@ static inline void check_struct() CHKSIZE(ExpoData, 18); CHKSIZE(SwashRingData, 8); CHKSIZE(CurveHeader, 4); - CHKSIZE(LogicalSwitchData, 9); + CHKSIZE(LogicalSwitchData, 19); CHKSIZE(TelemetrySensor, 14); CHKSIZE(ModuleData, 29); CHKSIZE(GVarData, 7); CHKSIZE(RFAlarmData, 2); CHKSIZE(TrainerData, 16); CHKSIZE(FlightModeData, 22 + 2 * MAX_TRIMS + LEN_FLIGHT_MODE_NAME); - CHKSIZE(CustomFunctionData, 11); + CHKSIZE(CustomFunctionData, 21); #if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) CHKSIZE(LimitData, 11); @@ -83,33 +83,33 @@ static inline void check_struct() #endif #if defined(PCBXLITES) - CHKSIZE(RadioData, 872); + CHKSIZE(RadioData, 1512); #elif defined(COLORLCD) - CHKSIZE(RadioData, 966); + CHKSIZE(RadioData, 1606); #else - CHKSIZE(RadioData, 870); + CHKSIZE(RadioData, 1510); #endif #if defined(RADIO_TPRO) || defined(RADIO_TPROV2) || defined(RADIO_BUMBLEBEE) - CHKSIZE(ModelData, 6354); + CHKSIZE(ModelData, 7634); #elif defined(RADIO_T14) || defined(RADIO_T12MAX) - CHKSIZE(ModelData, 6329); + CHKSIZE(ModelData, 7609); #elif defined(RADIO_FAMILY_T20) - CHKSIZE(ModelData, 6390); + CHKSIZE(ModelData, 7670); #elif defined(PCBX9E) - CHKSIZE(ModelData, 6771); + CHKSIZE(ModelData, 8051); #elif defined(PCBX9D) || defined(PCBX9DP) - CHKSIZE(ModelData, 6770); + CHKSIZE(ModelData, 8050); #elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) - CHKSIZE(ModelData, 6329); + CHKSIZE(ModelData, 7609); #elif defined(PCBNV14) - CHKSIZE(ModelData, 26463); + CHKSIZE(ModelData, 27743); #elif defined(PCBPL18) - CHKSIZE(ModelData, 26845); + CHKSIZE(ModelData, 28125); #elif defined(RADIO_T15) - CHKSIZE(ModelData, 26834); + CHKSIZE(ModelData, 28114); #elif defined(PCBHORUS) - CHKSIZE(ModelData, 26809); + CHKSIZE(ModelData, 28089); #else #error CHKSIZE not set up #endif diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 717433d196e..df3905c6e80 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -159,6 +159,7 @@ PACK(struct LogicalSwitchData { int16_t v2 SKIP; uint8_t delay; uint8_t duration; + NOBACKUP(char custName[LEN_LOGICSW_NAME]); }); /* @@ -168,6 +169,7 @@ PACK(struct LogicalSwitchData { PACK(struct CustomFunctionData { int16_t swtch:10 CUST(r_swtchSrc,w_swtchSrc); uint16_t func:6 ENUM(Functions); // TODO: 6 bits for Functions? + NOBACKUP(char custName[LEN_SPEC_FN_NAME]); CUST_ATTR(def,r_customFn,w_customFn); PACK(union { NOBACKUP(PACK(struct { diff --git a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp index 9c94cac0053..99251e644f7 100644 --- a/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp +++ b/radio/src/gui/colorlcd/mainview/view_logical_switches.cpp @@ -111,6 +111,14 @@ class LogicalSwitchDisplayFooter : public Window char s[20]; + //LS friendly name + /*const char* chrs = cs->custName; + if (strlen(chrs) > 0) { + dc->drawText(15, 1, cs->custName, textColor); + } else { + dc->drawTextAtIndex(5, 1, STR_VCSWFUNC, cs->func, textColor); + }*/ + lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]); // CSW params - V1 @@ -118,6 +126,7 @@ class LogicalSwitchDisplayFooter : public Window case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FAMILY_SAFE: lv_label_set_text(lsV1, getSwitchPositionName(ls->v1)); break; case LS_FAMILY_TIMER: @@ -135,6 +144,7 @@ class LogicalSwitchDisplayFooter : public Window switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: + case LS_FAMILY_SAFE: lv_label_set_text(lsV2, getSwitchPositionName(ls->v2)); break; case LS_FAMILY_EDGE: diff --git a/radio/src/gui/colorlcd/model/model_logical_switches.cpp b/radio/src/gui/colorlcd/model/model_logical_switches.cpp index 66a0f80cf7c..66c2e92aa04 100644 --- a/radio/src/gui/colorlcd/model/model_logical_switches.cpp +++ b/radio/src/gui/colorlcd/model/model_logical_switches.cpp @@ -108,6 +108,10 @@ class LogicalSwitchEditPage : public Page LogicalSwitchData* cs = lswAddress(index); uint8_t cstate = lswFamily(cs->func); + // new StaticText(logicalSwitchOneWindow, grid.getLabelSlot(), STR_CUST_LOGICALSWITCH_LABEL, 0, COLOR_THEME_PRIMARY1); + // new ModelTextEdit(logicalSwitchOneWindow, grid.getFieldSlot(), cs->custName, LEN_LOGICSW_NAME); + // grid.nextLine(); + // V1 auto line = logicalSwitchOneWindow->newLine(grid); new StaticText(line, rect_t{}, STR_V1); @@ -115,6 +119,7 @@ class LogicalSwitchEditPage : public Page case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FUNC_SAFE: choice = new SwitchChoice( line, rect_t{}, SWSRC_FIRST_IN_LOGICAL_SWITCHES, SWSRC_LAST_IN_LOGICAL_SWITCHES, GET_SET_DEFAULT(cs->v1)); @@ -216,11 +221,13 @@ class LogicalSwitchEditPage : public Page } // AND switch - line = logicalSwitchOneWindow->newLine(grid); - new StaticText(line, rect_t{}, STR_AND_SWITCH); - choice = new SwitchChoice(line, rect_t{}, -MAX_LS_ANDSW, MAX_LS_ANDSW, - GET_SET_DEFAULT(cs->andsw)); - choice->setAvailableHandler(isSwitchAvailableInLogicalSwitches); + if (cs->func != LS_FUNC_SAFE) { + line = logicalSwitchOneWindow->newLine(grid); + new StaticText(line, rect_t{}, STR_AND_SWITCH); + choice = new SwitchChoice(line, rect_t{}, -MAX_LS_ANDSW, MAX_LS_ANDSW, + GET_SET_DEFAULT(cs->andsw)); + choice->setAvailableHandler(isSwitchAvailableInLogicalSwitches); + } // Duration line = logicalSwitchOneWindow->newLine(grid); @@ -426,11 +433,14 @@ class LogicalSwitchButton : public ListLineButton lsName, getSwitchPositionName(SWSRC_FIRST_LOGICAL_SWITCH + index)); lv_label_set_text(lsFunc, STR_VCSWFUNC[ls->func]); + //dc->drawText(col1, line1, ls->custName, COLOR_THEME_SECONDARY1); + // CSW params - V1 switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: case LS_FAMILY_EDGE: + case LS_FUNC_SAFE: lv_label_set_text(lsV1, getSwitchPositionName(ls->v1)); break; case LS_FAMILY_TIMER: @@ -453,6 +463,7 @@ class LogicalSwitchButton : public ListLineButton switch (lsFamily) { case LS_FAMILY_BOOL: case LS_FAMILY_STICKY: + case LS_FUNC_SAFE: lv_label_set_text(lsV2, getSwitchPositionName(ls->v2)); break; case LS_FAMILY_EDGE: diff --git a/radio/src/gui/colorlcd/model/special_functions.cpp b/radio/src/gui/colorlcd/model/special_functions.cpp index 9d956dca8bc..733f40a2e2b 100644 --- a/radio/src/gui/colorlcd/model/special_functions.cpp +++ b/radio/src/gui/colorlcd/model/special_functions.cpp @@ -145,6 +145,9 @@ void FunctionLineButton::refresh() lv_label_set_text(sfName, (prefix + std::to_string(index + 1)).c_str()); lv_label_set_text(sfSwitch, getSwitchPositionName(CFN_SWITCH(cfn))); + //paint special function custom name + //dc->drawText(col3, line1, cfn->custName, COLOR_THEME_SECONDARY1); + strcpy(s, funcGetLabel(func)); strcat(s, " - "); @@ -656,9 +659,14 @@ void FunctionEditPage::buildBody(Window *form) FlexGridLayout grid(col_dsc, row_dsc, PAD_TINY); CustomFunctionData *cfn = customFunctionData(); + auto line = form->newLine(grid); + + // Custom label + new StaticText(line, rect_t{}, STR_CUST_FUNC_CUST_LABEL); + new ModelTextEdit(line, rect_t{}, cfn->custName, LEN_SPEC_FN_NAME); + line = form->newLine(grid); // Switch - auto line = form->newLine(grid); new StaticText(line, rect_t{}, STR_SF_SWITCH); auto switchChoice = new SwitchChoice(line, rect_t{}, SWSRC_FIRST, SWSRC_LAST, GET_SET_DEFAULT(CFN_SWITCH(cfn))); diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 3100f48136d..4246cbddaed 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -201,6 +201,7 @@ enum LogicalSwitchesFunctions { LS_FUNC_ADIFFEGREATER, LS_FUNC_TIMER, LS_FUNC_STICKY, + LS_FUNC_SAFE, LS_FUNC_COUNT SKIP, LS_FUNC_MAX SKIP = LS_FUNC_COUNT-1 }; diff --git a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp index f98c7c6617f..faabdfeefff 100644 --- a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -471,6 +473,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -805,8 +808,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_f16.cpp b/radio/src/storage/yaml/yaml_datastructs_f16.cpp index ddb86cc3755..01acabd206e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_f16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_f16.cpp @@ -141,6 +141,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -275,6 +276,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -499,6 +501,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -840,8 +843,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index 6e62f7d6f40..9f4e5d8d13e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -1940,6 +1940,14 @@ static void r_logicSw(void* user, uint8_t* data, uint32_t bitoffs, ls->v2 = r_swtchSrc(nullptr, val, val_len); break; + case LS_FAMILY_SAFE: + ls->v1 = r_swtchSrc(nullptr, val, l_sep); + val += l_sep; val_len -= l_sep; + if (!val_len || val[0] != ',') return; + val++; val_len--; + ls->v2 = r_swtchSrc(nullptr, val, val_len); + break; + case LS_FAMILY_EDGE: ls->v1 = r_swtchSrc(nullptr, val, l_sep); val += l_sep; val_len -= l_sep; @@ -2007,6 +2015,12 @@ static bool w_logicSw(void* user, uint8_t* data, uint32_t bitoffs, if (!w_swtchSrc_unquoted(&_ls_node_v2, ls->v2, wf, opaque)) return false; break; + case LS_FAMILY_SAFE: + if (!w_swtchSrc_unquoted(&_ls_node_v1, ls->v1, wf, opaque)) return false; + if (!wf(opaque,",",1)) return false; + if (!w_swtchSrc_unquoted(&_ls_node_v2, ls->v2, wf, opaque)) return false; + break; + case LS_FAMILY_EDGE: if (!w_swtchSrc_unquoted(&_ls_node_v1, ls->v1, wf, opaque)) return false; if (!wf(opaque,",",1)) return false; diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index ec06a121a3e..6c7ffb80db7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -139,6 +139,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -273,6 +274,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -496,6 +498,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -838,8 +841,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp index 95f127ea3a6..a37f56031d6 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -139,6 +139,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -273,6 +274,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -496,6 +498,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -838,8 +841,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t15.cpp b/radio/src/storage/yaml/yaml_datastructs_t15.cpp index b14aa266643..64fa26380fd 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15.cpp @@ -141,6 +141,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -275,6 +276,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -349,7 +351,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -499,6 +501,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -845,8 +848,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_t20.cpp b/radio/src/storage/yaml/yaml_datastructs_t20.cpp index faf052cf19b..6554b250eff 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t20.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t20.cpp @@ -132,6 +132,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -257,6 +258,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -333,7 +335,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -472,6 +474,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -806,8 +809,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp index 97eedc1dcda..c18a17be27b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -132,6 +132,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -257,6 +258,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -333,7 +335,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -472,6 +474,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -806,8 +809,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index cf6dab7dc16..c1f33b808c7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -140,6 +140,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -274,6 +275,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -348,7 +350,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -498,6 +500,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -839,8 +842,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index 36af8afae04..4025d33b93a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp b/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp index 9cc689ff730..cc5a991b6b9 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -471,6 +473,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -805,8 +808,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index ee42c348763..efb424446b8 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -471,6 +473,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -805,8 +808,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp index 6a0d2eb13ba..8a37e998555 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp @@ -131,6 +131,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -256,6 +257,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -332,7 +334,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -470,6 +472,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -804,8 +807,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index 03516dab30a..271042583c5 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -133,6 +133,7 @@ const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, { LS_FUNC_TIMER, "FUNC_TIMER" }, { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_SAFE, "FUNC_SAFE" }, { 0, NULL } }; const struct YamlIdStr enum_SwashType[] = { @@ -258,6 +259,7 @@ static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_ENUM("func", 6, enum_Functions), + YAML_STRING("custName", 10), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), @@ -334,7 +336,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), YAML_SIGNED( "varioRepeat", 8 ), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_CUSTOM("auxSerialMode",r_serialMode,nullptr), YAML_CUSTOM("aux2SerialMode",r_serialMode,nullptr), YAML_ARRAY("serialPort", 8, 4, struct_serialConfig, nullptr), @@ -474,6 +476,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "delay", 8 ), YAML_UNSIGNED( "duration", 8 ), + YAML_STRING("custName", 10), YAML_END }; static const struct YamlNode struct_SwashRingData[] = { @@ -808,8 +811,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("expoData", 144, 64, struct_ExpoData, NULL), YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), - YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), - YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ARRAY("logicalSw", 152, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 168, 64, struct_CustomFunctionData, cfn_is_active), YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 10a2eee0279..50e0f1f585c 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -518,77 +518,80 @@ bool getLogicalSwitch(uint8_t idx) LogicalSwitchContext &context = lswFm[mixerCurrentFlightMode].lsw[idx]; bool result; - swsrc_t s = ls->andsw; + if (ls->func == LS_FAMILY_SAFE) { + result = lswFm[mixerCurrentFlightMode].lsw[idx].state; + } else { + swsrc_t s = ls->andsw; - if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) { - if (ls->func != LS_FUNC_STICKY && ls->func != LS_FUNC_EDGE ) { - // AND switch must not affect STICKY and EDGE processing - context.lastValue = CS_LAST_VALUE_INIT; - } - result = false; - } - else if ((s=lswFamily(ls->func)) == LS_FAMILY_BOOL) { - bool res1 = getSwitch(ls->v1); - bool res2 = getSwitch(ls->v2); - switch (ls->func) { - case LS_FUNC_AND: - result = (res1 && res2); - break; - case LS_FUNC_OR: - result = (res1 || res2); - break; - // case LS_FUNC_XOR: - default: - result = (res1 ^ res2); - break; + if (ls->func == LS_FUNC_NONE || (s && !getSwitch(s))) { + if (ls->func != LS_FUNC_STICKY && ls->func != LS_FUNC_EDGE ) { + // AND switch must not affect STICKY and EDGE processing + context.lastValue = CS_LAST_VALUE_INIT; + } + result = false; } - } - else if (s == LS_FAMILY_TIMER) { - result = (context.lastValue <= 0); - } - else if (s == LS_FAMILY_STICKY) { - result = (context.lastValue & (1<<0)); - } - else if (s == LS_FAMILY_EDGE) { - result = (context.lastValue & (1<<0)); - } - else { - getvalue_t x = getValueForLogicalSwitch(ls->v1); - getvalue_t y; - if (s == LS_FAMILY_COMP) { - y = getValueForLogicalSwitch(ls->v2); - + else if ((s=lswFamily(ls->func)) == LS_FAMILY_BOOL) { + bool res1 = getSwitch(ls->v1); + bool res2 = getSwitch(ls->v2); switch (ls->func) { - case LS_FUNC_EQUAL: - result = (x==y); + case LS_FUNC_AND: + result = (res1 && res2); break; - case LS_FUNC_GREATER: - result = (x>y); + case LS_FUNC_OR: + result = (res1 || res2); break; + // case LS_FUNC_XOR: default: - result = (xv1; - // Telemetry - if (v1 >= MIXSRC_FIRST_TELEM) { - if (!TELEMETRY_STREAMING() || IS_FAI_FORBIDDEN(v1-1)) { - result = false; - goto DurationAndDelayProcessing; + getvalue_t x = getValueForLogicalSwitch(ls->v1); + getvalue_t y; + if (s == LS_FAMILY_COMP) { + y = getValueForLogicalSwitch(ls->v2); + + switch (ls->func) { + case LS_FUNC_EQUAL: + result = (x==y); + break; + case LS_FUNC_GREATER: + result = (x>y); + break; + default: + result = (xv1; + // Telemetry + if (v1 >= MIXSRC_FIRST_TELEM) { + if (!TELEMETRY_STREAMING() || IS_FAI_FORBIDDEN(v1 - 1)) { + result = false; + goto DurationAndDelayProcessing; + } - y = convertLswTelemValue(ls); + y = convertLswTelemValue(ls); - } - else if (v1 >= MIXSRC_FIRST_GVAR) { - y = ls->v2; - } - else { - y = calc100toRESX(ls->v2); - } + } + else if (v1 >= MIXSRC_FIRST_GVAR) { + y = ls->v2; + } + else { + y = calc100toRESX(ls->v2); + } switch (ls->func) { case LS_FUNC_VEQUAL: @@ -689,7 +692,7 @@ bool getLogicalSwitch(uint8_t idx) context.timer = 0; } } - + } return result; } @@ -782,6 +785,24 @@ uint8_t getXPotPosition(uint8_t idx) return potsPos[idx] & 0x0F; } +void evalLogicalSwitch_FUNC_SAFE(LogicalSwitchData *ls, + LogicalSwitchContext &context) +{ + if (ls->v1 != SWSRC_NONE) { + if (getSwitch(ls->v2)) { + // ON + if (getSwitch(ls->v1)) { + context.state = 1; + } + // OFF + if (!getSwitch(ls->v1)) { + context.state = 0; + } + } + } else { // no source set therfore switch is off + context.state = 0; + } +} /** @brief Calculates new state of logical switches for mixerCurrentFlightMode @@ -790,20 +811,26 @@ void evalLogicalSwitches(bool isCurrentFlightmode) { for (unsigned int idx=0; idxfunc == LS_FUNC_SAFE) { + evalLogicalSwitch_FUNC_SAFE(ls, context); + } else { + bool result = getLogicalSwitch(idx); + if (isCurrentFlightmode) { + if (result) { + if (!context.state) PLAY_LOGICAL_SWITCH_ON(idx); + } + else { + if (context.state) PLAY_LOGICAL_SWITCH_OFF(idx); + } } - else { - if (context.state) PLAY_LOGICAL_SWITCH_OFF(idx); + context.state = result; + if ((g_model.logicalSw[idx].func == LS_FUNC_STICKY) && (g_model.logicalSw[idx].lsState != result)) { + g_model.logicalSw[idx].lsState = result; + storageDirty(EE_MODEL); } } - context.state = result; - if ((g_model.logicalSw[idx].func == LS_FUNC_STICKY) && (g_model.logicalSw[idx].lsState != result)) { - g_model.logicalSw[idx].lsState = result; - storageDirty(EE_MODEL); - } } } @@ -1117,6 +1144,9 @@ void logicalSwitchesTimerTick() } } } + } else if (ls->func == LS_FUNC_SAFE) { + LogicalSwitchContext &context = lswFm[mixerCurrentFlightMode].lsw[i]; + evalLogicalSwitch_FUNC_SAFE(ls, context); } else if (ls->func == LS_FUNC_EDGE) { ls_stay_struct & lastValue = (ls_stay_struct &)LS_LAST_VALUE(fm, i); // if this ls was reset by the logicalSwitchesReset() the lastValue will be set to CS_LAST_VALUE_INIT(0x8000) diff --git a/radio/src/switches.h b/radio/src/switches.h index 59020d4fc14..b80cff522b9 100644 --- a/radio/src/switches.h +++ b/radio/src/switches.h @@ -32,6 +32,7 @@ enum LogicalSwitchFamilies { LS_FAMILY_DIFF, LS_FAMILY_TIMER, LS_FAMILY_STICKY, + LS_FAMILY_SAFE, LS_FAMILY_RANGE, LS_FAMILY_EDGE }; diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index c398a53a6b3..06c50aec59b 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -806,6 +806,8 @@ const char STR_BACKLIGHT_TIMER[] = TR_BACKLIGHT_TIMER; const char STR_LABELS_SELECT[] = TR_LABELS_SELECT; const char STR_LABELS_MATCH[] = TR_LABELS_MATCH; const char STR_FAV_MATCH[] = TR_FAV_MATCH; +const char STR_CUST_LOGICALSWITCH_LABEL[] = TR_CUST_LOGICALSWITCH_LABEL; +const char STR_CUST_FUNC_CUST_LABEL[] = TR_CUST_FUNC_CUST_LABEL; ISTR(LABELS_SELECT_MODE); ISTR(LABELS_MATCH_MODE); ISTR(FAV_MATCH_MODE); diff --git a/radio/src/translations.h b/radio/src/translations.h index f0c0722720c..4e0672b5f0c 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -811,6 +811,8 @@ extern const char STR_FAV_MATCH[]; extern const char* const STR_LABELS_SELECT_MODE[]; extern const char* const STR_LABELS_MATCH_MODE[]; extern const char* const STR_FAV_MATCH_MODE[]; +extern const char STR_CUST_LOGICALSWITCH_LABEL[]; +extern const char STR_CUST_FUNC_CUST_LABEL[]; #endif extern const char STR_EXECUTE_FILE[]; extern const char STR_DELETE_FILE[]; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index 8b843f5aefa..2d703d00cb0 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -76,6 +76,7 @@ #define TR_CSWTIMER "定时" #define TR_CSWSTICKY "粘滞" #define TR_CSWSTAY "边沿" +#define TR_CSWSAFE "Safe" #define TR_CSWEQUAL "a=x" #define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","a= 212 #define TR_CSWTIMER "Stopky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTICKY "Sticky" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" + #define TR_CSWSAFE "Safe" #define TR_CSWSTICKY "Stky" #define TR_CSWSTAY "Edge" #endif @@ -531,6 +533,10 @@ #define TR_MENUCURVES "KŘIVKY" #define TR_MENUCURVE "\002K" +#if defined(COLORLCD) +#define TR_CUST_LOGICALSWITCH_LABEL "Název" +#define TR_CUST_FUNC_CUST_LABEL "Název" +#endif #define TR_MENULOGICALSWITCH "LOG. SPÍNAČ" #define TR_MENULOGICALSWITCHES "LOGICKÉ SPÍNAČE" #define TR_MENUCUSTOMFUNC "SPECIÁLNÍ FUNKCE" diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index 387b8a28d66..1e564ceb62b 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -82,15 +82,17 @@ #if LCD_W >= 212 #define TR_CSWTIMER "Tid" #define TR_CSWSTICKY "Sej" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tid" #define TR_CSWSTICKY "Sej" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Takt" // TIM = Takt = Taktgenerator #define TR_CSWSTICKY "SRFF" // Sticky = RS-Flip-Flop + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Puls" // Edge = einstellbarer Impuls #else #define TR_CSWTIMER "Takt" // TIM = Takt = Taktgenerator #define TR_CSWSTICKY "SRFF" // Sticky = RS-Flip-Flop + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Puls" // Edge = einstellbarer Impuls #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Pega" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Borde" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Pega" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Bord" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Chrono" #define TR_CSWSTICKY "Bistb" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Chrono" #define TR_CSWSTICKY "Bist" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "שעון" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "שעון" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Glue" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stały" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Brzeg" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stały" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Brzeg" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Stcky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Stky" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Edge" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Таймер" #define TR_CSWSTICKY "Липучка" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Край" #else #define TR_CSWTIMER "Таймер" #define TR_CSWSTICKY "Липучка" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Кррай" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Timer" #define TR_CSWSTICKY "Seg" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Kant" #else #define TR_CSWTIMER "Tim" #define TR_CSWSTICKY "Seg" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Kant" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "定時" #define TR_CSWSTICKY "粘滯" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "邊沿" #else #define TR_CSWTIMER "定時" #define TR_CSWSTICKY "粘滯" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "邊沿" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a= 212 #define TR_CSWTIMER "Таймер" #define TR_CSWSTICKY "Липучка" + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Край" #else #define TR_CSWTIMER "Тмр" #define TR_CSWSTICKY "Лип." + #define TR_CSWSAFE "Safe" #define TR_CSWSTAY "Край" #endif #define TR_CSWEQUAL "a=x" -#define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","a