From 0c8c39b134c0385d3971263a9e347dc4c06949f5 Mon Sep 17 00:00:00 2001 From: philmoz Date: Mon, 28 Jul 2025 12:59:22 +1000 Subject: [PATCH] feat(radio): refactor of switch handling to better support customisable switches (#6095) Co-authored-by: philmoz Co-authored-by: 3djc <3djc@gh.com> Co-authored-by: elecpower --- companion/src/constants.h | 3 +- .../src/datamodels/compounditemmodels.cpp | 10 +- companion/src/firmwares/boardjson.cpp | 29 +- companion/src/firmwares/boardjson.h | 6 +- companion/src/firmwares/boards.cpp | 22 +- companion/src/firmwares/boards.h | 4 + .../src/firmwares/customfunctiondata.cpp | 2 +- .../firmwares/edgetx/yaml_generalsettings.cpp | 3 +- .../src/firmwares/edgetx/yaml_modeldata.cpp | 218 ++++++++---- .../firmwares/edgetx/yaml_switchconfig.cpp | 58 ++++ .../src/firmwares/edgetx/yaml_switchconfig.h | 14 + companion/src/firmwares/generalsettings.cpp | 9 + companion/src/firmwares/generalsettings.h | 18 + companion/src/firmwares/modeldata.cpp | 86 +++-- companion/src/firmwares/modeldata.h | 48 ++- companion/src/firmwares/rawsource.cpp | 2 +- companion/src/firmwares/rawswitch.cpp | 5 +- companion/src/generaledit/hardware.cpp | 144 +++++++- companion/src/modeledit/setup.cpp | 67 ++-- companion/src/modeledit/setup.h | 2 + .../src/modeledit/setup_function_switches.cpp | 216 ++++++++---- .../src/modeledit/setup_function_switches.h | 4 + companion/src/modelprinter.cpp | 17 +- companion/src/multimodelprinter.cpp | 2 +- companion/src/simulation/simulatorinterface.h | 1 + companion/src/simulation/simulatorwidget.cpp | 51 ++- companion/src/simulation/simulatorwidget.ui | 38 ++- .../simulation/widgets/radioswitchwidget.h | 59 ++++ .../src/simulation/widgets/radiowidget.h | 1 + companion/src/tests/gtests.h | 2 +- companion/src/wizarddata.cpp | 1 + radio/src/CMakeLists.txt | 1 + radio/src/boards/generic_stm32/rgb_leds.cpp | 6 - radio/src/boards/generic_stm32/switches.cpp | 29 +- radio/src/cli.cpp | 4 +- radio/src/dataconstants.h | 2 +- radio/src/datastructs.h | 22 +- radio/src/datastructs_private.cpp | 254 ++++++++++++++ radio/src/datastructs_private.h | 136 +++++++- radio/src/edgetx.cpp | 18 +- radio/src/edgetx.h | 1 + radio/src/edgetx_constants.h | 14 +- radio/src/functions.cpp | 15 +- radio/src/gui/128x64/model_setup.cpp | 277 +++++++++------ .../gui/128x64/model_special_functions.cpp | 9 +- radio/src/gui/128x64/radio_diagkeys.cpp | 51 ++- radio/src/gui/128x64/view_main.cpp | 32 +- radio/src/gui/212x64/model_setup.cpp | 14 +- radio/src/gui/colorlcd/CMakeLists.txt | 1 + .../colorlcd/controls/switch_warn_dialog.cpp | 13 +- .../gui/colorlcd/model/function_switches.cpp | 159 +++++---- .../gui/colorlcd/model/preflight_checks.cpp | 23 +- .../gui/colorlcd/model/special_functions.cpp | 11 +- radio/src/gui/colorlcd/radio/hw_inputs.cpp | 16 +- radio/src/gui/colorlcd/radio/radio_cfs.cpp | 318 ++++++++++++++++++ .../colorlcd/radio/radio_cfs.h} | 31 +- .../colorlcd/radio/radio_diagcustswitches.cpp | 46 +-- .../src/gui/colorlcd/radio/radio_diagkeys.cpp | 10 +- .../src/gui/colorlcd/radio/radio_hardware.cpp | 4 + radio/src/gui/colorlcd/radio/radio_hardware.h | 4 + .../src/gui/common/stdlcd/radio_hardware.cpp | 218 ++++++++++-- radio/src/gui/gui_common.cpp | 11 +- radio/src/hal/rgbleds.cpp | 35 +- radio/src/hal/rgbleds.h | 1 + radio/src/hal/switch_driver.cpp | 94 ++++-- radio/src/hal/switch_driver.h | 31 +- radio/src/logs.cpp | 4 +- radio/src/lua/api_colorlcd_lvgl.cpp | 2 +- radio/src/lua/api_general.cpp | 118 +++++-- radio/src/mixer.cpp | 30 +- radio/src/model_audio.cpp | 6 +- radio/src/model_init.cpp | 52 ++- radio/src/myeeprom.h | 28 +- radio/src/storage/sdcard_yaml.cpp | 7 +- .../storage/yaml/yaml_datastructs_128x64.cpp | 77 +++-- .../src/storage/yaml/yaml_datastructs_f16.cpp | 81 +++-- .../storage/yaml/yaml_datastructs_funcs.cpp | 230 ++++++++++--- .../storage/yaml/yaml_datastructs_gx12.cpp | 134 +++++--- .../storage/yaml/yaml_datastructs_nb4p.cpp | 81 +++-- .../yaml/yaml_datastructs_nv14_family.cpp | 85 +++-- .../storage/yaml/yaml_datastructs_pl18.cpp | 85 +++-- .../storage/yaml/yaml_datastructs_pl18u.cpp | 81 +++-- .../storage/yaml/yaml_datastructs_st16.cpp | 143 +++++--- .../src/storage/yaml/yaml_datastructs_t15.cpp | 112 +++--- .../src/storage/yaml/yaml_datastructs_t20.cpp | 107 ++++-- .../storage/yaml/yaml_datastructs_tpro.cpp | 107 ++++-- .../src/storage/yaml/yaml_datastructs_x10.cpp | 81 +++-- .../src/storage/yaml/yaml_datastructs_x9d.cpp | 77 +++-- .../yaml/yaml_datastructs_x9dp2019.cpp | 77 +++-- .../src/storage/yaml/yaml_datastructs_x9e.cpp | 77 +++-- .../storage/yaml/yaml_datastructs_xlite.cpp | 77 +++-- .../storage/yaml/yaml_datastructs_xlites.cpp | 77 +++-- radio/src/storage/yaml/yaml_node.h | 9 +- radio/src/storage/yaml/yaml_tree_walker.cpp | 7 + radio/src/strhelpers.cpp | 10 +- radio/src/switches.cpp | 318 +++++++----------- radio/src/switches.h | 18 +- .../common/arm/stm32/stm32_switch_driver.cpp | 2 +- .../common/arm/stm32/stm32_switch_driver.h | 13 +- radio/src/targets/horus/board.h | 13 - radio/src/targets/horus/hal.h | 8 + radio/src/targets/horus/led_driver.cpp | 18 +- radio/src/targets/nv14/bsp_io.h | 21 -- radio/src/targets/pl18/bsp_io.h | 2 - radio/src/targets/pl18/hal.h | 2 + radio/src/targets/pl18/nb4p_switch_driver.cpp | 4 +- radio/src/targets/simu/led_driver.cpp | 71 ++-- radio/src/targets/simu/opentxsimulator.cpp | 25 ++ radio/src/targets/simu/opentxsimulator.h | 1 + radio/src/targets/simu/sdl_simu.cpp | 81 +++-- radio/src/targets/simu/switch_driver.cpp | 57 ++-- radio/src/targets/st16/board.h | 13 - radio/src/targets/st16/bsp_io.cpp | 45 +-- radio/src/targets/st16/bsp_io.h | 13 - radio/src/targets/st16/hal.h | 44 ++- radio/src/targets/st16/led_driver.cpp | 12 +- radio/src/targets/stm32h7s78-dk/bsp_io.h | 2 - radio/src/targets/taranis/board.h | 21 +- radio/src/targets/taranis/bsp_io.h | 21 -- radio/src/targets/taranis/gx12/bsp_io.cpp | 98 ++---- radio/src/targets/taranis/gx12/bsp_io.h | 59 ---- radio/src/targets/taranis/hal.h | 104 +++++- radio/src/targets/taranis/led_driver.cpp | 7 +- radio/src/tests/functions.cpp | 43 ++- radio/src/tests/gtests.cpp | 8 + radio/src/tests/gtests.h | 25 +- radio/src/tests/mixer.cpp | 88 +++-- radio/src/tests/switches.cpp | 130 +++---- radio/src/translations.cpp | 3 +- radio/src/translations.h | 3 +- radio/src/translations/cn.h | 7 +- radio/src/translations/cz.h | 7 +- radio/src/translations/da.h | 9 +- radio/src/translations/de.h | 7 +- radio/src/translations/en.h | 7 +- radio/src/translations/es.h | 7 +- radio/src/translations/fi.h | 7 +- radio/src/translations/fr.h | 7 +- radio/src/translations/he.h | 7 +- radio/src/translations/it.h | 7 +- radio/src/translations/jp.h | 7 +- radio/src/translations/ko.h | 3 +- radio/src/translations/nl.h | 7 +- radio/src/translations/pl.h | 7 +- radio/src/translations/pt.h | 7 +- radio/src/translations/ru.h | 7 +- radio/src/translations/se.h | 9 +- radio/src/translations/tw.h | 7 +- radio/src/translations/ua.h | 7 +- radio/src/translations/untranslated.h | 2 +- radio/util/hw_defs/hal_switches.py | 18 +- radio/util/hw_defs/simu_switches.jinja | 36 +- radio/util/hw_defs/stm32_switches.jinja | 59 ++-- radio/util/hw_defs/switch_config.py | 86 ++++- radio/util/yaml_parser.tmpl | 2 +- 155 files changed, 4538 insertions(+), 2306 deletions(-) create mode 100644 radio/src/datastructs_private.cpp create mode 100644 radio/src/gui/colorlcd/radio/radio_cfs.cpp rename radio/src/{targets/horus/bsp_io.h => gui/colorlcd/radio/radio_cfs.h} (50%) delete mode 100644 radio/src/targets/nv14/bsp_io.h delete mode 100644 radio/src/targets/taranis/bsp_io.h delete mode 100644 radio/src/targets/taranis/gx12/bsp_io.h diff --git a/companion/src/constants.h b/companion/src/constants.h index 0dde000d6..003783ea3 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -40,7 +40,7 @@ #define CPN_MAX_TRIMS Board::TRIM_AXIS_COUNT #define CPN_MAX_CYC 3 #define CPN_MAX_SWITCHES_FLEX 4 // v2.10 cmake parameter FLEXSW -#define CPN_MAX_SWITCHES_FUNCTION 6 +#define CPN_MAX_SWITCHES_FUNCTION 8 #define CPN_MAX_SWITCHES_STD 20 #define CPN_MAX_SWITCHES (CPN_MAX_SWITCHES_STD + CPN_MAX_SWITCHES_FLEX + CPN_MAX_SWITCHES_FUNCTION) #define CPN_MAX_SENSORS 60 @@ -48,7 +48,6 @@ #define CPN_MAX_SCRIPT_INPUTS 10 #define CPN_MAX_SPACEMOUSE 6 #define CPN_MAX_INPUTS 32 // v2.10 replaces CPN_MAX_ANALOGS - the value is abitary as radio ADC refactor is still a WIP -#define CPN_MAX_FUNCTIONSWITCH_GROUP 3 // pre v2.10 #define CPN_MAX_POTS 8 diff --git a/companion/src/datamodels/compounditemmodels.cpp b/companion/src/datamodels/compounditemmodels.cpp index eaf177c6c..e00a997a6 100644 --- a/companion/src/datamodels/compounditemmodels.cpp +++ b/companion/src/datamodels/compounditemmodels.cpp @@ -107,6 +107,8 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett setId(IMID_RawSource); setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts)); + int groups = board->getCapability(Board::FunctionSwitchGroups); + // Descending source direction: inverted (!) sources addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, -firmware->getCapability(Sensors) * 3); addItems(SOURCE_TYPE_TIMER, RawSource::TelemGroup, -firmware->getCapability(Timers)); @@ -116,8 +118,8 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, -firmware->getCapability(TrainerInputs)); addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, -CPN_MAX_CYC); addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, -firmware->getCapability(LogicalSwitches)); - if (modelData) - addItems(SOURCE_TYPE_FUNCTIONSWITCH_GROUP, RawSource::SourcesGroup, -CPN_MAX_FUNCTIONSWITCH_GROUP); + if (modelData && groups > 0) + addItems(SOURCE_TYPE_FUNCTIONSWITCH_GROUP, RawSource::SourcesGroup, -groups); addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, -board->getCapability(Board::Switches)); addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, -1); addItems(SOURCE_TYPE_MIN, RawSource::SourcesGroup, -1); @@ -139,8 +141,8 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett addItems(SOURCE_TYPE_MIN, RawSource::SourcesGroup, 1); addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1); addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches)); - if (modelData) - addItems(SOURCE_TYPE_FUNCTIONSWITCH_GROUP, RawSource::SourcesGroup, CPN_MAX_FUNCTIONSWITCH_GROUP); + if (modelData && groups > 0) + addItems(SOURCE_TYPE_FUNCTIONSWITCH_GROUP, RawSource::SourcesGroup, groups); addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, firmware->getCapability(LogicalSwitches)); addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC); addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs)); diff --git a/companion/src/firmwares/boardjson.cpp b/companion/src/firmwares/boardjson.cpp index 10d520327..10792815b 100644 --- a/companion/src/firmwares/boardjson.cpp +++ b/companion/src/firmwares/boardjson.cpp @@ -50,7 +50,6 @@ static const StringTagMappingTable switchTypesLookupTable = { {std::to_string(Board::SWITCH_TOGGLE), "TOGGLE"}, {std::to_string(Board::SWITCH_2POS), "2POS"}, {std::to_string(Board::SWITCH_3POS), "3POS"}, - {std::to_string(Board::SWITCH_FUNC), "FSWITCH"}, {std::to_string(Board::SWITCH_ADC), "ADC"}, }; @@ -443,6 +442,24 @@ const int BoardJson::getSwitchIndex(const QString val, Board::LookupValueType lv return getSwitchIndex(m_switches, val, lvt); } +const int BoardJson::getCFSIndexForSwitch(int sw) const +{ + if (sw < (int)m_switches->size() && m_switches->at(sw).isCustomSwitch) + return m_switches->at(sw).customSwitchIdx; + + return -1; +} + +const int BoardJson::getSwitchIndexForCFS(int cfsIdx) const +{ + for (int i = 0; i < (int)m_switches->size(); i++) { + if (m_switches->at(i).isCustomSwitch && m_switches->at(i).customSwitchIdx == cfsIdx) + return i; + } + + return -1; +} + // static int BoardJson::getSwitchIndex(const SwitchesTable * switches, QString val, Board::LookupValueType lvt) { @@ -772,7 +789,7 @@ const bool BoardJson::isSwitchConfigurable(int index) const { if (index >= 0 && index < getCapability(Board::Switches)) { SwitchDefn &defn = m_switches->at(index); - if (isSwitchStd(defn)) + if (isSwitchStd(defn) || isSwitchFunc(defn)) return true; if (isSwitchFlex(defn)) { @@ -813,7 +830,7 @@ const bool BoardJson::isSwitchFunc(int index) const // static bool BoardJson::isSwitchFunc(const SwitchDefn & defn) { - return defn.type == Board::SWITCH_FUNC; + return defn.customSwitchIdx >= 0; } bool BoardJson::loadDefinition() @@ -996,6 +1013,12 @@ bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs sw.display.y = (unsigned int)d.at(1).toInt(0); } + if (!o.value("is_cfs").isUndefined()) + sw.isCustomSwitch = o.value("is_cfs").toBool(); + + if (!o.value("cfs_idx").isUndefined()) + sw.customSwitchIdx = o.value("cfs_idx").toInt(); + // special handing for ADC if (sw.type == Board::SWITCH_ADC) { if (sw.dflt == Board::SWITCH_TOGGLE) { diff --git a/companion/src/firmwares/boardjson.h b/companion/src/firmwares/boardjson.h index 856be965e..05e026556 100644 --- a/companion/src/firmwares/boardjson.h +++ b/companion/src/firmwares/boardjson.h @@ -61,13 +61,15 @@ class BoardJson }; struct SwitchDefn { - Board::SwitchType type = Board::SWITCH_NOT_AVAILABLE; std::string tag = ""; + Board::SwitchType type = Board::SWITCH_NOT_AVAILABLE; std::string name = ""; int flags = 0; bool inverted = false; Board::SwitchType dflt = Board::SWITCH_NOT_AVAILABLE; Display display; + bool isCustomSwitch = false; + int customSwitchIdx = -1; Board::LookupValueType cfgYaml = Board::LVT_TAG; Board::LookupValueType refYaml = Board::LVT_NAME; @@ -137,6 +139,8 @@ class BoardJson const int getKeyIndex(const QString key) const; const int getSwitchIndex(const QString val, Board::LookupValueType lvt) const; + const int getCFSIndexForSwitch(int sw) const; + const int getSwitchIndexForCFS(int customSwitchIdx) const; const Board::SwitchInfo getSwitchInfo(int index) const; const QString getSwitchName(int index) const; const QString getSwitchTag(int index) const; diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index ebc2550e9..9cad3a025 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -315,6 +315,12 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) else return getCapability(board, Board::Switches); + case FunctionSwitchGroups: + if (getCapability(board, FunctionSwitches)) { + return IS_RADIOMASTER_GX12(board) ? 4 : 3; + } + return 0; + case HasAudioMuteGPIO: // All color lcd (including NV14 and EL18) except Horus X12S // TX12, TX12MK2, ZORRO, BOXER, T8, TLITE, TPRO, LR3PRO, COMMANDO8 @@ -406,7 +412,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return IS_RADIOMASTER_MT12(board); case FunctionSwitchColors: - return IS_RADIOMASTER_GX12(board); + return IS_RADIOMASTER_GX12(board) || IS_FLYSKY_ST16(board); default: return getBoardJson(board)->getCapability(capability); @@ -679,6 +685,8 @@ QString Boards::switchTypeToString(int value) return tr("2 Positions"); case SWITCH_3POS: return tr("3 Positions"); + case SWITCH_GLOBAL: + return tr("Global"); case SWITCH_FUNC: return tr("Function"); default: @@ -692,7 +700,7 @@ AbstractStaticItemModel * Boards::switchTypeItemModel() AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); mdl->setName(AIM_BOARDS_SWITCH_TYPE); - for (int i = 0; i < SWITCH_FUNC; i++) { // Function not required in lists + for (int i = 0; i < SWITCH_GLOBAL; i++) { // Function not required in lists mdl->appendToItemList(switchTypeToString(i), i, true, 0, (i == SWITCH_NOT_AVAILABLE ? SwitchTypeFlagNone : (i < SWITCH_3POS ? SwitchTypeFlag2Pos : SwitchTypeFlag3Pos))); } @@ -1046,6 +1054,16 @@ int Boards::getSwitchIndex(QString val, Board::LookupValueType lvt, Board::Type return getBoardJson(board)->getSwitchIndex(val, lvt); } +int Boards::getCFSIndexForSwitch(int swIdx, Board::Type board) +{ + return getBoardJson(board)->getCFSIndexForSwitch(swIdx); +} + +int Boards::getSwitchIndexForCFS(int cfsIdx, Board::Type board) +{ + return getBoardJson(board)->getSwitchIndexForCFS(cfsIdx); +} + QString Boards::getSwitchName(int index, Board::Type board) { return getBoardJson(board)->getSwitchName(index); diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index b90ca4d02..96927e17f 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -119,6 +119,7 @@ namespace Board { SWITCH_TOGGLE, SWITCH_2POS, SWITCH_3POS, + SWITCH_GLOBAL, SWITCH_FUNC, SWITCH_ADC, SWITCH_TYPE_COUNT @@ -212,6 +213,7 @@ namespace Board { FlexSwitches, FunctionSwitches, FunctionSwitchColors, + FunctionSwitchGroups, Gyros, GyroAxes, HasAudioMuteGPIO, @@ -426,6 +428,8 @@ class Boards static Board::SwitchInfo getSwitchInfo(int index, Board::Type board = Board::BOARD_UNKNOWN); static int getSwitchIndex(QString val, Board::LookupValueType lvt, Board::Type board = Board::BOARD_UNKNOWN); + static int getCFSIndexForSwitch(int swIdx, Board::Type board = Board::BOARD_UNKNOWN); + static int getSwitchIndexForCFS(int cfsIdx, Board::Type board = Board::BOARD_UNKNOWN); static QString getSwitchName(int index, Board::Type board = Board::BOARD_UNKNOWN); static QString getSwitchTag(int index, Board::Type board = Board::BOARD_UNKNOWN); static int getSwitchTagNum(int index, Board::Type board = Board::BOARD_UNKNOWN); diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp index 8c27f8631..bd505ab63 100644 --- a/companion/src/firmwares/customfunctiondata.cpp +++ b/companion/src/firmwares/customfunctiondata.cpp @@ -262,7 +262,7 @@ bool CustomFunctionData::isFuncAvailable(const int index, const ModelData * mode ((index >= FuncAdjustGV1 && index <= FuncAdjustGVLast) && !fw->getCapability(Gvars)) || ((index == FuncDisableTouch) && !IS_HORUS_OR_TARANIS(fw->getBoard())) || ((index == FuncDisableAudioAmp && !Boards::getCapability(fw->getBoard(), Board::HasAudioMuteGPIO))) || - ((index == FuncRGBLed && !Boards::getCapability(fw->getBoard(), Board::HasLedStripGPIO))) || + ((index == FuncRGBLed && !(Boards::getCapability(fw->getBoard(), Board::HasLedStripGPIO) || Boards::getCapability(fw->getBoard(), Board::FunctionSwitchColors)))) || ((index == FuncLCDtoVideo && !IS_FATFISH_F16(fw->getBoard()))) || ((index >= FuncPushCustomSwitch1 && index <= FuncPushCustomSwitchLast) && !Boards::getCapability(fw->getBoard(), Board::FunctionSwitches)) ); diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index ea71c4928..367919f64 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -602,7 +602,8 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) // however when parsing saved settings set all switches to None and override with parsed values // thus any switches not parsed will be None rather than the default for (int i = 0; i < CPN_MAX_SWITCHES; i++) { - rhs.switchConfig[i].type = Board::SWITCH_NOT_AVAILABLE; + if (Boards::getCFSIndexForSwitch(i) < 0) + rhs.switchConfig[i].type = Board::SWITCH_NOT_AVAILABLE; } if (node["switchConfig"]) { diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index 666d3facb..0886a600a 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -31,7 +31,9 @@ #include "yaml_sensordata.h" #include "yaml_screendata.h" #include "yaml_usbjoystickdata.h" +#include "yaml_switchconfig.h" +#include "boardjson.h" #include "modeldata.h" #include "output_data.h" #include "eeprominterface.h" @@ -73,7 +75,7 @@ void YamlValidateLabelsNames(ModelData& model, Board::Type board) } for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i++) { - YamlValidateName(model.functionSwitchNames[i], board); + YamlValidateName(model.customSwitches[i].name, board); } for (int i = 0; i < CPN_MAX_INPUTS; i++) { @@ -149,6 +151,25 @@ static const YamlLookupTable hatsModeLut = { { GeneralSettings::HATSMODE_GLOBAL, "GLOBAL" }, }; +static const YamlLookupTable cfsSwitchConfig = { + { 0, "NONE" }, + { 1, "TOGGLE" }, + { 2, "2POS" }, + { 3, "3POS" }, + { 4, "GLOBAL" }, +}; + +static const YamlLookupTable cfsSwitchStart = { + { 0, "START_OFF" }, + { 1, "START_ON" }, + { 2, "START_PREVIOUS" }, +}; + +static const YamlLookupTable cfsSwitchLuaOverride = { + { 0, "OFF" }, + { 1, "ON" }, +}; + struct YamlTrim { int mode = 0; int ref = 0; @@ -283,27 +304,24 @@ struct YamlSwitchWarning { static constexpr size_t MASK_LEN = 2; static constexpr size_t MASK = (1 << MASK_LEN) - 1; - unsigned int enabled; - YamlSwitchWarning() = default; - YamlSwitchWarning(YAML::Node& node, uint64_t cpn_value, unsigned int switchWarningEnable) - : enabled(~switchWarningEnable) + YamlSwitchWarning(YAML::Node& node, uint64_t cpn_value) { uint64_t states = cpn_value; for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) { - if (!Boards::isSwitchFunc(i) && (enabled & (1 << i))) { + if (states & MASK) { std::string posn; switch(states & MASK) { - case 0: + case 1: posn = "up"; break; - case 1: + case 2: posn = "mid"; break; - case 2: + case 3: posn = "down"; break; } @@ -318,7 +336,6 @@ struct YamlSwitchWarning { uint64_t toCpn(const YAML::Node &warn) { uint64_t states = 0; - enabled = 0; if (warn.IsMap()) { for (const auto& sw : warn) { @@ -336,14 +353,13 @@ struct YamlSwitchWarning { int value = 0; if (posn == "up") - value = 0; - else if (posn == "mid") value = 1; - else if (posn == "down") + else if (posn == "mid") value = 2; + else if (posn == "down") + value = 3; states |= ((uint64_t)value << (index * MASK_LEN)); - enabled |= (1 << index); } } @@ -360,32 +376,30 @@ struct YamlSwitchWarningState { static constexpr size_t MASK = (1 << MASK_LEN) - 1; std::string src_str; - unsigned int enabled; YamlSwitchWarningState() = default; - YamlSwitchWarningState(uint64_t cpn_value, unsigned int switchWarningEnable) - : enabled(~switchWarningEnable) + YamlSwitchWarningState(uint64_t cpn_value) { uint64_t states = cpn_value; std::stringstream ss; for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) { //TODO: exclude 2-pos toggle from switch warnings - if (enabled & (1 << i)) { + if (states & MASK) { std::string tag = Boards::getSwitchTag(i).toStdString(); const char *sw = tag.data(); if (tag.size() >= 2 && sw[0] == 'S') { ss << sw[1]; switch(states & MASK) { - case 0: + case 1: ss << 'u'; break; - case 1: + case 2: ss << '-'; break; - case 2: + case 3: ss << 'd'; break; } @@ -400,7 +414,6 @@ struct YamlSwitchWarningState { uint64_t toCpn() { uint64_t states = 0; - enabled = 0; std::stringstream ss(src_str); while (!ss.eof()) { @@ -422,20 +435,19 @@ struct YamlSwitchWarningState { int value = 0; switch(s) { case 'u': - value = 0; - break; - case '-': value = 1; break; - case 'd': + case '-': value = 2; break; + case 'd': + value = 3; + break; default: continue; } states |= ((uint64_t)value << (index * MASK_LEN)); - enabled |= (1 << index); } return states; @@ -955,6 +967,47 @@ struct convert { } }; +template <> +struct convert { + static Node encode(const customSwitch& rhs); + static bool decode(const Node& node, customSwitch& rhs); +}; + +Node convert::encode(const customSwitch& rhs) +{ + Node node; + node["type"] = cfsSwitchConfig << rhs.type; + node["group"] = rhs.group; + node["start"] = cfsSwitchStart << rhs.start; + node["state"] = rhs.state; + node["name"] = rhs.name; + if (Boards::getCapability(getCurrentBoard(), Board::FunctionSwitchColors)) { + node["onColorLuaOverride"] = cfsSwitchLuaOverride << rhs.onColorLuaOverride; + node["offColorLuaOverride"] = cfsSwitchLuaOverride << rhs.offColorLuaOverride; + node["onColor"] = rhs.onColor; + node["offColor"] = rhs.offColor; + } + return node; +} + +bool convert::decode(const Node& node, customSwitch& rhs) +{ + if (!node.IsMap()) return false; + + unsigned type; + node["type"] >> cfsSwitchConfig >> type; + rhs.type = (Board::SwitchType)type; + node["group"] >> rhs.group; + node["start"] >> cfsSwitchStart >> rhs.start; + node["state"] >> rhs.state; + node["name"] >> rhs.name; + node["onColorLuaOverride"] >> cfsSwitchLuaOverride >> rhs.onColorLuaOverride; + node["offColorLuaOverride"] >> cfsSwitchLuaOverride >> rhs.offColorLuaOverride; + node["onColor"] >> rhs.onColor; + node["offColor"] >> rhs.offColor; + return true; +} + Node convert::encode(const ModelData& rhs) { modelSettingsVersion = SemanticVersion(VERSION); @@ -1076,7 +1129,7 @@ Node convert::encode(const ModelData& rhs) node["thrTraceSrc"] = thrTrace.src; Node sw_warn; - YamlSwitchWarning switchWarning(sw_warn, rhs.switchWarningStates, rhs.switchWarningEnable); + YamlSwitchWarning switchWarning(sw_warn, rhs.switchWarningStates); if (sw_warn && sw_warn.IsMap()) { node["switchWarning"] = sw_warn; } @@ -1194,29 +1247,16 @@ Node convert::encode(const ModelData& rhs) node["modelRegistrationID"] = rhs.registrationId; node["hatsMode"] = hatsModeLut << rhs.hatsMode; - if (Boards::getCapability(board, Board::FunctionSwitches)) { - node["functionSwitchConfig"] = rhs.functionSwitchConfig; - node["functionSwitchGroup"] = rhs.functionSwitchGroup; - node["functionSwitchStartConfig"] = rhs.functionSwitchStartConfig; - node["functionSwitchLogicalState"] = rhs.functionSwitchLogicalState; - - for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i++) { - if (strlen(rhs.functionSwitchNames[i]) > 0) { - node["switchNames"][std::to_string(i)]["val"] = rhs.functionSwitchNames[i]; - } + int funcSwCnt = Boards::getCapability(board, Board::FunctionSwitches); + if (funcSwCnt) { + for (int i = 0; i < funcSwCnt; i += 1) { + int sw = Boards::getSwitchIndexForCFS(i); + std::string tag = Boards::getSwitchYamlName(sw, BoardJson::YLT_CONFIG).toStdString(); + node["customSwitches"][tag] = rhs.customSwitches[i]; } - if (Boards::getCapability(board, Board::FunctionSwitchColors)) { - for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i += 1) { - node["functionSwitchLedONColor"][std::to_string(i)]["r"] = rhs.functionSwitchLedONColor[i].r; - node["functionSwitchLedONColor"][std::to_string(i)]["g"] = rhs.functionSwitchLedONColor[i].g; - node["functionSwitchLedONColor"][std::to_string(i)]["b"] = rhs.functionSwitchLedONColor[i].b; - } - for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i += 1) { - node["functionSwitchLedOFFColor"][std::to_string(i)]["r"] = rhs.functionSwitchLedOFFColor[i].r; - node["functionSwitchLedOFFColor"][std::to_string(i)]["g"] = rhs.functionSwitchLedOFFColor[i].g; - node["functionSwitchLedOFFColor"][std::to_string(i)]["b"] = rhs.functionSwitchLedOFFColor[i].b; - } + for (int i = 1; i < 4; i += 1) { + node["cfsGroupOn"][std::to_string(i)]["v"] = rhs.cfsGroupOn[i]; } } @@ -1351,16 +1391,13 @@ bool convert::decode(const Node& node, ModelData& rhs) if (node["switchWarning"]) { YamlSwitchWarning switchWarning; rhs.switchWarningStates = switchWarning.toCpn(node["switchWarning"]); - rhs.switchWarningEnable = ~switchWarning.enabled; } else if (node["switchWarningState"]) { // depreciated YamlSwitchWarningState switchWarningState; node["switchWarningState"] >> switchWarningState.src_str; rhs.switchWarningStates = switchWarningState.toCpn(); - rhs.switchWarningEnable = ~switchWarningState.enabled; } else { rhs.switchWarningStates = 0; - rhs.switchWarningEnable = ~0; } node["thrTrimSw"] >> rhs.thrTrimSwitch; @@ -1481,26 +1518,77 @@ bool convert::decode(const Node& node, ModelData& rhs) node["modelRegistrationID"] >> rhs.registrationId; node["hatsMode"] >> hatsModeLut >> rhs.hatsMode; - node["functionSwitchConfig"] >> rhs.functionSwitchConfig; - node["functionSwitchGroup"] >> rhs.functionSwitchGroup; - node["functionSwitchStartConfig"] >> rhs.functionSwitchStartConfig; - node["functionSwitchLogicalState"] >> rhs.functionSwitchLogicalState; - node["switchNames"] >> rhs.functionSwitchNames; + rhs.setDefaultFunctionSwitches(Boards::getCapability(board, Board::FunctionSwitches)); + + if (node["functionSwitchConfig"]) { + uint16_t v; + node["functionSwitchConfig"] >> v; + for (int i = 0; i < 6; i += 1) { + rhs.customSwitches[i].type = (Board::SwitchType)(v & 3); + v >>= 2; + } + } + if (node["functionSwitchGroup"]) { + uint16_t v; + node["functionSwitchGroup"] >> v; + for (int i = 0; i < 6; i += 1) { + rhs.customSwitches[i].group = v & 3; + v >>= 2; + } + for (int i = 0; i < 4; i += 1) { + rhs.cfsGroupOn[i] = v & 1; + v >>= 1; + } + } + if (node["functionSwitchStartConfig"]) { + uint16_t v; + node["functionSwitchStartConfig"] >> v; + for (int i = 0; i < 6; i += 1) { + rhs.customSwitches[i].start = v & 3; + v >>= 2; + } + } + if (node["functionSwitchLogicalState"]) { + uint16_t v; + node["functionSwitchLogicalState"] >> v; + for (int i = 0; i < 6; i += 1) { + rhs.customSwitches[i].state = v & 1; + v >>= 1; + } + } + if (node["switchNames"]) { + for (int i = 0; i < 6; i += 1) { + if (node["switchNames"][std::to_string(i)]) { + node["switchNames"][std::to_string(i)]["val"] >> rhs.customSwitches[i].name; + } + } + } if (node["functionSwitchLedONColor"]) { - for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i += 1) { + for (int i = 0; i < 6; i += 1) { if (node["functionSwitchLedONColor"][std::to_string(i)]) { - node["functionSwitchLedONColor"][std::to_string(i)]["r"] >> rhs.functionSwitchLedONColor[i].r; - node["functionSwitchLedONColor"][std::to_string(i)]["g"] >> rhs.functionSwitchLedONColor[i].g; - node["functionSwitchLedONColor"][std::to_string(i)]["b"] >> rhs.functionSwitchLedONColor[i].b; + node["functionSwitchLedONColor"][std::to_string(i)] >> rhs.customSwitches[i].onColor; } } } if (node["functionSwitchLedOFFColor"]) { - for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i += 1) { + for (int i = 0; i < 6; i += 1) { if (node["functionSwitchLedOFFColor"][std::to_string(i)]) { - node["functionSwitchLedOFFColor"][std::to_string(i)]["r"] >> rhs.functionSwitchLedOFFColor[i].r; - node["functionSwitchLedOFFColor"][std::to_string(i)]["g"] >> rhs.functionSwitchLedOFFColor[i].g; - node["functionSwitchLedOFFColor"][std::to_string(i)]["b"] >> rhs.functionSwitchLedOFFColor[i].b; + node["functionSwitchLedOFFColor"][std::to_string(i)] >> rhs.customSwitches[i].offColor; + } + } + } + int funcSwCnt = Boards::getCapability(board, Board::FunctionSwitches); + if (node["customSwitches"]) { + for (int i = 0; i < funcSwCnt; i += 1) { + int sw = Boards::getSwitchIndexForCFS(i); + std::string tag = Boards::getSwitchYamlName(sw, BoardJson::YLT_CONFIG).toStdString(); + node["customSwitches"][tag] >> rhs.customSwitches[i]; + } + } + if (node["cfsGroupOn"]) { + for (int i = 1; i < 4; i += 1) { + if (node["cfsGroupOn"][std::to_string(i)]) { + node["cfsGroupOn"][std::to_string(i)]["v"] >> rhs.cfsGroupOn[i]; } } } diff --git a/companion/src/firmwares/edgetx/yaml_switchconfig.cpp b/companion/src/firmwares/edgetx/yaml_switchconfig.cpp index 6b792070f..7e0b782e5 100644 --- a/companion/src/firmwares/edgetx/yaml_switchconfig.cpp +++ b/companion/src/firmwares/edgetx/yaml_switchconfig.cpp @@ -27,6 +27,11 @@ #include "boardjson.h" const YamlLookupTable switchConfigLut = { + {Board::SWITCH_NOT_AVAILABLE, "NONE"}, + {Board::SWITCH_TOGGLE, "TOGGLE"}, + {Board::SWITCH_2POS, "2POS"}, + {Board::SWITCH_3POS, "3POS"}, + {Board::SWITCH_GLOBAL, "GLOBAL"}, {Board::SWITCH_NOT_AVAILABLE, "none"}, {Board::SWITCH_TOGGLE, "toggle"}, {Board::SWITCH_2POS, "2pos"}, @@ -117,8 +122,13 @@ YamlSwitchConfig::YamlSwitchConfig(const GeneralSettings::SwitchConfig* rhs) for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) { config[i].tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString(); config[i].type = rhs[i].type; + config[i].start = rhs[i].start; memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN)); // config[i].inverted = rhs[i].inverted; + config[i].onColorLuaOverride = rhs[i].onColorLuaOverride; + config[i].offColorLuaOverride = rhs[i].offColorLuaOverride; + config[i].onColor = rhs[i].onColor; + config[i].offColor = rhs[i].offColor; } } @@ -128,7 +138,12 @@ void YamlSwitchConfig::copy(GeneralSettings::SwitchConfig* rhs) const if (config[i].type != (unsigned int)Board::SWITCH_NOT_AVAILABLE) { memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN)); rhs[i].type = (Board::SwitchType)config[i].type; + rhs[i].start = config[i].start; // rhs[i].inverted = config[i].inverted; + rhs[i].onColorLuaOverride = config[i].onColorLuaOverride; + rhs[i].offColorLuaOverride = config[i].offColorLuaOverride; + rhs[i].onColor = config[i].onColor; + rhs[i].offColor = config[i].offColor; } } } @@ -191,11 +206,32 @@ bool convert::decode(const Node& node, InputConfig& rhs) return true; } +static const YamlLookupTable cfsSwitchStart = { + { 0, "START_OFF" }, + { 1, "START_ON" }, + { 2, "START_PREVIOUS" }, +}; + +static const YamlLookupTable cfsSwitchLuaOverride = { + { 0, "OFF" }, + { 1, "ON" }, +}; + Node convert::encode(const SwitchConfig& rhs) { Node node; node["type"] = switchConfigLut << rhs.type; node["name"] = rhs.name; + if (Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) { + int idx = Boards::getSwitchYamlIndex(rhs.tag.c_str(), BoardJson::YLT_REF); + if (Boards::isSwitchFunc(idx, getCurrentBoard())) { + node["start"] = cfsSwitchStart << rhs.start; + node["onColorLuaOverride"] = cfsSwitchLuaOverride << rhs.onColorLuaOverride; + node["offColorLuaOverride"] = cfsSwitchLuaOverride << rhs.offColorLuaOverride; + node["onColor"] = rhs.onColor; + node["offColor"] = rhs.offColor; + } + } // node["inv"] = (int)rhs.inverted; in hwdef json but not implemented in radio yaml return node; } @@ -206,7 +242,12 @@ bool convert::decode(const Node& node, SwitchConfig& rhs) node["type"] >> switchConfigLut >> rhs.type; node["name"] >> rhs.name; + node["start"] >> cfsSwitchStart >> rhs.start; // node["inv"] >> rhs.inverted; in hwdef json but not implemented in radio yaml + node["onColorLuaOverride"] >> cfsSwitchLuaOverride >> rhs.onColorLuaOverride; + node["offColorLuaOverride"] >> cfsSwitchLuaOverride >> rhs.offColorLuaOverride; + node["onColor"] >> rhs.onColor; + node["offColor"] >> rhs.offColor; if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) { int idx = Boards::getSwitchYamlIndex(rhs.tag.c_str(), BoardJson::YLT_CONFIG); @@ -420,4 +461,21 @@ bool convert::decode(const Node& node, YamlSwitchesFlex& rhs) return true; } +Node convert::encode(const RGBLedColor& rhs) +{ + Node node; + node["r"] = rhs.r; + node["g"] = rhs.g; + node["b"] = rhs.b; + return node; +} + +bool convert::decode(const Node& node, RGBLedColor& rhs) +{ + node["r"] >> rhs.r; + node["g"] >> rhs.g; + node["b"] >> rhs.b; + return true; +} + } // namespace YAML diff --git a/companion/src/firmwares/edgetx/yaml_switchconfig.h b/companion/src/firmwares/edgetx/yaml_switchconfig.h index c19264556..ef9d089bd 100644 --- a/companion/src/firmwares/edgetx/yaml_switchconfig.h +++ b/companion/src/firmwares/edgetx/yaml_switchconfig.h @@ -69,7 +69,12 @@ struct SwitchConfig { std::string tag = std::string(); char name[HARDWARE_NAME_LEN + 1] = {'\0'}; unsigned int type = 0; + int start = 0; bool inverted = false; + unsigned int onColorLuaOverride = false; + unsigned int offColorLuaOverride = false; + RGBLedColor onColor; + RGBLedColor offColor; }; ENCODE_DECODE_CONFIG(SwitchConfig) @@ -87,3 +92,12 @@ INPUT_SWITCH_CONFIG(YamlSliderConfig, CPN_MAX_INPUTS, InputConfig, InputConfig) INPUT_SWITCH_CONFIG(YamlStickConfig, CPN_MAX_INPUTS, InputConfig, InputConfig) INPUT_SWITCH_CONFIG(YamlSwitchConfig, CPN_MAX_SWITCHES, SwitchConfig, SwitchConfig) INPUT_SWITCH_CONFIG(YamlSwitchesFlex, CPN_MAX_SWITCHES_FLEX, SwitchFlex, SwitchConfig) + +namespace YAML +{ +template <> +struct convert { + static Node encode(const RGBLedColor& rhs); + static bool decode(const Node& node, RGBLedColor& rhs); +}; +} diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index f35bbe907..7350ba6b1 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -170,6 +170,11 @@ bool GeneralSettings::isSwitchFlex(int index) const return Boards::isSwitchFlex(index); } +bool GeneralSettings::isSwitchFunc(int index) const +{ + return Boards::isSwitchFunc(index); +} + bool GeneralSettings::unassignedInputFlexSwitches() const { Board::Type board = getCurrentBoard(); @@ -372,6 +377,10 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board) switchConfig[i].type = info.dflt; switchConfig[i].inverted = info.inverted; switchConfig[i].inputIdx = SWITCH_INPUTINDEX_NONE; + if (Boards::isSwitchFunc(i)) { + switchConfig[i].start = ModelData::FUNC_SWITCH_START_PREVIOUS; + switchConfig[i].onColor.setColor(255, 255, 255); + } } for (uint8_t i = 0; i < 4; i++) { diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index 2f6827dff..75d704f3b 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -61,6 +61,17 @@ enum UartModes { UART_MODE_DEBUG }; +class RGBLedColor { + public: + RGBLedColor() { clear(); } + int r; + int g; + int b; + void clear() { memset(reinterpret_cast(this), 0, sizeof(RGBLedColor)); } + void setColor(int red, int green, int blue) { r = red; g = green; b = blue; } + QColor getQColor() { return QColor(r, g, b); } +}; + class TrainerMix { Q_DECLARE_TR_FUNCTIONS(TrainerMix) @@ -362,6 +373,12 @@ class GeneralSettings { Board::SwitchType type; bool inverted; int inputIdx; // used if switch tag = FLn, value -1 = none selected + // CFS settings + unsigned int start; + unsigned int onColorLuaOverride; + unsigned int offColorLuaOverride; + RGBLedColor onColor; + RGBLedColor offColor; }; SwitchConfig switchConfig[CPN_MAX_SWITCHES]; @@ -377,6 +394,7 @@ class GeneralSettings { bool isInputFlexSwitchAvailable(int index) const; bool isSwitchAvailable(int index) const; bool isSwitchFlex(int index) const; + bool isSwitchFunc(int index) const; bool unassignedInputFlexSwitches() const; QString antennaModeToString() const; diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 840ffb193..c574fc467 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -223,8 +223,13 @@ void ModelData::setDefaultFunctionSwitches(int functionSwitchCount) return; for (int i = 0; i < functionSwitchCount; i++) { - setFuncSwitchConfig(i, Board::SWITCH_2POS); - setFuncSwitchGroup(i, 1); + customSwitches[i].type = Board::SWITCH_GLOBAL; + customSwitches[i].group = 0; + customSwitches[i].start = ModelData::FUNC_SWITCH_START_PREVIOUS; + customSwitches[i].state = 0; + customSwitches[i].name[0] = 0; + customSwitches[i].onColor.setColor(255, 255, 255); + customSwitches[i].offColor.setColor(0, 0, 0); } } @@ -389,20 +394,18 @@ int ModelData::getChannelsMax(bool forceExtendedLimits) const return 100; } -bool ModelData::isFunctionSwitchPositionAvailable(int index) const +bool ModelData::isFunctionSwitchPositionAvailable(int swIndex, int swPos, const GeneralSettings * const gs) const { - if (index == 0) - return true; - - div_t qr = div(abs(index) - 1, 3); - int fs = getFuncSwitchConfig(qr.quot); - - if (qr.rem == 1) { + if (swPos == 1) return false; - } - else { - return fs != Board::SWITCH_NOT_AVAILABLE; - } + + int fsindex = Boards::getCFSIndexForSwitch(swIndex); + int fs = getFuncSwitchConfig(fsindex); + + if (fs == Board::SWITCH_GLOBAL) + return gs->switchConfig[swIndex].type != Board::SWITCH_NOT_AVAILABLE; + + return true; } bool ModelData::isFunctionSwitchSourceAllowed(int index) const @@ -1747,30 +1750,32 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings return mdl; } -unsigned int ModelData::getFuncSwitchConfig(unsigned int index) const +Board::SwitchType ModelData::getFuncSwitchConfig(unsigned int index) const { if (index < CPN_MAX_SWITCHES_FUNCTION) - return Helpers::getBitmappedValue(functionSwitchConfig, index, 2); + return customSwitches[index].type; else - return FUNC_SWITCH_CONFIG_NONE; + return Board::SWITCH_NOT_AVAILABLE; } -void ModelData::setFuncSwitchConfig(unsigned int index, unsigned int value) +void ModelData::setFuncSwitchConfig(unsigned int index, Board::SwitchType value) { if (index < CPN_MAX_SWITCHES_FUNCTION) - Helpers::setBitmappedValue(functionSwitchConfig, value, index, 2); + customSwitches[index].type = value; } // static QString ModelData::funcSwitchConfigToString(unsigned int value) { switch (value) { - case FUNC_SWITCH_CONFIG_NONE: + case Board::SWITCH_NOT_AVAILABLE: return tr("NONE"); - case FUNC_SWITCH_CONFIG_TOGGLE: + case Board::SWITCH_TOGGLE: return tr("TOGGLE"); - case FUNC_SWITCH_CONFIG_2POS: + case Board::SWITCH_2POS: return tr("2POS"); + case Board::SWITCH_GLOBAL: + return tr("Global"); default: return CPN_STR_UNKNOWN_ITEM; } @@ -1781,7 +1786,7 @@ AbstractStaticItemModel * ModelData::funcSwitchConfigItemModel() { AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); mdl->setName(AIM_MODELDATA_FUNCSWITCHCONFIG); - for (unsigned int i = FUNC_SWITCH_CONFIG_FIRST; i <= FUNC_SWITCH_CONFIG_LAST; i++) { + for (unsigned int i = Board::SWITCH_NOT_AVAILABLE; i <= Board::SWITCH_GLOBAL; i++) { mdl->appendToItemList(funcSwitchConfigToString(i), i); } mdl->loadItemList(); @@ -1809,7 +1814,7 @@ AbstractStaticItemModel * ModelData::funcSwitchGroupsModel() mdl->setName(AIM_MODELDATA_FUNCSWITCHGROUPS); mdl->appendToItemList(tr("---"), 0); - for (unsigned int i = 1; i <= 3; i += 1) { + for (unsigned int i = 1; i <= Boards::getCapability(getCurrentBoard(), Board::FunctionSwitchGroups); i += 1) { mdl->appendToItemList(tr("Group ") + QString::number(i), i); } @@ -1820,7 +1825,7 @@ AbstractStaticItemModel * ModelData::funcSwitchGroupsModel() unsigned int ModelData::getFuncSwitchGroup(unsigned int index) const { if (index < CPN_MAX_SWITCHES_FUNCTION) - return Helpers::getBitmappedValue(functionSwitchGroup, index, 2); + return customSwitches[index].group; else return 0; } @@ -1828,14 +1833,13 @@ unsigned int ModelData::getFuncSwitchGroup(unsigned int index) const void ModelData::setFuncSwitchGroup(unsigned int index, unsigned int value) { if (index < CPN_MAX_SWITCHES_FUNCTION) - Helpers::setBitmappedValue(functionSwitchGroup, value, index, 2); + customSwitches[index].group = value; } unsigned int ModelData::getFuncSwitchAlwaysOnGroup(unsigned int group) const { - if (group > 0 && group < 4) { - unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches); - return Helpers::getBitmappedValue(functionSwitchGroup, group, 1, 2 * switchcnt); + if (group > 0 && group <= Boards::getCapability(getCurrentBoard(), Board::FunctionSwitchGroups)) { + return cfsGroupOn[group]; } else return 0; @@ -1851,16 +1855,15 @@ unsigned int ModelData::getFuncSwitchAlwaysOnGroupForSwitch(unsigned int index) void ModelData::setFuncSwitchAlwaysOnGroup(unsigned int group, unsigned int value) { - if (group > 0 && group < 4) { - unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches); - Helpers::setBitmappedValue(functionSwitchGroup, value, group, 1, 2 * switchcnt); + if (group > 0 && group <= Boards::getCapability(getCurrentBoard(), Board::FunctionSwitchGroups)) { + cfsGroupOn[group] = value; } } unsigned int ModelData::getFuncSwitchStart(unsigned int index) const { if (index < CPN_MAX_SWITCHES_FUNCTION) - return Helpers::getBitmappedValue(functionSwitchStartConfig, index, 2); + return customSwitches[index].start; else return FUNC_SWITCH_START_OFF; } @@ -1868,7 +1871,7 @@ unsigned int ModelData::getFuncSwitchStart(unsigned int index) const void ModelData::setFuncSwitchStart(unsigned int index, unsigned int value) { if (index < CPN_MAX_SWITCHES_FUNCTION) - Helpers::setBitmappedValue(functionSwitchStartConfig, value, index, 2); + customSwitches[index].start = value; } int ModelData::getFuncGroupSwitchCount(unsigned int group, int switchcnt) const @@ -1916,7 +1919,7 @@ void ModelData::setGroupSwitchState(uint8_t group, int switchcnt) if (getFuncSwitchAlwaysOnGroup(group)) { for (int j = 0; j < switchcnt; j += 1) { if (getFuncSwitchGroup(j) == group) { - setFuncSwitchConfig(j, FUNC_SWITCH_CONFIG_2POS); // Toggle not valid + setFuncSwitchConfig(j, Board::SWITCH_2POS); // Toggle not valid } } if (getFuncGroupSwitchStart(group, switchcnt) == (unsigned int)switchcnt + 1) { @@ -2026,3 +2029,16 @@ int ModelData::getInputLine(int index) const return cnt; } + +const Board::SwitchType ModelData::getSwitchType(int sw, const GeneralSettings & gs) const +{ + if (sw < 0 || sw >= Boards::getCapability(getCurrentBoard(), Board::Switches)) + return Board::SWITCH_NOT_AVAILABLE; + + if (Boards::isSwitchFunc(sw)) { + int fsIndex = Boards::getCFSIndexForSwitch(sw); + if (customSwitches[fsIndex].type != Board::SWITCH_GLOBAL) + return customSwitches[fsIndex].type; + } + return gs.switchConfig[sw].type; +} diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 809568aa8..1424a7afd 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -104,13 +104,19 @@ class USBJoystickChData { void clear() { memset(reinterpret_cast(this), 0, sizeof(USBJoystickChData)); } }; -class RGBLedColor { +class customSwitch { public: - RGBLedColor() { clear(); } - int r; - int g; - int b; - void clear() { memset(reinterpret_cast(this), 0, sizeof(RGBLedColor)); } + customSwitch() { clear(); } + Board::SwitchType type; + unsigned int group; + unsigned int start; + unsigned int state; + char name[HARDWARE_NAME_LEN + 1]; + unsigned int onColorLuaOverride; + unsigned int offColorLuaOverride; + RGBLedColor onColor; + RGBLedColor offColor; + void clear() { memset(reinterpret_cast(this), 0, sizeof(customSwitch)); } }; class ModelData { @@ -171,7 +177,6 @@ class ModelData { SwashRingData swashRingData; unsigned int thrTraceSrc; uint64_t switchWarningStates; - unsigned int switchWarningEnable; unsigned int thrTrimSwitch; unsigned int potsWarningMode; bool potsWarnEnabled[CPN_MAX_INPUTS]; @@ -220,30 +225,17 @@ class ModelData { unsigned int modelCustomScriptsDisabled; unsigned int modelTelemetryDisabled; - enum FunctionSwitchConfig { - FUNC_SWITCH_CONFIG_NONE, - FUNC_SWITCH_CONFIG_FIRST = FUNC_SWITCH_CONFIG_NONE, - FUNC_SWITCH_CONFIG_TOGGLE, - FUNC_SWITCH_CONFIG_2POS, - FUNC_SWITCH_CONFIG_LAST = FUNC_SWITCH_CONFIG_2POS - }; - enum FunctionSwitchStart { - FUNC_SWITCH_START_ON, - FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_ON, FUNC_SWITCH_START_OFF, + FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_OFF, + FUNC_SWITCH_START_ON, FUNC_SWITCH_START_PREVIOUS, FUNC_SWITCH_START_LAST = FUNC_SWITCH_START_PREVIOUS }; // Function switches - unsigned int functionSwitchConfig; - unsigned int functionSwitchGroup; - unsigned int functionSwitchStartConfig; - unsigned int functionSwitchLogicalState; - char functionSwitchNames[CPN_MAX_SWITCHES_FUNCTION][HARDWARE_NAME_LEN + 1]; - RGBLedColor functionSwitchLedONColor[CPN_MAX_SWITCHES_FUNCTION]; - RGBLedColor functionSwitchLedOFFColor[CPN_MAX_SWITCHES_FUNCTION]; + customSwitch customSwitches[CPN_MAX_SWITCHES_FUNCTION]; + unsigned int cfsGroupOn[4]; // Custom USB joytsick mapping unsigned int usbJoystickExtMode; @@ -287,9 +279,11 @@ class ModelData { int getChannelsMax(bool forceExtendedLimits=false) const; bool isAvailable(const RawSwitch & swtch) const; - bool isFunctionSwitchPositionAvailable(int index) const; + bool isFunctionSwitchPositionAvailable(int swIndex, int swPos, const GeneralSettings * const gs) const; bool isFunctionSwitchSourceAllowed(int index) const; + const Board::SwitchType getSwitchType(int sw, const GeneralSettings & gs) const; + enum ReferenceUpdateAction { REF_UPD_ACT_CLEAR, REF_UPD_ACT_SHIFT, @@ -344,8 +338,8 @@ class ModelData { static QString trainerModeToString(const int value); bool isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value); AbstractStaticItemModel * trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware); - unsigned int getFuncSwitchConfig(unsigned int index) const; - void setFuncSwitchConfig(unsigned int index, unsigned int value); + Board::SwitchType getFuncSwitchConfig(unsigned int index) const; + void setFuncSwitchConfig(unsigned int index, Board::SwitchType value); static QString funcSwitchConfigToString(unsigned int value); static AbstractStaticItemModel * funcSwitchConfigItemModel(); static AbstractStaticItemModel * funcSwitchGroupStartSwitchModel(int switchcnt); diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp index bcb591788..98bdcfe23 100644 --- a/companion/src/firmwares/rawsource.cpp +++ b/companion/src/firmwares/rawsource.cpp @@ -203,7 +203,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con if (model) { int fsindex = Boards::getSwitchTagNum(index - 1, board) - 1; if (fsindex >= 0 && fsindex < CPN_MAX_SWITCHES_FUNCTION) - custName = QString(model->functionSwitchNames[fsindex]).trimmed(); + custName = QString(model->customSwitches[fsindex].name).trimmed(); } } else { diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index f9f73a2bf..196048626 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -93,7 +93,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen if (Boards::isSwitchFunc(qr.quot, board)) { if (modelData) { int fsindex = Boards::getSwitchTagNum(qr.quot, board) - 1; - custName = QString(modelData->functionSwitchNames[fsindex]).trimmed(); + custName = QString(modelData->customSwitches[fsindex].name).trimmed(); } } else { @@ -205,8 +205,7 @@ bool RawSwitch::isAvailable(const ModelData * const model, const GeneralSettings if (model) { if (type == SWITCH_TYPE_SWITCH && b.isSwitchFunc(sw.quot, board)) { - int fsindex = (((Boards::getSwitchTagNum(sw.quot, board) - 1) * 3) + sw.rem + 1) * ( index < 0 ? -1 : 1); - return model->isFunctionSwitchPositionAvailable(fsindex); + return model->isFunctionSwitchPositionAvailable(sw.quot, sw.rem, gs); } else return model->isAvailable(*this); diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 9bce66ab6..b69531350 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -140,6 +140,9 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings count = Boards::getCapability(board, Board::Sticks); if (count > 0) { + addLabel(""); + addLabel(tr("Name")); + addParams(); for (int i = 0; i < count; i++) { addStick(i); } @@ -158,22 +161,46 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings if (count > 0) { addSection(tr("Pots")); + addLabel(""); + addLabel(tr("Name")); + addLabel(tr("Type")); + addLabel(tr("Invert")); + addParams(); for (int i = Boards::getCapability(board, Board::Sticks); i < count; i++) { if (Boards::isInputConfigurable(i, board)) addFlex(i); } } - count = Boards::getCapability(board, Board::Switches); + if (Boards::getCapability(board, Board::Switches)) { + addSection(tr("Switches")); - if (count) { + addLabel(""); + addLabel(tr("Name")); + addLabel(tr("Type")); + addParams(); + + for (int i = 0; i < CPN_MAX_SWITCHES; i++) { + if (Boards::isSwitchConfigurable(i, board) && !generalSettings.isSwitchFunc(i) && !generalSettings.isSwitchFlex(i)) + addSwitch(i); + } + } + + if (Boards::getCapability(board, Board::FlexSwitches)) { // All values except -1 (None) are mutually exclusive exclFlexSwitchesGroup = new ExclusiveComboGroup( this, [=](const QVariant &value) { return value == -1; }); - addSection(tr("Switches")); - for (int i = 0; i < count && i < CPN_MAX_SWITCHES; i++) { - if (Boards::isSwitchConfigurable(i, board)) + addSection(tr("Flex Switches")); + + addLabel(""); + addLabel(tr("Name")); + addLabel(tr("Source")); + addLabel(tr("Type")); + addParams(); + + for (int i = 0; i < CPN_MAX_SWITCHES; i++) { + if (Boards::isSwitchConfigurable(i, board) && generalSettings.isSwitchFlex(i)) addSwitch(i); } @@ -184,6 +211,27 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings } } + if (Boards::getCapability(board, Board::FunctionSwitches)) { + addSection(tr("Customisable Switches")); + + addLabel(""); + addLabel(tr("Name")); + addLabel(tr("Type")); + addLabel(tr("Start")); + if (Boards::getCapability(board, Board::FunctionSwitchColors)) { + addLabel(tr("Off color")); + addLabel(tr("Lua override")); + addLabel(tr("On color")); + addLabel(tr("Lua override")); + } + addParams(); + + for (int i = 0; i < CPN_MAX_SWITCHES; i++) { + if (Boards::isSwitchConfigurable(i, board) && generalSettings.isSwitchFunc(i)) + addSwitch(i); + } + } + addLine(); if (Boards::getCapability(board, Board::HasRTC)) { @@ -502,7 +550,9 @@ void HardwarePanel::addSwitch(int index) GeneralSettings::SwitchConfig &config = generalSettings.switchConfig[index]; Board::SwitchInfo info = Boards::getSwitchInfo(index); - addLabel(Boards::getSwitchName(index)); + QLabel *label = new QLabel(this); + label->setText(Boards::getSwitchName(index)); + params->append(label); AutoLineEdit *name = new AutoLineEdit(this); name->setValidator(new NameValidator(board, this)); @@ -550,6 +600,76 @@ void HardwarePanel::addSwitch(int index) }); } + if (generalSettings.isSwitchFunc(index)) { + AutoComboBox *start = new AutoComboBox(this); + start->setSizeAdjustPolicy(QComboBox::AdjustToContents); + AbstractStaticItemModel *fsStart = ModelData::funcSwitchStartItemModel(); + start->setModel(fsStart); + int & swstart = (int &)config.start; + start->setField(swstart, this); + start->setEnabled(config.type == Board::SWITCH_2POS); + params->append(start); + + connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { + start->setEnabled(val == Board::SWITCH_2POS); + }); + + if (Boards::getCapability(board, Board::FunctionSwitchColors)) { + const QString qss = QString("border-style: outset; border-width: 2px; border-radius: 5px; border-color: darkgrey; padding: 2px; background-color: %1;"); + QPushButton * btnOffColor = new QPushButton(); + QColor off = generalSettings.switchConfig[index].offColor.getQColor(); + btnOffColor->setStyleSheet(QString(qss).arg(off.name())); + connect(btnOffColor, &QPushButton::clicked, [=]() { + QColorDialog *dlg = new QColorDialog(); + QColor color = dlg->getColor(generalSettings.switchConfig[index].offColor.getQColor()); + if (color.isValid()) { + generalSettings.switchConfig[index].offColor.setColor(color.red(), color.green(), color.blue()); + btnOffColor->setStyleSheet(QString(qss).arg(color.name())); + emit modified(); + } + }); + params->append(btnOffColor); + connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { + btnOffColor->setEnabled(val != Board::SWITCH_NOT_AVAILABLE); }); + + QCheckBox * cbOffLuaOverride = new QCheckBox(this); + cbOffLuaOverride->setChecked(generalSettings.switchConfig[index].offColorLuaOverride); + connect(cbOffLuaOverride, &QCheckBox::toggled, [=](int value) { + generalSettings.switchConfig[index].offColorLuaOverride = value; + emit modified(); + }); + params->append(cbOffLuaOverride); + connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { + cbOffLuaOverride->setEnabled(val != Board::SWITCH_NOT_AVAILABLE); }); + + QPushButton * btnOnColor = new QPushButton(tr("")); + QColor on = generalSettings.switchConfig[index].onColor.getQColor(); + btnOnColor->setStyleSheet(QString(qss).arg(on.name())); + connect(btnOnColor, &QPushButton::clicked, [=]() { + QColorDialog *dlg = new QColorDialog(); + QColor color = dlg->getColor(generalSettings.switchConfig[index].onColor.getQColor()); + if (color.isValid()) { + generalSettings.switchConfig[index].onColor.setColor(color.red(), color.green(), color.blue()); + btnOnColor->setStyleSheet(QString(qss).arg(color.name())); + emit modified(); + } + }); + params->append(btnOnColor); + connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { + btnOnColor->setEnabled(val != Board::SWITCH_NOT_AVAILABLE); }); + + QCheckBox * cbOnLuaOverride = new QCheckBox(this); + cbOnLuaOverride->setChecked(generalSettings.switchConfig[index].onColorLuaOverride); + connect(cbOnLuaOverride, &QCheckBox::toggled, [=](int value) { + generalSettings.switchConfig[index].onColorLuaOverride = value; + emit modified(); + }); + params->append(cbOnLuaOverride); + connect(type, &AutoComboBox::currentDataChanged, [=] (int val) { + cbOnLuaOverride->setEnabled(val != Board::SWITCH_NOT_AVAILABLE); }); + } + } + addParams(); } @@ -557,7 +677,7 @@ void HardwarePanel::addLabel(QString text) { QLabel *label = new QLabel(this); label->setText(text); - grid->addWidget(label, row, 0); + params->append(label); } void HardwarePanel::addLine() @@ -572,22 +692,18 @@ void HardwarePanel::addLine() void HardwarePanel::addParams() { - int col = 0; - QGridLayout *subgrid = new QGridLayout(); - for (int i = 0; i < params->size(); i++) { - subgrid->addWidget(params->at(i), 0, col++); + grid->addWidget(params->at(i), row, i); } - addHSpring(subgrid, col, 0); - grid->addLayout(subgrid, row++, 1); + row += 1; params->clear(); } void HardwarePanel::addSection(QString text) { addLabel(QString("%1").arg(text)); - row++; + addParams(); } void HardwarePanel::updateSerialPortUSBVCP() diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 924095d22..61b22d99b 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -219,12 +219,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge // Startup switches warnings for (int i = 0; i < Boards::getBoardCapability(board, Board::Switches); i++) { - GeneralSettings::SwitchConfig &swcfg = generalSettings.switchConfig[i]; - - if (Boards::isSwitchFunc(i, board) || !generalSettings.isSwitchAvailable(i) || swcfg.type == Board::SWITCH_TOGGLE) { - model.switchWarningEnable |= (1 << i); - continue; - } + Board::SwitchType swType = model.getSwitchType(i, generalSettings); RawSource src(RawSourceType::SOURCE_TYPE_SWITCH, i + 1); QLabel * label = new QLabel(this); @@ -242,7 +237,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge slider->setPageStep(1); slider->setTickInterval(1); label->setText(src.toString(&model, &generalSettings)); - slider->setMaximum(swcfg.type == Board::SWITCH_3POS ? 2 : 1); + slider->setMaximum(swType == Board::SWITCH_3POS ? 2 : 1); cb->setProperty("index", i); ui->switchesStartupLayout->addWidget(label, 0, i + 1); ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter); @@ -252,6 +247,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int))); connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool))); + startupSwitchesLabels << label; startupSwitchesSliders << slider; startupSwitchesCheckboxes << cb; QWidget::setTabOrder(prevFocus, slider); @@ -338,6 +334,12 @@ SetupPanel::~SetupPanel() delete panelItemModels; } +bool SetupPanel::canSwitchHaveWarning(int sw) +{ + Board::SwitchType type = model->getSwitchType(sw, generalSettings); + return (type == Board::SWITCH_2POS) || (type == Board::SWITCH_3POS); +} + void SetupPanel::on_extendedLimits_toggled(bool checked) { model->extendedLimits = checked; @@ -510,23 +512,20 @@ void SetupPanel::updateStartupSwitches() uint64_t value; for (int i = 0; i < startupSwitchesSliders.size(); i++) { + QLabel * label = startupSwitchesLabels[i]; QSlider * slider = startupSwitchesSliders[i]; QCheckBox * cb = startupSwitchesCheckboxes[i]; int index = slider->property("index").toInt(); - bool enabled = !(model->switchWarningEnable & (1 << index)); - if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - value = (switchStates >> (2 * index)) & 0x03; - if (generalSettings.switchConfig[index].type != Board::SWITCH_3POS && value == 2) { - value = 1; - } - } - else { - value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1); - switchStates >>= (i == 0 ? 2 : 1); - } - slider->setValue(value); + value = (switchStates >> (2 * index)) & 0x03; + bool enabled = value != 0; + if (model->getSwitchType(i, generalSettings) == Board::SWITCH_2POS && value == 3) value = 2; + slider->setValue((value > 0) ? value - 1 : 0); slider->setEnabled(enabled); cb->setChecked(enabled); + bool vis = canSwitchHaveWarning(i); + label->setVisible(vis); + slider->setVisible(vis); + cb->setVisible(vis); } lock = false; @@ -539,31 +538,14 @@ void SetupPanel::startupSwitchEdited(int value) uint64_t mask; int index = sender()->property("index").toInt(); - if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - shift = index * 2; - mask = 0x03ull << shift; - } - else { - if (index == 0) { - mask = 0x03; - } - else { - shift = index + 1; - mask = 0x01ull << shift; - } - } + shift = index * 2; + mask = 0x03ull << shift; model->switchWarningStates &= ~mask; - if (IS_HORUS_OR_TARANIS(firmware->getBoard()) && generalSettings.switchConfig[index].type != Board::SWITCH_3POS) { - if (value == 1) { - value = 2; - } - } + if (model->getSwitchType(index, generalSettings) == Board::SWITCH_2POS && value == 1) value = 2; - if (value) { - model->switchWarningStates |= ((uint64_t)value << shift); - } + model->switchWarningStates |= ((uint64_t)(value + 1) << shift); updateStartupSwitches(); emit modified(); @@ -576,9 +558,9 @@ void SetupPanel::startupSwitchToggled(bool checked) int index = sender()->property("index").toInt(); if (checked) - model->switchWarningEnable &= ~(1 << index); + model->switchWarningStates |= (1 << (index * 2)); else - model->switchWarningEnable |= (1 << index); + model->switchWarningStates &= ~(3 << (index * 2)); updateStartupSwitches(); emit modified(); @@ -866,5 +848,6 @@ void SetupPanel::onModuleUpdateItemModels() void SetupPanel::onFunctionSwitchesUpdateItemModels() { + updateStartupSwitches(); sharedItemModels->update(AbstractItemModel::IMUE_FunctionSwitches); } diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 4407e139c..8ed030b95 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -89,6 +89,7 @@ class SetupPanel : public ModelPanel private: Ui::Setup *ui; + QVector startupSwitchesLabels; QVector startupSwitchesSliders; QVector startupSwitchesCheckboxes; QVector potWarningCheckboxes; @@ -97,6 +98,7 @@ class SetupPanel : public ModelPanel TimerPanel * timers[CPN_MAX_TIMERS]; FunctionSwitchesPanel * funcswitches; + bool canSwitchHaveWarning(int sw); void updateStartupSwitches(); void updatePotWarnings(); void updateBeepCenter(); diff --git a/companion/src/modeledit/setup_function_switches.cpp b/companion/src/modeledit/setup_function_switches.cpp index c53a0a3bd..6cd876ab0 100644 --- a/companion/src/modeledit/setup_function_switches.cpp +++ b/companion/src/modeledit/setup_function_switches.cpp @@ -23,6 +23,7 @@ #include "ui_setup_function_switches.h" #include "namevalidator.h" #include "autolineedit.h" +#include #include @@ -42,13 +43,16 @@ bool FilteredGroupSwitchesModel::filterAcceptsRow(int sourceRow, const QModelInd bool FilteredSwitchGroupsModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const { if (sourceRow == 0) return true; - if (m_model->getFuncSwitchConfig(m_switch) == ModelData::FUNC_SWITCH_CONFIG_NONE) return false; + if (m_model->getFuncSwitchConfig(m_switch) == Board::SWITCH_NOT_AVAILABLE) return false; return true; } bool FilteredSwitchConfigsModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const { - if (sourceRow == ModelData::FUNC_SWITCH_CONFIG_NONE || sourceRow == ModelData::FUNC_SWITCH_CONFIG_2POS) return true; + if (sourceRow == Board::SWITCH_3POS) + return false; + if (sourceRow == Board::SWITCH_NOT_AVAILABLE || sourceRow == Board::SWITCH_2POS || sourceRow == Board::SWITCH_GLOBAL) + return true; return !m_model->getFuncSwitchAlwaysOnGroupForSwitch(m_switch); } @@ -70,51 +74,122 @@ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model fsGroupStart = ModelData::funcSwitchGroupStartSwitchModel(switchcnt); - for (int i = 0; i < switchcnt; i++) { - QLabel * lblSwitchId = new QLabel(this); - lblSwitchId->setText(tr("SW%1").arg(i + 1)); - - AutoLineEdit * aleName = new AutoLineEdit(this); - aleName->setProperty("index", i); - aleName->setValidator(new NameValidator(board, this)); - aleName->setField((char *)model.functionSwitchNames[i], 3); - - QComboBox * cboConfig = new QComboBox(this); - cboConfig->setProperty("index", i); - auto configFilter = new FilteredSwitchConfigsModel(fsConfig, i, &model); - cboConfig->setModel(configFilter); - filterSwitchConfigs << configFilter; - - QComboBox * cboStartPosn = new QComboBox(this); - cboStartPosn->setProperty("index", i); - cboStartPosn->setModel(fsStart); - - QComboBox * cboGroup = new QComboBox(this); - cboGroup->setProperty("index", i); - auto groupFilter = new FilteredSwitchGroupsModel(fsGroups, i, &model); - cboGroup->setModel(groupFilter); - filterSwitchGroups << groupFilter; - - int row = 0; - int coloffset = 1; - ui->gridSwitches->addWidget(lblSwitchId, row++, i + coloffset); - ui->gridSwitches->addWidget(aleName, row++, i + coloffset); - ui->gridSwitches->addWidget(cboConfig, row++, i + coloffset); - ui->gridSwitches->addWidget(cboStartPosn, row++, i + coloffset); - ui->gridSwitches->addWidget(cboGroup, row++, i + coloffset); - - connect(aleName, &AutoLineEdit::currentDataChanged, this, &FunctionSwitchesPanel::on_nameEditingFinished); - connect(cboConfig, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_configCurrentIndexChanged); - connect(cboStartPosn, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_startPosnCurrentIndexChanged); - connect(cboGroup, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_groupChanged); - - aleNames << aleName; - cboConfigs << cboConfig; - cboStartupPosns << cboStartPosn; - cboGroups << cboGroup; + if (Boards::getCapability(board, Board::FunctionSwitchColors)) { + QLabel * lblOffColor = new QLabel(this); + lblOffColor->setText(tr("Off color")); + ui->gridSwitches->addWidget(lblOffColor, 5, 0); + QLabel * lblOffLua = new QLabel(this); + lblOffLua->setText(tr(" Allow Lua override")); + ui->gridSwitches->addWidget(lblOffLua, 6, 0); + QLabel * lblOnColor = new QLabel(this); + lblOnColor->setText(tr("On color")); + ui->gridSwitches->addWidget(lblOnColor, 7, 0); + QLabel * lblOnLua = new QLabel(this); + lblOnLua->setText(tr(" Allow Lua override")); + ui->gridSwitches->addWidget(lblOnLua, 8, 0); } - for (int i = 0; i < 3; i += 1) { + for (int sw = 0, col = 0; sw < Boards::getCapability(board, Board::Switches); sw++) { + int i = Boards::getCFSIndexForSwitch(sw); + if (i >= 0) { + QLabel * lblSwitchId = new QLabel(this); + lblSwitchId->setText(Boards::getSwitchName(sw)); + + AutoLineEdit * aleName = new AutoLineEdit(this); + aleName->setProperty("index", i); + aleName->setValidator(new NameValidator(board, this)); + aleName->setField((char *)model.customSwitches[i].name, 3); + + QComboBox * cboConfig = new QComboBox(this); + cboConfig->setProperty("index", i); + auto configFilter = new FilteredSwitchConfigsModel(fsConfig, i, &model); + cboConfig->setModel(configFilter); + filterSwitchConfigs << configFilter; + + QComboBox * cboStartPosn = new QComboBox(this); + cboStartPosn->setProperty("index", i); + cboStartPosn->setModel(fsStart); + + QComboBox * cboGroup = new QComboBox(this); + cboGroup->setProperty("index", i); + auto groupFilter = new FilteredSwitchGroupsModel(fsGroups, i, &model); + cboGroup->setModel(groupFilter); + filterSwitchGroups << groupFilter; + + int row = 0; + int coloffset = 1; + ui->gridSwitches->addWidget(lblSwitchId, row++, col + coloffset); + ui->gridSwitches->addWidget(aleName, row++, col + coloffset); + ui->gridSwitches->addWidget(cboConfig, row++, col + coloffset); + ui->gridSwitches->addWidget(cboStartPosn, row++, col + coloffset); + ui->gridSwitches->addWidget(cboGroup, row++, col + coloffset); + + if (Boards::getCapability(board, Board::FunctionSwitchColors)) { + const QString qss = QString("border-style: outset; border-width: 2px; border-radius: 5px; border-color: darkgrey; padding: 2px; background-color: %1;"); + QPushButton * btnOffColor = new QPushButton(tr("")); + QColor off = this->model->customSwitches[i].offColor.getQColor(); + btnOffColor->setStyleSheet(QString(qss).arg(off.name())); + connect(btnOffColor, &QPushButton::clicked, [=]() { + QColorDialog *dlg = new QColorDialog(); + QColor color = dlg->getColor(this->model->customSwitches[i].offColor.getQColor()); + if (color.isValid()) { + this->model->customSwitches[i].offColor.setColor(color.red(), color.green(), color.blue()); + btnOffColor->setStyleSheet(QString(qss).arg(color.name())); + emit modified(); + } + }); + ui->gridSwitches->addWidget(btnOffColor, row++, col + coloffset); + btnOffColors << btnOffColor; + + QCheckBox * cbOffLuaOverride = new QCheckBox(this); + cbOffLuaOverride->setChecked(this->model->customSwitches[i].offColorLuaOverride); + connect(cbOffLuaOverride, &QCheckBox::toggled, [=](int value) { + this->model->customSwitches[i].offColorLuaOverride = value; + emit modified(); + }); + ui->gridSwitches->addWidget(cbOffLuaOverride, row++, col + coloffset); + cbOffLuaOverrides << cbOffLuaOverride; + + QPushButton * btnOnColor = new QPushButton(tr("")); + QColor on = this->model->customSwitches[i].onColor.getQColor(); + btnOnColor->setStyleSheet(QString(qss).arg(on.name())); + connect(btnOnColor, &QPushButton::clicked, [=]() { + QColorDialog *dlg = new QColorDialog(); + QColor color = dlg->getColor(this->model->customSwitches[i].onColor.getQColor()); + if (color.isValid()) { + this->model->customSwitches[i].onColor.setColor(color.red(), color.green(), color.blue()); + btnOnColor->setStyleSheet(QString(qss).arg(color.name())); + emit modified(); + } + }); + ui->gridSwitches->addWidget(btnOnColor, row++, col + coloffset); + btnOnColors << btnOnColor; + + QCheckBox * cbOnLuaOverride = new QCheckBox(this); + cbOnLuaOverride->setChecked(this->model->customSwitches[i].onColorLuaOverride); + connect(cbOnLuaOverride, &QCheckBox::toggled, [=](int value) { + this->model->customSwitches[i].onColorLuaOverride = value; + emit modified(); + }); + ui->gridSwitches->addWidget(cbOnLuaOverride, row++, col + coloffset); + cbOnLuaOverrides << cbOnLuaOverride; + } + + connect(aleName, &AutoLineEdit::currentDataChanged, this, &FunctionSwitchesPanel::on_nameEditingFinished); + connect(cboConfig, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_configCurrentIndexChanged); + connect(cboStartPosn, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_startPosnCurrentIndexChanged); + connect(cboGroup, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_groupChanged); + + aleNames << aleName; + cboConfigs << cboConfig; + cboStartupPosns << cboStartPosn; + cboGroups << cboGroup; + + col += 1; + } + } + + for (int i = 0; i < Boards::getCapability(board, Board::FunctionSwitchGroups); i += 1) { QLabel * lblGroupId = new QLabel(this); lblGroupId->setText(tr("Group %1").arg(i + 1)); @@ -154,22 +229,37 @@ void FunctionSwitchesPanel::update() { lock = true; - for (int i = 0; i < switchcnt; i++) { - filterSwitchConfigs[i]->invalidate(); - filterSwitchGroups[i]->invalidate(); + Board::Type board = firmware->getBoard(); - aleNames[i]->update(); - cboConfigs[i]->setCurrentIndex(filterSwitchConfigs[i]->mapFromSource(fsConfig->index(model->getFuncSwitchConfig(i), 0)).row()); - cboStartupPosns[i]->setCurrentIndex(model->getFuncSwitchStart(i)); - unsigned int grp = model->getFuncSwitchGroup(i); - cboGroups[i]->setCurrentIndex(grp); + for (int sw = 0, col = 0; sw < Boards::getCapability(firmware->getBoard(), Board::Switches); sw++) { + int i = Boards::getCFSIndexForSwitch(sw); + if (i >= 0) { + filterSwitchConfigs[col]->invalidate(); + filterSwitchGroups[col]->invalidate(); - cboStartupPosns[i]->setEnabled(cboConfigs[i]->currentIndex() >= ModelData::FUNC_SWITCH_CONFIG_2POS && (grp == 0)); + unsigned int cfg = model->getFuncSwitchConfig(i); + unsigned int grp = model->getFuncSwitchGroup(i); - cboGroups[i]->setEnabled(cboConfigs[i]->currentIndex() >= ModelData::FUNC_SWITCH_CONFIG_TOGGLE); + aleNames[col]->update(); + cboConfigs[col]->setCurrentIndex(filterSwitchConfigs[col]->mapFromSource(fsConfig->index(cfg, 0)).row()); + cboStartupPosns[col]->setCurrentIndex(model->getFuncSwitchStart(i)); + cboGroups[col]->setCurrentIndex(grp); + + cboStartupPosns[col]->setEnabled(cfg == Board::SWITCH_2POS && (grp == 0)); + cboGroups[col]->setEnabled(cfg >= Board::SWITCH_TOGGLE && cfg < Board::SWITCH_GLOBAL); + + if (Boards::getCapability(board, Board::FunctionSwitchColors)) { + btnOffColors[col]->setEnabled(cfg != Board::SWITCH_NOT_AVAILABLE && cfg != Board::SWITCH_GLOBAL); + cbOffLuaOverrides[col]->setEnabled(cfg != Board::SWITCH_NOT_AVAILABLE && cfg != Board::SWITCH_GLOBAL); + btnOnColors[col]->setEnabled(cfg != Board::SWITCH_NOT_AVAILABLE && cfg != Board::SWITCH_GLOBAL); + cbOnLuaOverrides[col]->setEnabled(cfg != Board::SWITCH_NOT_AVAILABLE && cfg != Board::SWITCH_GLOBAL); + } + + col += 1; + } } - for (int i = 0; i < 3; i += 1) { + for (int i = 0; i < Boards::getCapability(board, Board::FunctionSwitchGroups); i += 1) { filterGroupSwitches[i]->invalidate(); model->setGroupSwitchState(i + 1, switchcnt); @@ -200,10 +290,10 @@ void FunctionSwitchesPanel::on_configCurrentIndexChanged(int index) unsigned int sw = sender()->property("index").toInt(&ok); unsigned int config = filterSwitchConfigs[sw]->mapToSource(filterSwitchConfigs[sw]->index(index, 0)).row(); if (ok && model->getFuncSwitchConfig(sw) != config) { - model->setFuncSwitchConfig(sw, config); - if (config != ModelData::FUNC_SWITCH_CONFIG_2POS) { + model->setFuncSwitchConfig(sw, (Board::SwitchType)config); + if (config != Board::SWITCH_2POS && config != Board::SWITCH_GLOBAL) { model->setFuncSwitchStart(sw, ModelData::FUNC_SWITCH_START_PREVIOUS); - if ((config == ModelData::FUNC_SWITCH_CONFIG_NONE) || model->getFuncSwitchAlwaysOnGroupForSwitch(sw)) + if ((config == Board::SWITCH_NOT_AVAILABLE) || model->getFuncSwitchAlwaysOnGroupForSwitch(sw)) model->setFuncSwitchGroup(sw, 0); } update(); @@ -270,8 +360,8 @@ void FunctionSwitchesPanel::on_groupChanged(int value) if (ok && model->getFuncSwitchGroup(sw) != grp) { unsigned oldGrp = model->getFuncSwitchGroup(sw); if (model->getFuncSwitchAlwaysOnGroup(grp)) { - if (model->getFuncSwitchConfig(sw) == ModelData::FUNC_SWITCH_CONFIG_TOGGLE) - model->setFuncSwitchConfig(sw, ModelData::FUNC_SWITCH_CONFIG_2POS); + if (model->getFuncSwitchConfig(sw) == Board::SWITCH_TOGGLE) + model->setFuncSwitchConfig(sw, Board::SWITCH_2POS); } if ((grp == 0) || (model->getFuncGroupSwitchStart(grp, switchcnt) == 0)) model->setFuncSwitchStart(sw, ModelData::FUNC_SWITCH_START_PREVIOUS); @@ -304,8 +394,8 @@ void FunctionSwitchesPanel::on_alwaysOnGroupChanged(int value) model->setFuncSwitchAlwaysOnGroup(grp, (unsigned int)value); if (value) { for (int i = 0; i < switchcnt; i += 1) { - if (((int)model->getFuncSwitchGroup(i) == grp) && (model->getFuncSwitchConfig(i) == ModelData::FUNC_SWITCH_CONFIG_TOGGLE)) - model->setFuncSwitchConfig(i, ModelData::FUNC_SWITCH_CONFIG_2POS); + if (((int)model->getFuncSwitchGroup(i) == grp) && (model->getFuncSwitchConfig(i) == Board::SWITCH_TOGGLE)) + model->setFuncSwitchConfig(i, Board::SWITCH_2POS); } if ((int)model->getFuncGroupSwitchStart(grp, switchcnt) == switchcnt + 1) { for (int i = 0; i < switchcnt; i += 1) { diff --git a/companion/src/modeledit/setup_function_switches.h b/companion/src/modeledit/setup_function_switches.h index 3bf1ff687..effbc9b3f 100644 --- a/companion/src/modeledit/setup_function_switches.h +++ b/companion/src/modeledit/setup_function_switches.h @@ -157,6 +157,10 @@ class FunctionSwitchesPanel : public ModelPanel QVector cboGroups; QVector cbAlwaysOnGroups; QVector cboGroupStartupPosns; + QVector btnOffColors; + QVector cbOffLuaOverrides; + QVector btnOnColors; + QVector cbOnLuaOverrides; QVector filterGroupSwitches; QVector filterSwitchGroups; QVector filterSwitchConfigs; diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 1c28df380..12ccf93c8 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -765,20 +765,13 @@ QString ModelPrinter::printSwitchWarnings() uint64_t value; for (int i = 0; i < Boards::getCapability(board, Board::Switches); i++) { - Board::SwitchInfo switchInfo = Boards::getSwitchInfo(i); - if (switchInfo.type == Board::SWITCH_NOT_AVAILABLE || switchInfo.type == Board::SWITCH_TOGGLE) { + Board::SwitchType type = model.getSwitchType(i, generalSettings); + if (type != Board::SWITCH_2POS && type != Board::SWITCH_3POS) { continue; } - if (!(model.switchWarningEnable & (1 << i))) { - if (IS_HORUS_OR_TARANIS(board)) { - value = (switchStates >> (2 * i)) & 0x03; - } - else { - value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1); - switchStates >>= (i == 0 ? 2 : 1); - } - str += RawSwitch(SWITCH_TYPE_SWITCH, 1 + i * 3 + value).toString(board, &generalSettings, &model); - } + value = (switchStates >> (2 * i)) & 0x03; + if (value > 0) + str += RawSwitch(SWITCH_TYPE_SWITCH, i * 3 + value).toString(board, &generalSettings, &model); } return (str.isEmpty() ? tr("None") : str.join(" ")) ; } diff --git a/companion/src/multimodelprinter.cpp b/companion/src/multimodelprinter.cpp index d29cd2018..fa6c8f42c 100644 --- a/companion/src/multimodelprinter.cpp +++ b/companion/src/multimodelprinter.cpp @@ -975,7 +975,7 @@ QString MultiModelPrinter::printFunctionSwitches() columns.appendRowStart(tr("Name"), 20); for (int i = 0; i < numFS; i++) { - COMPARECELLWIDTH(model->functionSwitchNames[i], colwidth); + COMPARECELLWIDTH(model->customSwitches[i].name, colwidth); } columns.appendRowEnd(); diff --git a/companion/src/simulation/simulatorinterface.h b/companion/src/simulation/simulatorinterface.h index 19ac7ea03..2d9850eed 100644 --- a/companion/src/simulation/simulatorinterface.h +++ b/companion/src/simulation/simulatorinterface.h @@ -193,6 +193,7 @@ class SimulatorInterface : public QObject void auxSerialStart(const quint8 port_num); void auxSerialStop(const quint8 port_num); void txBatteryVoltageChanged(const int voltage); + void fsColorChange(quint8 index, qint32 color); }; class SimulatorFactory { diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index cc7312b98..b4e3e2686 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -519,6 +519,9 @@ void SimulatorWidget::setupRadioWidgets() case RadioWidget::RADIO_WIDGET_KNOB : ui->radioWidgetsHTLayout->removeWidget(rw); break; + case RadioWidget::RADIO_WIDGET_FUNC_SWITCH: + ui->radioWidgetsCSLayout->removeWidget(rw); + break; case RadioWidget::RADIO_WIDGET_FADER : case RadioWidget::RADIO_WIDGET_TRIM : ui->VCGridLayout->removeWidget(rw); @@ -534,22 +537,36 @@ void SimulatorWidget::setupRadioWidgets() // Now set up new widgets. - // switches - Board::SwitchType swcfg; - for (i = 0; i < ttlSwitches; ++i) { - if (!radioSettings.isSwitchAvailable(i) || Boards::isSwitchFunc(i)) - continue; - - swcfg = Board::SwitchType(radioSettings.switchConfig[i].type); - wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i + 1).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false); - RadioSwitchWidget * sw = new RadioSwitchWidget(swcfg, wname, -1, ui->radioWidgetsHT); - sw->setIndex(i); - ui->radioWidgetsHTLayout->addWidget(sw); - - m_radioWidgets.append(sw); + if (!Boards::getCapability(m_board, Board::FunctionSwitches)) { + ui->radioWidgetsCS->hide(); } - midpos = (int)floorf(m_radioWidgets.size() / 2.0f); + // switches + int swCnt = 0; + for (i = 0; i < ttlSwitches; ++i) { + if (radioSettings.isSwitchAvailable(i)) { + wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i + 1).toString(nullptr, &radioSettings, Board::BOARD_UNKNOWN, false); + RadioWidget * sw; + Board::SwitchType swcfg; + + if (Boards::isSwitchFunc(i)) { + swcfg = Board::SWITCH_2POS; // TODO: get this from model settings + sw = new RadioFuncSwitchWidget(simulator, swcfg, wname, -1, ui->radioWidgetsCS); + ui->radioWidgetsCSLayout->addWidget(sw); + } else { + swcfg = Board::SwitchType(radioSettings.switchConfig[i].type); + sw = new RadioSwitchWidget(swcfg, wname, -1, ui->radioWidgetsHT); + ui->radioWidgetsHTLayout->addWidget(sw); + swCnt += 1; + } + + sw->setIndex(i); + + m_radioWidgets.append(sw); + } + } + + midpos = (int)floorf(swCnt / 2.0f); // pots in middle of switches for (i = 0; i < ttlInputs; ++i) { @@ -746,7 +763,7 @@ void SimulatorWidget::onPhaseChanged(qint32 phase, const QString & name) void SimulatorWidget::onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, int index, int value) { - //qDebug() << type << index << value; + // qDebug() << type << index << value; if (!simulator || index < 0) return; @@ -765,6 +782,10 @@ void SimulatorWidget::onRadioWidgetValueChange(const RadioWidget::RadioWidgetTyp inpType = SimulatorInterface::INPUT_SRC_SWITCH; break; + case RadioWidget::RADIO_WIDGET_FUNC_SWITCH: + inpType = SimulatorInterface::INPUT_SRC_SWITCH; + break; + case RadioWidget::RADIO_WIDGET_KNOB : inpType = SimulatorInterface::INPUT_SRC_KNOB; break; diff --git a/companion/src/simulation/simulatorwidget.ui b/companion/src/simulation/simulatorwidget.ui index 21088103c..c545ed905 100644 --- a/companion/src/simulation/simulatorwidget.ui +++ b/companion/src/simulation/simulatorwidget.ui @@ -114,7 +114,43 @@ - + + + + + 0 + 0 + + + + QFrame::Panel + + + QFrame::Raised + + + 0 + + + + 10 + + + 6 + + + 9 + + + 6 + + + 9 + + + + + diff --git a/companion/src/simulation/widgets/radioswitchwidget.h b/companion/src/simulation/widgets/radioswitchwidget.h index eccda4972..ce5532da0 100644 --- a/companion/src/simulation/widgets/radioswitchwidget.h +++ b/companion/src/simulation/widgets/radioswitchwidget.h @@ -24,8 +24,10 @@ #include "radiowidget.h" #include "boards.h" #include "simulator.h" +#include "simulatorinterface.h" #include +#include #include #include @@ -143,5 +145,62 @@ class RadioSwitchWidget : public RadioWidget QSlider * m_slider; quint16 m_stepSize; +}; +class RadioFuncSwitchWidget : public RadioWidget +{ + Q_OBJECT + + public: + + explicit RadioFuncSwitchWidget(SimulatorInterface *simulator, Board::SwitchType type, const QString & labelText, int value, QWidget * parent, Qt::WindowFlags f = Qt::WindowFlags()) : + RadioWidget(labelText, value, parent, f) + { + init(simulator, type); + } + + void init(SimulatorInterface *simulator, Board::SwitchType swType) + { + m_type = RADIO_WIDGET_FUNC_SWITCH; + + m_button = new QPushButton(""); + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + m_button->setFixedWidth(30); + + setWidget(m_button); + + // TODO: connect custom function switches to model data? + + connect(m_button, &QPushButton::pressed, this, &RadioFuncSwitchWidget::onPressed); + connect(m_button, &QPushButton::released, this, &RadioFuncSwitchWidget::onReleased); + connect(this, &RadioWidget::valueChanged, m_button, [=](int value) { + m_value = value; + }); + connect(simulator, &SimulatorInterface::fsColorChange, this, &RadioFuncSwitchWidget::onFsColorChange); + } + + void onPressed() + { + setValue(1); + } + + void onReleased() + { + setValue(-1); + } + + private slots: + void onFsColorChange(quint8 index, qint32 color) + { + if (index == m_index && color != lastColor) { + lastColor = color; + QColor c = QColor((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); + QString qss = QString("background-color: %1; border: none;").arg(c.name()); + m_button->setStyleSheet(qss); + } + } + + private: + QPushButton * m_button; + qint32 lastColor = -1; }; diff --git a/companion/src/simulation/widgets/radiowidget.h b/companion/src/simulation/widgets/radiowidget.h index 90561aabb..0c377c1d9 100644 --- a/companion/src/simulation/widgets/radiowidget.h +++ b/companion/src/simulation/widgets/radiowidget.h @@ -46,6 +46,7 @@ class RadioWidget : public QWidget RADIO_WIDGET_TRIM, // trim axis, usually 2 buttons & slider RADIO_WIDGET_STICK, // actually one axis of a stick RADIO_WIDGET_KEY, // UI key/pushbutton + RADIO_WIDGET_FUNC_SWITCH, RADIO_WIDGET_ENUM_COUNT }; diff --git a/companion/src/tests/gtests.h b/companion/src/tests/gtests.h index 2d9d7528b..901730c5a 100644 --- a/companion/src/tests/gtests.h +++ b/companion/src/tests/gtests.h @@ -26,7 +26,7 @@ #include #include -class OpenTxTest : public testing::Test +class EdgeTxTest : public testing::Test { protected: // You should make the members protected s.t. they can be // accessed from sub-classes. diff --git a/companion/src/wizarddata.cpp b/companion/src/wizarddata.cpp index e992307ac..ec9e3fb56 100644 --- a/companion/src/wizarddata.cpp +++ b/companion/src/wizarddata.cpp @@ -91,6 +91,7 @@ WizMix::operator ModelData() model.used = true; model.moduleData[0].modelId = modelId; model.setDefaultInputs(settings); + model.setDefaultFunctionSwitches(Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches)); int mixIndex = 0; int timerIndex = 0; diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 8904e96df..ed36c9e3e 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -411,6 +411,7 @@ endif() set(SRC ${SRC} edgetx.cpp + datastructs_private.cpp functions.cpp strhelpers.cpp switches.cpp diff --git a/radio/src/boards/generic_stm32/rgb_leds.cpp b/radio/src/boards/generic_stm32/rgb_leds.cpp index 69c1547c3..e4b568821 100644 --- a/radio/src/boards/generic_stm32/rgb_leds.cpp +++ b/radio/src/boards/generic_stm32/rgb_leds.cpp @@ -40,13 +40,7 @@ static timer_handle_t _refresh_timer = TIMER_INITIALIZER; void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b) { -#if defined(SIXPOS_SWITCH_INDEX) - ws2812_set_color(led + 6, r, g, b); -#elif defined(RGB_LED_OFFSET) - ws2812_set_color(led + RGB_LED_OFFSET, r, g, b); -#else ws2812_set_color(led, r, g, b); -#endif } uint32_t rgbGetLedColor(uint8_t led) diff --git a/radio/src/boards/generic_stm32/switches.cpp b/radio/src/boards/generic_stm32/switches.cpp index b9584326c..3cc9f64d6 100644 --- a/radio/src/boards/generic_stm32/switches.cpp +++ b/radio/src/boards/generic_stm32/switches.cpp @@ -20,10 +20,11 @@ */ #include "hal/switch_driver.h" -#include "bsp_io.h" #include "stm32_switch_driver.h" #include "stm32_gpio_driver.h" +#include "drivers/pca95xx.h" + #include "definitions.h" #include "myeeprom.h" @@ -37,30 +38,33 @@ __weak void boardInitSwitches() _init_switches(); } -__weak SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) +__weak SwitchHwPos boardSwitchGetPosition(uint8_t idx) { - const stm32_switch_t* sw = &_switch_offsets[cat][idx]; - if(sw->type != SWITCH_HW_ADC && sw->GPIOx_high == nullptr) - return bsp_get_switch_position(sw, cat, idx); - + const stm32_switch_t* sw = &_switch_defs[idx]; return stm32_switch_get_position(sw); } -__weak const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx) +__weak const char* boardSwitchGetName(uint8_t idx) { - return _switch_offsets[cat][idx].name; + return _switch_defs[idx].name; } -__weak SwitchHwType boardSwitchGetType(SwitchCategory cat, uint8_t idx) +__weak SwitchHwType boardSwitchGetType(uint8_t idx) { - return _switch_offsets[cat][idx].type; + return _switch_defs[idx].type; } +const stm32_switch_t* boardGetSwitchDef(uint8_t idx) { return &_switch_defs[idx]; } + uint8_t boardGetMaxSwitches() { return n_switches; } -uint8_t boardGetMaxFctSwitches() { return n_fct_switches; } +#if defined(FUNCTION_SWITCHES) +bool boardIsCustomSwitch(uint8_t idx) { return _switch_defs[idx].isCustomSwitch; } +uint8_t boardGetCustomSwitchIdx(uint8_t idx) { return _switch_defs[idx].customSwitchIdx; } +#endif -swconfig_t boardSwitchGetDefaultConfig() { return _switch_default_config; } +SwitchConfig boardSwitchGetDefaultConfig(uint8_t idx) { return _switch_defs[idx].defaultType; } +#if !defined(COLORLCD) switch_display_pos_t switchGetDisplayPosition(uint8_t idx) { // TODO: find a solution for FLEX switches so they can be displayed on main view @@ -68,3 +72,4 @@ switch_display_pos_t switchGetDisplayPosition(uint8_t idx) return _switch_display[idx]; } +#endif diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp index ffbedfe50..a0e3f97f4 100644 --- a/radio/src/cli.cpp +++ b/radio/src/cli.cpp @@ -1452,11 +1452,11 @@ int cliDisplay(const char ** argv) cliSerialPrint("[Trim %s] = %s", getTrimLabel(i), keysGetTrimState(i) ? "on" : "off"); } - for (int i = 0; i < switchGetMaxSwitches(); i++) { + for (int i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_EXISTS(i)) { static const char * const SWITCH_POSITIONS[] = { "up", "mid", "down" }; auto pos = switchGetPosition(i); - cliSerialPrint("[%s] = %s", switchGetName(i), SWITCH_POSITIONS[pos]); + cliSerialPrint("[%s] = %s", switchGetDefaultName(i), SWITCH_POSITIONS[pos]); } } } diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index b101ed4fe..79a740723 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -560,7 +560,7 @@ enum MixSources { #define INPUTSRC_LAST MIXSRC_LAST_TELEM #if defined(FUNCTION_SWITCHES) -#define MIXSRC_LAST_REGULAR_SWITCH (MIXSRC_FIRST_SWITCH + switchGetMaxSwitches() - 1) +#define MIXSRC_LAST_REGULAR_SWITCH (MIXSRC_FIRST_SWITCH + switchGetMaxAllSwitches() - 1) #define MIXSRC_FIRST_FS_SWITCH (MIXSRC_LAST_REGULAR_SWITCH + 1) #endif diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index be522def9..7ba83e643 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -83,21 +83,27 @@ static inline void check_struct() #endif #if defined(PCBXLITES) - CHKSIZE(RadioData, 873); + CHKSIZE(RadioData, 945); +#elif defined(RADIO_ST16) + CHKSIZE(RadioData, 1159); #elif defined(COLORLCD) - CHKSIZE(RadioData, 967); + CHKSIZE(RadioData, 1039); +#elif defined(RADIO_GX12) + CHKSIZE(RadioData, 1063); +#elif defined(RADIO_GX12) + CHKSIZE(RadioData, 1062); #else - CHKSIZE(RadioData, 871); + CHKSIZE(RadioData, 943); #endif #if defined(RADIO_TPRO) || defined(RADIO_TPROV2) || defined(RADIO_BUMBLEBEE) - CHKSIZE(ModelData, 6354); + CHKSIZE(ModelData, 6355); #elif defined(RADIO_T14) || defined(RADIO_T12MAX) CHKSIZE(ModelData, 6329); #elif defined(RADIO_FAMILY_T20) - CHKSIZE(ModelData, 6390); + CHKSIZE(ModelData, 6391); #elif defined(RADIO_GX12) - CHKSIZE(ModelData, 6390); + CHKSIZE(ModelData, 6419); #elif defined(PCBX9E) CHKSIZE(ModelData, 6771); #elif defined(PCBX9D) || defined(PCBX9DP) @@ -113,9 +119,9 @@ static inline void check_struct() #elif defined(PCBNV14) CHKSIZE(ModelData, 27295); #elif defined(PCBST16) - CHKSIZE(ModelData, 27754); + CHKSIZE(ModelData, 27761); #elif defined(RADIO_T15) - CHKSIZE(ModelData, 27682); + CHKSIZE(ModelData, 27683); #elif defined(PCBHORUS) CHKSIZE(ModelData, 27657); #else diff --git a/radio/src/datastructs_private.cpp b/radio/src/datastructs_private.cpp new file mode 100644 index 000000000..1face10a2 --- /dev/null +++ b/radio/src/datastructs_private.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + #include "edgetx.h" + #include "hal/switch_driver.h" + +SwitchConfig ModelData::getSwitchType(uint8_t n) +{ +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsType(n); +#endif + return g_eeGeneral.switchType(n); +} + +void ModelData::setSwitchType(uint8_t n, SwitchConfig v) { +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + cfsSetType(n,v); +#endif + g_eeGeneral.switchSetType(n, v); +} + +char* ModelData::getSwitchCustomName(uint8_t n) +{ +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return g_model.cfsName(n); +#endif + return g_eeGeneral.getSwitchCustomName(n); +} + +bool ModelData::switchHasCustomName(uint8_t n) +{ +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return g_model.cfsName(n)[0] != 0; +#endif + return g_eeGeneral.switchHasCustomName(n); +} + +uint8_t ModelData::getSwitchStateForWarning(uint8_t n) +{ +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(n)) { + return cfsState(n) ? 3 : 1; + } +#endif + extern swarnstate_t switches_states; + return (switches_states >> (n * 2)) & 3; +} + +char* RadioData::getSwitchCustomName(uint8_t n) +{ + return switchConfig[n].name; +} + +bool RadioData::switchHasCustomName(uint8_t n) +{ + return switchConfig[n].name[0] != 0; +} + +SwitchConfig RadioData::switchType(uint8_t n) { + return (SwitchConfig)switchConfig[n].type; +} + +void RadioData::switchSetType(uint8_t n, SwitchConfig v) { + switchConfig[n].type = v; + storageDirty(EE_GENERAL); +} + +char* RadioData::switchName(uint8_t n) { + return switchConfig[n].name; +} + +#if defined(FUNCTION_SWITCHES) +uint8_t ModelData::getSwitchGroup(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsGroup(n); + return g_eeGeneral.switchGroup(n); +} + +fsStartPositionType ModelData::getSwitchStart(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsStart(n); + return g_eeGeneral.switchStart(n); +} + +void ModelData::setSwitchStart(uint8_t n, fsStartPositionType v) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + cfsSetStart(n, v); + g_eeGeneral.switchSetStart(n, v); +} + +SwitchConfig ModelData::cfsType(uint8_t n) { + return (SwitchConfig)customSwitches[switchGetCustomSwitchIdx(n)].type; +} + +void ModelData::cfsSetType(uint8_t n, SwitchConfig v) { + customSwitches[switchGetCustomSwitchIdx(n)].type = v; + storageDirty(EE_MODEL); +} + +char* ModelData::cfsName(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].name; +} + +uint8_t ModelData::cfsGroup(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].group; +} + +void ModelData::cfsSetGroup(uint8_t n, uint8_t v) { + customSwitches[switchGetCustomSwitchIdx(n)].group = v; + storageDirty(EE_MODEL); +} + +fsStartPositionType ModelData::cfsStart(uint8_t n) { + return (fsStartPositionType)customSwitches[switchGetCustomSwitchIdx(n)].start; +} + +void ModelData::cfsSetStart(uint8_t n, fsStartPositionType v) { + customSwitches[switchGetCustomSwitchIdx(n)].start = v; + storageDirty(EE_MODEL); +} + +bool ModelData::cfsState(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].state; +} + +void ModelData::cfsSetState(uint8_t n, bool v) { + customSwitches[switchGetCustomSwitchIdx(n)].state = v; + storageDirty(EE_MODEL); +} + +bool ModelData::cfsSFState(uint8_t n) { + return bfGet(sfPushState, switchGetCustomSwitchIdx(n), 1); +} + +void ModelData::cfsSetSFState(uint8_t n, bool v) { + // Note: n = cfs index, not switch index + sfPushState = bfSet(sfPushState, v, n, 1); +} + +void ModelData::cfsResetSFState() { + sfPushState = 0; +} + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +RGBLedColor& ModelData::getSwitchOnColor(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsOnColor(n); + return g_eeGeneral.switchOnColor(n); +} + +RGBLedColor& ModelData::getSwitchOffColor(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsOffColor(n); + return g_eeGeneral.switchOffColor(n); +} + +bool ModelData::getSwitchOnColorLuaOverride(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsOnColorLuaOverride(n); + return g_eeGeneral.cfsOnColorLuaOverride(n); +} + +bool ModelData::getSwitchOffColorLuaOverride(uint8_t n) { + if (switchIsCustomSwitch(n) && cfsType(n) != SWITCH_GLOBAL) + return cfsOffColorLuaOverride(n); + return g_eeGeneral.cfsOffColorLuaOverride(n); +} + +RGBLedColor& ModelData::cfsOnColor(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].onColor; +} + +RGBLedColor& ModelData::cfsOffColor(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].offColor; +} + +bool ModelData::cfsOnColorLuaOverride(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].onColorLuaOverride; +} + +bool ModelData::cfsOffColorLuaOverride(uint8_t n) { + return customSwitches[switchGetCustomSwitchIdx(n)].offColorLuaOverride; +} + +void ModelData::cfsSetOnColorLuaOverride(uint8_t n, bool v) { + customSwitches[switchGetCustomSwitchIdx(n)].onColorLuaOverride = v; + storageDirty(EE_MODEL); +} + +void ModelData::cfsSetOffColorLuaOverride(uint8_t n, bool v) { + customSwitches[switchGetCustomSwitchIdx(n)].offColorLuaOverride = v; + storageDirty(EE_MODEL); +} +#endif + +fsStartPositionType RadioData::switchStart(uint8_t n) { + return (fsStartPositionType)switchConfig[n].start; +} + +void RadioData::switchSetStart(uint8_t n, fsStartPositionType v) { + switchConfig[n].start = v; + storageDirty(EE_GENERAL); +} + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +RGBLedColor& RadioData::switchOnColor(uint8_t n) { + return switchConfig[n].onColor; +} + +RGBLedColor& RadioData::switchOffColor(uint8_t n) { + return switchConfig[n].offColor; +} + +bool RadioData::cfsOnColorLuaOverride(uint8_t n) { + return switchConfig[n].onColorLuaOverride; +} + +bool RadioData::cfsOffColorLuaOverride(uint8_t n) { + return switchConfig[n].offColorLuaOverride; +} + +void RadioData::cfsSetOnColorLuaOverride(uint8_t n, bool v) { + switchConfig[n].onColorLuaOverride = v; + storageDirty(EE_GENERAL); +} + +void RadioData::cfsSetOffColorLuaOverride(uint8_t n, bool v) { + switchConfig[n].offColorLuaOverride = v; + storageDirty(EE_GENERAL); +} +#endif +#endif diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 0ba85f40e..fda89273c 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -32,6 +32,7 @@ #include "usb_joystick.h" #include "input_mapping.h" #include "debug.h" +#include "bitfield.h" #if defined(PCBTARANIS) #define N_TARANIS_FIELD(x) @@ -643,21 +644,54 @@ struct RGBLedColor { } }; +#if defined(FUNCTION_SWITCHES) +PACK(struct customSwitch { + CUST_IDX(sw, cfs_idx_read, cfs_idx_write); + NOBACKUP(char name[LEN_SWITCH_NAME]); + uint8_t type:3 ENUM(SwitchConfig); +#if NUM_FUNCTIONS_GROUPS > 3 + uint8_t group:3; +#else + uint8_t group:2; +#endif + uint8_t start:2 ENUM(fsStartPositionType); + uint8_t state:1; +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + NOBACKUP(uint8_t onColorLuaOverride:1 ENUM(booleanEnum)); + NOBACKUP(uint8_t offColorLuaOverride:1 ENUM(booleanEnum)); +#if NUM_FUNCTIONS_GROUPS > 3 + NOBACKUP(uint8_t spare:5) SKIP; +#else + NOBACKUP(uint8_t spare:6) SKIP; +#endif + NOBACKUP(RGBLedColor onColor) FUNC(isAlwaysActive); + NOBACKUP(RGBLedColor offColor) FUNC(isAlwaysActive); +#else +#if NUM_FUNCTIONS_GROUPS > 3 + NOBACKUP(uint8_t spare:7) SKIP; +#endif +#endif +}); +#endif + +#if defined(FUNCTION_SWITCHES) #if defined(FUNCTION_SWITCHES_RGB_LEDS) #define FUNCTION_SWITCHS_RGB_LEDS_FIELDS \ - RGBLedColor functionSwitchLedONColor[NUM_FUNCTIONS_SWITCHES]; \ - RGBLedColor functionSwitchLedOFFColor[NUM_FUNCTIONS_SWITCHES]; + CUST_ARRAY(functionSwitchLedONColor, struct_cfsOnColorConfig, NUM_FUNCTIONS_SWITCHES, nullptr); \ + CUST_ARRAY(functionSwitchLedOFFColor, struct_cfsOffColorConfig, NUM_FUNCTIONS_SWITCHES, nullptr); #else #define FUNCTION_SWITCHS_RGB_LEDS_FIELDS #endif -#if defined(FUNCTION_SWITCHES) #define FUNCTION_SWITCHS_FIELDS \ - uint16_t functionSwitchConfig; \ - uint16_t functionSwitchGroup; \ - uint16_t functionSwitchStartConfig; \ - uint8_t functionSwitchLogicalState; \ - char switchNames[NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME]; \ - FUNCTION_SWITCHS_RGB_LEDS_FIELDS + CUST_ATTR(functionSwitchConfig, r_functionSwitchConfig, nullptr); \ + CUST_ATTR(functionSwitchGroup, r_functionSwitchGroup, nullptr); \ + CUST_ATTR(functionSwitchStartConfig, r_functionSwitchStartConfig, nullptr); \ + CUST_ATTR(functionSwitchLogicalState, r_functionSwitchLogicalState, nullptr); \ + CUST_ARRAY(switchNames, struct_cfsNameConfig, NUM_FUNCTIONS_SWITCHES, nullptr); \ + FUNCTION_SWITCHS_RGB_LEDS_FIELDS \ + customSwitch customSwitches[NUM_FUNCTIONS_SWITCHES] FUNC(isAlwaysActive) NO_IDX; \ + uint8_t cfsGroupOn ARRAY(1, struct_cfsGroupOn, cfsGroupIsActive); \ + NOBACKUP(uint8_t sfPushState) SKIP; #else #define FUNCTION_SWITCHS_FIELDS #endif @@ -744,7 +778,7 @@ PACK(struct ModelData { NOBACKUP(uint8_t thrTraceSrc CUST(r_thrSrc,w_thrSrc)); CUST_ATTR(switchWarningState, r_swtchWarn, nullptr); - NOBACKUP(swarnstate_t switchWarning ARRAY(3, struct_swtchWarn, nullptr)); + NOBACKUP(swarnstate_t switchWarning ARRAY(2, struct_swtchWarn, nullptr)); GVarData gvars[MAX_GVARS]; @@ -828,6 +862,47 @@ PACK(struct ModelData { uint8_t modelSFDisabled:2 ENUM(ModelOverridableEnable); uint8_t modelCustomScriptsDisabled:2 ENUM(ModelOverridableEnable); uint8_t modelTelemetryDisabled:2 ENUM(ModelOverridableEnable); + + SwitchConfig getSwitchType(uint8_t n); + void setSwitchType(uint8_t n, SwitchConfig v); + char* getSwitchCustomName(uint8_t n); + bool switchHasCustomName(uint8_t n); + + uint8_t getSwitchStateForWarning(uint8_t n); + NOBACKUP(uint8_t getSwitchWarning(uint8_t n) { return bfGet(switchWarning, n * 2, 2); }) + NOBACKUP(void setSwitchWarning(uint8_t n, uint8_t v) { switchWarning = bfSet(switchWarning, v, n * 2, 2); }) + +#if defined(FUNCTION_SWITCHES) + uint8_t getSwitchGroup(uint8_t n); + fsStartPositionType getSwitchStart(uint8_t n); + void setSwitchStart(uint8_t n, fsStartPositionType v); + SwitchConfig cfsType(uint8_t n); + void cfsSetType(uint8_t n, SwitchConfig v); + char* cfsName(uint8_t n); + uint8_t cfsGroup(uint8_t n); + void cfsSetGroup(uint8_t n, uint8_t v); + fsStartPositionType cfsStart(uint8_t n); + void cfsSetStart(uint8_t n, fsStartPositionType v); + bool cfsState(uint8_t n); + void cfsSetState(uint8_t n, bool v); + bool cfsSFState(uint8_t n); + void cfsSetSFState(uint8_t n, bool v); + void cfsResetSFState(); +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + RGBLedColor& getSwitchOnColor(uint8_t n); + RGBLedColor& getSwitchOffColor(uint8_t n); + bool getSwitchOnColorLuaOverride(uint8_t n); + bool getSwitchOffColorLuaOverride(uint8_t n); + RGBLedColor& cfsOnColor(uint8_t n); + RGBLedColor& cfsOffColor(uint8_t n); + bool cfsOnColorLuaOverride(uint8_t n); + bool cfsOffColorLuaOverride(uint8_t n); + void cfsSetOnColorLuaOverride(uint8_t n, bool v); + void cfsSetOffColorLuaOverride(uint8_t n, bool v); +#endif + bool cfsGroupAlwaysOn(uint8_t n) { return bfGet(cfsGroupOn, n, 1); } + void cfsSetGroupAlwaysOn(uint8_t n, bool v) { cfsGroupOn = bfSet(cfsGroupOn, v, n, 1); } +#endif }); /* @@ -877,6 +952,26 @@ PACK(struct TrainerData { #define BUZZER_FIELD int8_t spare2:2 SKIP #endif +PACK(struct switchDef { + CUST_IDX(sw, sw_idx_read, sw_idx_write); + NOBACKUP(char name[LEN_SWITCH_NAME]); + uint8_t type:3 ENUM(SwitchConfig); +#if defined(FUNCTION_SWITCHES) + uint8_t start:2 ENUM(fsStartPositionType) FUNC(switch_is_cfs); +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + NOBACKUP(uint8_t onColorLuaOverride:1 ENUM(booleanEnum)) FUNC(switch_is_cfs); + NOBACKUP(uint8_t offColorLuaOverride:1 ENUM(booleanEnum)) FUNC(switch_is_cfs); + NOBACKUP(uint8_t spare:1) SKIP; + NOBACKUP(RGBLedColor onColor) FUNC(switch_is_cfs); + NOBACKUP(RGBLedColor offColor) FUNC(switch_is_cfs); +#else + NOBACKUP(uint8_t spare:3) SKIP; +#endif +#else + NOBACKUP(uint8_t spare:5) SKIP; +#endif +}); + PACK(struct RadioData { // Real attributes @@ -967,7 +1062,7 @@ PACK(struct RadioData { CUST_ARRAY(slidersConfig, struct_sliderConfig, MAX_POTS, nullptr); uint8_t stickInvert SKIP; potconfig_t potsConfig ARRAY(4,struct_potConfig,nullptr); - swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); + switchDef switchConfig[MAX_SWITCHES] FUNC(switchIsActive) NO_IDX; \ CUST_ARRAY(flexSwitches, struct_flexSwitch, MAX_FLEX_SWITCHES, flex_sw_valid); EXTRA_GENERAL_FIELDS @@ -1035,6 +1130,25 @@ PACK(struct RadioData { return backlightBright; #endif }); + + char* getSwitchCustomName(uint8_t n); + bool switchHasCustomName(uint8_t n); + SwitchConfig switchType(uint8_t n); + void switchSetType(uint8_t n, SwitchConfig v); + char* switchName(uint8_t n); +#if defined(FUNCTION_SWITCHES) + uint8_t switchGroup(uint8_t n) { return 0; } + fsStartPositionType switchStart(uint8_t n); + void switchSetStart(uint8_t n, fsStartPositionType v); +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + RGBLedColor& switchOnColor(uint8_t n); + RGBLedColor& switchOffColor(uint8_t n); + bool cfsOnColorLuaOverride(uint8_t n); + bool cfsOffColorLuaOverride(uint8_t n); + void cfsSetOnColorLuaOverride(uint8_t n, bool v); + void cfsSetOffColorLuaOverride(uint8_t n, bool v); +#endif +#endif }); #undef SWITCHES_WARNING_DATA diff --git a/radio/src/edgetx.cpp b/radio/src/edgetx.cpp index efcb2c7cf..84dfb0b86 100644 --- a/radio/src/edgetx.cpp +++ b/radio/src/edgetx.cpp @@ -293,6 +293,22 @@ void setDefaultOwnerId() } #endif +void generalDefaultSwitches() +{ + for (uint8_t sw = 0; sw < switchGetMaxSwitches(); sw += 1) { + g_eeGeneral.switchConfig[sw].type = switchGetDefaultConfig(sw); + g_eeGeneral.switchConfig[sw].name[0] = 0; +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(sw)) + g_eeGeneral.switchConfig[sw].start = FS_START_PREVIOUS; +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + g_eeGeneral.switchConfig[sw].onColor.setColor(0xFFFFFF); + g_eeGeneral.switchConfig[sw].offColor.setColor(0); +#endif +#endif + } +} + void generalDefault() { memclear(&g_eeGeneral, sizeof(g_eeGeneral)); @@ -318,7 +334,7 @@ void generalDefault() adcCalibDefaults(); g_eeGeneral.potsConfig = adcGetDefaultPotsConfig(); - g_eeGeneral.switchConfig = switchGetDefaultConfig(); + generalDefaultSwitches(); #if defined(STICK_DEAD_ZONE) g_eeGeneral.stickDeadZone = DEFAULT_STICK_DEADZONE; diff --git a/radio/src/edgetx.h b/radio/src/edgetx.h index c82bfbacb..2b8b05586 100644 --- a/radio/src/edgetx.h +++ b/radio/src/edgetx.h @@ -353,6 +353,7 @@ uint16_t isqrt32(uint32_t n); void setDefaultOwnerId(); void generalDefault(); +void generalDefaultSwitches(); uint32_t hash(const void * ptr, uint32_t size); diff --git a/radio/src/edgetx_constants.h b/radio/src/edgetx_constants.h index 2efb67d44..626e154b5 100644 --- a/radio/src/edgetx_constants.h +++ b/radio/src/edgetx_constants.h @@ -26,6 +26,13 @@ enum SwitchConfig { SWITCH_TOGGLE, SWITCH_2POS, SWITCH_3POS, +#if defined(FUNCTION_SWITCHES) + SWITCH_GLOBAL, +#endif + SWITCH_none = SWITCH_NONE, + SWITCH_toggle = SWITCH_TOGGLE, + SWITCH_2pos = SWITCH_2POS, + SWITCH_3pos = SWITCH_3POS, }; enum FlexAnalogConfig { @@ -40,11 +47,16 @@ enum FlexAnalogConfig { }; enum fsStartPositionType { - FS_START_ON, FS_START_OFF, + FS_START_ON, FS_START_PREVIOUS }; +enum booleanEnum { + BOOL_OFF, + BOOL_ON +}; + enum CalibrationState { CALIB_START, CALIB_SET_MIDPOINT, diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index c337ae0b9..66b9862a4 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -154,7 +154,7 @@ void evalFunctions(CustomFunctionData * functions, CustomFunctionsContext & func MASK_FUNC_TYPE newActiveFunctions = 0; MASK_CFN_TYPE newActiveSwitches = 0; #if defined(FUNCTION_SWITCHES) - functionSwitchFunctionState = 0; + g_model.cfsResetSFState(); #endif uint8_t playFirstIndex = (functions == g_model.customFn ? 1 : 1+MAX_SPECIAL_FUNCTIONS); @@ -386,14 +386,13 @@ void evalFunctions(CustomFunctionData * functions, CustomFunctionsContext & func if (CFN_PARAM(cfn)) { // Duration is set if (! CFN_VAL2(cfn) ) { // Duration not started yet CFN_VAL2(cfn) = timersGetMsTick() + CFN_PARAM(cfn) * 100; - functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn); - } - else if (timersGetMsTick() < (uint32_t)CFN_VAL2(cfn) ) { // Still within push duration - functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn); + g_model.cfsSetSFState(CFN_CS_INDEX(cfn), 1); + } else if (timersGetMsTick() < (uint32_t)CFN_VAL2(cfn) ) { // Still within push duration + g_model.cfsSetSFState(CFN_CS_INDEX(cfn), 1); } + } else { // No duration set + g_model.cfsSetSFState(CFN_CS_INDEX(cfn), 1); } - else // No duration set - functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn); break; #endif @@ -473,7 +472,7 @@ void evalFunctions(CustomFunctionData * functions, CustomFunctionsContext & func if (CFN_FUNC(cfn) == FUNC_PUSH_CUST_SWITCH) { // Handling duration after function is active if (timersGetMsTick() < (uint32_t)CFN_VAL2(cfn)) { - functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn); + g_model.cfsSetSFState(CFN_CS_INDEX(cfn), 1); } else { CFN_VAL2(cfn) = 0; diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index e7b82295e..49f40edef 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -43,7 +43,7 @@ uint8_t g_moduleIdx; uint8_t getSwitchWarningsCount() { uint8_t count = 0; - for (int i = 0; i < switchGetMaxSwitches(); ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_WARNING_ALLOWED(i)) { ++count; } @@ -79,6 +79,20 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_SW4, ITEM_MODEL_SETUP_SW5, ITEM_MODEL_SETUP_SW6, + ITEM_MODEL_SETUP_SW7, + ITEM_MODEL_SETUP_SW8, + ITEM_MODEL_SETUP_SW9, + ITEM_MODEL_SETUP_SW10, + ITEM_MODEL_SETUP_SW11, + ITEM_MODEL_SETUP_SW12, + ITEM_MODEL_SETUP_SW13, + ITEM_MODEL_SETUP_SW14, + ITEM_MODEL_SETUP_SW15, + ITEM_MODEL_SETUP_SW16, + ITEM_MODEL_SETUP_SW17, + ITEM_MODEL_SETUP_SW18, + ITEM_MODEL_SETUP_SW19, + ITEM_MODEL_SETUP_SW20, ITEM_MODEL_SETUP_GROUP1_LABEL, ITEM_MODEL_SETUP_GROUP1_ALWAYS_ON, ITEM_MODEL_SETUP_GROUP1_START, @@ -88,6 +102,9 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_GROUP3_LABEL, ITEM_MODEL_SETUP_GROUP3_ALWAYS_ON, ITEM_MODEL_SETUP_GROUP3_START, + ITEM_MODEL_SETUP_GROUP4_LABEL, + ITEM_MODEL_SETUP_GROUP4_ALWAYS_ON, + ITEM_MODEL_SETUP_GROUP4_START, #endif ITEM_MODEL_SETUP_EXTENDED_LIMITS, ITEM_MODEL_SETUP_EXTENDED_TRIMS, @@ -107,6 +124,7 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_SWITCHES_WARNING1, #if defined(PCBTARANIS) ITEM_MODEL_SETUP_SWITCHES_WARNING2, + ITEM_MODEL_SETUP_SWITCHES_WARNING3, ITEM_MODEL_SETUP_POTS_WARNING, #endif ITEM_MODEL_SETUP_BEEP_CENTER, @@ -259,6 +277,7 @@ static uint8_t FS_ROW(uint8_t value) { return expandState.functionSwitches ? val uint8_t G1_ROW(int8_t value) { return (firstSwitchInGroup(1) >= 0) ? value : HIDDEN_ROW; } uint8_t G2_ROW(int8_t value) { return (firstSwitchInGroup(2) >= 0) ? value : HIDDEN_ROW; } uint8_t G3_ROW(int8_t value) { return (firstSwitchInGroup(3) >= 0) ? value : HIDDEN_ROW; } +uint8_t G4_ROW(int8_t value) { return (firstSwitchInGroup(4) >= 0) ? value : HIDDEN_ROW; } #endif static uint8_t VIEWOPT_ROW(uint8_t value) { return expandState.viewOpt ? value : HIDDEN_ROW; } @@ -304,17 +323,18 @@ static uint8_t VIEWOPT_ROW(uint8_t value) { return expandState.viewOpt ? value : #define CURRENT_RECEIVER_EDITED(k) (k - ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1) #endif -#define MAX_SWITCH_PER_LINE (getSwitchWarningsCount() > 5 ? 4 : 5) +#define MAX_SWITCH_PER_LINE 5 #if defined(PCBXLITE) // X-Lite needs an additional column for full line selection (<]) #define SW_WARN_ROWS \ PREFLIGHT_ROW(uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount())), \ - PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > 4 ? TITLE_ROW : HIDDEN_ROW)) + PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > MAX_SWITCH_PER_LINE ? TITLE_ROW : HIDDEN_ROW)) #else // Handle special case when there is only one switch that can trigger a warning (MT12) #define SW_WARN_ROWS \ PREFLIGHT_ROW(uint8_t(NAVIGATION_LINE_BY_LINE|((getSwitchWarningsCount() == 1) ? 1 : getSwitchWarningsCount()-1))), \ - PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > MAX_SWITCH_PER_LINE ? TITLE_ROW : HIDDEN_ROW)) + PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > MAX_SWITCH_PER_LINE ? TITLE_ROW : HIDDEN_ROW)), \ + PREFLIGHT_ROW(uint8_t(getSwitchWarningsCount() > (MAX_SWITCH_PER_LINE * 2) ? TITLE_ROW : HIDDEN_ROW)) #endif inline uint8_t MODULE_TYPE_ROWS(int moduleIdx) @@ -356,22 +376,23 @@ inline uint8_t TIMER_ROW(uint8_t timer, uint8_t value) #define EXTRA_MODULE_ROWS #if defined(FUNCTION_SWITCHES) - #define FUNCTION_SWITCHES_ROWS 0, \ - FS_ROW(0), \ - FS_ROW(0), \ - FS_ROW(0), \ - FS_ROW(0), \ - FS_ROW(0), \ - FS_ROW(0), \ - FS_ROW(G1_ROW(LABEL())), \ - FS_ROW(G1_ROW(0)), \ - FS_ROW(G1_ROW(0)), \ - FS_ROW(G2_ROW(LABEL())), \ - FS_ROW(G2_ROW(0)), \ - FS_ROW(G2_ROW(0)), \ - FS_ROW(G3_ROW(LABEL())), \ - FS_ROW(G3_ROW(0)), \ - FS_ROW(G3_ROW(0)), + #define FUNCTION_SWITCHES_ROWS 0, \ + FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), \ + FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), \ + FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), \ + FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), FS_ROW(0), \ + FS_ROW(G1_ROW(LABEL())), \ + FS_ROW(G1_ROW(0)), \ + FS_ROW(G1_ROW(0)), \ + FS_ROW(G2_ROW(LABEL())), \ + FS_ROW(G2_ROW(0)), \ + FS_ROW(G2_ROW(0)), \ + FS_ROW(G3_ROW(LABEL())), \ + FS_ROW(G3_ROW(0)), \ + FS_ROW(G3_ROW(0)), \ + FS_ROW(G4_ROW(LABEL())), \ + FS_ROW(G4_ROW(0)), \ + FS_ROW(G4_ROW(0)), #else #define FUNCTION_SWITCHES_ROWS #endif @@ -561,10 +582,6 @@ inline uint8_t USB_JOYSTICK_APPLYROW() #define USB_JOYSTICK_ROWS #endif -#if defined(FUNCTION_SWITCHES) -static const char* _fct_sw_start[] = { STR_CHAR_DOWN, STR_CHAR_UP, "=" }; -#endif - uint8_t viewOptChoice(coord_t y, const char* title, uint8_t value, uint8_t attr, event_t event) { lcdDrawText(INDENT_WIDTH-1, y, title); @@ -572,93 +589,99 @@ uint8_t viewOptChoice(coord_t y, const char* title, uint8_t value, uint8_t attr, } #if defined(FUNCTION_SWITCHES) -static int cfsIndex; +const char* _fct_sw_start[] = { STR_CHAR_UP, STR_CHAR_DOWN, "=" }; +static int swIndex; static uint8_t cfsGroup; bool checkCFSTypeAvailable(int val) { - int group = FSWITCH_GROUP(cfsIndex); - if (group > 0 && IS_FSWITCH_GROUP_ON(group) && val == SWITCH_TOGGLE) + if (val == SWITCH_3POS) return false; + int group = g_model.cfsGroup(swIndex); + if (group > 0 && g_model.cfsGroupAlwaysOn(group) && val == SWITCH_TOGGLE) return false; return true; } -bool checkCFSGroupAvailable(int group) +static bool checkCFSGroupAvailable(int group) { - if (FSWITCH_CONFIG(cfsIndex) == SWITCH_TOGGLE && group && IS_FSWITCH_GROUP_ON(group)) + if (g_model.cfsType(swIndex) == SWITCH_TOGGLE && group && g_model.cfsGroupAlwaysOn(group)) return false; return true; } -bool checkCFSSwitchAvailable(int sw) +static bool checkCFSSwitchAvailable(int sw) { - return (sw == 0) || (sw == NUM_FUNCTIONS_SWITCHES + 1) || (FSWITCH_GROUP(sw - 1) == cfsGroup); + return (sw == -1) || (sw == switchGetMaxSwitches()) || (switchIsCustomSwitch(sw) && (g_model.cfsGroup(sw) == cfsGroup)); } #if defined(FUNCTION_SWITCHES_RGB_LEDS) -bool checkCFSColorAvailable(int col) +static bool checkCFSColorAvailable(int col) { return col > 0; } #endif enum CFSFields { - CFS_FIELD_NAME, CFS_FIELD_TYPE, + CFS_FIELD_NAME, CFS_FIELD_GROUP, CFS_FIELD_START, #if defined(FUNCTION_SWITCHES_RGB_LEDS) CFS_FIELD_COLOR_LABEL, CFS_FIELD_ON_COLOR, + CFS_FIELD_ON_LUA_OVERRIDE, CFS_FIELD_OFF_COLOR, + CFS_FIELD_OFF_LUA_OVERRIDE, #endif CFS_FIELD_COUNT }; #if defined(FUNCTION_SWITCHES_RGB_LEDS) -static void menuCFSColor(coord_t y, RGBLedColor& color, const char* title, LcdFlags attr, event_t event) +void menuCFSColor(coord_t y, RGBLedColor& color, const char* title, LcdFlags attr, event_t event) { uint8_t selectedColor = getRGBColorIndex(color.getColor()); selectedColor = editChoice(30, y, title, \ STR_FS_COLOR_LIST, selectedColor, 0, DIM(colorTable), menuHorizontalPosition == 0 ? attr : 0, event, INDENT_WIDTH, checkCFSColorAvailable); if (attr && menuHorizontalPosition == 0 && checkIncDec_Ret) { color.setColor(colorTable[selectedColor - 1]); - storageDirty(EE_MODEL); + storageDirty((isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); } lcdDrawNumber(LCD_W - 6 * FW, y, color.r, (menuHorizontalPosition == 1 ? attr : 0) | RIGHT); if (attr && menuHorizontalPosition == 1) - color.r = checkIncDecModel(event, color.r, 0, 255); + color.r = checkIncDec(event, color.r, 0, 255, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); lcdDrawNumber(LCD_W - 3 * FW, y, color.g, (menuHorizontalPosition == 2 ? attr : 0) | RIGHT); if (attr && menuHorizontalPosition == 2) - color.g = checkIncDecModel(event, color.g, 0, 255); + color.g = checkIncDec(event, color.g, 0, 255, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); lcdDrawNumber(LCD_W, y, color.b, (menuHorizontalPosition == 3 ? attr : 0) | RIGHT); if (attr && menuHorizontalPosition == 3) - color.b = checkIncDecModel(event, color.b, 0, 255); + color.b = checkIncDec(event, color.b, 0, 255, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL); } #endif -void menuModelCFSOne(event_t event) +static void menuModelCFSOne(event_t event) { std::string s(STR_CHAR_SWITCH); - s += switchGetName(cfsIndex + switchGetMaxSwitches()); + s += switchGetDefaultName(swIndex); - int config = FSWITCH_CONFIG(cfsIndex); - uint8_t group = FSWITCH_GROUP(cfsIndex); - int startPos = FSWITCH_STARTUP(cfsIndex); + int config = g_model.cfsType(swIndex); + uint8_t group = g_model.cfsGroup(swIndex); + int startPos = g_model.cfsStart(swIndex); SUBMENU(s.c_str(), CFS_FIELD_COUNT, { 0, - 0, - (uint8_t)((config != SWITCH_NONE) ? 0 : HIDDEN_ROW), - (uint8_t)((config != SWITCH_NONE && config != SWITCH_TOGGLE && group == 0) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_TOGGLE && config != SWITCH_GLOBAL && group == 0) ? 0 : HIDDEN_ROW), #if defined(FUNCTION_SWITCHES_RGB_LEDS) - LABEL(), - 3, - 3, + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? LABEL() : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 3 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 3 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), #endif }); @@ -677,40 +700,42 @@ void menuModelCFSOne(event_t event) LcdFlags attr = (sub == i ? (editMode > 0 ? BLINK | INVERS : INVERS) : 0); switch(i) { + case CFS_FIELD_TYPE: + config = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_SWITCH_TYPE, STR_SWTYPES, config, SWITCH_NONE, SWITCH_GLOBAL, attr, event, 0, checkCFSTypeAvailable); + if (attr && checkIncDec_Ret) { + g_model.cfsSetType(swIndex, (SwitchConfig)config); + if (config == SWITCH_NONE) { +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + fsLedRGB(switchGetCustomSwitchIdx(swIndex), 0); +#endif + } else if (config == SWITCH_TOGGLE) { + g_model.cfsSetStart(swIndex, FS_START_PREVIOUS); // Toggle switches do not have startup position + } + } + break; + case CFS_FIELD_NAME: - editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_NAME, g_model.switchNames[cfsIndex], + editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_NAME, g_model.cfsName(swIndex), LEN_SWITCH_NAME, event, (attr != 0), editMode); break; - case CFS_FIELD_TYPE: - config = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_SWITCH_TYPE, STR_SWTYPES, config, SWITCH_NONE, SWITCH_2POS, attr, event, 0, checkCFSTypeAvailable); - if (attr && checkIncDec_Ret) { - FSWITCH_SET_CONFIG(cfsIndex, config); - if (config == SWITCH_TOGGLE) { - FSWITCH_SET_STARTUP(cfsIndex, FS_START_PREVIOUS); // Toggle switches do not have startup position - } - storageDirty(EE_MODEL); - } - break; - case CFS_FIELD_GROUP: - group = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_SWITCH_GROUP, STR_FSGROUPS, group, 0, 3, attr, event, 0, checkCFSGroupAvailable); + group = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_SWITCH_GROUP, STR_FSGROUPS, group, 0, NUM_FUNCTIONS_GROUPS, attr, event, 0, checkCFSGroupAvailable); if (attr && checkIncDec_Ret) { - int oldGroup = FSWITCH_GROUP(cfsIndex); + int oldGroup = g_model.cfsGroup(swIndex); if (groupHasSwitchOn(group)) - setFSLogicalState(cfsIndex, 0); - FSWITCH_SET_GROUP(cfsIndex, group); + setFSLogicalState(swIndex, 0); + g_model.cfsSetGroup(swIndex, group); if (group > 0) { - FSWITCH_SET_STARTUP(cfsIndex, groupDefaultSwitch(group) == -1 ? FS_START_PREVIOUS : FS_START_OFF); - if (config == SWITCH_TOGGLE && IS_FSWITCH_GROUP_ON(group)) - FSWITCH_SET_CONFIG(cfsIndex, SWITCH_2POS); - setGroupSwitchState(group, cfsIndex); + g_model.cfsSetStart(swIndex, groupDefaultSwitch(group) == -1 ? FS_START_PREVIOUS : FS_START_OFF); + if (config == SWITCH_TOGGLE && g_model.cfsGroupAlwaysOn(group)) + g_model.cfsSetType(swIndex, SWITCH_2POS); + setGroupSwitchState(group); } else { - FSWITCH_SET_STARTUP(cfsIndex, FS_START_PREVIOUS); + g_model.cfsSetStart(swIndex, FS_START_PREVIOUS); } setGroupSwitchState(oldGroup); - storageDirty(EE_MODEL); } break; @@ -718,9 +743,8 @@ void menuModelCFSOne(event_t event) lcdDrawText(0, y, STR_SWITCH_STARTUP); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, _fct_sw_start[startPos], attr ? (s_editMode ? INVERS + BLINK : INVERS) : 0); if (attr) { - startPos = checkIncDec(event, startPos, FS_START_ON, FS_START_PREVIOUS, EE_MODEL); - FSWITCH_SET_STARTUP(cfsIndex, startPos); - storageDirty(EE_MODEL); + startPos = checkIncDec(event, startPos, FS_START_OFF, FS_START_PREVIOUS, EE_MODEL); + g_model.cfsSetStart(swIndex, (fsStartPositionType)startPos); } break; @@ -733,11 +757,19 @@ void menuModelCFSOne(event_t event) break; case CFS_FIELD_ON_COLOR: - menuCFSColor(y, g_model.functionSwitchLedONColor[cfsIndex], STR_OFFON[1], attr, event); + menuCFSColor(y, g_model.cfsOnColor(swIndex), STR_OFFON[1], attr, event); + break; + + case CFS_FIELD_ON_LUA_OVERRIDE: + g_model.cfsSetOnColorLuaOverride(swIndex, editCheckBox(g_model.cfsOnColorLuaOverride(swIndex), LCD_W - 2 * FW, y, STR_LUA_OVERRIDE, attr, event, INDENT_WIDTH)); break; case CFS_FIELD_OFF_COLOR: - menuCFSColor(y, g_model.functionSwitchLedOFFColor[cfsIndex], STR_OFFON[0], attr, event); + menuCFSColor(y, g_model.cfsOffColor(swIndex), STR_OFFON[0], attr, event); + break; + + case CFS_FIELD_OFF_LUA_OVERRIDE: + g_model.cfsSetOffColorLuaOverride(swIndex, editCheckBox(g_model.cfsOffColorLuaOverride(swIndex), LCD_W - 2 * FW, y, STR_LUA_OVERRIDE, attr, event, INDENT_WIDTH)); break; #endif } @@ -812,6 +844,15 @@ void menuModelSetup(event_t event) USB_JOYSTICK_ROWS }); +#if defined(FUNCTION_SWITCHES) + int swCnt = switchGetMaxSwitches(); + uint8_t* p = (uint8_t*)mstate_tab; + for (int i = 0; i < MAX_SWITCHES; i += 1) { + if (i >= swCnt || !switchIsCustomSwitch(i)) + p[i + ITEM_MODEL_SETUP_SW1] = HIDDEN_ROW; + } +#endif + MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, HEADER_LINE + ITEM_MODEL_SETUP_LINES_COUNT); title(STR_MENU_MODEL_SETUP); @@ -988,33 +1029,48 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_SW4: case ITEM_MODEL_SETUP_SW5: case ITEM_MODEL_SETUP_SW6: + case ITEM_MODEL_SETUP_SW7: + case ITEM_MODEL_SETUP_SW8: + case ITEM_MODEL_SETUP_SW9: + case ITEM_MODEL_SETUP_SW10: + case ITEM_MODEL_SETUP_SW11: + case ITEM_MODEL_SETUP_SW12: + case ITEM_MODEL_SETUP_SW13: + case ITEM_MODEL_SETUP_SW14: + case ITEM_MODEL_SETUP_SW15: + case ITEM_MODEL_SETUP_SW16: + case ITEM_MODEL_SETUP_SW17: + case ITEM_MODEL_SETUP_SW18: + case ITEM_MODEL_SETUP_SW19: + case ITEM_MODEL_SETUP_SW20: { int index = (k - ITEM_MODEL_SETUP_SW1); + lcdDrawSizedText(INDENT_WIDTH, y, STR_CHAR_SWITCH, 2, attr); - lcdDrawText(lcdNextPos, y, switchGetName(index+switchGetMaxSwitches()), attr); + lcdDrawText(lcdNextPos, y, switchGetDefaultName(index), attr); if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { - cfsIndex = index; + swIndex = index; pushMenu(menuModelCFSOne); } - if (ZEXIST(g_model.switchNames[index])) { - char s[LEN_SWITCH_NAME + 1]; - strAppend(s, g_model.switchNames[index], LEN_SWITCH_NAME); - lcdDrawText(35, y, s); - } else { - lcdDrawMMM(35, y, 0); - } - - int config = FSWITCH_CONFIG(index); + int config = g_model.cfsType(index); lcdDrawText(30 + 5 * FW, y, STR_SWTYPES[config]); - if (config != SWITCH_NONE) { - uint8_t group = FSWITCH_GROUP(index); + if (config != SWITCH_NONE && config != SWITCH_GLOBAL) { + if (g_model.cfsName(index)[0]) { + char s[LEN_SWITCH_NAME + 1]; + strAppend(s, g_model.cfsName(index), LEN_SWITCH_NAME); + lcdDrawText(35, y, s); + } else { + lcdDrawMMM(35, y, 0); + } + + uint8_t group = g_model.cfsGroup(index); lcdDrawText(30 + 13 * FW, y, STR_FSGROUPS[group]); if (config != SWITCH_TOGGLE && group == 0) { - int startPos = FSWITCH_STARTUP(index); + int startPos = g_model.cfsStart(index); lcdDrawText(30 + 15 * FW, y, _fct_sw_start[startPos]); } } @@ -1024,6 +1080,7 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_GROUP1_LABEL: case ITEM_MODEL_SETUP_GROUP2_LABEL: case ITEM_MODEL_SETUP_GROUP3_LABEL: + case ITEM_MODEL_SETUP_GROUP4_LABEL: { int group = (k - ITEM_MODEL_SETUP_GROUP1_LABEL) / 3 + 1; lcdDrawText(INDENT_WIDTH, y, STR_GROUP); @@ -1034,13 +1091,14 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_GROUP1_ALWAYS_ON: case ITEM_MODEL_SETUP_GROUP2_ALWAYS_ON: case ITEM_MODEL_SETUP_GROUP3_ALWAYS_ON: + case ITEM_MODEL_SETUP_GROUP4_ALWAYS_ON: { uint8_t group = (k - ITEM_MODEL_SETUP_GROUP1_ALWAYS_ON) / 3 + 1; lcdDrawText(INDENT_WIDTH * 2, y, STR_GROUP_ALWAYS_ON); - int groupAlwaysOn = IS_FSWITCH_GROUP_ON(group); + int groupAlwaysOn = g_model.cfsGroupAlwaysOn(group); groupAlwaysOn = editCheckBox(groupAlwaysOn, MODEL_SETUP_2ND_COLUMN, y, nullptr, attr, event); if (attr && checkIncDec_Ret) { - SET_FSWITCH_GROUP_ON(group, groupAlwaysOn); + g_model.cfsSetGroupAlwaysOn(group, groupAlwaysOn); setGroupSwitchState(group); } } @@ -1049,20 +1107,27 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_GROUP1_START: case ITEM_MODEL_SETUP_GROUP2_START: case ITEM_MODEL_SETUP_GROUP3_START: + case ITEM_MODEL_SETUP_GROUP4_START: { uint8_t group = (k - ITEM_MODEL_SETUP_GROUP1_START) / 3 + 1; lcdDrawText(INDENT_WIDTH * 2, y, STR_START); - int sw = groupDefaultSwitch(group) + 1; + int sw = groupDefaultSwitch(group); cfsGroup = group; - sw = editChoice(MODEL_SETUP_2ND_COLUMN + 1, y, nullptr, STR_FSSWITCHES, sw, 0, IS_FSWITCH_GROUP_ON(group) ? NUM_FUNCTIONS_SWITCHES : NUM_FUNCTIONS_SWITCHES + 1, attr, event, 0, checkCFSSwitchAvailable); + if (sw == -1) + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 1, y, "=", attr); + else if (sw == switchGetMaxSwitches()) + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 1, y, STR_OFF, attr); + else + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 1, y, switchGetDefaultName(sw), attr); + sw = checkIncDec(event, sw, -1, switchGetMaxSwitches() - (g_model.cfsGroupAlwaysOn(group) ? 1 : 0), EE_MODEL, checkCFSSwitchAvailable); if (attr && checkIncDec_Ret) { - for (int i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) { - if (FSWITCH_GROUP(i) == group) { - FSWITCH_SET_STARTUP(i, sw ? FS_START_OFF : FS_START_PREVIOUS); + for (int i = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i) && g_model.cfsGroup(i) == group) { + g_model.cfsSetStart(i, (sw >= 0) ? FS_START_OFF : FS_START_PREVIOUS); } } - if (sw > 0 && sw <= NUM_FUNCTIONS_SWITCHES) { - FSWITCH_SET_STARTUP(sw - 1, FS_START_ON); + if (sw >= 0 && sw < switchGetMaxSwitches()) { + g_model.cfsSetStart(sw, FS_START_ON); } } } @@ -1162,6 +1227,7 @@ void menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_SWITCHES_WARNING2: + case ITEM_MODEL_SETUP_SWITCHES_WARNING3: if (i==0) { if (IS_PREVIOUS_EVENT(event)) menuVerticalOffset--; @@ -1186,8 +1252,6 @@ void menuModelSetup(event_t event) break; } - swarnstate_t states = g_model.switchWarning; - lcdDrawTextIndented(y, STR_SWITCHWARNING); #if defined(PCBXLITE) lcdDrawText(LCD_W, y, "<]", RIGHT); @@ -1213,17 +1277,15 @@ void menuModelSetup(event_t event) } int current = 0; - for (int i = 0; i < switchGetMaxSwitches(); i++) { + for (int i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) { div_t qr = div(current, MAX_SWITCH_PER_LINE); if (event == EVT_KEY_BREAK(KEY_ENTER) && attr && l_posHorz == current && old_posHorz >= 0) { - uint8_t curr_state = (states & 0x07); - // remove old setting - g_model.switchWarning &= ~(0x07 << (3 * i)); + uint8_t curr_state = g_model.getSwitchWarning(i); // add the new one (if switch UP and 2POS, jump directly to DOWN) curr_state += (curr_state != 1 || IS_CONFIG_3POS(i) ? 1 : 2); - g_model.switchWarning |= (curr_state & 0x03) << (3 * i); + g_model.setSwitchWarning(i, curr_state); storageDirty(EE_MODEL); #if defined(PCBXLITE) s_editMode = 0; @@ -1235,10 +1297,9 @@ void menuModelSetup(event_t event) y + FH * qr.quot, switchGetLetter(i), attr && (menuHorizontalPosition == current) ? INVERS : 0); lcdDrawText(lcdNextPos, y + FH * qr.quot, - getSwitchWarnSymbol(states & 0x03)); + getSwitchWarnSymbol(g_model.getSwitchWarning(i))); ++current; } - states >>= 3; } if (attr && ((menuHorizontalPosition < 0) || menuHorizontalPosition >= switchWarningsCount)) { diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index 179aabe75..f7df6e709 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -257,13 +257,13 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_CHANS, attr); else drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, MIXSRC_FIRST_STICK + param - 1, attr); + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam); } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { maxParam = MAX_GVARS - 1; drawStringWithIndex(lcdNextPos + 2, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags); - break; } #endif // GVARS else if (func == FUNC_SET_TIMER) { @@ -276,18 +276,17 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF if (attr) repeatLastCursorHorMove(event); } - break; } #if defined(FUNCTION_SWITCHES) else if (func == FUNC_PUSH_CUST_SWITCH) { - maxParam = NUM_FUNCTIONS_SWITCHES - 1; - drawStringWithIndex(lcdNextPos +5, y, "SW", CFN_CS_INDEX(cfn) + 1, attr); + uint8_t sw = switchGetSwitchFromCustomIdx(CFN_CS_INDEX(cfn)); + lcdDrawText(lcdNextPos + 5, y, switchGetDefaultName(sw), attr); + if (active) CFN_CS_INDEX(cfn) = switchGetCustomSwitchIdx(checkIncDec(event, sw, 0, switchGetMaxSwitches() - 1, eeFlags, switchIsCustomSwitch)); } #endif else if (attr) { repeatLastCursorHorMove(event); } - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam); break; } diff --git a/radio/src/gui/128x64/radio_diagkeys.cpp b/radio/src/gui/128x64/radio_diagkeys.cpp index 7c9a897b5..790eed5bf 100644 --- a/radio/src/gui/128x64/radio_diagkeys.cpp +++ b/radio/src/gui/128x64/radio_diagkeys.cpp @@ -65,21 +65,41 @@ void menuRadioDiagFS(event_t event) constexpr coord_t FS_3RD_COLUMN = 100; #endif SIMPLE_SUBMENU(STR_MENU_FSWITCH, 1); + lcdDrawText(FS_1ST_COLUMN, MENU_HEADER_HEIGHT + 1, "Phys"); lcdDrawText(FS_2ND_COLUMN, MENU_HEADER_HEIGHT + 1, "Log"); lcdDrawText(FS_3RD_COLUMN, MENU_HEADER_HEIGHT + 1, "Led"); - for(uint8_t i=0; i < NUM_FUNCTIONS_SWITCHES; i++) { - coord_t y = 2*FH + i*FH + 1; - lcdDrawTextIndented(y, STR_CHAR_SWITCH); - lcdDrawText(lcdNextPos, y, switchGetName(i+switchGetMaxSwitches()), 0); - lcdDrawText(FS_1ST_COLUMN + 7, y, getFSPhysicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP); - lcdDrawText(FS_2ND_COLUMN + 5, y, getFSLogicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP); + static uint8_t nxtSw = 0; + static uint8_t ofst = 0; + + if (event == EVT_ENTRY) + ofst = 0; + + for(uint8_t i=ofst, r=0; i < switchGetMaxSwitches(); i++) { + if (switchIsCustomSwitch(i)) { + if (r < 6) { + uint8_t sw = switchGetCustomSwitchIdx(i); + coord_t y = 2*FH + r*FH + 1; + lcdDrawTextIndented(y, STR_CHAR_SWITCH); + lcdDrawText(lcdNextPos, y, switchGetDefaultName(i)); + lcdDrawText(FS_1ST_COLUMN + 7, y, getFSPhysicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP); + lcdDrawText(FS_2ND_COLUMN + 5, y, g_model.cfsState(i) ? STR_CHAR_DOWN : STR_CHAR_UP); #if defined(FUNCTION_SWITCHES_RGB_LEDS) - lcdDrawText(FS_3RD_COLUMN, y, STR_FS_COLOR_LIST[getRGBColorIndex(fsGetLedRGB(i))], 0); + lcdDrawText(FS_3RD_COLUMN, y, STR_FS_COLOR_LIST[getRGBColorIndex(rgbGetLedColor(sw))], 0); #else - lcdDrawText(FS_3RD_COLUMN, y, STR_OFFON[fsLedState(i)]); + lcdDrawText(FS_3RD_COLUMN, y, STR_OFFON[fsLedState(sw)]); #endif + r += 1; + } else { + nxtSw = i; + break; + } + } + } + + if (nxtSw > 6 && event == EVT_KEY_BREAK(KEY_PAGEDN)) { + if (ofst == 0) ofst = nxtSw; else ofst = 0; } } #endif @@ -93,6 +113,8 @@ void menuRadioDiagKeys(event_t event) lcdDrawText(14*FW, 1, STR_VTRIM, INVERS); trim_yo = MENU_HEADER_HEIGHT + 1; } + uint8_t sw_y = MENU_HEADER_HEIGHT + 1; + uint8_t sw_x = 8 * FW - 9; for (uint8_t i = 0; i < 16; i++) { coord_t y; @@ -131,13 +153,18 @@ void menuRadioDiagKeys(event_t event) } } - if (i < switchGetMaxSwitches()) { - if (SWITCH_EXISTS(i)) { - y = (i > 4) ? FH * (i - 4) + 1 : MENU_HEADER_HEIGHT + FH * i + 1; + if (i < switchGetMaxAllSwitches()) { + if (SWITCH_EXISTS(i) && !switchIsCustomSwitch(i)) { getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i); getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3)); - drawSwitch(i > 4 ? 11 * FW - 5 : 8 * FW - 9, y, sw, 0, false); + drawSwitch(sw_x, sw_y, sw, 0, false); + if (i == 5) { + sw_x = 11 * FW - 5; + sw_y = MENU_HEADER_HEIGHT + 1; + } else { + sw_y += FH; + } } } } diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 924aa56a5..d3d24d043 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -351,7 +351,7 @@ void drawSmallSwitch(coord_t x, coord_t y, int width, unsigned int index) } } - lcdDrawChar(width == 5 ? x + 1 : x, y, 'A' + index, SMLSIZE); + lcdDrawChar(width == 5 ? x + 1 : x, y, switchGetDefaultName(index)[1], SMLSIZE); y += 7; if (val <= 0) { @@ -520,14 +520,25 @@ void menuMainView(event_t event) // -> 2 columns: one for each side // -> 4 slots on each side uint8_t maxSwitch = 0; + uint8_t leftMaxRow = 0; + uint8_t rightMaxRow = 0; for (uint8_t n = 0; n < switchGetMaxSwitches(); n += 1) - if (SWITCH_EXISTS(n) && !switchIsFlex(n)) + if (SWITCH_EXISTS(n) && !switchIsFlex(n) && !switchIsCustomSwitch(n)) { + auto switch_display = switchGetDisplayPosition(n); + if (switch_display.col) { + if (switch_display.row > rightMaxRow) + rightMaxRow = switch_display.row; + } else { + if (switch_display.row > leftMaxRow) + leftMaxRow = switch_display.row; + } maxSwitch = n + 1; + } - for (int i = 0; i < maxSwitch; ++i) { - if (SWITCH_EXISTS(i) && !switchIsFlex(i)) { - auto switch_display = switchGetDisplayPosition(i); - if (maxSwitch < 7) { + if (leftMaxRow < 3 && rightMaxRow < 3) { + for (int i = 0; i < maxSwitch; ++i) { + if (SWITCH_EXISTS(i) && !switchIsFlex(i) && !switchIsCustomSwitch(i)) { + auto switch_display = switchGetDisplayPosition(i); coord_t x = switch_display.col == 0 ? 3 * FW + 3 : 18 * FW + 1; coord_t y = 33 + switch_display.row * FH; getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i); @@ -537,9 +548,14 @@ void menuMainView(event_t event) : ((val == 0) ? 3 * i + 2 : 3 * i + 3)); drawSwitch(x, y, sw, CENTERED, false); } - else { + } + } + else { + for (int i = 0; i < maxSwitch; ++i) { + if (SWITCH_EXISTS(i) && !switchIsFlex(i) && !switchIsCustomSwitch(i)) { + auto switch_display = switchGetDisplayPosition(i); coord_t x = (switch_display.col == 0 ? 8 : 96) + switch_display.row * 5; - if (maxSwitch < 9) x += (switch_display.col == 0 ? 2 : 3); + if (maxSwitch < 9) x += 3; drawSmallSwitch(x, 5 * FH + 1, 4, i); } } diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index cf3ce9577..e34209ee6 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -41,7 +41,7 @@ uint8_t g_moduleIdx; uint8_t getSwitchWarningsCount() { uint8_t count = 0; - for (int i = 0; i < switchGetMaxSwitches(); ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_WARNING_ALLOWED(i)) { ++count; } @@ -870,7 +870,6 @@ void menuModelSetup(event_t event) } #endif lcdDrawTextIndented(y, STR_SWITCHWARNING); - swarnstate_t states = g_model.switchWarning; if (attr) { s_editMode = 0; @@ -888,17 +887,15 @@ void menuModelSetup(event_t event) LcdFlags line = attr; int current = 0; - for (int i = 0; i < switchGetMaxSwitches(); i++) { + for (int i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) { div_t qr = div(current, 8); if (event == EVT_KEY_BREAK(KEY_ENTER) && line && l_posHorz == current) { - uint8_t curr_state = (states & 0x07); - // remove old setting - g_model.switchWarning &= ~(0x07 << (3 * i)); + uint8_t curr_state = g_model.getSwitchWarning(i); // add the new one (if switch UP and 2POS, jump directly to DOWN) curr_state += (curr_state != 1 || IS_CONFIG_3POS(i) ? 1 : 2); - g_model.switchWarning |= (curr_state & 0x03) << (3 * i); + g_model.setSwitchWarning(i, curr_state); storageDirty(EE_MODEL); } lcdDrawChar( @@ -906,10 +903,9 @@ void menuModelSetup(event_t event) y + FH * qr.quot, 'A' + i, line && (menuHorizontalPosition == current) ? INVERS : 0); lcdDrawText(lcdNextPos, y + FH * qr.quot, - getSwitchWarnSymbol(states & 0x03)); + getSwitchWarnSymbol(g_model.getSwitchWarning(i))); ++current; } - states >>= 3; } if (attr && menuHorizontalPosition < 0) { #if defined(PCBX9E) diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index 3a6d9f03b..366191717 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -123,6 +123,7 @@ endif() if(FUNCTION_SWITCHES) add_gui_src(model/function_switches.cpp) + add_gui_src(radio/radio_cfs.cpp) add_gui_src(radio/radio_diagcustswitches.cpp) endif() diff --git a/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp b/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp index bd948f51a..73ec69d42 100644 --- a/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp +++ b/radio/src/gui/colorlcd/controls/switch_warn_dialog.cpp @@ -59,15 +59,14 @@ void SwitchWarnDialog::checkEvents() FullScreenDialog::checkEvents(); std::string warn_txt; - swarnstate_t states = g_model.switchWarning; - for (int i = 0; i < MAX_SWITCHES; ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_WARNING_ALLOWED(i)) { - swarnstate_t mask = ((swarnstate_t)0x07 << (i * 3)); - if (states & mask) { - if ((switches_states & mask) != (states & mask)) { - swarnstate_t state = (states >> (i * 3)) & 0x07; + uint8_t warnState = g_model.getSwitchWarning(i); + if (warnState) { + swarnstate_t swState = g_model.getSwitchStateForWarning(i); + if (warnState != swState) { warn_txt += - getSwitchPositionName(SWSRC_FIRST_SWITCH + i * 3 + state - 1); + getSwitchPositionName(SWSRC_FIRST_SWITCH + i * 3 + warnState - 1); warn_txt += " "; } } diff --git a/radio/src/gui/colorlcd/model/function_switches.cpp b/radio/src/gui/colorlcd/model/function_switches.cpp index 4d6a8dc71..b3909d50d 100644 --- a/radio/src/gui/colorlcd/model/function_switches.cpp +++ b/radio/src/gui/colorlcd/model/function_switches.cpp @@ -24,15 +24,16 @@ #include "function_switches.h" #include "edgetx.h" +#include "hal/rgbleds.h" #include "strhelpers.h" #include "switches.h" #include "color_picker.h" #define SET_DIRTY() storageDirty(EE_MODEL) -static const char* _fct_sw_start[] = {STR_CHAR_DOWN, STR_CHAR_UP, STR_LAST}; +const char* _fct_sw_start[] = {STR_CHAR_UP, STR_CHAR_DOWN, STR_LAST}; -const std::string edgetx_fs_manual_url = +const char* edgetx_fs_manual_url = "https://edgetx.gitbook.io/edgetx-user-manual/b-and-w-radios/model-select/" "setup#function-switches"; @@ -45,65 +46,70 @@ class FunctionSwitch : public Window padAll(PAD_TINY); std::string s(STR_CHAR_SWITCH); - s += switchGetName(switchIndex + switchGetMaxSwitches()); + s += switchGetDefaultName(switchIndex); new StaticText(this, {PAD_LARGE, PAD_MEDIUM, SW_W, EdgeTxStyles::STD_FONT_HEIGHT}, s); new ModelTextEdit(this, {NM_X, 0, NM_W, 0}, - g_model.switchNames[switchIndex], LEN_SWITCH_NAME); + g_model.cfsName(switchIndex), LEN_SWITCH_NAME); typeChoice = new Choice( - this, {TP_X, 0, TP_W, 0}, STR_SWTYPES, SWITCH_NONE, SWITCH_2POS, - [=]() { return FSWITCH_CONFIG(switchIndex); }, + this, {TP_X, 0, TP_W, 0}, STR_SWTYPES, SWITCH_NONE, SWITCH_GLOBAL, + [=]() { return g_model.cfsType(switchIndex); }, [=](int val) { - FSWITCH_SET_CONFIG(switchIndex, val); - if (val == SWITCH_TOGGLE) { - FSWITCH_SET_STARTUP(switchIndex, FS_START_PREVIOUS); + g_model.cfsSetType(switchIndex, (SwitchConfig)val); + if (val == SWITCH_NONE) { +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + fsLedRGB(switchGetCustomSwitchIdx(switchIndex), 0); +#endif + } else if (val == SWITCH_TOGGLE) { + g_model.cfsSetStart(switchIndex, FS_START_PREVIOUS); setFSLogicalState(switchIndex, 0); startChoice->setValue(startChoice->getIntValue()); } SET_DIRTY(); }); typeChoice->setAvailableHandler([=](int typ) -> bool { - int group = FSWITCH_GROUP(switchIndex); - if (group > 0 && IS_FSWITCH_GROUP_ON(group) && typ == SWITCH_TOGGLE) + if (typ == SWITCH_3POS) return false; + int group = g_model.cfsGroup(switchIndex); + if (group > 0 && g_model.cfsGroupAlwaysOn(group) && typ == SWITCH_TOGGLE) return false; return true; }); groupChoice = new Choice( this, {GR_X, 0, GR_W, 0}, STR_FUNCTION_SWITCH_GROUPS, 0, 3, - [=]() { return FSWITCH_GROUP(switchIndex); }, + [=]() { return g_model.cfsGroup(switchIndex); }, [=](int group) { - int oldGroup = FSWITCH_GROUP(switchIndex); + int oldGroup = g_model.cfsGroup(switchIndex); if (groupHasSwitchOn(group)) setFSLogicalState(switchIndex, 0); - FSWITCH_SET_GROUP(switchIndex, group); + g_model.cfsSetGroup(switchIndex, group); if (group > 0) { - FSWITCH_SET_STARTUP(switchIndex, groupDefaultSwitch(group) == -1 + g_model.cfsSetStart(switchIndex, groupDefaultSwitch(group) == -1 ? FS_START_PREVIOUS : FS_START_OFF); - if (FSWITCH_CONFIG(switchIndex) == SWITCH_TOGGLE && - IS_FSWITCH_GROUP_ON(group)) - FSWITCH_SET_CONFIG(switchIndex, SWITCH_2POS); - setGroupSwitchState(group, switchIndex); + if (g_model.cfsType(switchIndex) == SWITCH_TOGGLE && + g_model.cfsGroupAlwaysOn(group)) + g_model.cfsSetType(switchIndex, SWITCH_2POS); + setGroupSwitchState(group); } else { - FSWITCH_SET_STARTUP(switchIndex, FS_START_PREVIOUS); + g_model.cfsSetStart(switchIndex, FS_START_PREVIOUS); } setGroupSwitchState(oldGroup); SET_DIRTY(); }); groupChoice->setAvailableHandler([=](int group) -> bool { - if (FSWITCH_CONFIG(switchIndex) == SWITCH_TOGGLE && group && - IS_FSWITCH_GROUP_ON(group)) + if (g_model.cfsType(switchIndex) == SWITCH_TOGGLE && group && + g_model.cfsGroupAlwaysOn(group)) return false; return true; }); startChoice = new Choice( this, {ST_X, 0, ST_W, 0}, _fct_sw_start, 0, 2, - [=]() { return FSWITCH_STARTUP(switchIndex); }, + [=]() { return g_model.cfsStart(switchIndex); }, [=](int val) { - FSWITCH_SET_STARTUP(switchIndex, val); + g_model.cfsSetStart(switchIndex, (fsStartPositionType)val); SET_DIRTY(); }); @@ -113,23 +119,23 @@ class FunctionSwitch : public Window new StaticText(this, rect_t{C2_X - C2_W - PAD_TINY, C2_Y + PAD_SMALL, C2_W, 0}, STR_ON_ONE_SWITCHES[0], COLOR_THEME_PRIMARY1_INDEX, FONT(XS) | RIGHT); #endif - offValue = g_model.functionSwitchLedOFFColor[switchIndex]; - onValue = g_model.functionSwitchLedONColor[switchIndex]; + offValue = g_model.cfsOffColor(switchIndex); + onValue = g_model.cfsOnColor(switchIndex); offColor = new ColorPicker( this, {C1_X, C1_Y, C1_W, 0}, [=]() -> int { // getValue - return g_model.functionSwitchLedOFFColor[switchIndex].getColor() | RGB888_FLAG; + return g_model.cfsOffColor(switchIndex).getColor() | RGB888_FLAG; }, [=](int newValue) { // setValue - g_model.functionSwitchLedOFFColor[switchIndex] = offValue; - g_model.functionSwitchLedONColor[switchIndex] = onValue; + g_model.cfsOffColor(switchIndex) = offValue; + g_model.cfsOnColor(switchIndex) = onValue; // Convert color index to RGB newValue = color32ToRGB(newValue); - g_model.functionSwitchLedOFFColor[switchIndex].setColor(newValue); + g_model.cfsOffColor(switchIndex).setColor(newValue); - offValue = g_model.functionSwitchLedOFFColor[switchIndex]; + offValue = g_model.cfsOffColor(switchIndex); SET_DIRTY(); }, [=](int newValue) { previewColor(newValue); }, ETX_RGB888); @@ -137,20 +143,29 @@ class FunctionSwitch : public Window onColor = new ColorPicker( this, {C2_X, C2_Y, C2_W, 0}, [=]() -> int { // getValue - return g_model.functionSwitchLedONColor[switchIndex].getColor() | RGB888_FLAG; + return g_model.cfsOnColor(switchIndex).getColor() | RGB888_FLAG; }, [=](int newValue) { // setValue - g_model.functionSwitchLedOFFColor[switchIndex] = offValue; - g_model.functionSwitchLedONColor[switchIndex] = onValue; + g_model.cfsOffColor(switchIndex) = offValue; + g_model.cfsOnColor(switchIndex) = onValue; // Convert color index to RGB newValue = color32ToRGB(newValue); - g_model.functionSwitchLedONColor[switchIndex].setColor(newValue); + g_model.cfsOnColor(switchIndex).setColor(newValue); - onValue = g_model.functionSwitchLedONColor[switchIndex]; + onValue = g_model.cfsOnColor(switchIndex); SET_DIRTY(); }, [=](int newValue) { previewColor(newValue); }, ETX_RGB888); + + overrideLabel = new StaticText(this, {GR_X, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_LARGE, GR_W + ST_W - PAD_LARGE, 0}, + STR_LUA_OVERRIDE, COLOR_THEME_PRIMARY1_INDEX, FONT(XS) | RIGHT); + offOverride = new ToggleSwitch(this, {C1_X - PAD_MEDIUM * 2, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE, 0, 0}, + [=]() { return g_model.cfsOffColorLuaOverride(switchIndex); }, + [=](bool v) { g_model.cfsSetOffColorLuaOverride(switchIndex, v); }); + onOverride = new ToggleSwitch(this, {C2_X, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE, 0, 0}, + [=]() { return g_model.cfsOnColorLuaOverride(switchIndex); }, + [=](bool v) { g_model.cfsSetOnColorLuaOverride(switchIndex, v); }); #endif //FUNCTION_SWITCHES_RGB_LEDS setState(); @@ -167,7 +182,7 @@ class FunctionSwitch : public Window static constexpr coord_t ST_X = GR_X + GR_W + PAD_SMALL; static LAYOUT_VAL_SCALED(ST_W, 60) #if NARROW_LAYOUT - static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT * 2 + PAD_OUTLINE * 3; + static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT * 3 + PAD_OUTLINE * 4; static constexpr coord_t C1_X = TP_X; static constexpr coord_t C1_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; static LAYOUT_VAL_SCALED(C1_W, 40) @@ -175,7 +190,7 @@ class FunctionSwitch : public Window static constexpr coord_t C2_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; static LAYOUT_VAL_SCALED(C2_W, 40) #else - static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE * 2; + static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT * 2 + PAD_OUTLINE * 3; static constexpr coord_t C1_X = ST_X + ST_W + PAD_SMALL; static constexpr coord_t C1_Y = 0; static LAYOUT_VAL_SCALED(C1_W, 40) @@ -206,6 +221,9 @@ class FunctionSwitch : public Window ColorPicker* onColor = nullptr; RGBLedColor offValue; RGBLedColor onValue; + StaticText* overrideLabel = nullptr; + ToggleSwitch* onOverride = nullptr; + ToggleSwitch* offOverride = nullptr; #endif int lastType = -1; @@ -214,29 +232,37 @@ class FunctionSwitch : public Window { // Convert color index to RGB newValue = color32ToRGB(newValue); - if (getFSLogicalState(switchIndex)) { - g_model.functionSwitchLedONColor[switchIndex].setColor(newValue); + if (g_model.cfsState(switchIndex)) { + g_model.cfsOnColor(switchIndex).setColor(newValue); } else { - g_model.functionSwitchLedOFFColor[switchIndex].setColor(newValue); + g_model.cfsOffColor(switchIndex).setColor(newValue); } } #endif void setState() { - startChoice->show(FSWITCH_CONFIG(switchIndex) == SWITCH_2POS && FSWITCH_GROUP(switchIndex) == 0); - groupChoice->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE); + uint8_t typ = g_model.cfsType(switchIndex); + startChoice->show(typ == SWITCH_2POS && g_model.cfsGroup(switchIndex) == 0); + groupChoice->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); #if defined(FUNCTION_SWITCHES_RGB_LEDS) - offColor->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE); - onColor->show(FSWITCH_CONFIG(switchIndex) != SWITCH_NONE); + offColor->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + onColor->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + overrideLabel->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + onOverride->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + offOverride->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + if (typ != SWITCH_NONE && typ != SWITCH_GLOBAL) + setHeight(ROW_H); + else + setHeight(ROW_H - EdgeTxStyles::UI_ELEMENT_HEIGHT - PAD_OUTLINE); #endif } void checkEvents() override { setState(); - if (lastType != (int)FSWITCH_CONFIG(switchIndex)) { - lastType = FSWITCH_CONFIG(switchIndex); + if (lastType != (int)g_model.cfsType(switchIndex)) { + lastType = g_model.cfsType(switchIndex); typeChoice->setValue(lastType); } Window::checkEvents(); @@ -256,38 +282,43 @@ class SwitchGroup : public Window auto btn = new TextButton( this, {AO_X, 0, AO_W, 0}, STR_GROUP_ALWAYS_ON, [=]() -> int8_t { - int groupAlwaysOn = IS_FSWITCH_GROUP_ON(groupIndex); + int groupAlwaysOn = g_model.cfsGroupAlwaysOn(groupIndex); groupAlwaysOn ^= 1; - SET_FSWITCH_GROUP_ON(groupIndex, groupAlwaysOn); + g_model.cfsSetGroupAlwaysOn(groupIndex, groupAlwaysOn); setGroupSwitchState(groupIndex); startChoice->setValue(startChoice->getIntValue()); SET_DIRTY(); return groupAlwaysOn; }); - btn->check(IS_FSWITCH_GROUP_ON(groupIndex)); + btn->check(g_model.cfsGroupAlwaysOn(groupIndex)); new StaticText(this, {SL_X, PAD_MEDIUM, SL_W, EdgeTxStyles::STD_FONT_HEIGHT}, STR_SWITCH_STARTUP); startChoice = new Choice( - this, {ST_X, 0, ST_W, 0}, STR_FSSWITCHES, 0, - NUM_FUNCTIONS_SWITCHES + 1, + this, {ST_X, 0, ST_W, 0}, 0, switchGetMaxSwitches() + 1, [=]() { return groupDefaultSwitch(groupIndex) + 1; }, [=](int sw) { - for (int i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) { - if (FSWITCH_GROUP(i) == groupIndex) { - FSWITCH_SET_STARTUP(i, sw ? FS_START_OFF : FS_START_PREVIOUS); + for (int i = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i) && g_model.cfsGroup(i) == groupIndex) { + g_model.cfsSetStart(i, (sw > 0) ? FS_START_OFF : FS_START_PREVIOUS); } } - if (sw > 0 && sw <= NUM_FUNCTIONS_SWITCHES) { - FSWITCH_SET_STARTUP(sw - 1, FS_START_ON); + if (sw > 0 && sw <= switchGetMaxSwitches()) { + g_model.cfsSetStart(sw - 1, FS_START_ON); } SET_DIRTY(); }); + startChoice->setTextHandler([=](int sw) -> std::string { + if (sw == 0) + return "="; + if (sw == switchGetMaxSwitches() + 1) + return STR_OFF; + return switchGetDefaultName(sw - 1); + }); startChoice->setAvailableHandler([=](int sw) -> bool { return (sw == 0) || - (sw == NUM_FUNCTIONS_SWITCHES + 1 && - !IS_FSWITCH_GROUP_ON(groupIndex)) || - (FSWITCH_GROUP(sw - 1) == groupIndex); + (sw == switchGetMaxSwitches() + 1 && !g_model.cfsGroupAlwaysOn(groupIndex)) || + (switchIsCustomSwitch(sw - 1) && g_model.cfsGroup(sw - 1) == groupIndex); }); } @@ -331,8 +362,9 @@ ModelFunctionSwitches::ModelFunctionSwitches() : Page(ICON_MODEL_SETUP) new StaticText(box, rect_t{FunctionSwitch::C2_X + PAD_OUTLINE, 0, FunctionSwitch::C2_W, 0}, STR_ON_ONE_SWITCHES[0], COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); #endif - for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) { - new FunctionSwitch(body, i); + for (uint8_t i = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i)) + new FunctionSwitch(body, i); } for (uint8_t i = 1; i <= 3; i += 1) { @@ -349,8 +381,7 @@ ModelFunctionSwitches::ModelFunctionSwitches() : Page(ICON_MODEL_SETUP) auto qr = lv_qrcode_create(box->getLvObj(), 150, makeLvColor(COLOR_THEME_SECONDARY1), makeLvColor(COLOR_THEME_SECONDARY3)); - lv_qrcode_update(qr, edgetx_fs_manual_url.c_str(), - edgetx_fs_manual_url.length()); + lv_qrcode_update(qr, edgetx_fs_manual_url, strlen(edgetx_fs_manual_url)); lv_obj_set_pos(qr, (LCD_W - 150) / 2, EdgeTxStyles::STD_FONT_HEIGHT); #endif diff --git a/radio/src/gui/colorlcd/model/preflight_checks.cpp b/radio/src/gui/colorlcd/model/preflight_checks.cpp index 68a8d9c66..8d4b82462 100644 --- a/radio/src/gui/colorlcd/model/preflight_checks.cpp +++ b/radio/src/gui/colorlcd/model/preflight_checks.cpp @@ -38,7 +38,7 @@ class SwitchWarnMatrix : public ButtonMatrix { // Setup button layout & texts uint8_t btn_cnt = 0; - for (uint8_t i = 0; i < MAX_SWITCHES; i++) { + for (uint8_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) { sw_idx[btn_cnt] = i; btn_cnt++; @@ -66,17 +66,16 @@ class SwitchWarnMatrix : public ButtonMatrix return; } - if (btn_id >= MAX_SWITCHES) return; + if (btn_id >= switchGetMaxAllSwitches()) return; auto sw = sw_idx[btn_id]; - swarnstate_t newstate = bfGet(g_model.switchWarning, 3 * sw, 3); - if (newstate == 1 && SWITCH_CONFIG(sw) != SWITCH_3POS) + uint8_t newstate = g_model.getSwitchWarning(sw); + if (newstate == 1 && g_model.getSwitchType(sw) != SWITCH_3POS) newstate = 3; else - newstate = (newstate + 1) % 4; + newstate = (newstate + 1) & 3; - g_model.switchWarning = - bfSet(g_model.switchWarning, newstate, 3 * sw, 3); + g_model.setSwitchWarning(sw, newstate); SET_DIRTY(); setTextAndState(btn_id); @@ -84,15 +83,15 @@ class SwitchWarnMatrix : public ButtonMatrix bool isActive(uint8_t btn_id) override { - if (btn_id >= MAX_SWITCHES) return false; - return bfGet(g_model.switchWarning, 3 * sw_idx[btn_id], 3) != 0; + if (btn_id >= switchGetMaxAllSwitches()) return false; + return g_model.getSwitchWarning(sw_idx[btn_id]) != 0; } void setTextAndState(uint8_t btn_id) { swsrc_t index = sw_idx[btn_id]; - auto warn_pos = g_model.switchWarning >> (3 * index) & 0x07; - std::string s = std::string(switchGetName(index)) + + auto warn_pos = g_model.getSwitchWarning(index); + std::string s = std::string(switchGetDefaultName(index)) + std::string(getSwitchWarnSymbol(warn_pos)); setText(btn_id, s.c_str()); setChecked(btn_id); @@ -109,7 +108,7 @@ class SwitchWarnMatrix : public ButtonMatrix void setAllState() { uint8_t btn_id = 0; - for (uint8_t i = 0; i < MAX_SWITCHES; i++) { + for (uint8_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) { setTextAndState(btn_id); btn_id++; diff --git a/radio/src/gui/colorlcd/model/special_functions.cpp b/radio/src/gui/colorlcd/model/special_functions.cpp index 9759e16fb..d300a745f 100644 --- a/radio/src/gui/colorlcd/model/special_functions.cpp +++ b/radio/src/gui/colorlcd/model/special_functions.cpp @@ -220,7 +220,7 @@ void FunctionLineButton::refresh() #if defined(FUNCTION_SWITCHES) case FUNC_PUSH_CUST_SWITCH: - sprintf(s + strlen(s), "%s%d", STR_SWITCH, CFN_CS_INDEX(cfn) + 1); + strAppend(s + strlen(s), switchGetDefaultName(switchGetSwitchFromCustomIdx(CFN_CS_INDEX(cfn)))); break; #endif @@ -505,10 +505,15 @@ void FunctionEditPage::updateSpecialFunctionOneWindow() #if defined(FUNCTION_SWITCHES) case FUNC_PUSH_CUST_SWITCH: { new StaticText(line, rect_t{}, STR_SWITCH); - auto choice = new Choice(line, rect_t{}, 0, NUM_FUNCTIONS_SWITCHES - 1, GET_SET_DEFAULT(CFN_CS_INDEX(cfn)), STR_SWITCH); + auto choice = new Choice(line, rect_t{}, 0, switchGetMaxSwitches() - 1, + [=]() { return switchGetSwitchFromCustomIdx(CFN_CS_INDEX(cfn)); }, + [=](int n) { CFN_CS_INDEX(cfn) = switchGetCustomSwitchIdx(n); }, + STR_SWITCH); choice->setTextHandler([=](int n) { - return std::string(STR_SWITCH) + std::to_string(n + 1); + return std::string(switchGetDefaultName(n)); }); + choice->setAvailableHandler(switchIsCustomSwitch); + line = specialFunctionOneWindow->newLine(grid); auto edit = addNumberEdit(line, STR_INTERVAL, cfn, PUSH_CS_DURATION_MIN, diff --git a/radio/src/gui/colorlcd/radio/hw_inputs.cpp b/radio/src/gui/colorlcd/radio/hw_inputs.cpp index b989b87e4..34efb6d4b 100644 --- a/radio/src/gui/colorlcd/radio/hw_inputs.cpp +++ b/radio/src/gui/colorlcd/radio/hw_inputs.cpp @@ -171,7 +171,7 @@ class SwitchDynamicLabel : public StaticText std::string label() { - std::string str(switchGetCanonicalName(index)); + std::string str(switchGetDefaultName(index)); return str + getSwitchPositionSymbol(lastpos); } @@ -206,7 +206,7 @@ class HWSwitch HWSwitch(Window* parent, int swnum, coord_t y) { new SwitchDynamicLabel(parent, swnum, PAD_TINY, y + PAD_SMALL, HWSwitches::SW_CTRL_W); - new HWInputEdit(parent, (char*)switchGetCustomName(swnum), LEN_SWITCH_NAME, + new HWInputEdit(parent, g_eeGeneral.getSwitchCustomName(swnum), LEN_SWITCH_NAME, HWSwitches::SW_CTRL_W + PAD_SMALL, y); coord_t x = HWSwitches::SW_CTRL_W * 2 + PAD_SMALL * 2; @@ -233,12 +233,9 @@ class HWSwitch sw_cfg = new Choice( parent, {x, y, HWSwitches::SW_CTRL_W, 0}, STR_SWTYPES, SWITCH_NONE, switchGetMaxType(swnum), - [=]() -> int { return SWITCH_CONFIG(swnum); }, + [=]() -> int { return g_eeGeneral.switchType(swnum); }, [=](int newValue) { - swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(swnum); - g_eeGeneral.switchConfig = - (g_eeGeneral.switchConfig & ~mask) | - ((swconfig_t(newValue) & SW_CFG_MASK) << (SW_CFG_BITS * swnum)); + g_eeGeneral.switchSetType(swnum, (SwitchConfig)newValue); SET_DIRTY(); }); @@ -266,9 +263,10 @@ HWSwitches::HWSwitches(Window* parent) : { padAll(PAD_TINY); - auto max_switches = switchGetMaxSwitches(); + auto max_switches = switchGetMaxAllSwitches(); for (int i = 0; i < max_switches; i++) { - new HWSwitch(this, i, i * HWSwitch::SW_CTRL_H + PAD_OUTLINE); + if (!switchIsCustomSwitch(i)) + new HWSwitch(this, i, i * HWSwitch::SW_CTRL_H + PAD_OUTLINE); } } diff --git a/radio/src/gui/colorlcd/radio/radio_cfs.cpp b/radio/src/gui/colorlcd/radio/radio_cfs.cpp new file mode 100644 index 000000000..83489470c --- /dev/null +++ b/radio/src/gui/colorlcd/radio/radio_cfs.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if defined(FUNCTION_SWITCHES) + +#include "radio_cfs.h" + +#include "edgetx.h" +#include "hal/rgbleds.h" +#include "strhelpers.h" +#include "switches.h" +#include "color_picker.h" + +#define SET_DIRTY() storageDirty(EE_GENERAL) + +static const lv_coord_t cfs_line_col_dsc1[] = {LV_GRID_CONTENT, + LV_GRID_TEMPLATE_LAST}; + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +static const lv_coord_t cfs_line_col_dsc2[] = { + LV_GRID_FR(13), LV_GRID_FR(11), LV_GRID_FR(11), + LV_GRID_FR(12), LV_GRID_FR(10), LV_GRID_FR(7), LV_GRID_FR(7), + LV_GRID_TEMPLATE_LAST}; +#else +static const lv_coord_t cfs_line_col_dsc2[] = { + LV_GRID_FR(10), LV_GRID_FR(10), LV_GRID_FR(10), + LV_GRID_FR(12), LV_GRID_FR(8), LV_GRID_TEMPLATE_LAST}; +#endif + +static const lv_coord_t cfs_line_row_dsc[] = {LV_GRID_CONTENT, + LV_GRID_TEMPLATE_LAST}; + +extern const char* _fct_sw_start[]; +extern const char* edgetx_fs_manual_url; + +class RadioFunctionSwitch : public Window +{ + public: + RadioFunctionSwitch(Window* parent, uint8_t sw) : + Window(parent, {0, 0, LCD_W - PAD_SMALL * 2, ROW_H}), switchIndex(sw) + { + padAll(PAD_TINY); + + std::string s(STR_CHAR_SWITCH); + s += switchGetDefaultName(switchIndex); + + new StaticText(this, {PAD_LARGE, PAD_MEDIUM, SW_W, EdgeTxStyles::STD_FONT_HEIGHT}, s); + + new ModelTextEdit(this, {NM_X, 0, NM_W, 0}, + g_eeGeneral.switchName(switchIndex), LEN_SWITCH_NAME); + + typeChoice = new Choice( + this, {TP_X, 0, TP_W, 0}, STR_SWTYPES, SWITCH_NONE, SWITCH_GLOBAL, + [=]() { return g_eeGeneral.switchType(switchIndex); }, + [=](int val) { + g_eeGeneral.switchSetType(switchIndex, (SwitchConfig)val); + if (val == SWITCH_NONE) { +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + if (g_model.getSwitchType(switchIndex) == SWITCH_NONE) + fsLedRGB(switchGetCustomSwitchIdx(switchIndex), 0); +#endif + } else if (val == SWITCH_TOGGLE) { + g_eeGeneral.switchSetStart(switchIndex, FS_START_PREVIOUS); + setFSLogicalState(switchIndex, 0); + startChoice->setValue(startChoice->getIntValue()); + } + SET_DIRTY(); + }); + typeChoice->setAvailableHandler([=](int typ) -> bool { + if (typ == SWITCH_3POS || typ == SWITCH_GLOBAL) return false; + int group = g_eeGeneral.switchGroup(switchIndex); + if (group > 0 && g_model.cfsGroupAlwaysOn(group) && typ == SWITCH_TOGGLE) + return false; + return true; + }); + + startChoice = new Choice( + this, {ST_X, 0, ST_W, 0}, _fct_sw_start, 0, 2, + [=]() { return g_eeGeneral.switchStart(switchIndex); }, + [=](int val) { + g_eeGeneral.switchSetStart(switchIndex, (fsStartPositionType)val); + SET_DIRTY(); + }); + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +#if NARROW_LAYOUT + new StaticText(this, rect_t{C1_X - C1_W - PAD_TINY, C1_Y + PAD_SMALL, C1_W, 0}, STR_OFF, COLOR_THEME_PRIMARY1_INDEX, FONT(XS) | RIGHT); + new StaticText(this, rect_t{C2_X - C2_W - PAD_TINY, C2_Y + PAD_SMALL, C2_W, 0}, STR_ON_ONE_SWITCHES[0], COLOR_THEME_PRIMARY1_INDEX, FONT(XS) | RIGHT); +#endif + + offValue = g_eeGeneral.switchOffColor(switchIndex); + onValue = g_eeGeneral.switchOnColor(switchIndex); + + offColor = new ColorPicker( + this, {C1_X, 0, C1_W, 0}, + [=]() -> int { // getValue + return g_eeGeneral.switchOffColor(switchIndex).getColor() | RGB888_FLAG; + }, + [=](int newValue) { // setValue + g_eeGeneral.switchOffColor(switchIndex) = offValue; + g_eeGeneral.switchOnColor(switchIndex) = onValue; + + // Convert color index to RGB + newValue = color32ToRGB(newValue); + g_eeGeneral.switchOffColor(switchIndex).setColor(newValue); + + offValue = g_eeGeneral.switchOffColor(switchIndex); + SET_DIRTY(); + }, + [=](int newValue) { previewColor(newValue); }, ETX_RGB888); + + onColor = new ColorPicker( + this, {C2_X, 0, C2_W, 0}, + [=]() -> int { // getValue + return g_eeGeneral.switchOnColor(switchIndex).getColor() | RGB888_FLAG; + }, + [=](int newValue) { // setValue + g_eeGeneral.switchOffColor(switchIndex) = offValue; + g_eeGeneral.switchOnColor(switchIndex) = onValue; + + // Convert color index to RGB + newValue = color32ToRGB(newValue); + g_eeGeneral.switchOnColor(switchIndex).setColor(newValue); + + onValue = g_eeGeneral.switchOnColor(switchIndex); + SET_DIRTY(); + }, + [=](int newValue) { previewColor(newValue); }, ETX_RGB888); + + overrideLabel = new StaticText(this, {GR_X, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_LARGE, GR_W + ST_W - PAD_LARGE, 0}, + STR_LUA_OVERRIDE, COLOR_THEME_PRIMARY1_INDEX, FONT(XS) | RIGHT); + offOverride = new ToggleSwitch(this, {C1_X - PAD_MEDIUM * 2, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE, 0, 0}, + [=]() { return g_model.cfsOffColorLuaOverride(switchIndex); }, + [=](bool v) { g_model.cfsSetOffColorLuaOverride(switchIndex, v); }); + onOverride = new ToggleSwitch(this, {C2_X, C1_Y + EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE, 0, 0}, + [=]() { return g_model.cfsOnColorLuaOverride(switchIndex); }, + [=](bool v) { g_model.cfsSetOnColorLuaOverride(switchIndex, v); }); +#endif //FUNCTION_SWITCHES_RGB_LEDS + + setState(); + } + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + static LAYOUT_VAL_SCALED(SW_W, 70) + static constexpr coord_t NM_X = SW_W + PAD_SMALL; + static LAYOUT_VAL_SCALED(NM_W, 60) + static constexpr coord_t TP_X = NM_X + NM_W + PAD_SMALL; + static LAYOUT_VAL_SCALED(TP_W, 78) + static constexpr coord_t GR_X = TP_X + TP_W + PAD_SMALL; + static LAYOUT_VAL_SCALED(GR_W, 84) + static constexpr coord_t ST_X = GR_X + GR_W + PAD_SMALL; + static LAYOUT_VAL_SCALED(ST_W, 60) +#if NARROW_LAYOUT + static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT * 3 + PAD_OUTLINE * 4; + static constexpr coord_t C1_X = TP_X; + static constexpr coord_t C1_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; + static LAYOUT_VAL_SCALED(C1_W, 40) + static constexpr coord_t C2_X = GR_X; + static constexpr coord_t C2_Y = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE; + static LAYOUT_VAL_SCALED(C2_W, 40) +#else + static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT * 2 + PAD_OUTLINE * 3; + static constexpr coord_t C1_X = ST_X + ST_W + PAD_SMALL; + static constexpr coord_t C1_Y = 0; + static LAYOUT_VAL_SCALED(C1_W, 40) + static constexpr coord_t C2_X = C1_X + C1_W + PAD_SMALL; + static constexpr coord_t C2_Y = 0; + static LAYOUT_VAL_SCALED(C2_W, 40) +#endif +#else + static constexpr coord_t ROW_H = EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_OUTLINE * 2; + static constexpr coord_t SW_W = (LCD_W - PAD_SMALL * 2 - PAD_TINY * 4) / 5; + static constexpr coord_t NM_X = SW_W + PAD_TINY; + static LAYOUT_VAL_SCALED(NM_W, 80) + static constexpr coord_t TP_X = NM_X + SW_W + PAD_TINY; + static LAYOUT_VAL_SCALED(TP_W, 86) + static constexpr coord_t GR_X = TP_X + SW_W + PAD_TINY; + static LAYOUT_VAL_SCALED(GR_W, 94) + static constexpr coord_t ST_X = GR_X + SW_W + PAD_LARGE * 2 + PAD_SMALL; + static LAYOUT_VAL_SCALED(ST_W, 70) +#endif + + protected: + uint8_t switchIndex; + Choice* typeChoice = nullptr; + Choice* startChoice = nullptr; +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + ColorPicker* offColor = nullptr; + ColorPicker* onColor = nullptr; + RGBLedColor offValue; + RGBLedColor onValue; + StaticText* overrideLabel = nullptr; + ToggleSwitch* onOverride = nullptr; + ToggleSwitch* offOverride = nullptr; +#endif + int lastType = -1; + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + void previewColor(int newValue) + { + // Convert color index to RGB + newValue = color32ToRGB(newValue); + if (g_model.cfsState(switchIndex)) { + g_eeGeneral.switchOnColor(switchIndex).setColor(newValue); + } else { + g_eeGeneral.switchOffColor(switchIndex).setColor(newValue); + } + } +#endif + + void setState() + { + uint8_t typ = g_eeGeneral.switchType(switchIndex); + startChoice->show(typ == SWITCH_2POS && g_eeGeneral.switchGroup(switchIndex) == 0); +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + offColor->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + onColor->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + overrideLabel->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + onOverride->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + offOverride->show(typ != SWITCH_NONE && typ != SWITCH_GLOBAL); + if (typ != SWITCH_NONE && typ != SWITCH_GLOBAL) + setHeight(ROW_H); + else + setHeight(ROW_H - EdgeTxStyles::UI_ELEMENT_HEIGHT - PAD_OUTLINE); +#endif + } + + void checkEvents() override + { + setState(); + if (lastType != (int)g_eeGeneral.switchType(switchIndex)) { + lastType = g_eeGeneral.switchType(switchIndex); + typeChoice->setValue(lastType); + } + Window::checkEvents(); + } +}; + +RadioFunctionSwitches::RadioFunctionSwitches() : Page(ICON_RADIO_HARDWARE) +{ + header->setTitle(STR_HARDWARE); + header->setTitle2(STR_MENU_FSWITCH); + + body->padAll(PAD_TINY); + body->setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO); + + FlexGridLayout grid1(cfs_line_col_dsc1, cfs_line_row_dsc, PAD_TINY); + FlexGridLayout grid2(cfs_line_col_dsc2, cfs_line_row_dsc, PAD_TINY); + + auto line = body->newLine(grid2); + new StaticText(line, rect_t{}, STR_SWITCHES); + new StaticText(line, rect_t{}, STR_NAME, COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); + new StaticText(line, rect_t{}, STR_SWITCH_TYPE, + COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); + grid2.nextColumn(); + // new StaticText(line, rect_t{}, STR_GROUP, COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); + startupHeader = new StaticText(line, rect_t{}, STR_SWITCH_STARTUP, + COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + new StaticText(line, rect_t{}, STR_OFF, COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); + new StaticText(line, rect_t{}, STR_ON_ONE_SWITCHES[0], COLOR_THEME_PRIMARY1_INDEX, FONT(XS)); +#endif + + for (uint8_t i = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i)) + new RadioFunctionSwitch(body, i); + } + + setState(); + + line = body->newLine(grid1); + + new StaticText(line, rect_t{}, STR_MORE_INFO); + + line = body->newLine(grid1); + line->padBottom(PAD_LARGE); + line->padLeft((width() - 150) / 2); + + auto qr = lv_qrcode_create(line->getLvObj(), 150, + makeLvColor(COLOR_THEME_SECONDARY1), + makeLvColor(COLOR_THEME_SECONDARY3)); + lv_qrcode_update(qr, edgetx_fs_manual_url, strlen(edgetx_fs_manual_url)); +} + +void RadioFunctionSwitches::setState() +{ + // int cnt = 0; + // for (int i = 1; i <= 3; i += 1) { + // cnt += getSwitchCountInFSGroup(i); + // } + // startupHeader->show(cnt != NUM_FUNCTIONS_SWITCHES); +} + +void RadioFunctionSwitches::checkEvents() +{ + setState(); + Page::checkEvents(); +} + +#endif diff --git a/radio/src/targets/horus/bsp_io.h b/radio/src/gui/colorlcd/radio/radio_cfs.h similarity index 50% rename from radio/src/targets/horus/bsp_io.h rename to radio/src/gui/colorlcd/radio/radio_cfs.h index b74cedd30..23e6d09f0 100644 --- a/radio/src/targets/horus/bsp_io.h +++ b/radio/src/gui/colorlcd/radio/radio_cfs.h @@ -1,6 +1,12 @@ /* * Copyright (C) EdgeTX * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * * This program is free software; you can redistribute it and/or modify @@ -13,9 +19,24 @@ * GNU General Public License for more details. */ -#pragma once + #pragma once -#include "hal/switch_driver.h" -#include "stm32_switch_driver.h" - -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx) {return SWITCH_HW_MID;} + #if defined(FUNCTION_SWITCHES) + + #include "page.h" + + class RadioFunctionSwitches : public Page + { + public: + RadioFunctionSwitches(); + + protected: + BitmapBuffer* qrcode = nullptr; + StaticText* startupHeader = nullptr; + + void setState(); + void checkEvents() override; + }; + + #endif + \ No newline at end of file diff --git a/radio/src/gui/colorlcd/radio/radio_diagcustswitches.cpp b/radio/src/gui/colorlcd/radio/radio_diagcustswitches.cpp index 52a6f0fa3..a85c2e1b2 100644 --- a/radio/src/gui/colorlcd/radio/radio_diagcustswitches.cpp +++ b/radio/src/gui/colorlcd/radio/radio_diagcustswitches.cpp @@ -65,36 +65,40 @@ class RadioCustSwitchesDiagsWindow : public Window "Log"); new StaticText(this, {FS_3RD_COLUMN, PAD_SMALL, FS_LBL_WIDTH, LV_SIZE_CONTENT}, "Led"); - for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) { - coord_t y = (i + 2) * EdgeTxStyles::STD_FONT_HEIGHT; - std::string s(STR_CHAR_SWITCH); - s += switchGetName(i + switchGetMaxSwitches()); - new StaticText(this, {PAD_LARGE, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, s); - new DynamicText( - this, {FS_1ST_COLUMN + PAD_LARGE, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, - [=]() { - return getFSPhysicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP; - }); - new DynamicText( - this, {FS_2ND_COLUMN + PAD_LARGE, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, - [=]() { return getFSLogicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP; }); - + for (uint8_t i = 0, r = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i)) { + coord_t y = (r + 2) * EdgeTxStyles::STD_FONT_HEIGHT; + std::string s(STR_CHAR_SWITCH); + s += switchGetDefaultName(i); + new StaticText(this, {PAD_LARGE, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, s); + new DynamicText( + this, {FS_1ST_COLUMN + PAD_LARGE, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, + [=]() { + return getFSPhysicalState(i) ? STR_CHAR_DOWN : STR_CHAR_UP; + }); + new DynamicText( + this, {FS_2ND_COLUMN + 10, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, + [=]() { return g_model.cfsState(i) ? STR_CHAR_DOWN : STR_CHAR_UP; }); + #if defined(FUNCTION_SWITCHES_RGB_LEDS) - colorBox[i] = new ColorSwatch(this, {FS_3RD_COLUMN, y, FS_COLOR_WIDTH, - FS_COLOR_HEIGHT}, getLedColor(i)); + colorBox[r] = new ColorSwatch(this, {FS_3RD_COLUMN, y, FS_COLOR_WIDTH, + FS_COLOR_HEIGHT}, getLedColor(r)); #else - new DynamicText(this, - {FS_3RD_COLUMN, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, - [=]() { return STR_OFFON[getFSLedState(i)]; }); + new DynamicText(this, + {FS_3RD_COLUMN, y, FS_LBL_WIDTH, LV_SIZE_CONTENT}, + [=]() { return STR_OFFON[getFSLedState(i)]; }); #endif + r += 1; + } } } - + #if defined(FUNCTION_SWITCHES_RGB_LEDS) void checkEvents() override { Window::checkEvents(); for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i += 1) { - colorBox[i]->setColor(getLedColor(i)); + if (colorBox[i]) + colorBox[i]->setColor(getLedColor(i)); } } #endif diff --git a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp index db4007eac..bd71da62a 100644 --- a/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp +++ b/radio/src/gui/colorlcd/radio/radio_diagkeys.cpp @@ -125,14 +125,14 @@ class RadioKeyDiagsWindow : public Window void addSwitches(Window *form) { - switchValues = new lv_obj_t *[switchGetMaxSwitches()]; + switchValues = new lv_obj_t *[switchGetMaxAllSwitches()]; lv_obj_t *obj = form->getLvObj(); uint8_t i; uint8_t row = 0; // SWITCHES - for (i = 0; i < switchGetMaxSwitches(); i++) { - if (SWITCH_EXISTS(i)) { + for (i = 0; i < switchGetMaxAllSwitches(); i++) { + if (SWITCH_EXISTS(i) && !switchIsCustomSwitch(i)) { auto lbl = lv_label_create(obj); lv_label_set_text(lbl, ""); lv_obj_set_pos(lbl, 0, row * EdgeTxStyles::STD_FONT_HEIGHT); @@ -197,8 +197,8 @@ class RadioKeyDiagsWindow : public Window { uint8_t i; - for (i = 0; i < switchGetMaxSwitches(); i++) { - if (SWITCH_EXISTS(i)) { + for (i = 0; i < switchGetMaxAllSwitches(); i++) { + if (SWITCH_EXISTS(i) && !switchIsCustomSwitch(i)) { getvalue_t val = getValue(MIXSRC_FIRST_SWITCH + i); getvalue_t sw = ((val < 0) ? 3 * i + 1 : ((val == 0) ? 3 * i + 2 : 3 * i + 3)); diff --git a/radio/src/gui/colorlcd/radio/radio_hardware.cpp b/radio/src/gui/colorlcd/radio/radio_hardware.cpp index 4f6331ca1..f2e857ef1 100644 --- a/radio/src/gui/colorlcd/radio/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio/radio_hardware.cpp @@ -34,6 +34,7 @@ #include "radio_setup.h" #if defined(FUNCTION_SWITCHES) +#include "radio_cfs.h" #include "radio_diagcustswitches.h" #endif @@ -191,6 +192,9 @@ void RadioHardwarePage::build(Window* window) {STR_STICKS, []() { new HWInputDialog(STR_STICKS); }}, {STR_POTS, []() { new HWInputDialog(STR_POTS, HWPots::POTS_WINDOW_WIDTH); }}, {STR_SWITCHES, []() { new HWInputDialog(STR_SWITCHES, HWSwitches::SW_WINDOW_WIDTH); }}, +#if defined(FUNCTION_SWITCHES) + {STR_FUNCTION_SWITCHES, []() { new RadioFunctionSwitches(); }}, +#endif }); // Debugs diff --git a/radio/src/gui/colorlcd/radio/radio_hardware.h b/radio/src/gui/colorlcd/radio/radio_hardware.h index 4c1cd16d1..db1c9985f 100644 --- a/radio/src/gui/colorlcd/radio/radio_hardware.h +++ b/radio/src/gui/colorlcd/radio/radio_hardware.h @@ -32,7 +32,11 @@ class RadioHardwarePage : public PageTab void build(Window* window) override; +#if defined(FUNCTION_SWITCHES) + static LAYOUT_SIZE(BTN_COLS, 2, 2) +#else static LAYOUT_SIZE(BTN_COLS, 4, 3) +#endif static LAYOUT_SIZE(FS_BTN_COLS, 2, 2) protected: diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index 46b41e50d..a37737069 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -24,6 +24,7 @@ #include "hal/adc_driver.h" #include "hal/switch_driver.h" #include "hal/module_port.h" +#include "hal/rgbleds.h" #include "analogs.h" #include "switches.h" @@ -62,6 +63,11 @@ enum { ITEM_RADIO_HARDWARE_LABEL_SWITCHES, ITEM_RADIO_HARDWARE_SWITCH, ITEM_RADIO_HARDWARE_SWITCH_END = ITEM_RADIO_HARDWARE_SWITCH + MAX_SWITCHES - 1, +#if defined(FUNCTION_SWITCHES) + ITEM_RADIO_HARDWARE_LABEL_CFS, + ITEM_RADIO_HARDWARE_CFS, + ITEM_RADIO_HARDWARE_CFS_END = ITEM_RADIO_HARDWARE_CFS + MAX_SWITCHES - 1, +#endif CASE_BATTGRAPH(ITEM_RADIO_HARDWARE_BATT_RANGE) ITEM_RADIO_HARDWARE_BATTERY_CALIB, ITEM_RADIO_HARDWARE_RTC_BATTERY, @@ -114,6 +120,130 @@ static void onHardwareAntennaSwitchConfirm(const char * result) } #endif +#if defined(FUNCTION_SWITCHES) +#define RADIO_SETUP_2ND_COLUMN (LCD_W-11*FW) +extern char* _fct_sw_start[]; +static int swIndex; + +extern bool checkCFSTypeAvailable(int val); + +enum CFSFields { + CFS_FIELD_TYPE, + CFS_FIELD_NAME, + CFS_FIELD_START, +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + CFS_FIELD_COLOR_LABEL, + CFS_FIELD_ON_COLOR, + CFS_FIELD_ON_LUA_OVERRIDE, + CFS_FIELD_OFF_COLOR, + CFS_FIELD_OFF_LUA_OVERRIDE, +#endif + CFS_FIELD_COUNT +}; + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +extern void menuCFSColor(coord_t y, RGBLedColor& color, const char* title, LcdFlags attr, event_t event); +#endif + +static void menuRadioCFSOne(event_t event) +{ + std::string s(STR_CHAR_SWITCH); + s += switchGetDefaultName(swIndex); + + int config = g_eeGeneral.switchType(swIndex); + uint8_t group = g_eeGeneral.switchGroup(swIndex); + int startPos = g_eeGeneral.switchStart(swIndex); + + SUBMENU(s.c_str(), CFS_FIELD_COUNT, + { + 0, + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_TOGGLE && config != SWITCH_GLOBAL && group == 0) ? 0 : HIDDEN_ROW), +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? LABEL() : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 3 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 3 : HIDDEN_ROW), + (uint8_t)((config != SWITCH_NONE && config != SWITCH_GLOBAL) ? 0 : HIDDEN_ROW), +#endif + }); + + int8_t sub = menuVerticalPosition; + int8_t editMode = s_editMode; + + coord_t y = MENU_HEADER_HEIGHT + 1; + + for (int k = 0; k < NUM_BODY_LINES; k += 1) { + int i = k + menuVerticalOffset; + for (int j = 0; j <= i; j += 1) { + if (j < (int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) { + i += 1; + } + } + LcdFlags attr = (sub == i ? (editMode > 0 ? BLINK | INVERS : INVERS) : 0); + + switch(i) { + case CFS_FIELD_TYPE: + config = editChoice(RADIO_SETUP_2ND_COLUMN, y, STR_SWITCH_TYPE, STR_SWTYPES, config, SWITCH_NONE, SWITCH_3POS, attr, event, 0, checkCFSTypeAvailable); + if (attr && checkIncDec_Ret) { + g_eeGeneral.switchSetType(swIndex, (SwitchConfig)config); + if (config == SWITCH_NONE) { +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + if (g_model.getSwitchType(swIndex) == SWITCH_NONE) + fsLedRGB(switchGetCustomSwitchIdx(swIndex), 0); +#endif + } else if (config == SWITCH_TOGGLE) { + g_eeGeneral.switchSetStart(swIndex, FS_START_PREVIOUS); // Toggle switches do not have startup position + } + } + break; + + case CFS_FIELD_NAME: + editSingleName(RADIO_SETUP_2ND_COLUMN, y, STR_NAME, g_eeGeneral.switchName(swIndex), + LEN_SWITCH_NAME, event, (attr != 0), + editMode); + break; + + case CFS_FIELD_START: + lcdDrawText(0, y, STR_SWITCH_STARTUP); + lcdDrawText(RADIO_SETUP_2ND_COLUMN, y, _fct_sw_start[startPos], attr ? (s_editMode ? INVERS + BLINK : INVERS) : 0); + if (attr) { + startPos = checkIncDec(event, startPos, FS_START_OFF, FS_START_PREVIOUS, EE_MODEL); + g_eeGeneral.switchSetStart(swIndex, (fsStartPositionType)startPos); + } + break; + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + case CFS_FIELD_COLOR_LABEL: + lcdDrawText(0, y, STR_BLCOLOR); + lcdDrawText(LCD_W - 6 * FW, y, "R", RIGHT | SMLSIZE); + lcdDrawText(LCD_W - 3 * FW, y, "G", RIGHT | SMLSIZE); + lcdDrawText(LCD_W, y, "B", RIGHT | SMLSIZE); + break; + + case CFS_FIELD_ON_COLOR: + menuCFSColor(y, g_eeGeneral.switchOnColor(swIndex), STR_OFFON[1], attr, event); + break; + + case CFS_FIELD_ON_LUA_OVERRIDE: + g_eeGeneral.cfsSetOnColorLuaOverride(swIndex, editCheckBox(g_eeGeneral.cfsOnColorLuaOverride(swIndex), LCD_W - 2 * FW, y, STR_LUA_OVERRIDE, attr, event, INDENT_WIDTH)); + break; + + case CFS_FIELD_OFF_COLOR: + menuCFSColor(y, g_eeGeneral.switchOffColor(swIndex), STR_OFFON[0], attr, event); + break; + + case CFS_FIELD_OFF_LUA_OVERRIDE: + g_eeGeneral.cfsSetOffColorLuaOverride(swIndex, editCheckBox(g_eeGeneral.cfsOffColorLuaOverride(swIndex), LCD_W - 2 * FW, y, STR_LUA_OVERRIDE, attr, event, INDENT_WIDTH)); + break; +#endif + } + + y += FH; + } +} +#endif + static uint8_t _dispSerialPort(uint8_t port_nr) { auto port = serialGetPort(port_nr); @@ -147,11 +277,25 @@ static void _init_menu_tab_array(uint8_t* tab, size_t len) tab[i] = idx < max_pots ? (IS_POT_MULTIPOS(idx) ? 1 : 2) : HIDDEN_ROW; } - auto max_switches = switchGetMaxSwitches(); + int max_switches = switchGetMaxAllSwitches(); for (int i = ITEM_RADIO_HARDWARE_SWITCH; i <= ITEM_RADIO_HARDWARE_SWITCH_END; i++) { uint8_t idx = i - ITEM_RADIO_HARDWARE_SWITCH; - tab[i] = switchIsFlex(idx) ? 2 : idx < max_switches ? 1 : HIDDEN_ROW; + if (idx < max_switches && !switchIsCustomSwitch(idx)) { + tab[i] = switchIsFlex(idx) ? 2 : 1; + } else { + tab[i] = HIDDEN_ROW; + } } +#if defined (FUNCTION_SWITCHES) + for (int i = ITEM_RADIO_HARDWARE_CFS; i <= ITEM_RADIO_HARDWARE_CFS_END; i++) { + uint8_t idx = i - ITEM_RADIO_HARDWARE_CFS; + if (idx < max_switches && switchIsCustomSwitch(idx)) { + tab[i] = 0; + } else { + tab[i] = HIDDEN_ROW; + } + } +#endif #if defined(BATTGRAPH) tab[ITEM_RADIO_HARDWARE_BATT_RANGE] = 1; @@ -280,6 +424,12 @@ void menuRadioHardware(event_t event) lcdDrawTextAlignedLeft(y, STR_SWITCHES); break; +#if defined(FUNCTION_SWITCHES) + case ITEM_RADIO_HARDWARE_LABEL_CFS: + lcdDrawTextAlignedLeft(y, STR_FUNCTION_SWITCHES); + break; +#endif + #if defined(BATTGRAPH) case ITEM_RADIO_HARDWARE_BATT_RANGE: lcdDrawTextAlignedLeft(y, STR_BATTERY_RANGE); @@ -530,15 +680,14 @@ void menuRadioHardware(event_t event) setPotInversion(idx, 0); storageDirty(EE_GENERAL); } - } - else if (k <= ITEM_RADIO_HARDWARE_SWITCH_END) { + } else if (k <= ITEM_RADIO_HARDWARE_SWITCH_END) { // Switches int index = k - ITEM_RADIO_HARDWARE_SWITCH; - int config = SWITCH_CONFIG(index); + int config = g_eeGeneral.switchType(index); LcdFlags flags = menuHorizontalPosition < 0 ? attr : 0; lcdDrawText(INDENT_WIDTH, y, STR_CHAR_SWITCH, flags); - lcdDrawText(lcdNextPos, y, switchGetName(index), flags); + lcdDrawText(lcdNextPos, y, switchGetDefaultName(index), flags); if (switchIsFlex(index)) { // flexSwitch source @@ -550,10 +699,10 @@ void menuRadioHardware(event_t event) //Name flags = menuHorizontalPosition == 1 ? attr : 0; - if (switchHasCustomName(index) || + if (g_eeGeneral.switchHasCustomName(index) || (attr && s_editMode > 0 && menuHorizontalPosition == 1)) { editName(HW_SETTINGS_COLUMN2, y, - (char*)switchGetCustomName(index), LEN_SWITCH_NAME, + g_eeGeneral.getSwitchCustomName(index), LEN_SWITCH_NAME, event, flags, 0, old_editMode); } else { lcdDrawMMM(HW_SETTINGS_COLUMN2, y, flags); @@ -565,19 +714,14 @@ void menuRadioHardware(event_t event) SWITCH_NONE, switchGetMaxType(index), flags, event); if (attr && checkIncDec_Ret) { - swconfig_t mask = SWITCH_CONFIG_MASK(index); - g_eeGeneral.switchConfig = - (g_eeGeneral.switchConfig & ~mask) | - ((swconfig_t(config) & SW_CFG_MASK) << (SW_CFG_BITS * index)); - storageDirty(EE_GENERAL); + g_eeGeneral.switchSetType(index, (SwitchConfig)config); } - } - else { + } else { flags = menuHorizontalPosition == 0 ? attr : 0; - if (switchHasCustomName(index) || + if (g_eeGeneral.switchHasCustomName(index) || (attr && s_editMode > 0 && menuHorizontalPosition == 0)) { editName(HW_SETTINGS_COLUMN1, y, - (char*)switchGetCustomName(index), LEN_SWITCH_NAME, + g_eeGeneral.getSwitchCustomName(index), LEN_SWITCH_NAME, event, flags, 0, old_editMode); } else { lcdDrawMMM(HW_SETTINGS_COLUMN1, y, flags); @@ -589,13 +733,43 @@ void menuRadioHardware(event_t event) SWITCH_NONE, switchGetMaxType(index), flags, event); if (attr && checkIncDec_Ret) { - swconfig_t mask = SWITCH_CONFIG_MASK(index); - g_eeGeneral.switchConfig = - (g_eeGeneral.switchConfig & ~mask) | - ((swconfig_t(config) & SW_CFG_MASK) << (SW_CFG_BITS * index)); - storageDirty(EE_GENERAL); + g_eeGeneral.switchSetType(index, (SwitchConfig)config); } } +#if defined(FUNCTION_SWITCHES) + } else if (k <= ITEM_RADIO_HARDWARE_CFS_END) { + // Customisable Switches + int index = k - ITEM_RADIO_HARDWARE_CFS; + int config = g_eeGeneral.switchType(index); + + lcdDrawText(INDENT_WIDTH, y, STR_CHAR_SWITCH, attr); + lcdDrawText(lcdNextPos, y, switchGetDefaultName(index), attr); + + lcdDrawText(HW_SETTINGS_COLUMN2, y, STR_SWTYPES[config]); + + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { + swIndex = index; + pushMenu(menuRadioCFSOne); + } + + if (config != SWITCH_NONE) { + if (g_eeGeneral.switchName(index)[0]) { + char s[LEN_SWITCH_NAME + 1]; + strAppend(s, g_eeGeneral.switchName(index), LEN_SWITCH_NAME); + lcdDrawText(HW_SETTINGS_COLUMN1, y, s); + } else { + lcdDrawMMM(HW_SETTINGS_COLUMN1, y, 0); + } + + uint8_t group = g_eeGeneral.switchGroup(index); + // lcdDrawText(30 + 13 * FW, y, STR_FSGROUPS[group]); + + if (config != SWITCH_TOGGLE && group == 0) { + int startPos = g_eeGeneral.switchStart(index); + lcdDrawText(30 + 15 * FW, y, _fct_sw_start[startPos]); + } + } +#endif } else if (k <= ITEM_RADIO_HARDWARE_SERIAL_PORT_END) { auto port_nr = k - ITEM_RADIO_HARDWARE_SERIAL_PORT; auto port = serialGetPort(port_nr); diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 102913501..c0040cbc5 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -362,7 +362,7 @@ bool isSwitchAvailable(int swtch, SwitchContext context) if (swtch >= SWSRC_FIRST_SWITCH && swtch <= SWSRC_LAST_SWITCH) { div_t swinfo = switchInfo(swtch); - if (swinfo.quot >= switchGetMaxSwitches() + switchGetMaxFctSwitches()) { + if (swinfo.quot >= switchGetMaxAllSwitches()) { return false; } @@ -370,7 +370,7 @@ bool isSwitchAvailable(int swtch, SwitchContext context) return false; } - if (IS_SWITCH_FS(swinfo.quot) && context == GeneralCustomFunctionsContext) { + if (switchIsCustomSwitch(swinfo.quot) && context == GeneralCustomFunctionsContext) { return false; // FS are defined at model level, and cannot be in global functions } @@ -439,7 +439,7 @@ static bool isSwitchSwitchAvailable(int swtch, bool invert) { // Check normal switch if (swtch < MAX_SWITCHES * 3) { div_t swinfo = switchInfo(swtch + SWSRC_FIRST_SWITCH); - if (swinfo.quot >= switchGetMaxSwitches() + switchGetMaxFctSwitches()) { + if (swinfo.quot >= switchGetMaxAllSwitches()) { return false; } @@ -670,12 +670,9 @@ bool isAssignableFunctionAvailable(int function, bool modelFunctions) case FUNC_DISABLE_AUDIO_AMP: return false; #endif -#if !defined(LED_STRIP_GPIO) +#if !defined(LED_STRIP_LENGTH) case FUNC_RGB_LED: return false; -#elif defined(RGB_LED_OFFSET) - case FUNC_RGB_LED: - return (LED_STRIP_LENGTH > RGB_LED_OFFSET); #endif #if !defined(DEBUG) case FUNC_TEST: diff --git a/radio/src/hal/rgbleds.cpp b/radio/src/hal/rgbleds.cpp index fa9ba26f8..bfc095ecb 100644 --- a/radio/src/hal/rgbleds.cpp +++ b/radio/src/hal/rgbleds.cpp @@ -25,32 +25,59 @@ #include "dataconstants.h" #if defined(FUNCTION_SWITCHES_RGB_LEDS) +static bool hasLedOverride[NUM_FUNCTIONS_SWITCHES] = { false }; +static RGBLedColor ledOverride[NUM_FUNCTIONS_SWITCHES]; + +void setFSLedOverride(uint8_t index, bool state, uint8_t r, uint8_t g, uint8_t b) +{ + hasLedOverride[index] = state; + ledOverride[index].r = r; + ledOverride[index].g = g; + ledOverride[index].b = b; +} + void setFSLedOFF(uint8_t index) { - fsLedRGB(index, g_model.functionSwitchLedOFFColor[index].getColor()); + if (g_model.getSwitchType(index) != SWITCH_NONE) { + uint8_t cfsIdx = switchGetCustomSwitchIdx(index); + if (hasLedOverride[cfsIdx] && g_model.getSwitchOffColorLuaOverride(index)) + fsLedRGB(cfsIdx, ledOverride[cfsIdx].getColor()); + else + fsLedRGB(cfsIdx, g_model.getSwitchOffColor(index).getColor()); + } } void setFSLedON(uint8_t index) { - fsLedRGB(index, g_model.functionSwitchLedONColor[index].getColor()); + if (g_model.getSwitchType(index) != SWITCH_NONE) { + uint8_t cfsIdx = switchGetCustomSwitchIdx(index); + if (hasLedOverride[cfsIdx] && g_model.getSwitchOnColorLuaOverride(index)) + fsLedRGB(cfsIdx, ledOverride[cfsIdx].getColor()); + else + fsLedRGB(cfsIdx, g_model.getSwitchOnColor(index).getColor()); + } } bool getFSLedState(uint8_t index) { - return fsGetLedRGB(index) == g_model.functionSwitchLedONColor[index].getColor(); + uint8_t cfsIdx = switchGetCustomSwitchIdx(index); + return rgbGetLedColor(cfsIdx) == g_model.getSwitchOnColor(index).getColor(); } uint32_t getFSLedRGBColor(uint8_t index) { - return fsGetLedRGB(index); + return fsGetLedRGB(index); } #else void setFSLedOFF(uint8_t index) { + index = switchGetCustomSwitchIdx(index); fsLedOff(index); } void setFSLedON(uint8_t index) { + index = switchGetCustomSwitchIdx(index); fsLedOn(index); } bool getFSLedState(uint8_t index) { + index = switchGetCustomSwitchIdx(index); return fsLedState(index); } #endif diff --git a/radio/src/hal/rgbleds.h b/radio/src/hal/rgbleds.h index 92b070f97..575230c2a 100644 --- a/radio/src/hal/rgbleds.h +++ b/radio/src/hal/rgbleds.h @@ -25,6 +25,7 @@ // "Off", "White", "Red", "Green", "Yellow", "Orange", "Blue", "Pink" constexpr uint32_t colorTable[] = {0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0xFFFF00, 0xFF4000, 0x0000FF, 0xFF00FF}; +void setFSLedOverride(uint8_t index, bool state, uint8_t r, uint8_t g, uint8_t b); void setFSLedOFF(uint8_t index); void setFSLedON(uint8_t index); bool getFSLedState(uint8_t index); diff --git a/radio/src/hal/switch_driver.cpp b/radio/src/hal/switch_driver.cpp index eebe67474..384d99042 100644 --- a/radio/src/hal/switch_driver.cpp +++ b/radio/src/hal/switch_driver.cpp @@ -31,15 +31,18 @@ // Board API void boardInitSwitches(); -SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx); +SwitchHwPos boardSwitchGetPosition(uint8_t idx); -const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx); -SwitchHwType boardSwitchGetType(SwitchCategory cat, uint8_t idx); +const char* boardSwitchGetName(uint8_t idx); +SwitchHwType boardSwitchGetType(uint8_t idx); +#if defined(FUNCTION_SWITCHES) +bool boardIsCustomSwitch(uint8_t idx); +uint8_t boardGetCustomSwitchIdx(uint8_t idx); +#endif uint8_t boardGetMaxSwitches(); -uint8_t boardGetMaxFctSwitches(); -swconfig_t boardSwitchGetDefaultConfig(); +SwitchConfig boardSwitchGetDefaultConfig(uint8_t n); constexpr uint8_t _INVALID_ADC_CH = 0xFF; @@ -51,14 +54,39 @@ void switchInit() boardInitSwitches(); } -swconfig_t switchGetDefaultConfig() { return boardSwitchGetDefaultConfig(); } +SwitchConfig switchGetDefaultConfig(uint8_t n) { return boardSwitchGetDefaultConfig(n); } + +#if defined(FUNCTION_SWITCHES) +bool switchIsCustomSwitch(int sw) +{ + return boardIsCustomSwitch(sw); +} + +uint8_t switchGetCustomSwitchIdx(uint8_t sw) +{ + return boardGetCustomSwitchIdx(sw); +} + +uint8_t switchGetSwitchFromCustomIdx(uint8_t idx) +{ + for (uint8_t i = 0; i < switchGetMaxSwitches(); i += 1) + if (switchIsCustomSwitch(i) && switchGetCustomSwitchIdx(i) == idx) + return i; + return switchGetMaxSwitches(); +} +#else +bool switchIsCustomSwitch(int sw) { return false; } +#endif uint8_t switchGetMaxSwitches() { - return boardGetMaxSwitches() + MAX_FLEX_SWITCHES; + return boardGetMaxSwitches(); } -uint8_t switchGetMaxFctSwitches() { return boardGetMaxFctSwitches(); } +uint8_t switchGetMaxAllSwitches() +{ + return boardGetMaxSwitches() + MAX_FLEX_SWITCHES; +} uint32_t switchState(uint8_t pos_idx) { @@ -72,9 +100,9 @@ uint32_t switchState(uint8_t pos_idx) SwitchHwPos switchGetPosition(uint8_t sw_idx) { auto idx = (int)sw_idx; - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) { - return boardSwitchGetPosition(SWITCH_PHYSICAL, idx); + return boardSwitchGetPosition(idx); } idx -= max_switches; @@ -95,12 +123,6 @@ SwitchHwPos switchGetPosition(uint8_t sw_idx) return ret; } - - idx -= MAX_FLEX_SWITCHES; - } - - if (idx < boardGetMaxFctSwitches()) { - return boardSwitchGetPosition(SWITCH_FUNCTION, idx); } return SWITCH_HW_UP; @@ -113,12 +135,12 @@ static const char * const _flex_sw_canon_names[] = { static_assert(DIM(_flex_sw_canon_names) >= MAX_FLEX_SWITCHES, "Missing canonical name for flex switches"); -const char* switchGetName(uint8_t sw_idx) +const char* switchGetDefaultName(uint8_t sw_idx) { auto idx = (int)sw_idx; - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) { - return boardSwitchGetName(SWITCH_PHYSICAL, idx); + return boardSwitchGetName(idx); } idx -= max_switches; @@ -129,20 +151,25 @@ const char* switchGetName(uint8_t sw_idx) idx -= MAX_FLEX_SWITCHES; } - - if (idx < boardGetMaxFctSwitches()) { - return boardSwitchGetName(SWITCH_FUNCTION, idx); - } return nullptr; } +int8_t switchGetIndexFromName(const char* name) +{ + for (uint8_t i = 0; i < switchGetMaxSwitches(); i += 1) + if (strcmp(name, boardSwitchGetName(i)) == 0) + return i; + + return -1; +} + SwitchHwType switchGetHwType(uint8_t sw_idx) { auto idx = (int)sw_idx; - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) { - return boardSwitchGetType(SWITCH_PHYSICAL, idx); + return boardSwitchGetType(idx); } idx -= max_switches; @@ -155,8 +182,8 @@ SwitchHwType switchGetHwType(uint8_t sw_idx) bool switchIsFlex(uint8_t idx) { - auto max_switches = boardGetMaxSwitches(); - return idx >= max_switches && idx < max_switches + MAX_FLEX_SWITCHES; + auto max_switches = switchGetMaxSwitches(); + return idx >= max_switches && idx < switchGetMaxAllSwitches(); } void switchConfigFlex_raw(uint8_t idx, int8_t channel) @@ -179,7 +206,7 @@ uint8_t switchGetFlexChannel(uint8_t idx) void switchConfigFlex(uint8_t idx, int8_t channel) { - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) return; idx -= max_switches; switchConfigFlex_raw(idx, channel); @@ -193,7 +220,7 @@ int8_t switchGetFlexConfig_raw(uint8_t idx) int8_t switchGetFlexConfig(uint8_t idx) { - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) return _INVALID_ADC_CH; idx -= max_switches; return switchGetFlexConfig_raw(idx); @@ -208,7 +235,7 @@ bool switchIsFlexValid_raw(uint8_t sw_idx) bool switchIsFlexValid(uint8_t idx) { - auto max_switches = boardGetMaxSwitches(); + auto max_switches = switchGetMaxSwitches(); if (idx < max_switches) return false; idx -= max_switches; return switchIsFlexValid_raw(idx); @@ -229,7 +256,7 @@ bool switchIsFlexInputAvailable(uint8_t idx, uint8_t channel) if (MAX_FLEX_SWITCHES == 0) return false; if (POT_CONFIG(channel) != FLEX_SWITCH) return false; - auto phy_switches = boardGetMaxSwitches(); + auto phy_switches = switchGetMaxSwitches(); if (idx < phy_switches) return false; return is_flex_input_available(idx - phy_switches, channel); @@ -237,9 +264,8 @@ bool switchIsFlexInputAvailable(uint8_t idx, uint8_t channel) static void invalidate_flex_config(uint8_t flex_idx) { - auto sw_idx = flex_idx + boardGetMaxSwitches(); - swconfig_t mask = (swconfig_t)SWITCH_CONFIG_MASK(sw_idx); - g_eeGeneral.switchConfig &= ~mask; + auto sw_idx = flex_idx + switchGetMaxSwitches(); + g_eeGeneral.switchSetType(sw_idx, SWITCH_NONE); _flex_switches[flex_idx] = _INVALID_ADC_CH; } diff --git a/radio/src/hal/switch_driver.h b/radio/src/hal/switch_driver.h index 03a511617..d0daa4a13 100644 --- a/radio/src/hal/switch_driver.h +++ b/radio/src/hal/switch_driver.h @@ -23,6 +23,7 @@ #include #include "edgetx_types.h" +#include "edgetx_constants.h" enum SwitchHwType { SWITCH_HW_2POS = 0, @@ -36,21 +37,22 @@ enum SwitchHwPos { SWITCH_HW_DOWN, }; -enum SwitchCategory { - SWITCH_PHYSICAL=0, - SWITCH_FUNCTION, -}; - #define SWITCH_HW_INVERTED 1 // init hardware for switches void switchInit(); // returns the factory configuration for all switches -swconfig_t switchGetDefaultConfig(); +SwitchConfig switchGetDefaultConfig(uint8_t n); -// returns the maximum number of regular switches supported in hardware (customizable switches NOT included) +bool switchIsCustomSwitch(int sw); +uint8_t switchGetCustomSwitchIdx(uint8_t sw); +uint8_t switchGetSwitchFromCustomIdx(uint8_t sw); + +// returns the maximum number of physical + custom switches supported in hardware uint8_t switchGetMaxSwitches(); +// returns the maximum number of physical + custom + flex switches supported in hardware +uint8_t switchGetMaxAllSwitches(); // returns the number of configured switches uint8_t getSwitchCount(); @@ -58,9 +60,6 @@ uint8_t getSwitchCount(); // returns the highest row for a specified column uint8_t switchGetMaxRow(uint8_t col); -// returns the maximum number of customizable switches supported in hardware -uint8_t switchGetMaxFctSwitches(); - struct switch_display_pos_t { uint8_t col; uint8_t row; @@ -83,20 +82,12 @@ void switchConfigFlex_raw(uint8_t idx, int8_t channel); int8_t switchGetFlexConfig_raw(uint8_t idx); bool switchIsFlexValid_raw(uint8_t idx); -// The functions bellow support regular as well as customizable switches. -// -// Regular switches are indexed from `0` to `switchGetMaxSwitches() - 1` -// Customizable switches are indexed above the previous range. -// -// The total number of switches (and max index + 1) is: -// switchGetMaxSwitches() + switchGetMaxFctSwitches() -// - // returns state (0 / 1) of a specific switch position uint32_t switchState(uint8_t pos_idx); // returns a position for a switch index SwitchHwPos switchGetPosition(uint8_t idx); -const char* switchGetName(uint8_t idx); +const char* switchGetDefaultName(uint8_t idx); SwitchHwType switchGetHwType(uint8_t idx); +int8_t switchGetIndexFromName(const char* name); diff --git a/radio/src/logs.cpp b/radio/src/logs.cpp index 0d2bc1916..c1dcf235b 100644 --- a/radio/src/logs.cpp +++ b/radio/src/logs.cpp @@ -198,7 +198,7 @@ void writeHeader() f_puts(",", &g_oLogFile); } - for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + for (uint8_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_EXISTS(i)) { char s[LEN_SWITCH_NAME + 2]; char * temp; @@ -341,7 +341,7 @@ void logsWrite() f_printf(&g_oLogFile, "%d,", calibratedAnalogs[offset + i]); } - for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + for (uint8_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_EXISTS(i)) { f_printf(&g_oLogFile, "%d,", getSwitchState(i)); } diff --git a/radio/src/lua/api_colorlcd_lvgl.cpp b/radio/src/lua/api_colorlcd_lvgl.cpp index da1d80bf9..af38915ea 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -377,7 +377,7 @@ LROT_BEGIN(lvgllib, NULL, 0) LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetBox(); }); }) LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSetting(); }, true); }) LROT_FUNCENTRY(page, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetPage(); }, true); }) - LROT_FUNCENTRY(dialog, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetDialog(); }, true); }) + LROT_FUNCENTRY(dialog, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetDialog(); }, true); }) // Dialogs LROT_FUNCENTRY(confirm, [](lua_State* L) { return luaLvglPopup(L, []() { return new LvglWidgetConfirmDialog(); }); }) LROT_FUNCENTRY(message, [](lua_State* L) { return luaLvglPopup(L, []() { return new LvglWidgetMessageDialog(); }); }) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 003f46312..8479902ea 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -34,6 +34,7 @@ #include "input_mapping.h" #if defined(LED_STRIP_GPIO) #include "boards/generic_stm32/rgb_leds.h" +#include "hal/rgbleds.h" #endif @@ -2843,7 +2844,15 @@ static int luaGetTrainerStatus(lua_State * L) return 1; } -#if defined(LED_STRIP_GPIO) +// To simplify code below +#if !defined(BLING_LED_STRIP_LENGTH) + #define BLING_LED_STRIP_LENGTH 0 +#endif +#if !defined(CFS_LED_STRIP_LENGTH) + #define CFS_LED_STRIP_LENGTH 0 +#endif + +#if (BLING_LED_STRIP_LENGTH > 0) || (CFS_LED_STRIP_LENGTH > 0) /*luadoc @function setRGBLedColor(id, rvalue, bvalue, cvalue) @@ -2855,28 +2864,101 @@ static int luaGetTrainerStatus(lua_State * L) @param bvalue: interger, value of blue channel +@retval: true if LED index is valid, false otherwise + @status current Introduced in 2.10 */ static int luaSetRgbLedColor(lua_State * L) { uint8_t id = luaL_checkunsigned(L, 1); + + if (id >= (BLING_LED_STRIP_LENGTH + CFS_LED_STRIP_LENGTH)) { + lua_pushboolean(L, false); + return 1; + } + uint8_t r = luaL_checkunsigned(L, 2); uint8_t g = luaL_checkunsigned(L, 3); uint8_t b = luaL_checkunsigned(L, 4); - #if defined(LED_STRIP_RESERVED_AT_END) - if (id >= LED_STRIP_LENGTH - LED_STRIP_RESERVED_AT_END) { +#if CFS_LED_STRIP_LENGTH > 0 + if (id >= BLING_LED_STRIP_LENGTH) { + id -= BLING_LED_STRIP_LENGTH; + uint8_t swIdx = switchGetSwitchFromCustomIdx(id / CFS_LEDS_PER_SWITCH); + if (g_model.getSwitchType(swIdx) == SWITCH_NONE) { + rgbSetLedColor(id + CFS_LED_STRIP_START, r, g, b); + } else { lua_pushboolean(L, false); return 1; } - #endif - - rgbSetLedColor(id, r, g, b); + } else { + rgbSetLedColor(id + BLING_LED_STRIP_START, r, g, b); + } +#else + rgbSetLedColor(id + BLING_LED_STRIP_START, r, g, b); +#endif + lua_pushboolean(L, true); return 1; } +#endif +#if (CFS_LED_STRIP_LENGTH > 0) +/*luadoc +@function setCFSLedColor(id, rvalue, bvalue, cvalue) + +Overrides the LED color for a custom function switch + - if passed 4 arguments (id, r, g, b) then sets override color + - if passed 1 argument (id) then cancels override color + +@param id: string identifying a custom function switch name + +@param rvalue: interger, value of red channel + +@param gvalue: interger, value of green channel + +@param bvalue: interger, value of blue channel + +@retval: true if LED index is valid, false otherwise + +@status current Introduced in ??? +*/ + +static int luaSetCFSLedColor(lua_State * L) +{ + uint8_t r = 0, g = 0, b = 0; + int n = lua_gettop(L); + const char* nm = luaL_checkstring(L, 1); + + int8_t id = switchGetIndexFromName(nm); + + if (id < 0) { + lua_pushboolean(L, false); + return 1; + } + + uint8_t cfsIdx = switchGetCustomSwitchIdx(id); + + if (cfsIdx >= CFS_LED_STRIP_LENGTH / CFS_LEDS_PER_SWITCH) { + lua_pushboolean(L, false); + return 1; + } + + if (n > 1) { + r = luaL_checkunsigned(L, 2); + g = luaL_checkunsigned(L, 3); + b = luaL_checkunsigned(L, 4); + } + + setFSLedOverride(cfsIdx, n > 1, r, g, b); + + lua_pushboolean(L, true); + return 1; +} +#endif + +#if defined(LED_STRIP_LENGTH) /*luadoc @function applyRGBLedColors() @@ -2892,7 +2974,6 @@ static int luaApplyRGBLedColors(lua_State * L) return 1; } - #endif @@ -2997,9 +3078,12 @@ LROT_BEGIN(etxlib, NULL, 0) LROT_FUNCENTRY( getSourceIndex, luaGetSourceIndex ) LROT_FUNCENTRY( getSourceName, luaGetSourceName ) LROT_FUNCENTRY( sources, luaSources ) -#if defined(LED_STRIP_GPIO) - LROT_FUNCENTRY(setRGBLedColor, luaSetRgbLedColor ) - LROT_FUNCENTRY(applyRGBLedColors, luaApplyRGBLedColors ) +#if (BLING_LED_STRIP_LENGTH > 0) || (CFS_LED_STRIP_LENGTH > 0) + LROT_FUNCENTRY( setRGBLedColor, luaSetRgbLedColor ) + LROT_FUNCENTRY( applyRGBLedColors, luaApplyRGBLedColors ) +#endif +#if (CFS_LED_STRIP_LENGTH > 0) + LROT_FUNCENTRY( setCFSLedColor, luaSetCFSLedColor ) #endif LROT_FUNCENTRY( getStickMode, luaGetStickMode ) LROT_END(etxlib, NULL, 0) @@ -3144,18 +3228,8 @@ LROT_BEGIN(etxcst, NULL, 0) LROT_NUMENTRY( PLAY_NOW, PLAY_NOW ) LROT_NUMENTRY( PLAY_BACKGROUND, PLAY_BACKGROUND ) LROT_NUMENTRY( TIMEHOUR, TIMEHOUR ) -#if defined(LED_STRIP_GPIO) - #if defined(RADIO_V16) - LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH - 6 ) - #elif defined(RGB_LED_OFFSET) - // Exclude function switch LEDs - LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH - RGB_LED_OFFSET ) - #elif defined(LED_STRIP_RESERVED_AT_END) - // Exclude leds at the end of the strip - LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH - LED_STRIP_RESERVED_AT_END ) - #else - LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH ) - #endif +#if (BLING_LED_STRIP_LENGTH > 0) || (CFS_LED_STRIP_LENGTH > 0) + LROT_NUMENTRY( LED_STRIP_LENGTH, BLING_LED_STRIP_LENGTH + CFS_LED_STRIP_LENGTH ) #endif LROT_NUMENTRY( UNIT_RAW, UNIT_RAW ) LROT_NUMENTRY( UNIT_VOLTS, UNIT_VOLTS ) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index de51312ba..3e255f305 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -424,18 +424,14 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_SWITCH) { auto sw_idx = (uint8_t)(i - MIXSRC_FIRST_SWITCH); #if defined(FUNCTION_SWITCHES) - auto max_reg_switches = switchGetMaxSwitches(); - if (sw_idx >= max_reg_switches) { - auto fct_idx = sw_idx - max_reg_switches; - auto max_fct_switches = switchGetMaxFctSwitches(); - if (fct_idx < max_fct_switches) { - return _switch_2pos_lookup[getFSLogicalState(fct_idx)]; - } + auto max_switches = switchGetMaxSwitches(); + if (sw_idx < max_switches && switchIsCustomSwitch(sw_idx)) { + return _switch_2pos_lookup[g_model.cfsState(sw_idx)]; } #endif - auto sw_cfg = (SwitchConfig)SWITCH_CONFIG(sw_idx); + auto sw_cfg = g_model.getSwitchType(sw_idx); switch(sw_cfg) { - case SWITCH_NONE: + default: if (valid != nullptr) *valid = false; return 0; case SWITCH_TOGGLE: @@ -452,18 +448,20 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) if (stepcount == 0) return 0; - if (IS_FSWITCH_GROUP_ON(group_idx)) + if (g_model.cfsGroupAlwaysOn(group_idx)) stepcount--; int stepsize = (2 * RESX) / stepcount; int value = -RESX; - for (uint8_t i = 0; i < switchGetMaxFctSwitches(); i++) { - if(FSWITCH_GROUP(i) == group_idx) { - if (getFSLogicalState(i) == 1) - return value + (IS_FSWITCH_GROUP_ON(group_idx) ? 0 : stepsize); - else - value += stepsize; + for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + if (switchIsCustomSwitch(i)) { + if (g_model.getSwitchGroup(i) == group_idx) { + if (g_model.cfsState(i) == 1) + return value + (g_model.cfsGroupAlwaysOn(group_idx) ? 0 : stepsize); + else + value += stepsize; + } } } return -RESX; diff --git a/radio/src/model_audio.cpp b/radio/src/model_audio.cpp index 6fb3d3fda..6933a1802 100644 --- a/radio/src/model_audio.cpp +++ b/radio/src/model_audio.cpp @@ -58,7 +58,7 @@ bool getSwitchAudioFile(char* path, swsrc_t index) if (index <= SWSRC_LAST_SWITCH) { div_t swinfo = switchInfo(index); - auto sw_name = switchGetName(swinfo.quot); + auto sw_name = switchGetDefaultName(swinfo.quot); if (!sw_name) return false; str = strAppend(str, sw_name); str = strAppend(str, _sw_positions[swinfo.rem]); @@ -116,9 +116,9 @@ bool matchModeAudioFile(const char* filename, int& index, int& event) bool matchSwitchAudioFile(const char* filename, int& sw_pos) { // Switches Audio Files -[up|mid|down].wav - for (int i = 0; i < switchGetMaxSwitches(); i++) { + for (int i = 0; i < switchGetMaxAllSwitches(); i++) { auto* c = filename; - auto sw_name = switchGetName(i); + auto sw_name = switchGetDefaultName(i); auto sw_name_len = strlen(sw_name); if (strncasecmp(c, sw_name, sw_name_len) != 0) continue; c += sw_name_len; diff --git a/radio/src/model_init.cpp b/radio/src/model_init.cpp index b5ba631a7..de4d8c76c 100644 --- a/radio/src/model_init.cpp +++ b/radio/src/model_init.cpp @@ -100,6 +100,26 @@ void setVendorSpecificModelDefaults(uint8_t id) #endif } +#if defined(FUNCTION_SWITCHES) +void initCustomSwitches() +{ + for (int i = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i)) { + uint8_t idx = switchGetCustomSwitchIdx(i); + g_model.customSwitches[idx].type = SWITCH_GLOBAL; + g_model.customSwitches[idx].group = 0; + g_model.customSwitches[idx].start = FS_START_PREVIOUS; + g_model.customSwitches[idx].state = 0; + g_model.customSwitches[idx].name[0] = 0; +#if defined(FUNCTION_SWITCHES_RGB_LEDS) + g_model.customSwitches[idx].offColor.setColor(0); + g_model.customSwitches[idx].onColor.setColor(0xFFFFFF); +#endif + } + } +} +#endif + void applyDefaultTemplate() { setDefaultInputs(); @@ -110,42 +130,18 @@ void applyDefaultTemplate() setDefaultModelRegistrationID(); #if defined(FUNCTION_SWITCHES) - g_model.functionSwitchConfig = DEFAULT_FS_CONFIG; - g_model.functionSwitchGroup = DEFAULT_FS_GROUPS; - g_model.functionSwitchStartConfig = DEFAULT_FS_STARTUP_CONFIG; - g_model.functionSwitchLogicalState = 0; -#if defined(FUNCTION_SWITCHES_RGB_LEDS) - for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { - g_model.functionSwitchLedOFFColor[i].setColor(0); - g_model.functionSwitchLedONColor[i].setColor(0xFFFFFF); - } -#endif -#endif - -#if defined(FUNCTION_SWITCHES_RGB_LEDS) - for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { - g_model.functionSwitchLedOFFColor[i].setColor(0); - g_model.functionSwitchLedONColor[i].setColor(0xFFFFFF); - } + initCustomSwitches(); #endif #if defined(COLORLCD) - LayoutFactory::loadDefaultLayout(); +#endif // enable switch warnings - for (uint64_t i = 0; i < MAX_SWITCHES; i++) { - if (SWITCH_EXISTS(i)) { - g_model.switchWarning |= (1ull << (3ull * i)); - } - } -#else - // enable switch warnings - for (uint64_t i = 0; i < MAX_SWITCHES; i++) { + for (uint64_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) - g_model.switchWarning |= (1ull << (3ull * i)); + g_model.setSwitchWarning(i, 1); } -#endif #if defined(USE_HATS_AS_KEYS) g_model.hatsMode = HATSMODE_GLOBAL; diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index bb4ad96c8..835c08f1d 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -85,28 +85,10 @@ #define SW_CFG_MASK ((1 << SW_CFG_BITS) - 1) #define SWITCH_CONFIG_MASK(x) ((swconfig_t)SW_CFG_MASK << (SW_CFG_BITS * (x))) -#define SWITCH_CONFIG(x) (bfGet(g_eeGeneral.switchConfig, SW_CFG_BITS * (x), SW_CFG_BITS)) -#if defined(FUNCTION_SWITCHES) - #define FSW_CFG_BITS 2 - #define FSWITCH_CONFIG(x) (bfGet(g_model.functionSwitchConfig, FSW_CFG_BITS * (x), FSW_CFG_BITS)) - #define FSWITCH_SET_CONFIG(x,v) g_model.functionSwitchConfig = bfSet(g_model.functionSwitchConfig, v, FSW_CFG_BITS * (x), FSW_CFG_BITS) - #define FSWITCH_GROUP(x) (bfGet(g_model.functionSwitchGroup, FSW_CFG_BITS * (x), FSW_CFG_BITS)) - #define FSWITCH_SET_GROUP(x,v) g_model.functionSwitchGroup = bfSet(g_model.functionSwitchGroup, v, FSW_CFG_BITS * (x), FSW_CFG_BITS) - #define FSWITCH_STARTUP(x) (bfGet(g_model.functionSwitchStartConfig, FSW_CFG_BITS * (x), FSW_CFG_BITS)) - #define FSWITCH_SET_STARTUP(x,v) g_model.functionSwitchStartConfig = bfSet(g_model.functionSwitchStartConfig, v, FSW_CFG_BITS * (x), FSW_CFG_BITS) - #define IS_FSWITCH_GROUP_ON(x) (bfGet(g_model.functionSwitchGroup, FSW_CFG_BITS * NUM_FUNCTIONS_SWITCHES + x, 1)) - #define SET_FSWITCH_GROUP_ON(x,v) g_model.functionSwitchGroup = bfSet(g_model.functionSwitchGroup, v, FSW_CFG_BITS * NUM_FUNCTIONS_SWITCHES + x, 1) - #define IS_SWITCH_FS(x) (x >= switchGetMaxSwitches() && x < (switchGetMaxSwitches() + switchGetMaxFctSwitches())) - #define SWITCH_EXISTS(x) (IS_SWITCH_FS(x) ? true : (SWITCH_CONFIG(x) != SWITCH_NONE)) - #define IS_CONFIG_3POS(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - switchGetMaxSwitches()) == SWITCH_3POS) : (SWITCH_CONFIG(x) == SWITCH_3POS)) - #define IS_CONFIG_TOGGLE(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - switchGetMaxSwitches()) == SWITCH_TOGGLE) : (SWITCH_CONFIG(x) == SWITCH_TOGGLE)) -#else - #define SWITCH_EXISTS(x) (SWITCH_CONFIG(x) != SWITCH_NONE) - #define IS_CONFIG_3POS(x) (SWITCH_CONFIG(x) == SWITCH_3POS) - #define IS_CONFIG_TOGGLE(x) (SWITCH_CONFIG(x) == SWITCH_TOGGLE) - #define IS_SWITCH_FS(x) (false) -#endif -#define SWITCH_WARNING_ALLOWED(x) (SWITCH_EXISTS(x) && !(IS_CONFIG_TOGGLE(x) || IS_SWITCH_FS(x))) +#define SWITCH_EXISTS(x) (g_model.getSwitchType(x) != SWITCH_NONE) +#define IS_CONFIG_3POS(x) (g_model.getSwitchType(x) == SWITCH_3POS) +#define IS_CONFIG_TOGGLE(x) (g_model.getSwitchType(x) == SWITCH_TOGGLE) +#define SWITCH_WARNING_ALLOWED(x) (SWITCH_EXISTS(x) && !IS_CONFIG_TOGGLE(x)) #define ALTERNATE_VIEW 0x10 @@ -267,4 +249,4 @@ constexpr uint8_t EE_GENERAL = 0x01; constexpr uint8_t EE_MODEL = 0x02; constexpr uint8_t EE_LABELS = 0x04; -#endif // _MYEEPROM_H_ \ No newline at end of file +#endif // _MYEEPROM_H_ diff --git a/radio/src/storage/sdcard_yaml.cpp b/radio/src/storage/sdcard_yaml.cpp index 9754ffe13..246ca4f7d 100644 --- a/radio/src/storage/sdcard_yaml.cpp +++ b/radio/src/storage/sdcard_yaml.cpp @@ -181,6 +181,7 @@ const char * loadRadioSettings() #endif adcCalibDefaults(); + generalDefaultSwitches(); const char* error = loadRadioSettingsYaml(true); if (!error) { @@ -191,8 +192,6 @@ const char * loadRadioSettings() return error; } - - struct yaml_checksummer_ctx { FRESULT result; uint16_t checksum; @@ -341,6 +340,10 @@ const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t siz memset(buffer,0,size); if (init_model) { +#if defined(FUNCTION_SWITCHES) + extern void initCustomSwitches(); + initCustomSwitches(); +#endif auto md = reinterpret_cast(buffer); #if defined(FLIGHT_MODES) && defined(GVARS) // reset GVars to default values diff --git a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp index 8e2cd75fe..1db00afad 100644 --- a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -221,7 +232,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -255,13 +266,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -275,12 +293,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -313,7 +331,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -340,7 +358,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -381,7 +399,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -402,7 +420,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -462,7 +480,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -475,7 +493,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -633,7 +651,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -683,7 +701,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -727,7 +745,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -776,7 +794,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -816,16 +834,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -840,19 +857,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_f16.cpp b/radio/src/storage/yaml/yaml_datastructs_f16.cpp index a31962d61..69ad0e413 100644 --- a/radio/src/storage/yaml/yaml_datastructs_f16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_f16.cpp @@ -90,6 +90,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -240,7 +251,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -274,13 +285,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -292,12 +310,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -330,7 +348,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -357,7 +375,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -409,7 +427,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -430,7 +448,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -490,7 +508,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -503,7 +521,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -661,7 +679,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -711,7 +729,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -755,7 +773,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -779,7 +797,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -811,7 +829,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -851,16 +869,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -876,20 +893,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index 0bbcac312..3e8d1a35d 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -359,7 +359,7 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, } else if (val >= MIXSRC_FIRST_SWITCH && val <= MIXSRC_LAST_SWITCH) { - str = switchGetCanonicalName(val - MIXSRC_FIRST_SWITCH); + str = switchGetDefaultName(val - MIXSRC_FIRST_SWITCH); } #if defined(FUNCTION_SWITCHES) else if (val >= MIXSRC_FIRST_CUSTOMSWITCH_GROUP @@ -847,60 +847,30 @@ static const struct YamlNode struct_sliderConfig[] = { YAML_END }; -static uint32_t sw_read(void* user, const char* val, uint8_t val_len) +static uint32_t sw_idx_read(void* user, const char* val, uint8_t val_len) { (void)user; return switchLookupIdx(val, val_len); } -bool sw_write(void* user, yaml_writer_func wf, void* opaque) +static bool currentSwitchIsCFS = false; + +bool sw_idx_write(void* user, yaml_writer_func wf, void* opaque) { auto tw = reinterpret_cast(user); uint16_t idx = tw->getElmts(); - const char* str = switchGetCanonicalName(idx); + currentSwitchIsCFS = switchIsCustomSwitch(idx); + + const char* str = switchGetDefaultName(idx); return str ? wf(opaque, str, strlen(str)) : true; } -static void sw_name_read(void* user, uint8_t* data, uint32_t bitoffs, - const char* val, uint8_t val_len) +bool switch_is_cfs(void* user, uint8_t* data, uint32_t bitoffs) { - auto tw = reinterpret_cast(user); - uint16_t idx = tw->getElmts(1); - - - switchSetCustomName(idx, val, val_len); + return currentSwitchIsCFS; } -static bool sw_name_write(void* user, uint8_t* data, uint32_t bitoffs, - yaml_writer_func wf, void* opaque) -{ - auto tw = reinterpret_cast(user); - uint16_t idx = tw->getElmts(1); - - - const char* str = switchGetCustomName(idx); - if (!wf(opaque, "\"", 1)) return false; - if (!wf(opaque, str, strnlen(str, LEN_SWITCH_NAME))) - return false; - return wf(opaque, "\"", 1); -} - -static const struct YamlIdStr enum_SwitchConfig[] = { - { SWITCH_NONE, "none" }, - { SWITCH_TOGGLE, "toggle" }, - { SWITCH_2POS, "2pos" }, - { SWITCH_3POS, "3pos" }, - { 0, NULL } -}; - -static const struct YamlNode struct_switchConfig[] = { - YAML_IDX_CUST( "sw", sw_read, sw_write), - YAML_ENUM( "type", 2, enum_SwitchConfig), - YAML_CUSTOM( "name", sw_name_read, sw_name_write), - YAML_END -}; - static bool flex_sw_valid(void* user, uint8_t* data, uint32_t bitoffs) { auto tw = reinterpret_cast(user); @@ -908,13 +878,11 @@ static bool flex_sw_valid(void* user, uint8_t* data, uint32_t bitoffs) return switchIsFlexValid_raw(idx); } -uint8_t boardGetMaxSwitches(); - static uint32_t flex_sw_read(void* user, const char* val, uint8_t val_len) { (void)user; auto idx = switchLookupIdx(val, val_len); - return idx - boardGetMaxSwitches(); + return idx - switchGetMaxSwitches(); } bool flex_sw_write(void* user, yaml_writer_func wf, void* opaque) @@ -922,8 +890,8 @@ bool flex_sw_write(void* user, yaml_writer_func wf, void* opaque) auto tw = reinterpret_cast(user); uint16_t idx = tw->getElmts(); - auto sw_offset = boardGetMaxSwitches(); - const char* str = switchGetCanonicalName(idx + sw_offset); + auto sw_offset = switchGetMaxSwitches(); + const char* str = switchGetDefaultName(idx + sw_offset); return str ? wf(opaque, str, strlen(str)) : true; } @@ -1002,7 +970,7 @@ static const struct YamlIdStr enum_PotConfig[] = { static const struct YamlNode struct_potConfig[] = { YAML_IDX_CUST("pot", pot_read, pot_write ), - YAML_ENUM("type", POT_CFG_TYPE_BITS, enum_PotConfig), + YAML_ENUM("type", POT_CFG_TYPE_BITS, enum_PotConfig, NULL), YAML_UNSIGNED("inv", POT_CFG_INV_BITS), YAML_CUSTOM("name", pot_name_read, pot_name_write), YAML_END @@ -1121,7 +1089,7 @@ static bool w_swtchSrc_unquoted(const YamlNode* node, uint32_t val, if (sval <= SWSRC_LAST_SWITCH) { auto sw_info = switchInfo(sval); - str = switchGetCanonicalName(sw_info.quot); + str = switchGetDefaultName(sw_info.quot); if (!str) return true; wf(opaque, str, strlen(str)); str = yaml_unsigned2str(sw_info.rem); @@ -1270,8 +1238,8 @@ static const struct YamlIdStr enum_SwitchWarnPos[] = { }; static const struct YamlNode struct_swtchWarn[] { - YAML_IDX_CUST( "sw", sw_read, sw_write ), - YAML_ENUM( "pos", 2, enum_SwitchWarnPos ), + YAML_IDX_CUST( "sw", sw_idx_read, sw_idx_write ), + YAML_ENUM( "pos", 2, enum_SwitchWarnPos, NULL ), YAML_END, }; @@ -2340,7 +2308,7 @@ static bool port_write(void* user, yaml_writer_func wf, void* opaque) static const struct YamlNode struct_serialConfig[] = { YAML_IDX_CUST( "port", port_read, port_write), - YAML_ENUM( "mode", 4, enum_UartModes), + YAML_ENUM( "mode", 4, enum_UartModes, NULL), YAML_PADDING( 3 ), YAML_UNSIGNED( "power", 1 ), YAML_END @@ -2369,3 +2337,165 @@ static void r_serialMode(void* user, uint8_t* data, uint32_t bitoffs, *serialPort = (*serialPort & ~(0xF << port_nr * SERIAL_CONF_BITS_PER_PORT)) | (m << port_nr * SERIAL_CONF_BITS_PER_PORT); } + +#if defined(FUNCTION_SWITCHES) + +static uint16_t getIdx(void *user) +{ + auto tw = reinterpret_cast(user); + return tw->getElmts(1); +} + +static void r_cfs_name(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + strAppend(g_model.customSwitches[idx].name, val, LEN_SWITCH_NAME); +} + +static const struct YamlNode struct_cfsNameConfig[] = { + YAML_IDX, + YAML_CUSTOM( "val", r_cfs_name, nullptr), + YAML_END +}; + +#if defined(FUNCTION_SWITCHES_RGB_LEDS) +static void r_cfs_on_color_r(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].onColor.r = yaml_str2uint(val, val_len); +} + +static void r_cfs_on_color_g(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].onColor.g = yaml_str2uint(val, val_len); +} + +static void r_cfs_on_color_b(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].onColor.b = yaml_str2uint(val, val_len); +} + +static const struct YamlNode struct_cfsOnColorConfig[] = { + YAML_IDX, + YAML_CUSTOM( "r", r_cfs_on_color_r, nullptr), + YAML_CUSTOM( "g", r_cfs_on_color_g, nullptr), + YAML_CUSTOM( "b", r_cfs_on_color_b, nullptr), + YAML_END +}; + +static void r_cfs_off_color_r(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].offColor.r = yaml_str2uint(val, val_len); +} + +static void r_cfs_off_color_g(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].offColor.g = yaml_str2uint(val, val_len); +} + +static void r_cfs_off_color_b(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint16_t idx = getIdx(user); + g_model.customSwitches[idx].offColor.b = yaml_str2uint(val, val_len); +} + +static const struct YamlNode struct_cfsOffColorConfig[] = { + YAML_IDX, + YAML_CUSTOM( "r", r_cfs_off_color_r, nullptr), + YAML_CUSTOM( "g", r_cfs_off_color_g, nullptr), + YAML_CUSTOM( "b", r_cfs_off_color_b, nullptr), + YAML_END +}; +#endif + +static uint32_t cfs_idx_read(void* user, const char* val, uint8_t val_len) +{ + return switchGetCustomSwitchIdx(switchLookupIdx(val, val_len)); +} + +static bool cfs_idx_write(void* user, yaml_writer_func wf, void* opaque) +{ + auto tw = reinterpret_cast(user); + uint16_t idx = tw->getElmts(); + + const char* str = switchGetDefaultName(switchGetSwitchFromCustomIdx(idx)); + return str ? wf(opaque, str, strlen(str)) : true; +} + +static const struct YamlNode struct_cfsGroupOn[] { + YAML_IDX, + YAML_UNSIGNED( "v", 1 ), + YAML_END, +}; + +static void r_functionSwitchConfig(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint32_t v = yaml_str2uint(val, val_len); + for (int i = 0; i < 6; i += 1) { + g_model.customSwitches[i].type = (SwitchConfig)bfGet(v, 2 * i, 2); + } +} + +static void r_functionSwitchStartConfig(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint32_t v = yaml_str2uint(val, val_len); + for (int i = 0; i < 6; i += 1) { + uint8_t b = bfGet(v, 2 * i, 2); + if (b < 2) b ^= 1; // Swap On & Off + g_model.customSwitches[i].start = (fsStartPositionType)b; + } +} + +static void r_functionSwitchGroup(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint32_t v = yaml_str2uint(val, val_len); + for (int i = 0; i < 6; i += 1) { + g_model.customSwitches[i].group = bfGet(v, 2 * i, 2); + } + for (int i = 0; i <= 3; i += 1) { + g_model.cfsSetGroupAlwaysOn(i, bfGet(v, 2 * 6 + i, 1)); + } +} + +static void r_functionSwitchLogicalState(void* user, uint8_t* data, uint32_t bitoffs, + const char* val, uint8_t val_len) +{ + uint32_t v = yaml_str2uint(val, val_len); + for (int i = 0; i < 6; i += 1) { + g_model.customSwitches[i].state = bfGet(v, 1 * i, 1); + } +} + +bool cfsGroupIsActive(void* user, uint8_t* data, uint32_t bitoffs) +{ + auto tw = reinterpret_cast(user); + uint16_t idx = tw->getElmts(); + return idx > 0 && idx <= NUM_FUNCTIONS_GROUPS; +} + +bool isAlwaysActive(void* user, uint8_t* data, uint32_t bitoffs) +{ + return true; +} +#endif + +bool switchIsActive(void* user, uint8_t* data, uint32_t bitoffs) +{ + auto tw = reinterpret_cast(user); + uint16_t idx = tw->getElmts(); + return idx < switchGetMaxSwitches(); +} diff --git a/radio/src/storage/yaml/yaml_datastructs_gx12.cpp b/radio/src/storage/yaml/yaml_datastructs_gx12.cpp index 7666c6241..75b79c689 100644 --- a/radio/src/storage/yaml/yaml_datastructs_gx12.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_gx12.cpp @@ -89,6 +89,29 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; +const struct YamlIdStr enum_booleanEnum[] = { + { BOOL_OFF, "OFF" }, + { BOOL_ON, "ON" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -222,7 +245,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -256,13 +279,31 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_RGBLedColor[] = { + YAML_UNSIGNED( "r", 8 ), + YAML_UNSIGNED( "g", 8 ), + YAML_UNSIGNED( "b", 8 ), + YAML_END +}; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_PADDING( 1 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, switch_is_cfs), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -276,12 +317,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -314,7 +355,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -341,7 +382,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 80, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -382,7 +423,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -403,7 +444,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -463,7 +504,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -476,7 +517,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -634,7 +675,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -684,7 +725,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -728,7 +769,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -775,16 +816,23 @@ static const struct YamlNode struct_TelemetryScreenData[] = { YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data), YAML_END }; -static const struct YamlNode struct_RGBLedColor[] = { - YAML_IDX, - YAML_UNSIGNED( "r", 8 ), - YAML_UNSIGNED( "g", 8 ), - YAML_UNSIGNED( "b", 8 ), +static const struct YamlNode struct_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 3 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_PADDING( 5 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, isAlwaysActive), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, isAlwaysActive), YAML_END }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -824,16 +872,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -847,27 +894,30 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), - YAML_UNSIGNED( "functionSwitchConfig", 16 ), - YAML_UNSIGNED( "functionSwitchGroup", 16 ), - YAML_UNSIGNED( "functionSwitchStartConfig", 16 ), - YAML_UNSIGNED( "functionSwitchLogicalState", 8 ), - YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL), - YAML_ARRAY("functionSwitchLedONColor", 24, 6, struct_RGBLedColor, NULL), - YAML_ARRAY("functionSwitchLedOFFColor", 24, 6, struct_RGBLedColor, NULL), + YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("functionSwitchLedONColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOnColorConfig, nullptr), + YAML_ARRAY("functionSwitchLedOFFColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOffColorConfig, nullptr), + YAML_ARRAY("customSwitches", 88, 8, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp b/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp index 641d26ebc..5182a29f7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nb4p.cpp @@ -89,6 +89,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -231,7 +242,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -265,13 +276,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -285,12 +303,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -323,7 +341,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -350,7 +368,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -400,7 +418,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -421,7 +439,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -481,7 +499,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -494,7 +512,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -652,7 +670,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -702,7 +720,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -746,7 +764,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -770,7 +788,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -802,7 +820,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -842,16 +860,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -867,20 +884,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14_family.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14_family.cpp index b8758646b..8c3b0e2e4 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14_family.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14_family.cpp @@ -96,6 +96,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -238,7 +249,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -272,18 +283,25 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), YAML_UNSIGNED( "ppmunit", 2 ), - YAML_ENUM("hatsMode", 2, enum_HatsMode), + YAML_ENUM("hatsMode", 2, enum_HatsMode, NULL), YAML_CUSTOM("semver",nullptr,w_semver), YAML_CUSTOM("board",nullptr,w_board), YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL), @@ -292,12 +310,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -330,7 +348,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -357,7 +375,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -407,7 +425,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -428,7 +446,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -488,7 +506,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -501,7 +519,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -659,7 +677,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -709,7 +727,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -753,7 +771,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -777,7 +795,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -809,7 +827,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -835,7 +853,7 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), YAML_UNSIGNED( "checklistInteractive", 1 ), - YAML_ENUM("hatsMode", 2, enum_HatsMode), + YAML_ENUM("hatsMode", 2, enum_HatsMode, NULL), YAML_PADDING( 2 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), @@ -850,16 +868,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -875,20 +892,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp index e3ee88974..fe612fea6 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -96,6 +96,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -238,7 +249,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -272,18 +283,25 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), YAML_UNSIGNED( "ppmunit", 2 ), - YAML_ENUM("hatsMode", 2, enum_HatsMode), + YAML_ENUM("hatsMode", 2, enum_HatsMode, NULL), YAML_CUSTOM("semver",nullptr,w_semver), YAML_CUSTOM("board",nullptr,w_board), YAML_ARRAY("calib", 48, 20, struct_CalibData, NULL), @@ -292,12 +310,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -330,7 +348,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -357,7 +375,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -407,7 +425,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -428,7 +446,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -488,7 +506,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -501,7 +519,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -659,7 +677,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -709,7 +727,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -753,7 +771,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -777,7 +795,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -809,7 +827,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -835,7 +853,7 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), YAML_UNSIGNED( "checklistInteractive", 1 ), - YAML_ENUM("hatsMode", 2, enum_HatsMode), + YAML_ENUM("hatsMode", 2, enum_HatsMode, NULL), YAML_PADDING( 2 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), @@ -850,16 +868,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -875,20 +892,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp index 7b16d79a5..91e12a002 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18u.cpp @@ -89,6 +89,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -231,7 +242,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -265,13 +276,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -285,12 +303,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -323,7 +341,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -350,7 +368,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -400,7 +418,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -421,7 +439,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -481,7 +499,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -494,7 +512,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -652,7 +670,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -702,7 +720,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -746,7 +764,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -770,7 +788,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -802,7 +820,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -842,16 +860,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -867,20 +884,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_st16.cpp b/radio/src/storage/yaml/yaml_datastructs_st16.cpp index 8366a1ef1..01d8a3f61 100644 --- a/radio/src/storage/yaml/yaml_datastructs_st16.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_st16.cpp @@ -90,6 +90,29 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; +const struct YamlIdStr enum_booleanEnum[] = { + { BOOL_OFF, "OFF" }, + { BOOL_ON, "ON" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -240,7 +263,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -274,13 +297,31 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_RGBLedColor[] = { + YAML_UNSIGNED( "r", 8 ), + YAML_UNSIGNED( "g", 8 ), + YAML_UNSIGNED( "b", 8 ), + YAML_END +}; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, switch_is_cfs), + YAML_PADDING( 1 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, switch_is_cfs), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, switch_is_cfs), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -292,12 +333,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -330,7 +371,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -357,7 +398,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 80, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -409,7 +450,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -430,7 +471,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -490,7 +531,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -503,7 +544,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -661,7 +702,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -711,7 +752,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -755,7 +796,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -779,7 +820,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -809,21 +850,23 @@ static const struct YamlNode struct_TopBarPersistentData[] = { YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL), YAML_END }; -static const struct YamlNode struct_string_24[] = { - YAML_IDX, - YAML_STRING("val", 3), - YAML_END -}; -static const struct YamlNode struct_RGBLedColor[] = { - YAML_IDX, - YAML_UNSIGNED( "r", 8 ), - YAML_UNSIGNED( "g", 8 ), - YAML_UNSIGNED( "b", 8 ), +static const struct YamlNode struct_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 2 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), + YAML_ENUM("onColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_ENUM("offColorLuaOverride", 1, enum_booleanEnum, NULL), + YAML_PADDING( 6 ), + YAML_STRUCT("onColor", 24, struct_RGBLedColor, isAlwaysActive), + YAML_STRUCT("offColor", 24, struct_RGBLedColor, isAlwaysActive), YAML_END }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -863,16 +906,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 384, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -887,28 +929,31 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL), YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), - YAML_UNSIGNED( "functionSwitchConfig", 16 ), - YAML_UNSIGNED( "functionSwitchGroup", 16 ), - YAML_UNSIGNED( "functionSwitchStartConfig", 16 ), - YAML_UNSIGNED( "functionSwitchLogicalState", 8 ), - YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL), - YAML_ARRAY("functionSwitchLedONColor", 24, 6, struct_RGBLedColor, NULL), - YAML_ARRAY("functionSwitchLedOFFColor", 24, 6, struct_RGBLedColor, NULL), + YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("functionSwitchLedONColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOnColorConfig, nullptr), + YAML_ARRAY("functionSwitchLedOFFColor", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsOffColorConfig, nullptr), + YAML_ARRAY("customSwitches", 88, 6, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t15.cpp b/radio/src/storage/yaml/yaml_datastructs_t15.cpp index b68d60bec..c78b50a5a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t15.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t15.cpp @@ -90,6 +90,24 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -240,7 +258,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -274,13 +292,21 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_PADDING( 3 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -292,12 +318,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -330,7 +356,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -357,7 +383,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -409,7 +435,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -430,7 +456,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -490,7 +516,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -503,7 +529,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -661,7 +687,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -711,7 +737,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -755,7 +781,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -779,7 +805,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -809,14 +835,18 @@ static const struct YamlNode struct_TopBarPersistentData[] = { YAML_ARRAY("options", 128, 1, struct_ZoneOptionValueTyped, NULL), YAML_END }; -static const struct YamlNode struct_string_24[] = { - YAML_IDX, - YAML_STRING("val", 3), +static const struct YamlNode struct_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 2 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), YAML_END }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -856,16 +886,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -880,26 +909,29 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL), YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), - YAML_UNSIGNED( "functionSwitchConfig", 16 ), - YAML_UNSIGNED( "functionSwitchGroup", 16 ), - YAML_UNSIGNED( "functionSwitchStartConfig", 16 ), - YAML_UNSIGNED( "functionSwitchLogicalState", 8 ), - YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL), + YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("customSwitches", 32, 6, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t20.cpp b/radio/src/storage/yaml/yaml_datastructs_t20.cpp index bde9c2e07..62cc1b270 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t20.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t20.cpp @@ -89,6 +89,24 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -222,7 +240,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -256,13 +274,21 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_PADDING( 3 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -276,12 +302,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -314,7 +340,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -341,7 +367,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -382,7 +408,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -403,7 +429,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -463,7 +489,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -476,7 +502,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -634,7 +660,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -684,7 +710,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -728,7 +754,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -775,9 +801,18 @@ static const struct YamlNode struct_TelemetryScreenData[] = { YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data), YAML_END }; +static const struct YamlNode struct_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 2 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), + YAML_END +}; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -817,16 +852,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -840,25 +874,28 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), - YAML_UNSIGNED( "functionSwitchConfig", 16 ), - YAML_UNSIGNED( "functionSwitchGroup", 16 ), - YAML_UNSIGNED( "functionSwitchStartConfig", 16 ), - YAML_UNSIGNED( "functionSwitchLogicalState", 8 ), - YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL), + YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("customSwitches", 32, 6, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp index 497bb1e48..2302b663a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -89,6 +89,24 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_GLOBAL, "GLOBAL" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; +const struct YamlIdStr enum_fsStartPositionType[] = { + { FS_START_OFF, "START_OFF" }, + { FS_START_ON, "START_ON" }, + { FS_START_PREVIOUS, "START_PREVIOUS" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -222,7 +240,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -256,13 +274,21 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_ENUM("start", 2, enum_fsStartPositionType, switch_is_cfs), + YAML_PADDING( 3 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -276,12 +302,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -314,7 +340,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -341,7 +367,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -382,7 +408,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -403,7 +429,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -463,7 +489,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -476,7 +502,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -634,7 +660,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -684,7 +710,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -728,7 +754,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -775,9 +801,18 @@ static const struct YamlNode struct_TelemetryScreenData[] = { YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data), YAML_END }; +static const struct YamlNode struct_customSwitch[] = { + YAML_IDX_CUST("sw",cfs_idx_read,cfs_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_UNSIGNED( "group", 2 ), + YAML_ENUM("start", 2, enum_fsStartPositionType, NULL), + YAML_UNSIGNED( "state", 1 ), + YAML_END +}; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -817,16 +852,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -840,25 +874,28 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), - YAML_UNSIGNED( "functionSwitchConfig", 16 ), - YAML_UNSIGNED( "functionSwitchGroup", 16 ), - YAML_UNSIGNED( "functionSwitchStartConfig", 16 ), - YAML_UNSIGNED( "functionSwitchLogicalState", 8 ), - YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL), + YAML_CUSTOM("functionSwitchConfig",r_functionSwitchConfig,nullptr), + YAML_CUSTOM("functionSwitchGroup",r_functionSwitchGroup,nullptr), + YAML_CUSTOM("functionSwitchStartConfig",r_functionSwitchStartConfig,nullptr), + YAML_CUSTOM("functionSwitchLogicalState",r_functionSwitchLogicalState,nullptr), + YAML_ARRAY("switchNames", 0, NUM_FUNCTIONS_SWITCHES, struct_cfsNameConfig, nullptr), + YAML_ARRAY("customSwitches", 32, 6, struct_customSwitch, isAlwaysActive), + YAML_ARRAY("cfsGroupOn", 1, 8, struct_cfsGroupOn, cfsGroupIsActive), + YAML_PADDING( 8 ), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 16796d0d2..66b7d8a93 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -89,6 +89,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -239,7 +250,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -273,13 +284,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -291,12 +309,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 16 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -329,7 +347,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -356,7 +374,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 16, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_STRING("currModelFilename", 17), YAML_UNSIGNED( "modelQuickSelect", 1 ), @@ -408,7 +426,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -429,7 +447,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -489,7 +507,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -502,7 +520,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -660,7 +678,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -710,7 +728,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -754,7 +772,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -778,7 +796,7 @@ static const struct YamlNode union_ZoneOptionValue_elmts[] = { }; static const struct YamlNode struct_ZoneOptionValueTyped[] = { YAML_IDX, - YAML_ENUM("type", 32, enum_ZoneOptionValueEnum), + YAML_ENUM("type", 32, enum_ZoneOptionValueEnum, NULL), YAML_UNION("value", 96, union_ZoneOptionValue_elmts, select_zov), YAML_END }; @@ -810,7 +828,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -850,16 +868,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -875,20 +892,20 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioThemesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index 8e07e844b..a746bbe34 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -221,7 +232,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -255,13 +266,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -275,12 +293,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -313,7 +331,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -340,7 +358,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -381,7 +399,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -402,7 +420,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -462,7 +480,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -475,7 +493,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -633,7 +651,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -683,7 +701,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -727,7 +745,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -776,7 +794,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -816,8 +834,7 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), @@ -826,8 +843,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -842,19 +859,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp b/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp index 8e07e844b..a746bbe34 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9dp2019.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -221,7 +232,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -255,13 +266,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -275,12 +293,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -313,7 +331,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -340,7 +358,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -381,7 +399,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -402,7 +420,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -462,7 +480,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -475,7 +493,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -633,7 +651,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -683,7 +701,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -727,7 +745,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -776,7 +794,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -816,8 +834,7 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), @@ -826,8 +843,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -842,19 +859,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index 4200d4937..1299ae64a 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -221,7 +232,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -255,13 +266,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -275,12 +293,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -313,7 +331,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -340,7 +358,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -381,7 +399,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -402,7 +420,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -462,7 +480,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -475,7 +493,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -633,7 +651,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -683,7 +701,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -727,7 +745,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -776,7 +794,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -816,8 +834,7 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), @@ -826,8 +843,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -843,19 +860,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp index 8e2cd75fe..1db00afad 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -221,7 +232,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -255,13 +266,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -275,12 +293,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -313,7 +331,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -340,7 +358,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -381,7 +399,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -402,7 +420,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -462,7 +480,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -475,7 +493,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -633,7 +651,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -683,7 +701,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -727,7 +745,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -776,7 +794,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -816,16 +834,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -840,19 +857,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index 6a50c8458..763f8e792 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -88,6 +88,17 @@ const struct YamlIdStr enum_Functions[] = { { FUNC_TEST, "TEST" }, { 0, NULL } }; +const struct YamlIdStr enum_SwitchConfig[] = { + { SWITCH_NONE, "NONE" }, + { SWITCH_TOGGLE, "TOGGLE" }, + { SWITCH_2POS, "2POS" }, + { SWITCH_3POS, "3POS" }, + { SWITCH_none, "none" }, + { SWITCH_toggle, "toggle" }, + { SWITCH_2pos, "2pos" }, + { SWITCH_3pos, "3pos" }, + { 0, NULL } +}; const struct YamlIdStr enum_TimerModes[] = { { TMRMODE_OFF, "OFF" }, { TMRMODE_ON, "ON" }, @@ -223,7 +234,7 @@ static const struct YamlNode struct_signed_16[] = { static const struct YamlNode struct_TrainerMix[] = { YAML_IDX, YAML_UNSIGNED( "srcChn", 6 ), - YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_ENUM("mode", 2, enum_TrainerMultiplex, NULL), YAML_SIGNED( "studWeight", 8 ), YAML_END }; @@ -257,13 +268,20 @@ static const struct YamlNode union_anonymous_0_elmts[] = { static const struct YamlNode struct_CustomFunctionData[] = { YAML_IDX, YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), - YAML_ENUM("func", 6, enum_Functions), + YAML_ENUM("func", 6, enum_Functions, NULL), YAML_CUSTOM("def",r_customFn,w_customFn), YAML_PADDING( 64 ), YAML_PADDING( 1 ), YAML_PADDING( 7 ), YAML_END }; +static const struct YamlNode struct_switchDef[] = { + YAML_IDX_CUST("sw",sw_idx_read,sw_idx_write), + YAML_STRING("name", 3), + YAML_ENUM("type", 3, enum_SwitchConfig, NULL), + YAML_PADDING( 5 ), + YAML_END +}; static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "manuallyEdited", 1 ), YAML_SIGNED( "timezoneMinutes", 3 ), @@ -277,12 +295,12 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "contrast", 8 ), YAML_UNSIGNED( "vBatWarn", 8 ), YAML_SIGNED( "txVoltageCalibration", 8 ), - YAML_ENUM("backlightMode", 3, enum_BacklightMode), - YAML_ENUM("antennaMode", 2, enum_AntennaModes), + YAML_ENUM("backlightMode", 3, enum_BacklightMode, NULL), + YAML_ENUM("antennaMode", 2, enum_AntennaModes, NULL), YAML_UNSIGNED( "disableRtcWarning", 1 ), YAML_UNSIGNED( "keysBacklight", 1 ), YAML_UNSIGNED( "dontPlayHello", 1 ), - YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_ENUM("internalModule", 8, enum_ModuleType, NULL), YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), YAML_UNSIGNED( "view", 8 ), YAML_PADDING( 2 ), @@ -315,7 +333,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "backlightBright", 8 ), YAML_UNSIGNED( "globalTimer", 32 ), YAML_UNSIGNED( "bluetoothBaudrate", 4 ), - YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes, NULL), YAML_UNSIGNED( "countryCode", 2 ), YAML_SIGNED( "pwrOnSpeed", 3 ), YAML_SIGNED( "pwrOffSpeed", 3 ), @@ -342,7 +360,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_ARRAY("slidersConfig", 0, MAX_POTS, struct_sliderConfig, nullptr), YAML_PADDING( 8 ), YAML_ARRAY("potsConfig", 4, 8, struct_potConfig, nullptr), - YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr), + YAML_ARRAY("switchConfig", 32, 20, struct_switchDef, switchIsActive), YAML_ARRAY("flexSwitches", 0, MAX_FLEX_SWITCHES, struct_flexSwitch, flex_sw_valid), YAML_UNSIGNED( "backlightColor", 8 ), YAML_STRING("bluetoothName", 10), @@ -385,7 +403,7 @@ static const struct YamlNode struct_TimerData[] = { YAML_UNSIGNED( "start", 22 ), YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), YAML_SIGNED( "value", 22 ), - YAML_ENUM("mode", 3, enum_TimerModes), + YAML_ENUM("mode", 3, enum_TimerModes, NULL), YAML_UNSIGNED( "countdownBeep", 2 ), YAML_UNSIGNED( "minuteBeep", 1 ), YAML_UNSIGNED( "persistent", 2 ), @@ -406,7 +424,7 @@ static const struct YamlNode struct_MixData[] = { YAML_SIGNED_CUST( "srcRaw", 10, r_mixSrcRawEx, w_mixSrcRawEx ), YAML_UNSIGNED( "carryTrim", 1 ), YAML_UNSIGNED( "mixWarn", 2 ), - YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex, NULL), YAML_UNSIGNED( "delayPrec", 1 ), YAML_UNSIGNED( "speedPrec", 1 ), YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), @@ -466,7 +484,7 @@ static const struct YamlNode struct_signed_8[] = { }; static const struct YamlNode struct_LogicalSwitchData[] = { YAML_IDX, - YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions, NULL), YAML_CUSTOM("def",r_logicSw,w_logicSw), YAML_PADDING( 10 ), YAML_PADDING( 10 ), @@ -479,7 +497,7 @@ static const struct YamlNode struct_LogicalSwitchData[] = { YAML_END }; static const struct YamlNode struct_SwashRingData[] = { - YAML_ENUM("type", 8, enum_SwashType), + YAML_ENUM("type", 8, enum_SwashType, NULL), YAML_UNSIGNED( "value", 8 ), YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), @@ -637,7 +655,7 @@ static const struct YamlNode struct_ModuleData[] = { YAML_CUSTOM("subType",r_modSubtype,w_modSubtype), YAML_UNSIGNED( "channelsStart", 8 ), YAML_SIGNED_CUST( "channelsCount", 8, r_channelsCount, w_channelsCount ), - YAML_ENUM("failsafeMode", 4, enum_FailsafeModes), + YAML_ENUM("failsafeMode", 4, enum_FailsafeModes, NULL), YAML_PADDING( 4 ), YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), YAML_END @@ -687,7 +705,7 @@ static const struct YamlNode struct_anonymous_16[] = { static const struct YamlNode union_anonymous_15_elmts[] = { YAML_STRUCT("frskyInstance", 8, struct_anonymous_16, NULL), YAML_UNSIGNED( "instance", 8 ), - YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula, NULL), YAML_END }; static const struct YamlNode struct_anonymous_18[] = { @@ -731,7 +749,7 @@ static const struct YamlNode struct_TelemetrySensor[] = { YAML_UNION("id2", 8, union_anonymous_15_elmts, select_id2), YAML_STRING("label", 4), YAML_UNSIGNED( "subId", 8 ), - YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_ENUM("type", 1, enum_TelemetrySensorType, NULL), YAML_PADDING( 1 ), YAML_UNSIGNED( "unit", 6 ), YAML_UNSIGNED( "prec", 2 ), @@ -780,7 +798,7 @@ static const struct YamlNode struct_TelemetryScreenData[] = { }; static const struct YamlNode struct_USBJoystickChData[] = { YAML_IDX, - YAML_ENUM("mode", 3, enum_USBJoystickCh), + YAML_ENUM("mode", 3, enum_USBJoystickCh, NULL), YAML_UNSIGNED( "inversion", 1 ), YAML_UNSIGNED( "param", 4 ), YAML_UNSIGNED( "btn_num", 5 ), @@ -820,16 +838,15 @@ static const struct YamlNode struct_ModelData[] = { YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active), YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), YAML_CUSTOM("switchWarningState",r_swtchWarn,nullptr), - YAML_ARRAY("switchWarning", 3, 21, struct_swtchWarn, nullptr), - YAML_PADDING(1), + YAML_ARRAY("switchWarning", 2, 32, struct_swtchWarn, nullptr), YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL), YAML_STRUCT("varioData", 40, struct_VarioData, NULL), YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ), YAML_STRUCT("rssiAlarms", 0, struct_RssiAlarmData, NULL), YAML_STRUCT("rfAlarms", 16, struct_RFAlarmData, NULL), YAML_UNSIGNED( "thrTrimSw", 3 ), - YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), - YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode, NULL), + YAML_ENUM("jitterFilter", 2, enum_ModelOverridableEnable, NULL), YAML_PADDING( 1 ), YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), @@ -844,19 +861,19 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "view", 8 ), YAML_STRING("modelRegistrationID", 8), YAML_UNSIGNED( "usbJoystickExtMode", 1 ), - YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode), + YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode, NULL), YAML_UNSIGNED( "usbJoystickCircularCut", 4 ), YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL), - YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable), - YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable), + YAML_ENUM("radioGFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("radioTrainerDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelHeliDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelFMDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCurvesDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelGVDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelLSDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelSFDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelCustomScriptsDisabled", 2, enum_ModelOverridableEnable, NULL), + YAML_ENUM("modelTelemetryDisabled", 2, enum_ModelOverridableEnable, NULL), YAML_END }; static const struct YamlNode struct_PartialModel[] = { diff --git a/radio/src/storage/yaml/yaml_node.h b/radio/src/storage/yaml/yaml_node.h index 3ee409ec3..860ccdb2a 100644 --- a/radio/src/storage/yaml/yaml_node.h +++ b/radio/src/storage/yaml/yaml_node.h @@ -88,6 +88,7 @@ struct YamlNode struct { const YamlIdStr* choices; + is_active_func is_active; } _enum; struct { @@ -141,8 +142,8 @@ struct YamlNode #define YAML_ARRAY(tag, bits, max_elmts, nodes, f_is_active) \ { .size=(bits), .type=YDT_ARRAY, .elmts=(max_elmts), YAML_TAG(tag), .u={._array={ .child=(nodes), .u={.is_active=(f_is_active)}}} } -#define YAML_ENUM(tag, bits, id_strs) \ - { .size=(bits), .type=YDT_ENUM, .elmts=0, YAML_TAG(tag), .u={._enum={ .choices=(id_strs) }} } +#define YAML_ENUM(tag, bits, id_strs, f_is_active) \ + { .size=(bits), .type=YDT_ENUM, .elmts=0, YAML_TAG(tag), .u={._enum={ .choices=(id_strs), .is_active=(f_is_active) }} } #define YAML_UNION(tag, bits, nodes, f_sel_m) \ { .size=(bits), .type=YDT_UNION, .elmts=0, YAML_TAG(tag), .u={._array={ .child=(nodes), .u={.select_member=(f_sel_m) }}} } @@ -193,8 +194,8 @@ struct YamlNode #define YAML_ARRAY(tag, bits, max_elmts, nodes, f_is_active) \ { (bits), YDT_ARRAY, (max_elmts), YAML_TAG(tag), {{ (nodes), {{ (f_is_active) }}}} } -#define YAML_ENUM(tag, bits, id_strs) \ - { (bits), YDT_ENUM, .elmts=0, YAML_TAG(tag), {{ (const YamlNode*)(id_strs) }} } +#define YAML_ENUM(tag, bits, id_strs, f_is_active) \ + { (bits), YDT_ENUM, .elmts=0, YAML_TAG(tag), {{ (const YamlNode*)(id_strs, {{ (f_is_active) }}) }} } #define YAML_UNION(tag, bits, nodes, f_sel_m) \ { (bits), YDT_UNION, .elmts=0, YAML_TAG(tag), {{ (nodes), {{ (YamlNode::is_active_func)(f_sel_m) }}}} } diff --git a/radio/src/storage/yaml/yaml_tree_walker.cpp b/radio/src/storage/yaml/yaml_tree_walker.cpp index f425a2c18..b6d1a5554 100644 --- a/radio/src/storage/yaml/yaml_tree_walker.cpp +++ b/radio/src/storage/yaml/yaml_tree_walker.cpp @@ -622,6 +622,13 @@ bool YamlTreeWalker::generate(yaml_writer_func wf, void* opaque) } else { + if (attr->type == YDT_ENUM && attr->u._enum.is_active) { + if (!attr->u._enum.is_active(this, data, getBitOffset())) { + toNextAttr(); + continue; + } + } + // only for lists: // - arrays have IDX upfront // - structs are not marked as arrays diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index 132c413b2..c4d5fcaab 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -420,19 +420,19 @@ char *getFlightModeString(char *dest, int8_t idx) return dest; } -char *getCustomSwitchesGroupName(char *dest, uint8_t idx) +char* getCustomSwitchesGroupName(char *dest, uint8_t idx) { dest = strAppendStringWithIndex(dest, "GR", idx + 1); return dest; } -char *getSwitchName(char *dest, uint8_t idx, bool defaultOnly) +char* getSwitchName(char *dest, uint8_t idx, bool defaultOnly) { - if (!defaultOnly && switchHasCustomName(idx)) { - dest = strAppend(dest, switchGetCustomName(idx), LEN_SWITCH_NAME); + if (!defaultOnly && g_model.switchHasCustomName(idx)) { + dest = strAppend(dest, g_model.getSwitchCustomName(idx), LEN_SWITCH_NAME); } else { - dest = strAppend(dest, switchGetName(idx), LEN_SWITCH_NAME); + dest = strAppend(dest, switchGetDefaultName(idx), LEN_SWITCH_NAME); } return dest; diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 3d4084471..47437b215 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -88,72 +88,59 @@ uint8_t potsPos[MAX_POTS]; // Non pushed : SWSRC_Sx0 = -1024 = Sx(up) = state 0 // Pushed : SWSRC_Sx2 = +1024 = Sx(down) = state 1 -uint8_t fsPreviousState = 0; -uint8_t functionSwitchFunctionState = 0; +uint16_t fsPreviousState = 0; void setFSStartupPosition() { - for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { - uint8_t startPos = (g_model.functionSwitchStartConfig >> 2 * i) & 0x03; - if (FSWITCH_CONFIG(i) == SWITCH_TOGGLE) - startPos = FS_START_OFF; - switch(startPos) { - case FS_START_OFF: - g_model.functionSwitchLogicalState &= ~(1 << i); // clear state - break; + for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + if (switchIsCustomSwitch(i)) { + uint8_t startPos = g_model.getSwitchStart(i); + if (g_model.getSwitchType(i) == SWITCH_TOGGLE) + startPos = FS_START_OFF; + switch(startPos) { + case FS_START_OFF: + g_model.cfsSetState(i, 0); + break; - case FS_START_ON: - g_model.functionSwitchLogicalState |= 1 << i; - break; + case FS_START_ON: + g_model.cfsSetState(i, 1); + break; - case FS_START_PREVIOUS: - default: - // Do nothing, use existing g_model.functionSwitchLogicalState value - break; + case FS_START_PREVIOUS: + default: + // Do nothing, use existing value + break; + } } } } -uint8_t getFSLogicalState() -{ - return g_model.functionSwitchLogicalState; -} - -uint8_t getFSLogicalState(uint8_t index) -{ - return (uint8_t )(bfSingleBitGet(getFSLogicalState(), index) >> (index)); -} - void setFSLogicalState(uint8_t index, uint8_t value) { - if (value) - g_model.functionSwitchLogicalState |= 1 << index; // Set bit - else - g_model.functionSwitchLogicalState &= ~(1 << index); // clear state + g_model.cfsSetState(index, value ? 1 : 0); } -uint8_t getFSPhysicalState(uint8_t index) +bool getFSPhysicalState(uint8_t index) { #if defined(FUNCTION_SWITCHES) - if (bfSingleBitGet(functionSwitchFunctionState, index)) + if (switchIsCustomSwitch(index) && g_model.cfsSFState(index)) return true; #endif - index += switchGetMaxSwitches(); return switchGetPosition(index) != SWITCH_HW_UP; } -uint8_t getFSPreviousPhysicalState(uint8_t index) +static bool getFSPreviousPhysicalState(uint8_t index) { - return (uint8_t )(bfSingleBitGet(fsPreviousState, index) >> (index)); + return (uint8_t)(bfSingleBitGet(fsPreviousState, index) >> (index)); } uint8_t getSwitchCountInFSGroup(uint8_t index) { uint8_t count = 0; - for (uint8_t i = 0; i < switchGetMaxFctSwitches(); i++) { - if (FSWITCH_GROUP(i) == index) + for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + if (switchIsCustomSwitch(i) && g_model.getSwitchGroup(i) == index) count++; } @@ -167,63 +154,63 @@ bool isFSGroupUsed(uint8_t index) void evalFunctionSwitches() { - uint8_t fct_switches = switchGetMaxFctSwitches(); - for (uint8_t i = 0; i < fct_switches; i++) { - if (FSWITCH_CONFIG(i) == SWITCH_NONE) { - setFSLedOFF(i); - //fsLedRGB(i, 0); - continue; - } - - uint8_t physicalState = getFSPhysicalState(i); - if (physicalState != getFSPreviousPhysicalState(i)) { - // FS was moved - inactivityTimerReset(ActivitySource::MainControls); - if ((FSWITCH_CONFIG(i) == SWITCH_2POS && physicalState == 1) || - (FSWITCH_CONFIG(i) == SWITCH_TOGGLE)) { - if (IS_FSWITCH_GROUP_ON(FSWITCH_GROUP(i)) != 0) { - // In an always on group - g_model.functionSwitchLogicalState |= 1 << i; // Set bit - } else { - g_model.functionSwitchLogicalState ^= 1 << i; // Toggle bit - } + for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + if (switchIsCustomSwitch(i)) { + if (g_model.getSwitchType(i) == SWITCH_NONE) { + continue; } - if (FSWITCH_GROUP(i) && physicalState == 1) { - // switch is in a group, other in group need to be turned off - for (uint8_t j = 0; j < NUM_FUNCTIONS_SWITCHES; j++) { - if (i == j) continue; - if (FSWITCH_GROUP(j) == FSWITCH_GROUP(i)) { - g_model.functionSwitchLogicalState &= ~(1 << j); // clear state + bool physicalState = getFSPhysicalState(i); + if (physicalState != getFSPreviousPhysicalState(i)) { + // FS was moved + inactivityTimerReset(ActivitySource::MainControls); + if ((g_model.getSwitchType(i) == SWITCH_2POS && physicalState) || + (g_model.getSwitchType(i) == SWITCH_TOGGLE)) { + if (g_model.cfsGroupAlwaysOn(g_model.getSwitchGroup(i)) != 0) { + // In an always on group + g_model.cfsSetState(i, 1); + } else { + g_model.cfsSetState(i, g_model.cfsState(i) ^ 1); // Toggle bit } } + + if (g_model.getSwitchGroup(i) && physicalState) { + // switch is in a group, other in group need to be turned off + for (uint8_t j = 0; j < switchGetMaxSwitches(); j++) { + if ((i != j) && switchIsCustomSwitch(j)) { + if (g_model.getSwitchGroup(j) == g_model.getSwitchGroup(i)) { + g_model.cfsSetState(j, 0); + } + } + } + } + + fsPreviousState ^= 1 << i; // Toggle state + storageDirty(EE_MODEL); } - fsPreviousState ^= 1 << i; // Toggle state - storageDirty(EE_MODEL); - } - - if (!pwrPressed()) { - if (getFSLogicalState(i)) - setFSLedON(i); - else - setFSLedOFF(i); + if (!pwrPressed()) { + if (g_model.cfsState(i)) + setFSLedON(i); + else + setFSLedOFF(i); + } } } } bool groupHasSwitchOn(uint8_t group) { - for (int j = 0; j < NUM_FUNCTIONS_SWITCHES; j += 1) - if (FSWITCH_GROUP(j) == group && getFSLogicalState(j)) + for (int j = 0; j < switchGetMaxSwitches(); j += 1) + if (switchIsCustomSwitch(j) && g_model.getSwitchGroup(j) == group && g_model.cfsState(j)) return true; return false; } int firstSwitchInGroup(uint8_t group) { - for (int j = 0; j < NUM_FUNCTIONS_SWITCHES; j += 1) - if (FSWITCH_GROUP(j) == group) + for (int j = 0; j < switchGetMaxSwitches(); j += 1) + if (switchIsCustomSwitch(j) && g_model.getSwitchGroup(j) == group) return j; return -1; } @@ -231,28 +218,30 @@ int firstSwitchInGroup(uint8_t group) int groupDefaultSwitch(uint8_t group) { bool allOff = true; - for (int j = 0; j < NUM_FUNCTIONS_SWITCHES; j += 1) { - if (FSWITCH_GROUP(j) == group) { - if (FSWITCH_STARTUP(j) == FS_START_ON) - return j; - if (FSWITCH_STARTUP(j) != FS_START_OFF) - allOff = false; + for (int j = 0; j < switchGetMaxSwitches(); j += 1) { + if (switchIsCustomSwitch(j)) { + if (g_model.getSwitchGroup(j) == group) { + if (g_model.getSwitchStart(j) == FS_START_ON) + return j; + if (g_model.getSwitchStart(j) != FS_START_OFF) + allOff = false; + } } } if (allOff) - return NUM_FUNCTIONS_SWITCHES; + return switchGetMaxSwitches(); return -1; } -void setGroupSwitchState(uint8_t group, int defaultSwitch) +void setGroupSwitchState(uint8_t group) { // Check rules for always on group // - Toggle switch type not valid, change all switches to 2POS // - One switch must be turned on, turn on first switch if needed - if (IS_FSWITCH_GROUP_ON(group)) { - for (int j = 0; j < NUM_FUNCTIONS_SWITCHES; j += 1) { - if (FSWITCH_GROUP(j) == group) { - FSWITCH_SET_CONFIG(j, SWITCH_2POS); // Toggle not valid + if (g_model.cfsGroupAlwaysOn(group)) { + for (int j = 0; j < switchGetMaxSwitches(); j += 1) { + if (switchIsCustomSwitch(j) && g_model.getSwitchGroup(j) == group) { + g_model.setSwitchType(j, SWITCH_2POS); // Toggle not valid } } if (!groupHasSwitchOn(group)) { @@ -260,16 +249,14 @@ void setGroupSwitchState(uint8_t group, int defaultSwitch) if (sw >= 0) setFSLogicalState(sw, 1); // Make sure a switch is on } - if (groupDefaultSwitch(group) == NUM_FUNCTIONS_SWITCHES) { + if (groupDefaultSwitch(group) == switchGetMaxSwitches()) { // Start state for all switches is off - set all to 'last' - for (int j = 0; j < NUM_FUNCTIONS_SWITCHES; j += 1) - if (FSWITCH_GROUP(j) == group) - FSWITCH_SET_STARTUP(j, FS_START_PREVIOUS); + for (int j = 0; j < switchGetMaxSwitches(); j += 1) + if (switchIsCustomSwitch(j) && g_model.getSwitchGroup(j) == group) + g_model.setSwitchStart(j, FS_START_PREVIOUS); } } } -#else -uint8_t getFSLogicalState(uint8_t) { return false; } #endif // FUNCTION_SWITCHES div_t switchInfo(int switchPosition) @@ -284,9 +271,9 @@ int switchLookupIdx(char c) idx = 2; // SWx } - auto max_switches = switchGetMaxSwitches() + switchGetMaxFctSwitches(); + auto max_switches = switchGetMaxAllSwitches(); for (int i = 0; i < max_switches; i++) { - const char *name = switchGetName(i); + const char *name = switchGetDefaultName(i); if (name[idx] == c) return i; } @@ -297,9 +284,9 @@ int switchLookupIdx(const char* name, size_t len) { if (len < 2 || (name[0] != 'S' && name[0] != 'F')) return -1; - auto max_switches = switchGetMaxSwitches() + switchGetMaxFctSwitches(); + auto max_switches = switchGetMaxAllSwitches(); for (int i = 0; i < max_switches; i++) { - const char *sw_name = switchGetCanonicalName(i); + const char *sw_name = switchGetDefaultName(i); if (strncmp(sw_name, name, len) == 0) return i; } @@ -308,44 +295,13 @@ int switchLookupIdx(const char* name, size_t len) char switchGetLetter(uint8_t idx) { - if (idx >= switchGetMaxSwitches() + switchGetMaxFctSwitches()) + if (idx >= switchGetMaxAllSwitches() + MAX_FLEX_SWITCHES) return -1; - - uint8_t c = 1; - if (idx >= switchGetMaxSwitches() || switchIsFlex(idx)) c = 2; - const char* name = switchGetName(idx); + const char* name = switchGetDefaultName(idx); if (!name) return -1; - return name[c]; -} - -static char _switchNames[MAX_SWITCHES][LEN_SWITCH_NAME + 1] = { 0 }; - -void switchSetCustomName(uint8_t idx, const char* str, size_t len) -{ - strncpy(_switchNames[idx], str, min(LEN_SWITCH_NAME, len)); - _switchNames[idx][LEN_SWITCH_NAME] = '\0'; -} - -const char* switchGetCustomName(uint8_t idx) -{ -#if defined(FUNCTION_SWITCHES) - if (idx >= switchGetMaxSwitches()) // Switch is a customisable switch - return g_model.switchNames[idx - switchGetMaxSwitches()]; - else -#endif - return _switchNames[idx]; -} - -bool switchHasCustomName(uint8_t idx) -{ - return *switchGetCustomName(idx) != 0; -} - -const char* switchGetCanonicalName(uint8_t idx) -{ - return switchGetName(idx); + return name[strlen(name) - 1]; } const char* fsSwitchGroupGetCanonicalName(uint8_t idx) @@ -412,7 +368,7 @@ static uint64_t checkSwitchPosition(uint8_t idx, bool startup) void getSwitchesPosition(bool startup) { uint64_t newPos = 0; - for (unsigned i = 0; i < switchGetMaxSwitches(); i++) { + for (unsigned i = 0; i < switchGetMaxAllSwitches(); i++) { if (!SWITCH_EXISTS(i)) continue; newPos |= checkSwitchPosition(i, startup); } @@ -453,7 +409,7 @@ void getSwitchesPosition(bool startup) uint8_t getSwitchCount() { int count = 0; - for (int i = 0; i < switchGetMaxSwitches(); ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_EXISTS(i)) { ++count; } @@ -461,10 +417,11 @@ uint8_t getSwitchCount() return count; } +#if !defined(COLORLCD) uint8_t switchGetMaxRow(uint8_t col) { uint8_t lastrow = 0; - for (int i = 0; i < switchGetMaxSwitches(); ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_EXISTS(i)) { auto switch_display = switchGetDisplayPosition(i); if (switch_display.col == col) @@ -473,6 +430,7 @@ uint8_t switchGetMaxRow(uint8_t col) } return lastrow; } +#endif getvalue_t getValueForLogicalSwitch(mixsrc_t i) { @@ -719,18 +677,16 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) else if (cs_idx <= SWSRC_LAST_SWITCH) { cs_idx -= SWSRC_FIRST_SWITCH; #if defined(FUNCTION_SWITCHES) - auto max_reg_pos = switchGetMaxSwitches() * 3; - if (cs_idx >= max_reg_pos && cs_idx - max_reg_pos < switchGetMaxFctSwitches() * 3) { - cs_idx -= max_reg_pos; - div_t qr = div(cs_idx, 3); - auto value = getFSLogicalState(qr.quot); + div_t qr = div(cs_idx, 3); + if (switchIsCustomSwitch(qr.quot)) { + auto value = g_model.cfsState(qr.quot); result = qr.rem == 0 ? !value : (qr.rem == 2 ? value : false); } else #endif { div_t qr = div(cs_idx, 3); if (SWITCH_EXISTS(qr.quot)) { - auto sw_cfg = (SwitchConfig)SWITCH_CONFIG(qr.quot); + auto sw_cfg = g_model.getSwitchType(qr.quot); if (flags & GETSWITCH_MIDPOS_DELAY) { result = SWITCH_POSITION(cs_idx); // Handle 2POS switch installed in 3POS slot @@ -829,7 +785,6 @@ static inline uint8_t _bits_set(uint8_t val, uint8_t bits) } swarnstate_t switches_states = 0; -uint8_t fsswitches_states = 0; swsrc_t getMovedSwitch() { @@ -837,40 +792,28 @@ swsrc_t getMovedSwitch() swsrc_t result = 0; // Switches - auto max_reg_switches = switchGetMaxSwitches(); - for (uint8_t i = 0; i < max_reg_switches; i++) { + auto max_switches = switchGetMaxAllSwitches(); + for (uint8_t i = 0; i < max_switches; i++) { if (SWITCH_EXISTS(i)) { - swarnstate_t mask = ((swarnstate_t) 0x07 << (i * 3)); - uint8_t prev = (switches_states & mask) >> (i * 3); - uint8_t next = (1024 + getValue(MIXSRC_FIRST_SWITCH + i)) / 1024 + 1; + swarnstate_t mask = ((swarnstate_t) 0x03 << (i * 2)); + uint8_t prev = (switches_states & mask) >> (i * 2); + uint8_t next; +#if defined(FUNCTION_SWITCHES) + if (switchIsCustomSwitch(i)) + next = g_model.cfsState(i) ? 3 : 1; + else + next = (1024 + getValue(MIXSRC_FIRST_SWITCH + i)) / 1024 + 1; +#else + next = (1024 + getValue(MIXSRC_FIRST_SWITCH + i)) / 1024 + 1; +#endif if (prev != next) { switches_states = - (switches_states & (~mask)) | ((swarnstate_t)(next) << (i * 3)); + (switches_states & (~mask)) | ((swarnstate_t)(next) << (i * 2)); result = (3 * i) + next; } } } -#if defined(FUNCTION_SWITCHES) - auto fsswitches_cur_state = getFSLogicalState(); - auto fsswitches_xor = fsswitches_cur_state ^ fsswitches_states; - fsswitches_states = fsswitches_cur_state; - - if (fsswitches_xor) { - // we have some change... - if (_bits_set(fsswitches_xor, switchGetMaxFctSwitches()) > 1) { - // multiple bits change: use the one that turned ON - fsswitches_xor &= fsswitches_cur_state; - } else { - // only one bit changed: use the one that changed - } - - auto sw = __builtin_ctz(fsswitches_xor); - auto pos = (fsswitches_cur_state & fsswitches_xor) ? 2 : 0; - result = (max_reg_switches + sw) * 3 + pos + SWSRC_FIRST_SWITCH; - } -#endif - // Multipos for (int i = 0; i < MAX_POTS; i++) { if (IS_POT_MULTIPOS(i)) { @@ -894,17 +837,18 @@ swsrc_t getMovedSwitch() bool isSwitchWarningRequired(uint16_t &bad_pots) { - swarnstate_t states = g_model.switchWarning; - if (!mixerTaskRunning()) getADC(); getMovedSwitch(); bool warn = false; - for (int i = 0; i < switchGetMaxSwitches(); i++) { + for (int i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) { - swarnstate_t mask = ((swarnstate_t)0x07 << (i * 3)); - if ((states & mask) && !((states & mask) == (switches_states & mask))) { - warn = true; + uint8_t warnState = g_model.getSwitchWarning(i); + if (warnState) { + swarnstate_t swState = g_model.getSwitchStateForWarning(i); + if (warnState != swState) { + warn = true; + } } } } @@ -943,7 +887,6 @@ void checkSwitches() void checkSwitches() { swarnstate_t last_bad_switches = 0xff; - swarnstate_t states = g_model.switchWarning; uint16_t bad_pots = 0, last_bad_pots = 0xff; #if defined(PWR_BUTTON_PRESS) @@ -968,17 +911,16 @@ void checkSwitches() int x = SWITCH_WARNING_LIST_X; int y = SWITCH_WARNING_LIST_Y; int numWarnings = 0; - for (int i = 0; i < switchGetMaxSwitches(); ++i) { + for (int i = 0; i < switchGetMaxAllSwitches(); ++i) { if (SWITCH_WARNING_ALLOWED(i)) { - swarnstate_t mask = ((swarnstate_t)0x07 << (i*3)); - if (states & mask) { - LcdFlags attr = - ((states & mask) == (switches_states & mask)) ? 0 : INVERS; - if (attr) { + uint8_t warnState = g_model.getSwitchWarning(i); + if (warnState) { + swarnstate_t swState = g_model.getSwitchStateForWarning(i); + if (warnState != swState) { if (++numWarnings < 6) { - const char* s = getSwitchWarnSymbol((states & mask) >> (i * 3)); - drawSource(x, y, MIXSRC_FIRST_SWITCH + i, attr); - lcdDrawText(lcdNextPos, y, s, attr); + const char* s = getSwitchWarnSymbol(warnState); + drawSource(x, y, MIXSRC_FIRST_SWITCH + i, INVERS); + lcdDrawText(lcdNextPos, y, s, INVERS); x = lcdNextPos + 3; } } @@ -1219,10 +1161,10 @@ void setAllPreflightSwitchStates() getMovedSwitch(); // Mask switches enabled for warnings swarnstate_t sw_mask = 0; - for(uint8_t i = 0; i < switchGetMaxSwitches(); i++) { + for(uint8_t i = 0; i < switchGetMaxAllSwitches(); i++) { if (SWITCH_WARNING_ALLOWED(i)) - if (g_model.switchWarning & (0x07 << (3 * i))) - sw_mask |= (0x07 << (3 * i)); + if (g_model.getSwitchWarning(i)) + sw_mask |= (0x03 << (2 * i)); } g_model.switchWarning = switches_states & sw_mask; AUDIO_WARNING1(); diff --git a/radio/src/switches.h b/radio/src/switches.h index 3743e34f5..d29a4cff5 100644 --- a/radio/src/switches.h +++ b/radio/src/switches.h @@ -78,14 +78,8 @@ int switchLookupIdx(const char* name, size_t len); // note: no customizable switches char switchGetLetter(uint8_t idx); -// note: no customizable switches -const char* switchGetCanonicalName(uint8_t idx); - // customizable switches supported const char* fsSwitchGroupGetCanonicalName(uint8_t idx); -void switchSetCustomName(uint8_t idx, const char* str, size_t len); -const char* switchGetCustomName(uint8_t idx); -bool switchHasCustomName(uint8_t idx); uint8_t getSwitchCountInFSGroup(uint8_t index); SwitchConfig switchGetMaxType(uint8_t idx); @@ -96,20 +90,18 @@ void logicalSwitchesInit(bool force); #if defined(FUNCTION_SWITCHES) void setFSStartupPosition(); void evalFunctionSwitches(); -uint8_t getFSLogicalState(uint8_t index); void setFSLogicalState(uint8_t index, uint8_t value); bool groupHasSwitchOn(uint8_t group); int firstSwitchInGroup(uint8_t group); int groupDefaultSwitch(uint8_t group); -void setGroupSwitchState(uint8_t group, int defaultSwitch = -1); -uint8_t getFSPhysicalState(uint8_t index); -extern uint8_t functionSwitchFunctionState; +void setGroupSwitchState(uint8_t group); +bool getFSPhysicalState(uint8_t index); //led_driver.cpp -void fsLedOff(uint8_t); -void fsLedOn(uint8_t); +void fsLedOff(uint8_t index); +void fsLedOn(uint8_t index); bool fsLedState(uint8_t index); -void fsLedRGB(uint8_t, uint32_t color); +void fsLedRGB(uint8_t index, uint32_t color); uint32_t fsGetLedRGB(uint8_t index); uint8_t getRGBColorIndex(uint32_t color); #endif diff --git a/radio/src/targets/common/arm/stm32/stm32_switch_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_switch_driver.cpp index 7b6fcda89..d0c0e5ef2 100644 --- a/radio/src/targets/common/arm/stm32/stm32_switch_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_switch_driver.cpp @@ -24,7 +24,7 @@ SwitchHwPos stm32_switch_get_position(const stm32_switch_t* sw) { - bool inv = sw->flags & SWITCH_HW_INVERTED; + bool inv = sw->inverted; SwitchHwPos ret = SWITCH_HW_UP; switch (sw->type) { diff --git a/radio/src/targets/common/arm/stm32/stm32_switch_driver.h b/radio/src/targets/common/arm/stm32/stm32_switch_driver.h index 11d67630e..330059d1f 100644 --- a/radio/src/targets/common/arm/stm32/stm32_switch_driver.h +++ b/radio/src/targets/common/arm/stm32/stm32_switch_driver.h @@ -21,20 +21,29 @@ #pragma once +#include "hal.h" #include "stm32_hal_ll.h" #include "hal/switch_driver.h" +#include "edgetx_constants.h" struct stm32_switch_t { const char* name; + GPIO_TypeDef* GPIOx_high; uint32_t Pin_high; GPIO_TypeDef* GPIOx_low; uint32_t Pin_low; - SwitchHwType type; - uint8_t flags; + SwitchHwType type; + bool inverted; + SwitchConfig defaultType; + +#if defined(FUNCTION_SWITCHES) + bool isCustomSwitch; + uint8_t customSwitchIdx; +#endif }; SwitchHwPos stm32_switch_get_position(const stm32_switch_t* sw); diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 50ff2aff2..aac03fdf7 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -302,19 +302,6 @@ void bluetoothDisable(); #if defined(FUNCTION_SWITCHES) #define NUM_FUNCTIONS_SWITCHES 6 #define NUM_FUNCTIONS_GROUPS 3 -#define DEFAULT_FS_CONFIG \ - (SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \ - (SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0) - -#define DEFAULT_FS_GROUPS \ - (1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \ - (1 << 0) // Set all FS to group 1 to act like a 6pos - -#define DEFAULT_FS_STARTUP_CONFIG \ - ((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \ - (FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \ - (FS_START_PREVIOUS << 2) + \ - (FS_START_PREVIOUS << 0)) // keep last state by default #else #define NUM_FUNCTIONS_SWITCHES 0 diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index e77847804..4ba5a3baf 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -156,36 +156,42 @@ #define HARDWARE_SWITCH_G #define SWITCHES_GPIO_REG_G GPIOB #define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_14 // PB.14 + #define SWITCHES_G_CFS_IDX 0 //SW2 #define FUNCTION_SWITCH_2 SH #define STORAGE_SWITCH_H #define HARDWARE_SWITCH_H #define SWITCHES_GPIO_REG_H GPIOD #define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_13 // PD.13 + #define SWITCHES_H_CFS_IDX 1 //SW3 #define FUNCTION_SWITCH_3 SI #define STORAGE_SWITCH_I #define HARDWARE_SWITCH_I #define SWITCHES_GPIO_REG_I GPIOJ #define SWITCHES_GPIO_PIN_I LL_GPIO_PIN_7 // PJ.07 + #define SWITCHES_I_CFS_IDX 2 //SW4 #define FUNCTION_SWITCH_4 SJ #define STORAGE_SWITCH_J #define HARDWARE_SWITCH_J #define SWITCHES_GPIO_REG_J GPIOG #define SWITCHES_GPIO_PIN_J LL_GPIO_PIN_13 // PG.13 + #define SWITCHES_J_CFS_IDX 3 //SW5 #define FUNCTION_SWITCH_5 SK #define STORAGE_SWITCH_K #define HARDWARE_SWITCH_K #define SWITCHES_GPIO_REG_K GPIOJ #define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_8 // PJ.08 + #define SWITCHES_K_CFS_IDX 4 //SW6 #define FUNCTION_SWITCH_6 SL #define STORAGE_SWITCH_L #define HARDWARE_SWITCH_L #define SWITCHES_GPIO_REG_L GPIOB #define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_13 // PB.13 + #define SWITCHES_L_CFS_IDX 5 #else #define STORAGE_SWITCH_A #define HARDWARE_SWITCH_A @@ -1044,6 +1050,8 @@ #if defined(RADIO_V16) // LED Strip #define LED_STRIP_LENGTH 40 + #define BLING_LED_STRIP_START 6 + #define BLING_LED_STRIP_LENGTH 34 #define LED_STRIP_GPIO GPIO_PIN(GPIOA, 10) // PA.10 / TIM1_CH3 #define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1/2 #define LED_STRIP_TIMER TIM1 diff --git a/radio/src/targets/horus/led_driver.cpp b/radio/src/targets/horus/led_driver.cpp index 8710e3538..4ff554e54 100644 --- a/radio/src/targets/horus/led_driver.cpp +++ b/radio/src/targets/horus/led_driver.cpp @@ -50,23 +50,7 @@ void ledInit() #endif } -#if defined(FUNCTION_SWITCHES_RGB_LEDS) -// used to map switch number to led number in the rgbled chain -uint8_t ledMapping[] = {1, 2, 3, 4, 5, 6}; - -void fsLedOff(uint8_t index, uint32_t color) -{ - rgbSetLedColor(ledMapping[index], GET_RED(color), GET_GREEN(color), - GET_BLUE(color)); -} - -void fsLedOn(uint8_t index, uint32_t color) -{ - rgbSetLedColor(ledMapping[index], GET_RED(color), GET_GREEN(color), - GET_BLUE(color)); -} - -#elif defined(FUNCTION_SWITCHES) +#if defined(FUNCTION_SWITCHES) && !defined(FUNCTION_SWITCHES_RGB_LEDS) gpio_t fsLeds[] = {FSLED_GPIO_1, FSLED_GPIO_2, FSLED_GPIO_3, FSLED_GPIO_4, FSLED_GPIO_5, FSLED_GPIO_6}; diff --git a/radio/src/targets/nv14/bsp_io.h b/radio/src/targets/nv14/bsp_io.h deleted file mode 100644 index b74cedd30..000000000 --- a/radio/src/targets/nv14/bsp_io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#pragma once - -#include "hal/switch_driver.h" -#include "stm32_switch_driver.h" - -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx) {return SWITCH_HW_MID;} diff --git a/radio/src/targets/pl18/bsp_io.h b/radio/src/targets/pl18/bsp_io.h index b74cedd30..c220d27d1 100644 --- a/radio/src/targets/pl18/bsp_io.h +++ b/radio/src/targets/pl18/bsp_io.h @@ -17,5 +17,3 @@ #include "hal/switch_driver.h" #include "stm32_switch_driver.h" - -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx) {return SWITCH_HW_MID;} diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index 626b9c530..a53851692 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -830,6 +830,8 @@ // LED Strip #if !defined(RADIO_NV14_FAMILY) #define LED_STRIP_LENGTH 4 + #define BLING_LED_STRIP_START 0 + #define BLING_LED_STRIP_LENGTH 4 #define LED_STRIP_GPIO GPIO_PIN(GPIOH, 12) // PH.12 / TIM5_CH3 #define LED_STRIP_GPIO_AF LL_GPIO_AF_2 // TIM3/4/5 #define LED_STRIP_TIMER TIM5 diff --git a/radio/src/targets/pl18/nb4p_switch_driver.cpp b/radio/src/targets/pl18/nb4p_switch_driver.cpp index 0c0c035f0..521fbb05e 100644 --- a/radio/src/targets/pl18/nb4p_switch_driver.cpp +++ b/radio/src/targets/pl18/nb4p_switch_driver.cpp @@ -32,7 +32,7 @@ static const char _switch_names[][4] = {"SW2", "SW3"}; -SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) +SwitchHwPos boardSwitchGetPosition(uint8_t idx) { if (idx <= 1) { // uint16_t swVal = getAnalogValue(4); @@ -55,7 +55,7 @@ SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) return SWITCH_HW_UP; } -const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx) +const char* boardSwitchGetName(uint8_t idx) { return _switch_names[idx]; } diff --git a/radio/src/targets/simu/led_driver.cpp b/radio/src/targets/simu/led_driver.cpp index 17e51fc50..ccf6f3b3a 100644 --- a/radio/src/targets/simu/led_driver.cpp +++ b/radio/src/targets/simu/led_driver.cpp @@ -19,21 +19,26 @@ * GNU General Public License for more details. */ -#include +#include "edgetx.h" #include "hal/rgbleds.h" #include "definitions.h" -#include "board.h" - bool usbChargerLed() { return true; } void ledRed() {} void ledGreen() {} void ledBlue() {} void ledOff() {} - -void rgbSetLedColor(uint8_t, uint8_t, uint8_t, uint8_t) {} void rgbLedColorApply() {} +bool fsLedState(uint8_t i) +{ +#if defined(FUNCTION_SWITCHES) + return g_model.customSwitches[i].state; +#else + return false; +#endif +} + uint8_t getRGBColorIndex(uint32_t color) { for (uint8_t i = 0; i < DIM(colorTable); i++) { @@ -43,39 +48,37 @@ uint8_t getRGBColorIndex(uint32_t color) return 0; // Custom value set with Companion } -#if NUM_FUNCTIONS_SWITCHES > 0 -static uint32_t _fs_switch_colors[NUM_FUNCTIONS_SWITCHES] = {0}; -static uint32_t _fs_switch_color_mask = 0; -static uint32_t _fs_switch_mask = 0; +// RGB +#define WS2812_BYTES_PER_LED 3 -void fsLedRGB(uint8_t index, uint32_t col) +// Maximum number of supported LEDs +#if !defined(WS2812_MAX_LEDS) +# define WS2812_MAX_LEDS 48 +#endif + +// Pixel values +static uint8_t _led_colors[WS2812_BYTES_PER_LED * WS2812_MAX_LEDS]; + +void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b) { - _fs_switch_color_mask |= (1 << index); - _fs_switch_colors[index] = col; + uint8_t* pixel = &_led_colors[led * WS2812_BYTES_PER_LED]; + pixel[0] = g; + pixel[1] = r; + pixel[2] = b; +} + +uint32_t rgbGetLedColor(uint8_t led) +{ + uint8_t* pixel = &_led_colors[led * WS2812_BYTES_PER_LED]; + return (pixel[1] << 16) + (pixel[0] << 8) + pixel[2]; +} + +void fsLedRGB(uint8_t idx, uint32_t color) +{ + rgbSetLedColor(idx, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF); } uint32_t fsGetLedRGB(uint8_t index) { - return _fs_switch_colors[index]; + return rgbGetLedColor(index); } - -bool fsLedIsColorSet(uint8_t index) -{ - return _fs_switch_color_mask & (1 << index); -} - -bool fsLedState(uint8_t index) -{ - return _fs_switch_mask & (1 << index); -} - -void fsLedOn(uint8_t index) -{ - _fs_switch_mask |= (1 << index); -} - -void fsLedOff(uint8_t index) -{ - _fs_switch_mask &= ~(1 << index); -} -#endif diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index cf77ab788..1c96ef2b0 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -30,6 +30,7 @@ #include "hal/adc_driver.h" #include "hal/rotary_encoder.h" #include "os/time.h" +#include "boards/generic_stm32/rgb_leds.h" #include #include @@ -90,6 +91,16 @@ void firmwareTraceCb(const char * text) } } +void fsLedOn(uint8_t idx) +{ + rgbSetLedColor(idx, 0xFF, 0xFF, 0xFF); +} + +void fsLedOff(uint8_t idx) +{ + rgbSetLedColor(idx, 0, 0, 0); +} + // Serial port handling needs to know about OpenTxSimulator, so we we // need to update what's in simpgmspace.cpp when we have a simulator // to point at. @@ -751,6 +762,7 @@ void OpenTxSimulator::run() ++loops; checkLcdChanged(); + checkFuncSwitchChanged(); if (!(loops % 5)) { checkOutputsChanged(); @@ -783,6 +795,19 @@ bool OpenTxSimulator::checkLcdChanged() return false; } +void OpenTxSimulator::checkFuncSwitchChanged() +{ +#if defined(FUNCTION_SWITCHES) + for (int i = 0; i < CPN_MAX_SWITCHES; i += 1) { + if (switchIsCustomSwitch(i)) { + uint8_t cfs = switchGetCustomSwitchIdx(i); + uint32_t c = rgbGetLedColor(cfs); + emit fsColorChange(i, c); + } + } +#endif +} + void OpenTxSimulator::checkOutputsChanged() { static TxOutputs lastOutputs; diff --git a/radio/src/targets/simu/opentxsimulator.h b/radio/src/targets/simu/opentxsimulator.h index 736cc6666..4936d3212 100644 --- a/radio/src/targets/simu/opentxsimulator.h +++ b/radio/src/targets/simu/opentxsimulator.h @@ -102,6 +102,7 @@ class DLLEXPORT OpenTxSimulator : public SimulatorInterface void setStopRequested(bool stop); bool checkLcdChanged(); void checkOutputsChanged(); + void checkFuncSwitchChanged(); uint8_t getStickMode(); const char * getPhaseName(unsigned int phase); const QString getCurrentPhaseName(); diff --git a/radio/src/targets/simu/sdl_simu.cpp b/radio/src/targets/simu/sdl_simu.cpp index d8e6b8a7e..86918dad9 100644 --- a/radio/src/targets/simu/sdl_simu.cpp +++ b/radio/src/targets/simu/sdl_simu.cpp @@ -65,6 +65,7 @@ #include "simpgmspace.h" #include "hal/key_driver.h" +#include "hal/switch_driver.h" #include "switches.h" #include "audio.h" @@ -316,26 +317,28 @@ static void draw_switches() int sw_idx = 0; for (int i = 0; i < switchGetMaxSwitches(); i++) { if (sw_idx) ImGui::SameLine(); - if (++sw_idx >= MAX_SWITCHES / 2) sw_idx = 0; - if (!SWITCH_EXISTS(i)) { - switches[i] = 0; - ImGui::Dummy(sw_size); - } else { - ImGui::PushID(i); - ImGui::VSliderInt("##sw", sw_size, - &switches[i], IS_CONFIG_3POS(i) ? 2 : 1, - 0, "", ImGuiSliderFlags_NoInput); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) { - ImGui::SetTooltip("%s", switchGetCanonicalName(i)); + if (!switchIsCustomSwitch(i)) { + if (++sw_idx >= MAX_SWITCHES / 2) sw_idx = 0; + if (!SWITCH_EXISTS(i)) { + switches[i] = 0; + ImGui::Dummy(sw_size); + } else { + ImGui::PushID(i); + ImGui::VSliderInt("##sw", sw_size, + &switches[i], IS_CONFIG_3POS(i) ? 2 : 1, + 0, "", ImGuiSliderFlags_NoInput); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", switchGetDefaultName(i)); + } + ImGui::PopID(); + } + + if (IS_CONFIG_3POS(i)) { + simuSetSwitch(i, switches[i] == 0 ? -1 : switches[i] == 1 ? 0 : 1); + } else { + simuSetSwitch(i, switches[i] == 0 ? -1 : 1); } - ImGui::PopID(); - } - - if (IS_CONFIG_3POS(i)) { - simuSetSwitch(i, switches[i] == 0 ? -1 : switches[i] == 1 ? 0 : 1); - } else { - simuSetSwitch(i, switches[i] == 0 ? -1 : 1); } } @@ -346,8 +349,6 @@ static void draw_switches() } #if defined(FUNCTION_SWITCHES) -extern bool fsLedIsColorSet(uint8_t index); - static ImVec4 rgb2rgba(uint32_t col) { float r = (float)((col >> 16) & 0xff) / 255.0f; @@ -365,9 +366,10 @@ static inline ImVec4 blend(const ImVec4& a, const ImVec4& b) static void push_custom_switch_styles(int index) { - bool sw_on = getFSLogicalState(index); - bool rgb_set = fsLedIsColorSet(index); - ImVec4 rgb = rgb2rgba(fsGetLedRGB(index)); + int cfsIdx = switchGetCustomSwitchIdx(index); + bool sw_on = fsLedState(cfsIdx); + bool rgb_set = switchIsCustomSwitch(index); + ImVec4 rgb = rgb2rgba(fsGetLedRGB(cfsIdx)); ImVec4 btn, border; if (sw_on) { @@ -408,24 +410,29 @@ static void draw_custom_switches() ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f); ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding, 4.0f); - int sw_idx = switchGetMaxSwitches(); - for (int i = 0; i < switchGetMaxFctSwitches(); i++, sw_idx++) { - if (i) ImGui::SameLine(); - ImGui::PushID(i); + for (int i = 0, n = 0; i < switchGetMaxSwitches(); i += 1) { + if (switchIsCustomSwitch(i)) { + int cfsIdx = switchGetCustomSwitchIdx(i); - push_custom_switch_styles(i); - ImGui::Button("##csw", sw_size); - pop_custom_switch_styles(); + if (n) ImGui::SameLine(); + ImGui::PushID(i); - bool active = ImGui::IsItemActive(); - if (active || ImGui::IsItemHovered()) { - const char* name = switchGetCanonicalName(sw_idx); - const char* on_off = getFSLogicalState(i) ? "on" : "off"; - ImGui::SetTooltip("%s (%s)", name, on_off); + push_custom_switch_styles(i); + ImGui::Button("##csw", sw_size); + pop_custom_switch_styles(); + + bool active = ImGui::IsItemActive(); + if (active || ImGui::IsItemHovered()) { + const char* name = switchGetDefaultName(i); + const char* on_off = fsLedState(cfsIdx) ? "on" : "off"; + ImGui::SetTooltip("%s (%s)", name, on_off); + } + simuSetSwitch(i, active ? 1 : -1); + + ImGui::PopID(); } - simuSetSwitch(sw_idx, active ? 1 : -1); - ImGui::PopID(); + n += 1; } ImGui::PopStyleVar(3); diff --git a/radio/src/targets/simu/switch_driver.cpp b/radio/src/targets/simu/switch_driver.cpp index c90672552..b1a03134d 100644 --- a/radio/src/targets/simu/switch_driver.cpp +++ b/radio/src/targets/simu/switch_driver.cpp @@ -29,17 +29,22 @@ #include struct hw_switch_def { - const char* name; - SwitchHwType type; + const char* name; + SwitchHwType type; + SwitchConfig defaultType; +#if defined(FUNCTION_SWITCHES) + bool isCustomSwitch; + uint8_t customSwitchIdx; +#endif }; #include "simu_switches.inc" -int8_t switchesStates[MAX_SWITCHES] = { 0 }; +int8_t switchesStates[MAX_SWITCHES]; void simuSetSwitch(uint8_t swtch, int8_t state) { - assert(swtch < switchGetMaxSwitches() + switchGetMaxFctSwitches()); + assert(swtch < switchGetMaxAllSwitches()); switchesStates[swtch] = state; } @@ -47,34 +52,8 @@ void boardInitSwitches() { memset(switchesStates, -1, sizeof(switchesStates)); } -static uint8_t get_switch_index(uint8_t cat, uint8_t idx) +SwitchHwPos boardSwitchGetPosition(uint8_t idx) { - switch(cat) { - case SWITCH_PHYSICAL: - assert(idx < n_switches); - return idx; - - case SWITCH_FUNCTION: - assert(idx < n_fct_switches); - return idx + n_switches; - - default: - assert(0); - return 0; - } -} - -SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) -{ - idx = get_switch_index(cat, idx); - -#if defined(FUNCTION_SWITCHES) - if (IS_SWITCH_FS(idx)) { - if (bfSingleBitGet(functionSwitchFunctionState, idx - n_switches)) - return SWITCH_HW_DOWN; - } -#endif - if (switchesStates[idx] < 0) return SWITCH_HW_UP; else if (switchesStates[idx] == 0) @@ -83,26 +62,30 @@ SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) return SWITCH_HW_DOWN; } -const char* boardSwitchGetName(SwitchCategory cat, uint8_t idx) +const char* boardSwitchGetName(uint8_t idx) { - idx = get_switch_index(cat, idx); return _switch_defs[idx].name; } -SwitchHwType boardSwitchGetType(SwitchCategory cat, uint8_t idx) +SwitchHwType boardSwitchGetType(uint8_t idx) { - idx = get_switch_index(cat, idx); return _switch_defs[idx].type; } uint8_t boardGetMaxSwitches() { return n_switches; } -uint8_t boardGetMaxFctSwitches() { return n_fct_switches; } -swconfig_t boardSwitchGetDefaultConfig() { return _switch_default_config; } +SwitchConfig boardSwitchGetDefaultConfig(uint8_t idx) { return _switch_defs[idx].defaultType; } +#if defined(FUNCTION_SWITCHES) +bool boardIsCustomSwitch(uint8_t idx) { return _switch_defs[idx].isCustomSwitch; } +uint8_t boardGetCustomSwitchIdx(uint8_t idx) { return _switch_defs[idx].customSwitchIdx; } +#endif + +#if !defined(COLORLCD) switch_display_pos_t switchGetDisplayPosition(uint8_t idx) { if (idx >= DIM(_switch_display)) return {0, 0}; return _switch_display[idx]; } +#endif diff --git a/radio/src/targets/st16/board.h b/radio/src/targets/st16/board.h index 863ead25e..cc95deef4 100644 --- a/radio/src/targets/st16/board.h +++ b/radio/src/targets/st16/board.h @@ -96,19 +96,6 @@ void EXTERNAL_MODULE_OFF(); /*gpio_clear(EXTMODULE_PWR_GPIO)*/ #if defined(FUNCTION_SWITCHES) #define NUM_FUNCTIONS_SWITCHES 6 #define NUM_FUNCTIONS_GROUPS 3 -#define DEFAULT_FS_CONFIG \ - (SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \ - (SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0) - -#define DEFAULT_FS_GROUPS \ - (1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \ - (1 << 0) // Set all FS to group 1 to act like a 6pos - -#define DEFAULT_FS_STARTUP_CONFIG \ - ((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \ - (FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \ - (FS_START_PREVIOUS << 2) + \ - (FS_START_PREVIOUS << 0)) // keep last state by default #else #define NUM_FUNCTIONS_SWITCHES 0 diff --git a/radio/src/targets/st16/bsp_io.cpp b/radio/src/targets/st16/bsp_io.cpp index 0cebfde95..d80a6ded9 100644 --- a/radio/src/targets/st16/bsp_io.cpp +++ b/radio/src/targets/st16/bsp_io.cpp @@ -21,10 +21,11 @@ #include "bsp_io.h" -#include "drivers/pca95xx.h" #include "stm32_i2c_driver.h" #include "stm32_switch_driver.h" +extern const stm32_switch_t* boardGetSwitchDef(uint8_t idx); + #define BSP_IN_I2C_BUS I2C_Bus_2 #define BSP_IN_I2C_ADDR 0x20 @@ -95,45 +96,19 @@ uint16_t bsp_input_get() return inputState; } -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, - SwitchCategory cat, uint8_t idx) +SwitchHwPos boardSwitchGetPosition(uint8_t idx) { + const stm32_switch_t* sw = boardGetSwitchDef(idx); + + if (sw->type == SWITCH_HW_ADC || sw->GPIOx_high != nullptr) + return stm32_switch_get_position(sw); + bool val = false; uint16_t pins = bsp_input_get(); - if (cat == SWITCH_PHYSICAL) { - switch (idx) { - case 6: - val = (pins & BSP_BACK_KEY1) != 0; - break; - case 7: - val = (pins & BSP_BACK_KEY2) != 0; - break; - } - } else if (cat == SWITCH_FUNCTION) { - switch (idx) { - case 0: - val = (pins & BSP_EXT_KEY1) != 0; - break; - case 1: - val = (pins & BSP_EXT_KEY2) != 0; - break; - case 2: - val = (pins & BSP_EXT_KEY3) != 0; - break; - case 3: - val = (pins & BSP_EXT_KEY4) != 0; - break; - case 4: - val = (pins & BSP_EXT_KEY5) != 0; - break; - case 5: - val = (pins & BSP_EXT_KEY6) != 0; - break; - } - } + val = (pins & sw->Pin_high) != 0; - if (sw->flags & SWITCH_HW_INVERTED) val = !val; + if (sw->inverted) val = !val; return val ? SWITCH_HW_UP : SWITCH_HW_DOWN; } diff --git a/radio/src/targets/st16/bsp_io.h b/radio/src/targets/st16/bsp_io.h index c01f33524..6b3259d70 100644 --- a/radio/src/targets/st16/bsp_io.h +++ b/radio/src/targets/st16/bsp_io.h @@ -25,16 +25,6 @@ #include "hal/switch_driver.h" // Input port expander -#define BSP_EXT_KEY1 PCA95XX_PIN_0 -#define BSP_EXT_KEY2 PCA95XX_PIN_1 -#define BSP_EXT_KEY3 PCA95XX_PIN_2 -#define BSP_EXT_KEY4 PCA95XX_PIN_3 -#define BSP_EXT_KEY5 PCA95XX_PIN_4 -#define BSP_EXT_KEY6 PCA95XX_PIN_5 - -#define BSP_BACK_KEY1 PCA95XX_PIN_6 -#define BSP_BACK_KEY2 PCA95XX_PIN_7 - #define BSP_TR1U PCA95XX_PIN_8 #define BSP_TR1D PCA95XX_PIN_9 #define BSP_TR3L PCA95XX_PIN_10 @@ -63,6 +53,3 @@ void bsp_output_set(uint16_t pin); void bsp_output_clear(uint16_t pin); uint16_t bsp_input_get(); -struct stm32_switch_t; -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx); - diff --git a/radio/src/targets/st16/hal.h b/radio/src/targets/st16/hal.h index 108d7c944..f6abdbbd9 100644 --- a/radio/src/targets/st16/hal.h +++ b/radio/src/targets/st16/hal.h @@ -79,12 +79,30 @@ // function switches -#define FUNCTION_SWITCH_1 I2C -#define FUNCTION_SWITCH_2 I2C -#define FUNCTION_SWITCH_3 I2C -#define FUNCTION_SWITCH_4 I2C -#define FUNCTION_SWITCH_5 I2C -#define FUNCTION_SWITCH_6 I2C +#define FUNCTION_SWITCH_1 SK +#define SWITCHES_GPIO_REG_K +#define SWITCHES_GPIO_PIN_K PCA95XX_PIN_0 +#define SWITCHES_K_CFS_IDX 0 +#define FUNCTION_SWITCH_2 SL +#define SWITCHES_GPIO_REG_L +#define SWITCHES_GPIO_PIN_L PCA95XX_PIN_1 +#define SWITCHES_L_CFS_IDX 1 +#define FUNCTION_SWITCH_3 SM +#define SWITCHES_GPIO_REG_M +#define SWITCHES_GPIO_PIN_M PCA95XX_PIN_2 +#define SWITCHES_M_CFS_IDX 2 +#define FUNCTION_SWITCH_4 SN +#define SWITCHES_GPIO_REG_N +#define SWITCHES_GPIO_PIN_N PCA95XX_PIN_3 +#define SWITCHES_N_CFS_IDX 3 +#define FUNCTION_SWITCH_5 SO +#define SWITCHES_GPIO_REG_O +#define SWITCHES_GPIO_PIN_O PCA95XX_PIN_4 +#define SWITCHES_O_CFS_IDX 4 +#define FUNCTION_SWITCH_6 SP +#define SWITCHES_GPIO_REG_P +#define SWITCHES_GPIO_PIN_P PCA95XX_PIN_5 +#define SWITCHES_P_CFS_IDX 5 // Direct switches @@ -92,15 +110,15 @@ #define STORAGE_SWITCH_G #define HARDWARE_SWITCH_G #define SWITCHES_G_2POS -//#define SWITCHES_GPIO_REG_G GPIOI -//#define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_3 // PI.03 +#define SWITCHES_GPIO_REG_G +#define SWITCHES_GPIO_PIN_G PCA95XX_PIN_6 // Key 2 #define STORAGE_SWITCH_H #define HARDWARE_SWITCH_H #define SWITCHES_H_2POS -//#define SWITCHES_GPIO_REG_H GPIOI -//#define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_11 // PI.11 +#define SWITCHES_GPIO_REG_H +#define SWITCHES_GPIO_PIN_H PCA95XX_PIN_7 // Key 3 @@ -402,7 +420,11 @@ // LED Strip #define LED_STRIP_LENGTH 24 -#define LED_STRIP_RESERVED_AT_END 12 +#define BLING_LED_STRIP_START 0 +#define BLING_LED_STRIP_LENGTH 12 +#define CFS_LED_STRIP_START 12 +#define CFS_LED_STRIP_LENGTH 12 +#define CFS_LEDS_PER_SWITCH 2 #define LED_STRIP_GPIO GPIO_PIN(GPIOA, 15) // PA.15 / TIM2_CH1 #define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1/2/16/17 #define LED_STRIP_TIMER TIM2 diff --git a/radio/src/targets/st16/led_driver.cpp b/radio/src/targets/st16/led_driver.cpp index b37de2da2..84c740479 100644 --- a/radio/src/targets/st16/led_driver.cpp +++ b/radio/src/targets/st16/led_driver.cpp @@ -60,20 +60,16 @@ void ledInit() } #if defined(FUNCTION_SWITCHES_RGB_LEDS) -// used to map switch number to led number in the rgbled chain -uint8_t ledMapping[] = {12, 14, 16, 18, 20, 22}; - void fsLedRGB(uint8_t index, uint32_t color) { - rgbSetLedColor(ledMapping[index], GET_RED(color), \ - GET_GREEN(color),GET_BLUE(color)); - rgbSetLedColor(ledMapping[index]+1, GET_RED(color), \ - GET_GREEN(color),GET_BLUE(color)); + index = (index * 2) + CFS_LED_STRIP_START; + rgbSetLedColor(index, GET_RED(color), GET_GREEN(color),GET_BLUE(color)); + rgbSetLedColor(index+1, GET_RED(color), GET_GREEN(color),GET_BLUE(color)); } uint32_t fsGetLedRGB(uint8_t index) { - return rgbGetLedColor(ledMapping[index]); + return rgbGetLedColor((index * 2) + CFS_LED_STRIP_START); } uint8_t getRGBColorIndex(uint32_t color) diff --git a/radio/src/targets/stm32h7s78-dk/bsp_io.h b/radio/src/targets/stm32h7s78-dk/bsp_io.h index b74cedd30..c220d27d1 100644 --- a/radio/src/targets/stm32h7s78-dk/bsp_io.h +++ b/radio/src/targets/stm32h7s78-dk/bsp_io.h @@ -17,5 +17,3 @@ #include "hal/switch_driver.h" #include "stm32_switch_driver.h" - -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx) {return SWITCH_HW_MID;} diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 04576b8f9..d5194c08e 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -96,24 +96,15 @@ enum { #if defined(FUNCTION_SWITCHES) +#if defined(RADIO_GX12) +#define NUM_FUNCTIONS_SWITCHES 8 +#define NUM_FUNCTIONS_GROUPS 4 +#else #define NUM_FUNCTIONS_SWITCHES 6 #define NUM_FUNCTIONS_GROUPS 3 +#endif -#define DEFAULT_FS_CONFIG \ - (SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \ - (SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0) - -#define DEFAULT_FS_GROUPS \ - (1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \ - (1 << 0) // Set all FS to group 1 to act like a 6pos - -#define DEFAULT_FS_STARTUP_CONFIG \ - ((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \ - (FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \ - (FS_START_PREVIOUS << 2) + \ - (FS_START_PREVIOUS << 0)) // keep last state by default - -#else +#else //FUNCTION_SWITCHES #define NUM_FUNCTIONS_SWITCHES 0 diff --git a/radio/src/targets/taranis/bsp_io.h b/radio/src/targets/taranis/bsp_io.h deleted file mode 100644 index b74cedd30..000000000 --- a/radio/src/targets/taranis/bsp_io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#pragma once - -#include "hal/switch_driver.h" -#include "stm32_switch_driver.h" - -SwitchHwPos bsp_get_switch_position(const stm32_switch_t *sw, SwitchCategory cat, uint8_t idx) {return SWITCH_HW_MID;} diff --git a/radio/src/targets/taranis/gx12/bsp_io.cpp b/radio/src/targets/taranis/gx12/bsp_io.cpp index 4256093d3..0041efd8c 100644 --- a/radio/src/targets/taranis/gx12/bsp_io.cpp +++ b/radio/src/targets/taranis/gx12/bsp_io.cpp @@ -19,19 +19,24 @@ * GNU General Public License for more details. */ -#include "bsp_io.h" #include "hal/switch_driver.h" #include "drivers/pca95xx.h" #include "stm32_i2c_driver.h" #include "timers_driver.h" #include "delays_driver.h" #include "stm32_ws2812.h" +#include "stm32_switch_driver.h" #include "os/async.h" #include "os/timer.h" #include "myeeprom.h" +#define IO_INT_GPIO GPIO_PIN(GPIOE, 14) +#define IO_RESET_GPIO GPIO_PIN(GPIOE, 15) + +extern const stm32_switch_t* boardGetSwitchDef(uint8_t idx); + struct bsp_io_expander { pca95xx_t exp; uint32_t mask; @@ -79,8 +84,8 @@ static void _poll_switches(void *param1, uint32_t trigger_source) timer_reset(&_poll_timer); } - bsp_io_read_switches(); - bsp_io_read_fs_switches(); + _read_io_expander(&_io_switches); + _read_io_expander(&_io_fs_switches); } static void _io_int_handler() @@ -126,90 +131,41 @@ int bsp_io_init() gpio_init(IO_RESET_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW); gpio_set(IO_RESET_GPIO); - bsp_io_read_switches(); - bsp_io_read_fs_switches(); + _read_io_expander(&_io_switches); + _read_io_expander(&_io_fs_switches); start_poll_timer(); return 0; } -uint32_t bsp_io_read_switches() -{ - return _read_io_expander(&_io_switches); -} - -uint32_t bsp_io_read_fs_switches() -{ - return _read_io_expander(&_io_fs_switches); -} - void boardInitSwitches() { bsp_io_init(); } -struct bsp_io_sw_def { - uint32_t pin_high; - uint32_t pin_low; -}; - -static constexpr uint32_t RGB_OFFSET = (1 << 16); // first after bspio pins -static uint16_t soft2POSLogicalState = 0xFFFF; - -static const bsp_io_sw_def _switch_defs[] = { - { SWITCH_A, RGB_OFFSET + 7 }, - { SWITCH_B_H, SWITCH_B_L }, - { SWITCH_C_H, SWITCH_C_L }, - { SWITCH_D, RGB_OFFSET + 6 }, - { SWITCH_E_H, SWITCH_E_L }, - { SWITCH_F_H, SWITCH_F_L }, - { SWITCH_G, 0 }, - { SWITCH_H, 0 }, -}; - static SwitchHwPos _get_switch_pos(uint8_t idx) { - static uint32_t oldState = 0; SwitchHwPos pos = SWITCH_HW_UP; - const bsp_io_sw_def* def = &_switch_defs[idx]; + const stm32_switch_t* def = boardGetSwitchDef(idx); uint32_t state = _io_switches.state; - if (def->pin_low > RGB_OFFSET) { - // Potential soft 2pos - if ((SWITCH_CONFIG(idx) == SWITCH_TOGGLE)) { - if ((state & def->pin_high) == 0) { - pos = SWITCH_HW_DOWN; - } - } - else { - if (((state & def->pin_high) == 0) && ((state & def->pin_high) != (oldState & def->pin_high))) { - soft2POSLogicalState ^= def->pin_high; - } - if ((soft2POSLogicalState & def->pin_high) == 0) { - pos = SWITCH_HW_DOWN; - } - else { - pos = SWITCH_HW_UP; - } - - } - - if (pos == SWITCH_HW_UP) { - ws2812_set_color(def->pin_low - RGB_OFFSET, 0x0, 0x0, 0x0); + if (def->isCustomSwitch) { + if ((state & def->Pin_high) == 0) { + return SWITCH_HW_DOWN; } else { - ws2812_set_color(def->pin_low - RGB_OFFSET, 0xFF, 0xFF, 0xFF); + return SWITCH_HW_UP; } } - else if (!def->pin_low) { + else if (!def->Pin_low) { // 2POS switch - if ((state & def->pin_high) == 0) { + if ((state & def->Pin_high) == 0) { pos = SWITCH_HW_DOWN; } } else { - bool hi = state & def->pin_high; - bool lo = state & def->pin_low; + bool hi = state & def->Pin_high; + bool lo = state & def->Pin_low; if (hi && lo) { pos = SWITCH_HW_MID; @@ -218,29 +174,23 @@ static SwitchHwPos _get_switch_pos(uint8_t idx) } } - if (idx == switchGetMaxSwitches() - 1) - oldState = state; - return pos; } static SwitchHwPos _get_fs_switch_pos(uint8_t idx) { + const stm32_switch_t* def = boardGetSwitchDef(idx); uint32_t state = _io_fs_switches.state; - if ((state & (1 << idx)) == 0) { + if ((state & def->Pin_high) == 0) { return SWITCH_HW_DOWN; } else { return SWITCH_HW_UP; } } -SwitchHwPos boardSwitchGetPosition(SwitchCategory cat, uint8_t idx) +SwitchHwPos boardSwitchGetPosition(uint8_t idx) { - if (cat == SWITCH_PHYSICAL) { + if (idx < 8) return _get_switch_pos(idx); - } else if (cat == SWITCH_FUNCTION){ - return _get_fs_switch_pos(idx); - } - - return SWITCH_HW_UP; + return _get_fs_switch_pos(idx); } diff --git a/radio/src/targets/taranis/gx12/bsp_io.h b/radio/src/targets/taranis/gx12/bsp_io.h deleted file mode 100644 index bb1f322ee..000000000 --- a/radio/src/targets/taranis/gx12/bsp_io.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#pragma once - -#include "drivers/pca95xx.h" - -// Port expander 1 (0x74) -#define SWITCH_H PCA95XX_PIN_0 -#define SWITCH_D PCA95XX_PIN_1 - -#define SWITCH_F_H PCA95XX_PIN_3 -#define SWITCH_F_L PCA95XX_PIN_2 - -#define SWITCH_C_L PCA95XX_PIN_4 -#define SWITCH_C_H PCA95XX_PIN_5 - -#define SWITCH_B_H PCA95XX_PIN_10 -#define SWITCH_B_L PCA95XX_PIN_11 - -#define SWITCH_E_H PCA95XX_PIN_12 -#define SWITCH_E_L PCA95XX_PIN_13 - -#define SWITCH_A PCA95XX_PIN_14 -#define SWITCH_G PCA95XX_PIN_15 - -#define IO_INT_GPIO GPIO_PIN(GPIOE, 14) -#define IO_RESET_GPIO GPIO_PIN(GPIOE, 15) - -// Port expander 1 (0x75) -#define FSSWITCH_1 PCA95XX_PIN_0 -#define FSSWITCH_2 PCA95XX_PIN_1 -#define FSSWITCH_3 PCA95XX_PIN_2 -#define FSSWITCH_4 PCA95XX_PIN_3 -#define FSSWITCH_5 PCA95XX_PIN_4 -#define FSSWITCH_6 PCA95XX_PIN_5 - - -int bsp_io_init(); -uint32_t bsp_io_read_switches(); -uint32_t bsp_io_read_fs_switches(); diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index efdcbb584..e89d43e3e 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -645,6 +645,9 @@ #define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_13 // PC.13 #elif defined(RADIO_GX12) #define SWITCHES_A_2POS + #define SWITCHES_A_CFS_IDX 7 + #define SWITCHES_GPIO_REG_A + #define SWITCHES_GPIO_PIN_A PCA95XX_PIN_14 #elif defined(RADIO_T14) || defined(RADIO_T12MAX) #define SWITCHES_GPIO_REG_A GPIOC #define SWITCHES_GPIO_PIN_A LL_GPIO_PIN_5 // PC.05 @@ -747,6 +750,10 @@ #define SWITCHES_GPIO_PIN_B LL_GPIO_PIN_11 // PD.11 #elif defined(RADIO_GX12) #define SWITCHES_B_3POS + #define SWITCHES_GPIO_REG_B_H + #define SWITCHES_GPIO_PIN_B_H PCA95XX_PIN_10 + #define SWITCHES_GPIO_REG_B_L + #define SWITCHES_GPIO_PIN_B_L PCA95XX_PIN_11 #elif defined(RADIO_V14) || defined(RADIO_V12) // ADC based switch #elif defined(PCBX7) @@ -825,6 +832,10 @@ #define SWITCHES_GPIO_PIN_C LL_GPIO_PIN_13 // PC.13 #elif defined(RADIO_GX12) #define SWITCHES_C_3POS + #define SWITCHES_GPIO_REG_C_H + #define SWITCHES_GPIO_PIN_C_H PCA95XX_PIN_5 + #define SWITCHES_GPIO_REG_C_L + #define SWITCHES_GPIO_PIN_C_L PCA95XX_PIN_4 #elif defined(RADIO_V14) || defined(RADIO_V12) // ADC based switch #elif defined(PCBX7) @@ -892,6 +903,9 @@ #define SWITCHES_GPIO_PIN_D LL_GPIO_PIN_3 // PC.03 #elif defined(RADIO_GX12) #define SWITCHES_D_2POS + #define SWITCHES_D_CFS_IDX 6 + #define SWITCHES_GPIO_REG_D + #define SWITCHES_GPIO_PIN_D PCA95XX_PIN_1 #elif defined(RADIO_V14) || defined(RADIO_V12) #define STORAGE_SWITCH_D #define HARDWARE_SWITCH_D @@ -968,6 +982,10 @@ // ADC based switch/pot #elif defined(RADIO_GX12) #define SWITCHES_E_3POS + #define SWITCHES_GPIO_REG_E_H + #define SWITCHES_GPIO_PIN_E_H PCA95XX_PIN_12 + #define SWITCHES_GPIO_REG_E_L + #define SWITCHES_GPIO_PIN_E_L PCA95XX_PIN_13 #elif defined(RADIO_V14) || defined(RADIO_V12) // ADC based switch #elif defined(PCBX7) @@ -1025,12 +1043,16 @@ #define SWITCHES_GPIO_PIN_F LL_GPIO_PIN_5 // PB.05 #elif defined(RADIO_MT12) // ADC based switch/pot -#elif defined(RADIO_T8) || defined(RADIO_TLITE) || defined(RADIO_TPROV2) || defined(RADIO_COMMANDO8) || defined(RADIO_LR3PRO) || defined(RADIO_POCKET) +#elif defined(RADIO_T8) || defined(RADIO_TLITE) || defined(RADIO_COMMANDO8) || defined(RADIO_LR3PRO) || defined(RADIO_POCKET) // no SWF #elif defined(RADIO_T12) // no SWF #elif defined(RADIO_GX12) #define SWITCHES_F_3POS + #define SWITCHES_GPIO_REG_F_H + #define SWITCHES_GPIO_PIN_F_H PCA95XX_PIN_3 + #define SWITCHES_GPIO_REG_F_L + #define SWITCHES_GPIO_PIN_F_L PCA95XX_PIN_2 #elif defined(RADIO_V14) || defined(RADIO_V12) // ADC based switch #elif defined(PCBX7) @@ -1061,6 +1083,7 @@ #define FUNCTION_SWITCH_1 SG #define SWITCHES_GPIO_REG_G GPIOG #define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_7 // PG.07 + #define SWITCHES_G_CFS_IDX 0 #elif defined(RADIO_BUMBLEBEE) #define SWITCHES_GPIO_REG_G GPIOD #define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_15// PD.15 - Left trim push @@ -1070,6 +1093,8 @@ #define SWITCHES_GPIO_PIN_G LL_GPIO_PIN_15 // PD.15 #elif defined(RADIO_GX12) #define SWITCHES_G_2POS + #define SWITCHES_GPIO_REG_G + #define SWITCHES_GPIO_PIN_G PCA95XX_PIN_15 #elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_T8) || defined(RADIO_COMMANDO8) || defined(RADIO_MT12) || defined(RADIO_POCKET) || defined(RADIO_T14) || defined(RADIO_T12MAX) || defined(RADIO_TPROS) // no SWG #else @@ -1099,6 +1124,7 @@ #define FUNCTION_SWITCH_2 SH #define SWITCHES_GPIO_REG_H GPIOG #define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_6 // PG.06 + #define SWITCHES_H_CFS_IDX 1 #elif defined(RADIO_BUMBLEBEE) #define SWITCHES_GPIO_REG_H GPIOF #define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_0 // PF.00 - Right trim push @@ -1106,10 +1132,12 @@ //TRIM right low #define SWITCHES_GPIO_REG_H GPIOF #define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_0 // PF.00 -#elif defined(RADIO_TLITE) || defined(RADIO_TPROV2) || defined(RADIO_TPROS) || defined(RADIO_LR3PRO) +#elif defined(RADIO_TLITE) || defined(RADIO_TPROS) || defined(RADIO_LR3PRO) // no SWH #elif defined(RADIO_GX12) #define SWITCHES_H_2POS + #define SWITCHES_GPIO_REG_H + #define SWITCHES_GPIO_PIN_H PCA95XX_PIN_0 #elif defined(PCBX7) #define SWITCHES_GPIO_REG_H GPIOD #define SWITCHES_GPIO_PIN_H LL_GPIO_PIN_14 // PD.14 @@ -1147,68 +1175,84 @@ #define FUNCTION_SWITCH_1 SI #define SWITCHES_GPIO_REG_I GPIOG #define SWITCHES_GPIO_PIN_I LL_GPIO_PIN_7 // PG.07 + #define SWITCHES_I_CFS_IDX 0 // SW2 #define FUNCTION_SWITCH_2 SJ #define SWITCHES_GPIO_REG_J GPIOG #define SWITCHES_GPIO_PIN_J LL_GPIO_PIN_6 // PG.06 + #define SWITCHES_J_CFS_IDX 1 // SW3 #define FUNCTION_SWITCH_3 SK #define SWITCHES_GPIO_REG_K GPIOG #define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_5 // PG.05 + #define SWITCHES_K_CFS_IDX 2 // SW4 #define FUNCTION_SWITCH_4 SL #define SWITCHES_GPIO_REG_L GPIOG #define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_4 // PG.04 + #define SWITCHES_L_CFS_IDX 3 // SW5 #define FUNCTION_SWITCH_5 SM #define SWITCHES_GPIO_REG_M GPIOG #define SWITCHES_GPIO_PIN_M LL_GPIO_PIN_3 // PG.03 + #define SWITCHES_M_CFS_IDX 4 // SW6 - #define FUNCTION_SWITCH_6 SO - #define SWITCHES_GPIO_REG_O GPIOG - #define SWITCHES_GPIO_PIN_O LL_GPIO_PIN_2 // PG.02 + #define FUNCTION_SWITCH_6 SN + #define SWITCHES_GPIO_REG_N GPIOG + #define SWITCHES_GPIO_PIN_N LL_GPIO_PIN_2 // PG.02 + #define SWITCHES_N_CFS_IDX 5 #elif defined(RADIO_BUMBLEBEE) // SW1 #define FUNCTION_SWITCH_1 SJ #define SWITCHES_GPIO_REG_J GPIOE #define SWITCHES_GPIO_PIN_J LL_GPIO_PIN_15 // PE.15 + #define SWITCHES_J_CFS_IDX 0 // SW2 #define FUNCTION_SWITCH_2 SK #define SWITCHES_GPIO_REG_K GPIOE #define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_14 // PE.14 + #define SWITCHES_K_CFS_IDX 1 // SW3 #define FUNCTION_SWITCH_3 SL #define SWITCHES_GPIO_REG_L GPIOE #define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_13 // PE.13 + #define SWITCHES_L_CFS_IDX 2 // SW4 #define FUNCTION_SWITCH_4 SM #define SWITCHES_GPIO_REG_M GPIOE #define SWITCHES_GPIO_PIN_M LL_GPIO_PIN_10 // PE.10 + #define SWITCHES_M_CFS_IDX 3 // SW5 #define FUNCTION_SWITCH_5 SO #define SWITCHES_GPIO_REG_O GPIOE #define SWITCHES_GPIO_PIN_O LL_GPIO_PIN_8 // PE.08 + #define SWITCHES_O_CFS_IDX 4 // SW6 #define FUNCTION_SWITCH_6 SP #define SWITCHES_GPIO_REG_P GPIOE #define SWITCHES_GPIO_PIN_P LL_GPIO_PIN_12 // PE.12 + #define SWITCHES_P_CFS_IDX 5 #elif defined(RADIO_TPRO) // SW3 #define FUNCTION_SWITCH_3 SI #define SWITCHES_GPIO_REG_I GPIOG #define SWITCHES_GPIO_PIN_I LL_GPIO_PIN_5 // PG.05 + #define SWITCHES_I_CFS_IDX 2 // SW4 #define FUNCTION_SWITCH_4 SJ #define SWITCHES_GPIO_REG_J GPIOG #define SWITCHES_GPIO_PIN_J LL_GPIO_PIN_4 // PG.04 + #define SWITCHES_J_CFS_IDX 3 // SW5 #define FUNCTION_SWITCH_5 SK #define SWITCHES_GPIO_REG_K GPIOG #define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_3 // PG.03 + #define SWITCHES_K_CFS_IDX 4 // SW6 #define FUNCTION_SWITCH_6 SL #define SWITCHES_GPIO_REG_L GPIOG #define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_2 // PG.02 + #define SWITCHES_L_CFS_IDX 5 #elif defined(RADIO_FAMILY_T20) //TRIM left up #define SWITCHES_GPIO_REG_I GPIOG @@ -1230,41 +1274,65 @@ #define FUNCTION_SWITCH_1 SK #define SWITCHES_GPIO_REG_K GPIOE #define SWITCHES_GPIO_PIN_K LL_GPIO_PIN_10 // PE.10 + #define SWITCHES_K_CFS_IDX 0 //SW2 #define FUNCTION_SWITCH_2 SL #define SWITCHES_GPIO_REG_L GPIOE #define SWITCHES_GPIO_PIN_L LL_GPIO_PIN_8 // PE.08 + #define SWITCHES_L_CFS_IDX 1 //SW3 #define FUNCTION_SWITCH_3 SM #define SWITCHES_GPIO_REG_M GPIOE #define SWITCHES_GPIO_PIN_M LL_GPIO_PIN_12 // PE.12 + #define SWITCHES_M_CFS_IDX 2 //SW4 #define FUNCTION_SWITCH_4 SN #define SWITCHES_GPIO_REG_N GPIOE #define SWITCHES_GPIO_PIN_N LL_GPIO_PIN_13 // PE.13 + #define SWITCHES_N_CFS_IDX 3 //SW5 #define FUNCTION_SWITCH_5 SO #define SWITCHES_GPIO_REG_O GPIOE #define SWITCHES_GPIO_PIN_O LL_GPIO_PIN_14 // PE.14 + #define SWITCHES_O_CFS_IDX 4 //SW6 #define FUNCTION_SWITCH_6 SP #define SWITCHES_GPIO_REG_P GPIOE #define SWITCHES_GPIO_PIN_P LL_GPIO_PIN_15 // PE.15 + #define SWITCHES_P_CFS_IDX 5 #endif #if defined(RADIO_GX12) //SW1 - #define FUNCTION_SWITCH_1 + #define SWITCHES_GPIO_REG_I + #define SWITCHES_GPIO_PIN_I PCA95XX_PIN_0 + #define SWITCHES_I_CFS_IDX 0 + #define FUNCTION_SWITCH_1 SI //SW2 - #define FUNCTION_SWITCH_2 + #define SWITCHES_GPIO_REG_J + #define SWITCHES_GPIO_PIN_J PCA95XX_PIN_1 + #define SWITCHES_J_CFS_IDX 1 + #define FUNCTION_SWITCH_2 SJ //SW3 - #define FUNCTION_SWITCH_3 + #define SWITCHES_GPIO_REG_K + #define SWITCHES_GPIO_PIN_K PCA95XX_PIN_2 + #define SWITCHES_K_CFS_IDX 2 + #define FUNCTION_SWITCH_3 SK //SW4 - #define FUNCTION_SWITCH_4 + #define SWITCHES_GPIO_REG_L + #define SWITCHES_GPIO_PIN_L PCA95XX_PIN_3 + #define SWITCHES_L_CFS_IDX 3 + #define FUNCTION_SWITCH_4 SL //SW5 - #define FUNCTION_SWITCH_5 + #define SWITCHES_GPIO_REG_M + #define SWITCHES_GPIO_PIN_M PCA95XX_PIN_4 + #define SWITCHES_M_CFS_IDX 4 + #define FUNCTION_SWITCH_5 SM //SW6 - #define FUNCTION_SWITCH_6 + #define SWITCHES_GPIO_REG_N + #define SWITCHES_GPIO_PIN_N PCA95XX_PIN_5 + #define SWITCHES_N_CFS_IDX 5 + #define FUNCTION_SWITCH_6 SN #endif #if defined(PCBX9E) @@ -1979,9 +2047,15 @@ #if defined(RGBLEDS) #if defined(RADIO_GX12) #define LED_STRIP_LENGTH 8 - #define RGB_LED_OFFSET 8 + #define BLING_LED_STRIP_START 0 + #define BLING_LED_STRIP_LENGTH 0 + #define CFS_LED_STRIP_START 0 + #define CFS_LED_STRIP_LENGTH 8 + #define CFS_LEDS_PER_SWITCH 1 #else #define LED_STRIP_LENGTH 7 + #define BLING_LED_STRIP_START 0 + #define BLING_LED_STRIP_LENGTH 7 #endif #define LED_STRIP_GPIO GPIO_PIN(GPIOA, 8) // PA.08 / TIM1_CH1 #define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1 / TIM2 @@ -1997,10 +2071,14 @@ #elif defined(RADIO_T14) || defined(RADIO_V14) || defined(RADIO_V12) #if defined(RADIO_V14) #define LED_STRIP_LENGTH 38 + #define BLING_LED_STRIP_START 6 + #define BLING_LED_STRIP_LENGTH 32 #elif defined(RADIO_V12) - #define LED_STRIP_LENGTH 6 + #define LED_STRIP_LENGTH 6 // 6POS switches only? #else #define LED_STRIP_LENGTH 1 + #define BLING_LED_STRIP_START 0 + #define BLING_LED_STRIP_LENGTH 1 #endif #define LED_STRIP_GPIO GPIO_PIN(GPIOA, 10) // PA.10 / TIM1_CH3 #define LED_STRIP_GPIO_AF LL_GPIO_AF_1 diff --git a/radio/src/targets/taranis/led_driver.cpp b/radio/src/targets/taranis/led_driver.cpp index 8f98d31e3..e0561ba89 100644 --- a/radio/src/targets/taranis/led_driver.cpp +++ b/radio/src/targets/taranis/led_driver.cpp @@ -60,18 +60,15 @@ void ledInit() } #if defined(FUNCTION_SWITCHES_RGB_LEDS) -// used to map switch number to led number in the rgbled chain -uint8_t ledMapping[] = {0, 1, 2, 3, 4, 5, 6}; - void fsLedRGB(uint8_t index, uint32_t color) { - ws2812_set_color(ledMapping[index], GET_RED(color), GET_GREEN(color), + ws2812_set_color(index + CFS_LED_STRIP_START, GET_RED(color), GET_GREEN(color), GET_BLUE(color)); } uint32_t fsGetLedRGB(uint8_t index) { - return rgbGetLedColor(ledMapping[index]); + return rgbGetLedColor(index + CFS_LED_STRIP_START); } uint8_t getRGBColorIndex(uint32_t color) diff --git a/radio/src/tests/functions.cpp b/radio/src/tests/functions.cpp index 112c78b3c..f741fe817 100644 --- a/radio/src/tests/functions.cpp +++ b/radio/src/tests/functions.cpp @@ -21,7 +21,7 @@ #include "gtests.h" -class SpecialFunctionsTest : public OpenTxTest {}; +class SpecialFunctionsTest : public EdgeTxTest {}; TEST_F(SpecialFunctionsTest, SwitchFiledSize) { @@ -38,22 +38,27 @@ TEST_F(SpecialFunctionsTest, SwitchFiledSize) TEST_F(SpecialFunctionsTest, FlightReset) { - g_model.customFn[0].swtch = SWSRC_FIRST_SWITCH; + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + int swPos = (sw * 3) + SWSRC_FIRST_SWITCH; + + g_model.customFn[0].swtch = swPos; g_model.customFn[0].func = FUNC_RESET; g_model.customFn[0].all.val = FUNC_RESET_FLIGHT; g_model.customFn[0].active = true; - mainRequestFlags = 0; - simuSetSwitch(0, 0); - EXPECT_EQ(false, getSwitch(SWSRC_FIRST_SWITCH)); + simuSetSwitch(sw, 0); + EXPECT_EQ(false, getSwitch(swPos)); evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ((bool)(mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)), false); // now trigger SA0 - simuSetSwitch(0, -1); - EXPECT_EQ(true, getSwitch(SWSRC_FIRST_SWITCH)); + simuSetSwitch(sw, -1); + EXPECT_EQ(true, getSwitch(swPos)); // flightReset() should be called evalFunctions(g_model.customFn, modelFunctionsContext); @@ -68,9 +73,15 @@ TEST_F(SpecialFunctionsTest, FlightReset) #if defined(GVARS) TEST_F(SpecialFunctionsTest, GvarsInc) { - simuSetSwitch(0, 0); // SA- + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + int swPos = (sw * 3) + SWSRC_FIRST_SWITCH; - g_model.customFn[0].swtch = SWSRC_FIRST_SWITCH; + simuSetSwitch(sw, 0); // SA- + + g_model.customFn[0].swtch = swPos; g_model.customFn[0].func = FUNC_ADJUST_GVAR; g_model.customFn[0].all.mode = FUNC_ADJUST_GVAR_INCDEC; g_model.customFn[0].all.param = 0; // GV1 @@ -82,39 +93,39 @@ TEST_F(SpecialFunctionsTest, GvarsInc) EXPECT_EQ(g_model.flightModeData[0].gvars[0], 10); // now trigger SA0 - simuSetSwitch(0, -1); // SAdown + simuSetSwitch(sw, -1); // SAdown evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); - simuSetSwitch(0, 0); // SA- + simuSetSwitch(sw, 0); // SA- evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); - simuSetSwitch(0, -1); // SAdown + simuSetSwitch(sw, -1); // SAdown evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); - simuSetSwitch(0, 0); // SA- + simuSetSwitch(sw, 0); // SA- evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); g_model.customFn[0].all.val = 10; // inc/dec value - simuSetSwitch(0, -1); // SAdown + simuSetSwitch(sw, -1); // SAdown evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); - simuSetSwitch(0, 0); // SA- + simuSetSwitch(sw, 0); // SA- evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); - simuSetSwitch(0, -1); // SAdown + simuSetSwitch(sw, -1); // SAdown evalFunctions(g_model.customFn, modelFunctionsContext); EXPECT_EQ(g_model.flightModeData[0].gvars[0], 28); evalFunctions(g_model.customFn, modelFunctionsContext); diff --git a/radio/src/tests/gtests.cpp b/radio/src/tests/gtests.cpp index e822c934a..5f53be78b 100644 --- a/radio/src/tests/gtests.cpp +++ b/radio/src/tests/gtests.cpp @@ -129,6 +129,14 @@ uint16_t simu_get_analog(uint8_t idx) void simuQueueAudio(const uint8_t*, uint32_t) {} +void fsLedOn(uint8_t idx) +{ +} + +void fsLedOff(uint8_t idx) +{ +} + static char _stringResult[200]; const char * nchar2string(const char * string, int size) diff --git a/radio/src/tests/gtests.h b/radio/src/tests/gtests.h index 70be42f36..af213581b 100644 --- a/radio/src/tests/gtests.h +++ b/radio/src/tests/gtests.h @@ -44,8 +44,27 @@ extern const char * nchar2string(const char * string, int size); #define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string))) #define EXPECT_STRNEQ(c_string, n_string) EXPECT_STREQ(c_string, nchar2string(n_string, sizeof(n_string))) +#if defined(RADIO_GX12) #define RADIO_RESET() \ - g_eeGeneral.switchConfig = 0x00007bff + g_eeGeneral.switchSetType(0, SWITCH_2POS); \ + g_eeGeneral.switchSetType(1, SWITCH_3POS); \ + g_eeGeneral.switchSetType(2, SWITCH_3POS); \ + g_eeGeneral.switchSetType(3, SWITCH_2POS); \ + g_eeGeneral.switchSetType(4, SWITCH_3POS); \ + g_eeGeneral.switchSetType(5, SWITCH_2POS); \ + g_eeGeneral.switchSetType(6, SWITCH_TOGGLE); \ + g_eeGeneral.switchSetType(7, SWITCH_TOGGLE) +#else +#define RADIO_RESET() \ + g_eeGeneral.switchSetType(0, SWITCH_3POS); \ + g_eeGeneral.switchSetType(1, SWITCH_3POS); \ + g_eeGeneral.switchSetType(2, SWITCH_3POS); \ + g_eeGeneral.switchSetType(3, SWITCH_3POS); \ + g_eeGeneral.switchSetType(4, SWITCH_3POS); \ + g_eeGeneral.switchSetType(5, SWITCH_2POS); \ + g_eeGeneral.switchSetType(6, SWITCH_3POS); \ + g_eeGeneral.switchSetType(7, SWITCH_TOGGLE) +#endif inline void SYSTEM_RESET() { @@ -54,7 +73,7 @@ inline void SYSTEM_RESET() #endif generalDefault(); g_eeGeneral.templateSetup = 0; - for (int i=0; i= switchGetMaxAllSwitches()) return; + g_model.mixData[0].destCh = 0; g_model.mixData[0].mltpx = MLTPX_ADD; - g_eeGeneral.switchConfig = 0x03; - g_model.mixData[0].srcRaw = MIXSRC_FIRST_SWITCH; - int switchIndex = 0; + g_model.mixData[0].srcRaw = sw + MIXSRC_FIRST_SWITCH; g_model.mixData[0].weight = makeSourceNumVal(100); g_model.mixData[0].speedUp = 50; g_model.mixData[0].speedDown = 50; s_mixer_first_run_done = true; - simuSetSwitch(switchIndex, -1); + simuSetSwitch(sw, -1); CHECK_SLOW_MOVEMENT(0, -1, 250, 500); EXPECT_EQ(chans[0], -CHANNEL_MAX); - simuSetSwitch(switchIndex, 1); + simuSetSwitch(sw, 1); CHECK_SLOW_MOVEMENT(0, +1, 500, 500); } @@ -755,11 +759,15 @@ TEST_F(MixerTest, SlowOnPhasePrec10ms) TEST_F(MixerTest, SlowOnSwitchSourcePrec10ms) { + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + if (sw >= switchGetMaxAllSwitches()) return; + g_model.mixData[0].destCh = 0; g_model.mixData[0].mltpx = MLTPX_ADD; - g_eeGeneral.switchConfig = 0x03; - g_model.mixData[0].srcRaw = MIXSRC_FIRST_SWITCH; - int switchIndex = 0; + g_model.mixData[0].srcRaw = sw + MIXSRC_FIRST_SWITCH; g_model.mixData[0].weight = makeSourceNumVal(100); g_model.mixData[0].speedUp = 50; g_model.mixData[0].speedDown = 50; @@ -767,11 +775,11 @@ TEST_F(MixerTest, SlowOnSwitchSourcePrec10ms) s_mixer_first_run_done = true; - simuSetSwitch(switchIndex, -1); + simuSetSwitch(sw, -1); CHECK_SLOW_MOVEMENT(0, -1, 25, 50); EXPECT_EQ(chans[0], -CHANNEL_MAX); - simuSetSwitch(switchIndex, 1); + simuSetSwitch(sw, 1); CHECK_SLOW_MOVEMENT(0, +1, 50, 50); } @@ -790,61 +798,66 @@ TEST_F(MixerTest, SlowDisabledOnStartup) TEST_F(MixerTest, DelayOnSwitch) { + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + if (sw >= switchGetMaxAllSwitches()) return; + int swPos = (sw * 3) + SWSRC_FIRST_SWITCH + 2; + g_model.mixData[0].destCh = 0; g_model.mixData[0].mltpx = MLTPX_ADD; g_model.mixData[0].srcRaw = MIXSRC_MAX; g_model.mixData[0].weight = makeSourceNumVal(100); - g_model.mixData[0].swtch = SWSRC_FIRST_SWITCH + 2; + g_model.mixData[0].swtch = swPos; g_model.mixData[0].delayUp = 50; g_model.mixData[0].delayDown = 50; - int switch_index = 0; - simuSetSwitch(switch_index, -1); + simuSetSwitch(sw, -1); evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); - simuSetSwitch(switch_index, 1); + simuSetSwitch(sw, 1); CHECK_DELAY(0, 500); evalFlightModeMixes(e_perout_mode_normal, 1); EXPECT_EQ(chans[0], CHANNEL_MAX); - auto sw_cfg = (SwitchConfig)SWITCH_CONFIG(switch_index); - if (sw_cfg == SWITCH_3POS) { - simuSetSwitch(switch_index, 0); - CHECK_DELAY(0, 500); + simuSetSwitch(sw, 0); + CHECK_DELAY(0, 500); - evalFlightModeMixes(e_perout_mode_normal, 1); - EXPECT_EQ(chans[0], 0); - } + evalFlightModeMixes(e_perout_mode_normal, 1); + EXPECT_EQ(chans[0], 0); } TEST_F(MixerTest, DelayOnSwitch2) { - g_eeGeneral.switchConfig = SWITCH_3POS; - + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + if (sw >= switchGetMaxAllSwitches()) return; + g_model.mixData[0].destCh = 0; g_model.mixData[0].mltpx = MLTPX_ADD; - g_model.mixData[0].srcRaw = MIXSRC_FIRST_SWITCH; + g_model.mixData[0].srcRaw = sw + MIXSRC_FIRST_SWITCH; g_model.mixData[0].weight = makeSourceNumVal(100); - // g_model.mixData[0].swtch = SWSRC_ON; g_model.mixData[0].delayUp = 50; g_model.mixData[0].delayDown = 50; - int switch_index = 0; - simuSetSwitch(switch_index, -1); + simuSetSwitch(sw, -1); evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); - simuSetSwitch(switch_index, 1); + simuSetSwitch(sw, 1); CHECK_DELAY(0, 500); evalFlightModeMixes(e_perout_mode_normal, 1); EXPECT_EQ(chans[0], CHANNEL_MAX); - simuSetSwitch(switch_index, 0); + simuSetSwitch(sw, 0); CHECK_DELAY(0, 500); evalFlightModeMixes(e_perout_mode_normal, 1); @@ -1018,11 +1031,18 @@ TEST(Trainer, UnpluggedTest) TEST_F(MixerTest, flightModeTransition) { + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + if (sw >= switchGetMaxAllSwitches()) return; + int swPos = (sw * 3) + SWSRC_FIRST_SWITCH + 2; + SYSTEM_RESET(); MODEL_RESET(); MIXER_RESET(); setModelDefaults(); - g_model.flightModeData[1].swtch = SWSRC_FIRST_SWITCH + 2; + g_model.flightModeData[1].swtch = swPos; g_model.flightModeData[0].fadeIn = 100; g_model.flightModeData[0].fadeOut = 100; g_model.flightModeData[1].fadeIn = 100; @@ -1038,7 +1058,7 @@ TEST_F(MixerTest, flightModeTransition) g_model.mixData[1].flightModes = 0b11101; g_model.mixData[1].weight = makeSourceNumVal(-10); evalMixes(1); - simuSetSwitch(0, 1); + simuSetSwitch(sw, 1); CHECK_FLIGHT_MODE_TRANSITION(0, 1000, 1024, -102); } diff --git a/radio/src/tests/switches.cpp b/radio/src/tests/switches.cpp index 796813d0c..089079ada 100644 --- a/radio/src/tests/switches.cpp +++ b/radio/src/tests/switches.cpp @@ -47,22 +47,28 @@ TEST(getSwitch, OldTypeStickyCSW) MODEL_RESET(); MIXER_RESET(); - setLogicalSwitch(0, LS_FUNC_AND, SWSRC_FIRST_SWITCH, SWSRC_NONE); + int sw; + for (sw = 0; sw < switchGetMaxAllSwitches(); sw += 1) + if (g_model.getSwitchType(sw) == SWITCH_3POS) + break; + int swPos = (sw * 3) + SWSRC_FIRST_SWITCH; + + setLogicalSwitch(0, LS_FUNC_AND, swPos, SWSRC_NONE); setLogicalSwitch(1, LS_FUNC_OR, SWSRC_SW1, SWSRC_SW2); - simuSetSwitch(0, 0); + simuSetSwitch(sw, 0); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); // now trigger SA0, both switches should become true - simuSetSwitch(0, -1); + simuSetSwitch(sw, -1); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); EXPECT_EQ(getSwitch(SWSRC_SW2), true); // now release SA0 and SW2 should stay true - simuSetSwitch(0, 0); + simuSetSwitch(sw, 0); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), true); @@ -135,38 +141,41 @@ TEST(evalLogicalSwitches, playFile) #undef MODELNAME } -#define SWSRC_SA2 (SWSRC_FIRST_SWITCH + 2) -#define SWSRC_SD2 (SWSRC_FIRST_SWITCH + 3 * 3 + 2) - TEST(getSwitch, edgeInstant) { - if (switchGetMaxSwitches() < 6) return; + int sw1, sw2; + for (sw1 = 0; sw1 < switchGetMaxAllSwitches(); sw1 += 1) + if (g_model.getSwitchType(sw1) == SWITCH_3POS) + break; + for (sw2 = sw1 + 1; sw2 < switchGetMaxAllSwitches(); sw2 += 1) + if (g_model.getSwitchType(sw2) == SWITCH_3POS) + break; + int sw1Pos = (sw1 * 3) + SWSRC_FIRST_SWITCH; + int sw2Pos = (sw2 * 3) + SWSRC_FIRST_SWITCH; MODEL_RESET(); MIXER_RESET(); - // LS1 setup: EDGE SDup (0:instant) - // LS2 setup: (EDGE SDup (0:instant)) AND SAup - setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SD2, -129, -1); - setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SD2, -129, -1, 0, 0, SWSRC_SA2); + // LS1 setup: EDGE SD down (0:instant) + // LS2 setup: (EDGE SD down (0:instant)) AND SA down + setLogicalSwitch(0, LS_FUNC_EDGE, sw2Pos + 2, -129, -1); + setLogicalSwitch(1, LS_FUNC_EDGE, sw2Pos + 2, -129, -1, 0, 0, sw1Pos + 2); - simuSetSwitch(0, -1); //SA down - simuSetSwitch(3, 0); //SD down - // EXPECT_EQ(getSwitch(SWSRC_SD2), false); + simuSetSwitch(sw1, -1); //SA up + simuSetSwitch(sw2, 0); //SD mid logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - // now trigger SFup, LS1 should become true - simuSetSwitch(3, 1); //SD up - // EXPECT_EQ(getSwitch(SWSRC_SD2), true); + // now trigger SD donw, LS1 should become true + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - // now release SA0 and SW2 should stay true - simuSetSwitch(3, 0); //SD down + // now release SD and LS1 should become false + simuSetSwitch(sw2, 0); //SD mid logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); @@ -179,27 +188,24 @@ TEST(getSwitch, edgeInstant) EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); + // second part with SA down - // second part with SAup - - simuSetSwitch(0, 1); //SA up - simuSetSwitch(3, 0); //SD down - // EXPECT_EQ(getSwitch(SWSRC_SD2), false); + simuSetSwitch(sw1, 1); //SA down + simuSetSwitch(sw2, 0); //SD mid logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - // now trigger SFup, LS1 should become true - simuSetSwitch(3, 1); //SD up - // EXPECT_EQ(getSwitch(SWSRC_SD2), true); + // now trigger SD down, LS1 & LS2 should become true + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); EXPECT_EQ(getSwitch(SWSRC_SW2), true); - // now release SA0 and SW2 should stay true - simuSetSwitch(3, 0); //SD down + // now release SA and LS1 & LS2 should stay false + simuSetSwitch(sw2, 0); //SD mid logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); @@ -213,23 +219,23 @@ TEST(getSwitch, edgeInstant) EXPECT_EQ(getSwitch(SWSRC_SW2), false); // now bug #2939 - // SD is kept up and SA is toggled - simuSetSwitch(0, -1); //SA down - simuSetSwitch(3, 1); //SD up + // SD is kept down and SA is toggled + simuSetSwitch(sw1, -1); //SA up + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(0, 1); //SA up - simuSetSwitch(3, 1); //SD up + simuSetSwitch(sw1, 1); //SA down + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(0, -1); //SA down - simuSetSwitch(3, 1); //SD up + simuSetSwitch(sw1, -1); //SA up + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); @@ -238,8 +244,8 @@ TEST(getSwitch, edgeInstant) //test what happens when EDGE condition is true and //logical switches are reset - the switch should fire again - simuSetSwitch(0, 1); //SA up - simuSetSwitch(3, 1); //SD up + simuSetSwitch(sw1, 1); //SA down + simuSetSwitch(sw2, 1); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); //switch will not trigger, because SF was already up @@ -259,30 +265,38 @@ TEST(getSwitch, edgeInstant) TEST(getSwitch, edgeRelease) { - if (switchGetMaxSwitches() < 6) return; - + int sw1, sw2; + for (sw1 = 0; sw1 < switchGetMaxAllSwitches(); sw1 += 1) + if (g_model.getSwitchType(sw1) == SWITCH_3POS) + break; + for (sw2 = sw1 + 1; sw2 < switchGetMaxAllSwitches(); sw2 += 1) + if (g_model.getSwitchType(sw2) == SWITCH_3POS) + break; + int sw1Pos = (sw1 * 3) + SWSRC_FIRST_SWITCH; + int sw2Pos = (sw2 * 3) + SWSRC_FIRST_SWITCH; + MODEL_RESET(); MIXER_RESET(); // test for issue #2728 // LS1 setup: EDGE SDup (0:release) // LS2 setup: (EDGE SDup (0:release)) AND SAup - setLogicalSwitch(0, LS_FUNC_EDGE, SWSRC_SD2, -129, 0); - setLogicalSwitch(1, LS_FUNC_EDGE, SWSRC_SD2, -129, 0, 0, 0, SWSRC_SA2 ); + setLogicalSwitch(0, LS_FUNC_EDGE, sw2Pos + 2, -129, 0); + setLogicalSwitch(1, LS_FUNC_EDGE, sw2Pos + 2, -129, 0, 0, 0, sw1Pos + 2 ); - simuSetSwitch(0, -1); //SA down - simuSetSwitch(3, 0); //SD down + simuSetSwitch(sw1, -1); //SA down + simuSetSwitch(sw2, 0); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(3, 1); //SD up + simuSetSwitch(sw2, 1); //SD up logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(3, 0); //SD down + simuSetSwitch(sw2, 0); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); @@ -290,20 +304,20 @@ TEST(getSwitch, edgeRelease) // second part with SAup - simuSetSwitch(0, 1); //SA up - simuSetSwitch(3, 0); //SD down + simuSetSwitch(sw1, 1); //SA up + simuSetSwitch(sw2, 0); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(3, 1); //SD up + simuSetSwitch(sw2, 1); //SD up logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), false); EXPECT_EQ(getSwitch(SWSRC_SW2), false); - simuSetSwitch(3, 0); //SD down + simuSetSwitch(sw2, 0); //SD down logicalSwitchesTimerTick(); evalLogicalSwitches(); EXPECT_EQ(getSwitch(SWSRC_SW1), true); @@ -327,7 +341,7 @@ TEST(FlexSwitches, switchGetPosition) switchInit(); auto sw_idx = boardGetMaxSwitches(); - auto sw_name = switchGetName(sw_idx); + auto sw_name = switchGetDefaultName(sw_idx); EXPECT_STREQ("FL1", sw_name); EXPECT_FALSE(switchIsFlexValid(sw_idx)); @@ -358,8 +372,8 @@ TEST(FlexSwitches, getValue) auto sw_idx = boardGetMaxSwitches(); switchConfigFlex(sw_idx, 0); - g_eeGeneral.switchConfig = (swconfig_t)SWITCH_3POS << (sw_idx * SW_CFG_BITS); - EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(sw_idx)); + g_eeGeneral.switchSetType(sw_idx, SWITCH_3POS); + EXPECT_EQ(SWITCH_3POS, g_model.getSwitchType(sw_idx)); auto offset = adcGetInputOffset(ADC_INPUT_FLEX); anaSetFiltered(offset, -1024); @@ -371,8 +385,8 @@ TEST(FlexSwitches, getValue) anaSetFiltered(offset, +1024); EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx)); - g_eeGeneral.switchConfig = (swconfig_t)SWITCH_2POS << (sw_idx * SW_CFG_BITS); - EXPECT_EQ(SWITCH_2POS, SWITCH_CONFIG(sw_idx)); + g_eeGeneral.switchSetType(sw_idx, SWITCH_2POS); + EXPECT_EQ(SWITCH_2POS, g_model.getSwitchType(sw_idx)); anaSetFiltered(offset, -1024); EXPECT_EQ(-1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx)); @@ -395,8 +409,8 @@ TEST(FlexSwitches, getSwitch) auto sw_idx = boardGetMaxSwitches(); switchConfigFlex(sw_idx, 0); - g_eeGeneral.switchConfig = (swconfig_t)SWITCH_3POS << (sw_idx * SW_CFG_BITS); - EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(sw_idx)); + g_eeGeneral.switchSetType(sw_idx, SWITCH_3POS); + EXPECT_EQ(SWITCH_3POS, g_model.getSwitchType(sw_idx)); auto offset = adcGetInputOffset(ADC_INPUT_FLEX); anaSetFiltered(offset, -1024); diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 38671688a..9b22cc3f0 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -170,8 +170,7 @@ const char STR_MS[] = TR_MS; const char STR_SWITCH[] = TR_SWITCH; #if defined(FUNCTION_SWITCHES) const char STR_GROUPS[] = TR_GROUPS; -const char STR_FS_ON_COLOR[] = TR_FS_ON_COLOR; -const char STR_FS_OFF_COLOR[] = TR_FS_OFF_COLOR; +const char STR_LUA_OVERRIDE[] = TR_LUA_OVERRIDE; const char STR_LAST[] = TR_LAST; const char STR_MORE_INFO[] = TR_MORE_INFO; const char STR_SWITCH_TYPE[] = TR_SWITCH_TYPE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 370771031..80db8c291 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -295,8 +295,7 @@ extern const char STR_MS[]; extern const char STR_SWITCH[]; extern const char STR_FUNCTION_SWITCHES[]; extern const char STR_GROUP[]; -extern const char STR_FS_ON_COLOR[]; -extern const char STR_FS_OFF_COLOR[]; +extern const char STR_LUA_OVERRIDE[]; extern const char* const STR_FS_COLOR_LIST[]; extern const char STR_GROUP_ALWAYS_ON[]; extern const char STR_GROUPS[]; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index 1b8d9bec3..ae6abc66a 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -50,7 +50,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "调试","回传镜像","回传输入","SBUS教练","LUA脚本","CLI","GPS","Debug","SpaceMouse","外置发射" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "无","回弹","2段","3段","全局" +#else #define TR_SWTYPES "无","回弹","2段","3段" +#endif #define TR_POTTYPES "无","无中点旋钮",TR("中点旋钮","有中点旋钮"),"侧滑块",TR("多段","多段按键"),"X 轴","Y 轴","开关" #define TR_VPERSISTENT "禁用","随飞行记录复位","随手动复位" #define TR_COUNTRY_CODES "美国","日本","欧洲" @@ -289,8 +293,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/cz.h b/radio/src/translations/cz.h index 8bf01469b..94c1e2110 100644 --- a/radio/src/translations/cz.h +++ b/radio/src/translations/cz.h @@ -53,7 +53,11 @@ #define TR_TRNMODE "X","Sečíst","Zaměnit" #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "VYP","Telemetrie zrcadlení","Telemetrie vstup","SBUS Trenér","LUA","CLI","GPS","Debug","SpaceMouse","Externí modul" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Žádný","Bez aretace","2-polohový","3-polohový","Globální" +#else #define TR_SWTYPES "Žádný","Bez aretace","2-polohový","3-polohový" +#endif #define TR_POTTYPES "Žádný",TR("Pot","Potenciometr"),TR("Pot s aret.","Pot s aretací"),"Slider",TR("Vícepol př.","Vícepol. přep."),"Osa X","Osa Y","Přepínač" #define TR_VPERSISTENT "Ne","V rámci letu","Reset ručně" #define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japonsko"),TR("EU","Evropa") @@ -302,8 +306,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index 0c92afead..73cdd9945 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -51,10 +51,10 @@ #define TR_TRNCHN "KA1","KA2","KA3","KA4" #define TR_AUX_SERIAL_MODES "FRA","Telem spejlet","Telemetri ind","SBUS træner","LUA","CLI","GPS","Debug","SpaceMouse","Eksternt modul" -#if !NARROW_LAYOUT - #define TR_SWTYPES "Ingen", "2 pos skift","2 position","3 position" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Ingen", "2 pos skift","2 position","3 position","Global" #else - #define TR_SWTYPES "Ingen","Skift","2POS","3POS" +#define TR_SWTYPES "Ingen", "2 pos skift","2 position","3 position" #endif #define TR_POTTYPES "Ingen",TR("Drejek.", "Drejekontakt"),TR("Drejek./klik","Drejekontakt med klik"),"Skyder",TR("Multipos","Multipos kontakt"),"Axis X","Axis Y","Switch" @@ -296,8 +296,7 @@ #define TR_FS_COLOR_LIST "Bruger","Fra","Hvid","Rød","Grøn","Gul","Orange","Blå","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Altid til" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Altid til gruppe" #define TR_LAST "Sidste" #define TR_MORE_INFO "Mere info" diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index b30618f98..acdf50a87 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -53,7 +53,11 @@ #define TR_TRNMODE "AUS",TR("+=","Addiere"),TR(":=","Ersetze") #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "AUS","Telem weiterl.","Telemetrie In","SBUS Eingang","LUA","CLI","GPS","Debug","SpaceMouse","Externes Modul" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Kein","Taster","2POS","3POS","Global" +#else #define TR_SWTYPES "Kein","Taster","2POS","3POS" +#endif #define TR_POTTYPES "Kein","Poti", TR("Pot o. Ras","Poti mit Raste"),"Schieber",TR("Multipos.","Multipos. Schalter"),"Knüppel X","Knüppel Y","Schalter" #define TR_VPERSISTENT "AUS","Flugzeit","Manuell Rück" #define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa") @@ -294,8 +298,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index 5cae303cb..3dc5937d6 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -49,7 +49,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "None","Toggle","2POS","3POS","Global" +#else #define TR_SWTYPES "None","Toggle","2POS","3POS" +#endif #define TR_POTTYPES "None","Pot",TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Multipos Switch"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "OFF","Flight","Manual Reset" #define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europe") @@ -293,8 +297,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/es.h b/radio/src/translations/es.h index 657a1e792..30d6ba17b 100644 --- a/radio/src/translations/es.h +++ b/radio/src/translations/es.h @@ -51,7 +51,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "UIT","Telem Mirror","Telemetría","Entrenador SBUS","LUA","CLI","GPS","Debug","SpaceMouse","Módulo externo" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Nada","Palanca","2POS","3POS","Global" +#else #define TR_SWTYPES "Nada","Palanca","2POS","3POS" +#endif #define TR_POTTYPES "Nada","Pot",TR("Pot con fij","Pot con fijador"),"Slider",TR("Multipos","Switch multipos"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "OFF","Vuelo","Reset manual" #define TR_COUNTRY_CODES TR("US","América"),TR("JP","Japón"),TR("EU", "Europa") @@ -290,8 +294,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/fi.h b/radio/src/translations/fi.h index f8335ae1d..1bf24c0df 100644 --- a/radio/src/translations/fi.h +++ b/radio/src/translations/fi.h @@ -53,7 +53,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "POIS","S-Port Pelik","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "None","Toggle","2POS","3POS","Global" +#else #define TR_SWTYPES "None","Toggle","2POS","3POS" +#endif #define TR_POTTYPES "None",TR("Pot","Potikka"),TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Monias. Kytkin"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "OFF","Flight","Manual Reset" #define TR_COUNTRY_CODES TR("US","Amerikk"),TR("JP","Japani"),TR("EU","Euroopp") @@ -303,8 +307,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/fr.h b/radio/src/translations/fr.h index 3f2176722..caae27b9b 100644 --- a/radio/src/translations/fr.h +++ b/radio/src/translations/fr.h @@ -53,7 +53,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "OFF","Recopie Télém.","Télémétrie In","Écolage SBUS","LUA","CLI","GPS","Débug","SpaceMouse","Module externe" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Rien","Monostable","2-POS","3-POS","Global" +#else #define TR_SWTYPES "Rien","Monostable","2-POS","3-POS" +#endif #define TR_POTTYPES "Rien",TR("Pots","Potentiomètre"),TR("Pots av. ctr","Pots avec centre"),"Curseurs",TR("Multipos.","Inter multi-pos""Potentiomètre"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "OFF","Vol","Reset Manuel" @@ -298,8 +302,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/he.h b/radio/src/translations/he.h index b478dc72d..9191be367 100644 --- a/radio/src/translations/he.h +++ b/radio/src/translations/he.h @@ -52,7 +52,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "OFF","Telem Mirror","Telemetry In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","External module" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "None","Toggle","2POS","3POS","Global" +#else #define TR_SWTYPES "None","Toggle","2POS","3POS" +#endif #define TR_POTTYPES "None","Pot",TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Multipos Switch"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "OFF","Flight","Manual Reset" #define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europe") @@ -297,8 +301,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/it.h b/radio/src/translations/it.h index 6b995de48..eba3d66b7 100644 --- a/radio/src/translations/it.h +++ b/radio/src/translations/it.h @@ -49,7 +49,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "OFF","Replica Telem","Telemetria In","SBUS Trainer","LUA","CLI","GPS","Debug","SpaceMouse","Modulo esterno" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Disab.","Toggle","2POS","3POS","Globali" +#else #define TR_SWTYPES "Disab.","Toggle","2POS","3POS" +#endif #define TR_POTTYPES "Disab.",TR("Pot","Potenziometro"),TR("Pot c. fer","Pot. con centro"),"Slider",TR("Multipos","Inter. Multipos"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "NO","Volo","Reset Manuale" #define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europa") @@ -293,8 +297,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Gruppo" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Colore") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Colore") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Sempre in gruppi" #define TR_LAST "Ultimo" #define TR_MORE_INFO "Più info" diff --git a/radio/src/translations/jp.h b/radio/src/translations/jp.h index 2b12aaa56..7ceca09cc 100644 --- a/radio/src/translations/jp.h +++ b/radio/src/translations/jp.h @@ -49,7 +49,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "OFF","テレメトリーミラー","テレメトリーIN","SBUSトレーナー","LUAスクリプト","CLI","GPS","デバッグ","SpaceMouse","外部モジュール" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "なし","トグル","2POS","3POS","グローバル" +#else #define TR_SWTYPES "なし","トグル","2POS","3POS" +#endif #define TR_POTTYPES "なし","ダイヤル",TR("Pot w. det","ダイヤル(ノッチ)"),"スライダー",TR("Multipos","マルチPOS-Sw"),"X軸","Y軸","スイッチ" #define TR_VPERSISTENT "無効","飛行時","手動リセット" #define TR_COUNTRY_CODES TR("US","アメリカ"),TR("JP","日本"),TR("EU","ヨーロッパ") @@ -292,8 +296,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/ko.h b/radio/src/translations/ko.h index ce936eca3..16deb8dc2 100644 --- a/radio/src/translations/ko.h +++ b/radio/src/translations/ko.h @@ -298,8 +298,7 @@ #define TR_FS_COLOR_LIST "사용자 정의", "끄기", "흰색", "빨강", "초록", "노랑", "주황", "파랑", "분홍" #define TR_GROUP "그룹" #define TR_GROUP_ALWAYS_ON "항상 켜짐" -#define TR_FS_ON_COLOR TR("켜짐:", "켜짐 색상") -#define TR_FS_OFF_COLOR TR("꺼짐:", "꺼짐 색상") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "항상 켜짐 그룹" #define TR_LAST "마지막" #define TR_MORE_INFO "자세히 보기" diff --git a/radio/src/translations/nl.h b/radio/src/translations/nl.h index 729722a57..29a4bb3e4 100644 --- a/radio/src/translations/nl.h +++ b/radio/src/translations/nl.h @@ -52,7 +52,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "UIT","Telem Mirror","Telemetry In","SBUS Leerling","LUA","CLI","GPS","Debug","SpaceMouse","External module" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Geen","Wissel","2POS","3POS","Globale" +#else #define TR_SWTYPES "Geen","Wissel","2POS","3POS" +#endif #define TR_POTTYPES "Geen",TR("Pot", "Pot zonder Klik"),TR("Pot w. det","Pot met Klik"),"Schuif",TR("Multipos","Standenschakelaar"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "UIT","Vliegtijd","Handmatige Reset" #define TR_COUNTRY_CODES TR("US","Amerika"),TR("JP","Japan"),TR("EU","Europa") @@ -290,8 +294,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/pl.h b/radio/src/translations/pl.h index 24846cf19..1090879a4 100644 --- a/radio/src/translations/pl.h +++ b/radio/src/translations/pl.h @@ -51,7 +51,11 @@ #define TR_TRNMODE "Wył",TR("+=","Dodaj"),TR(":=","Zastąp") #define TR_TRNCHN "KN1","KN2","KN3","KN4" #define TR_AUX_SERIAL_MODES "Wyłącz","S-Port Kopia","Telemetria","Trener SBUS","LUA","CLI","GPS","Debug","SpaceMouse","Moduł zewnętrzny" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Brak","Chwil.","2POZ","3POZ","Globalne" +#else #define TR_SWTYPES "Brak","Chwil.","2POZ","3POZ" +#endif #define TR_POTTYPES "Brak","Pot.",TR("Pot. z. zap.","Pot. z zapadką"),"Suwak",TR("Wielopoz.","Przeł.wielopoz."),"Oś X","Oś Y","Przełącznik" #define TR_VPERSISTENT "Wyłącz","Lot","Ręczny Reset" #define TR_COUNTRY_CODES TR("US","Ameryka"),TR("JP","Japonia"),TR("EU", "Europa") @@ -289,8 +293,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/pt.h b/radio/src/translations/pt.h index cd9110069..d22bc7b06 100644 --- a/radio/src/translations/pt.h +++ b/radio/src/translations/pt.h @@ -52,7 +52,11 @@ #define TR_TRNMODE "DESL",TR("+=","Adicionar"),TR(":=","Trocar") #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "DESL","Espelhar Telem","Entr Telem","Trainer SBUS","LUA","CLI","GPS","Debug","SpaceMouse","External module" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Nenhum","Tátil","2POS","3POS","Global" +#else #define TR_SWTYPES "Nenhum","Tátil","2POS","3POS" +#endif #define TR_POTTYPES "Nenhum","Pot",TR("Pot c. trav","Pot com trava"),"Slider",TR("Multipos","Chave Multipos"),"Eixo X","Eixo Y","Chave" #define TR_VPERSISTENT "DESL","Voo","Reset Manual" #define TR_COUNTRY_CODES TR("US","América"),TR("JP","Japão"),TR("EU","Europa") @@ -296,8 +300,7 @@ #define TR_FS_COLOR_LIST "Custom","Desl","Branco","Verm","Verd","Amarl","Larj","Azul","Pink" #define TR_GROUP "Grupo" #define TR_GROUP_ALWAYS_ON "Sempre lig" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/ru.h b/radio/src/translations/ru.h index 909488df4..9d8a43f43 100644 --- a/radio/src/translations/ru.h +++ b/radio/src/translations/ru.h @@ -51,7 +51,11 @@ #define TR_TRNCHN "КН1","КН2","КН3","КН4" #define TR_AUX_SERIAL_MODES "Выкл","Зерк телем","Телем вход","SBUS Тренаж","LUA","CLI","GPS","Отлад","SpaceMouse","Внеш модуль" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Нет","тумбл","2Х-поз пер","3Х-поз пер","Глоб" +#else #define TR_SWTYPES "Нет","тумбл","2Х-поз пер","3Х-поз пер" +#endif #define TR_POTTYPES "None","Pot",TR("Pot w. det","Pot with detent"),"Slider",TR("Multipos","Multipos Switch"),"Axis X","Axis Y","Switch" #define TR_VPERSISTENT "Выкл","Полет","Руч сброс" #define TR_COUNTRY_CODES TR("US","США"),TR("JP","Япония"),TR("EU","Евро") @@ -297,8 +301,7 @@ #define TR_FS_COLOR_LIST "Свой","Выкл","Белый","Красн","Зелен","Желт","Оранж","Синий","Розов" #define TR_GROUP "Группа" #define TR_GROUP_ALWAYS_ON "Включить все" -#define TR_FS_ON_COLOR TR("Вкл:","Вкл цвет") -#define TR_FS_OFF_COLOR TR("Выкл:","Выкл цвет") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Вкл все группы" #define TR_LAST "послед" #define TR_MORE_INFO "Доп инфо" diff --git a/radio/src/translations/se.h b/radio/src/translations/se.h index fd9ae613e..bf4619fb8 100644 --- a/radio/src/translations/se.h +++ b/radio/src/translations/se.h @@ -55,10 +55,10 @@ #define TR_TRNCHN "KA1","KA2","KA3","KA4" #define TR_AUX_SERIAL_MODES "AV","Speglad telemetri","Telemetri in","SBUS Lärare","LUA","CLI","GPS","Debug","SpaceMouse","Extern modul" -#if !NARROW_LAYOUT - #define TR_SWTYPES "Ingen", "2 pos flipp","2 pos","3 pos" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Ingen", "2 pos flipp","2 pos","3 pos","Global" #else - #define TR_SWTYPES "Ingen","Flipp","2 pos","3 pos" +#define TR_SWTYPES "Ingen", "2 pos flipp","2 pos","3 pos" #endif #define TR_POTTYPES "Ingen","Vred",TR("Vred m. mitt","Vred med mittläge"),"Reglage",TR("Multipos","Flerlägesväljare"),"Axel X","Axel Y","Brytare" @@ -307,8 +307,7 @@ #define TR_FS_COLOR_LIST "Anpassad","Av","Vit","Röd","Grön","Gul","Orange","Blå","Rosa" #define TR_GROUP "Grupp" #define TR_GROUP_ALWAYS_ON "Alltid på" -#define TR_FS_ON_COLOR TR("PÅ:","PÅ färg") -#define TR_FS_OFF_COLOR TR("AV:","AV färg") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Alltid på grupper" #define TR_LAST "Sist" #define TR_MORE_INFO "Mer info" diff --git a/radio/src/translations/tw.h b/radio/src/translations/tw.h index ead408f46..12176bf9a 100644 --- a/radio/src/translations/tw.h +++ b/radio/src/translations/tw.h @@ -50,7 +50,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" #define TR_AUX_SERIAL_MODES "禁用","回傳鏡像","回傳輸入","SBUS教練","LUA腳本","CLI","GPS","調試","SpaceMouse","外置發射" +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "無","回彈","2段","3段","全局" +#else #define TR_SWTYPES "無","回彈","2段","3段" +#endif #define TR_POTTYPES "無","無中點旋鈕",TR("中點旋鈕","有中點旋鈕"),"側滑塊",TR("多段","多段按鍵"),"X 軸","Y 軸","開關" #define TR_VPERSISTENT "禁用","隨飛行記錄重啟","隨手動重啟" #define TR_COUNTRY_CODES "美國","日本","歐洲" @@ -294,8 +298,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/ua.h b/radio/src/translations/ua.h index ac50b868a..ea14983f3 100644 --- a/radio/src/translations/ua.h +++ b/radio/src/translations/ua.h @@ -51,7 +51,11 @@ #define TR_TRNCHN "CH1","CH2","CH3","CH4" /* use english */ #define TR_AUX_SERIAL_MODES "OFF","Дзерк. телем.","Вх. телем.","SBUS Трен.","LUA","CLI","GPS","Відлаг.","SpaceMouse","Зовн. модуль" /* for untranslated - use english */ +#if defined(FUNCTION_SWITCHES) +#define TR_SWTYPES "Немає","Перемик.","2поз. пер.","3поз. пер.","Global" +#else #define TR_SWTYPES "Немає","Перемик.","2поз. пер.","3поз. пер." +#endif #define TR_POTTYPES "Немає","Потенц.",TR("Пот. з крок.","Потенц. з кроком"),"Повзун.",TR("Баг.поз.пер.","Багатопозиц. перем."),"Вісь X","Вісь Y","Перемик." #define TR_VPERSISTENT "OFF","Політ","Ручн. скид." /* for untranslated - use english */ #define TR_COUNTRY_CODES TR("US","America"),TR("JP","Japan"),TR("EU","Europe") /* use english */ @@ -295,8 +299,7 @@ #define TR_FS_COLOR_LIST "Custom","Off","White","Red","Green","Yellow","Orange","Blue","Pink" #define TR_GROUP "Group" #define TR_GROUP_ALWAYS_ON "Always on" -#define TR_FS_ON_COLOR TR("ON:","ON Color") -#define TR_FS_OFF_COLOR TR("OFF:","OFF Color") +#define TR_LUA_OVERRIDE "Allow Lua override" #define TR_GROUPS "Always on groups" #define TR_LAST "Last" #define TR_MORE_INFO "More info" diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index ea47b0154..9c2e7875d 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -318,7 +318,7 @@ #define STR_CHAR_BW_GREATEREQUAL '}' #define STR_CHAR_BW_DEGREE '@' -#define TR_FSGROUPS "-","1","2","3" +#define TR_FSGROUPS "-","1","2","3","4" #if defined(COLORLCD) #define TR_FSSWITCHES TR_LAST, "SW1", "SW2", "SW3", "SW4", "SW5", "SW6", TR_OFF #else diff --git a/radio/util/hw_defs/hal_switches.py b/radio/util/hw_defs/hal_switches.py index e60317e34..7d1a40fb5 100644 --- a/radio/util/hw_defs/hal_switches.py +++ b/radio/util/hw_defs/hal_switches.py @@ -1,6 +1,5 @@ from switch_config import switch_cfg_by_target - class Switch: TYPE_2POS = "2POS" TYPE_3POS = "3POS" @@ -12,7 +11,7 @@ class Switch: self.flags = flags self.inverted = False self.default = None - self.display = [] + self.display = None class Switch2POS(Switch): @@ -86,6 +85,8 @@ def parse_switches(target, hw_defs, adc_parser): adc_input_name = f"SW{s}" custom = f"SWITCHES_{s}_" + cfs_idx = f"SWITCHES_{s}_CFS_IDX" + switch = None if reg in hw_defs: # 2POS switch @@ -111,11 +112,18 @@ def parse_switches(target, hw_defs, adc_parser): if inverted in hw_defs: switch.inverted = True + if cfs_idx in hw_defs: + switch.is_cfs = True + switch.cfs_idx = hw_defs[cfs_idx] + else: + switch.is_cfs = False + cfg = switch_cfg_by_target(target, name) if cfg: switch.default = cfg.get("default") switch.display = cfg.get("display") - # eprint(switch.default) + else: + switch.default = "NONE" switches.append(switch) @@ -124,11 +132,9 @@ def parse_switches(target, hw_defs, adc_parser): if f_sw_marker in hw_defs: switch = find_switch(hw_defs[f_sw_marker]) if switch: - switch.type = "FSWITCH" switch.name = f"SW{i}" else: switch = SwitchCustom(f"SW{i}", Switch.TYPE_2POS) - switch.type = "FSWITCH" switches.append(switch) - return switches \ No newline at end of file + return switches diff --git a/radio/util/hw_defs/simu_switches.jinja b/radio/util/hw_defs/simu_switches.jinja index cb03bcbf7..30753c6fb 100644 --- a/radio/util/hw_defs/simu_switches.jinja +++ b/radio/util/hw_defs/simu_switches.jinja @@ -1,29 +1,26 @@ -{% set regular_switches = switches | selectattr('type','!=','FSWITCH') | list %} -{% set function_switches = switches | selectattr('type','==','FSWITCH') | list %} +// +// WARNING: DO NOT EDIT THIS FILE +// This file has been generated from the target's JSON hardware description +// + +{% set regular_switches = switches | selectattr('is_cfs','==',False) | list %} +{% set display_switches = regular_switches | selectattr('display','!=',None) | list %} const hw_switch_def _switch_defs[] = { -{% for switch in regular_switches %} - { "{{ switch.name }}", SWITCH_HW_{{ switch.type }} }, -{% endfor %} -{% for switch in function_switches %} - { "{{ switch.name }}", SWITCH_HW_2POS }, +{% for switch in switches %} + {% if switch.is_cfs %} + { "{{ switch.name }}", SWITCH_HW_{{ switch.type }}, SWITCH_{{ switch.default }}, true, {{ switch.cfs_idx }} }, + {% else %} + { "{{ switch.name }}", SWITCH_HW_{{ switch.type }}, SWITCH_{{ switch.default }} }, + {% endif %} {% endfor %} }; -constexpr uint8_t n_switches = {{ regular_switches | count }}; -constexpr uint8_t n_fct_switches = {{ function_switches | count }}; -constexpr uint8_t n_total_switches = {{ switches | count }}; - -constexpr swconfig_t _switch_default_config = (swconfig_t)0 -{% for sw in regular_switches %} - {% if sw.default %} - | ((swconfig_t)SWITCH_{{ sw.default }} << ({{ loop.index0 }} * SW_CFG_BITS)) - {% endif %} -{% endfor %} -; +constexpr uint8_t n_switches = {{ switches | count }}; +{% if display_switches | count > 0 %} const switch_display_pos_t _switch_display[] = { -{% for sw in regular_switches %} +{% for sw in switches %} {% if sw.display %} { {{ sw.display[0] }}, {{ sw.display[1] }} }, {% else %} @@ -31,3 +28,4 @@ const switch_display_pos_t _switch_display[] = { {% endif %} {% endfor %} }; +{% endif %} \ No newline at end of file diff --git a/radio/util/hw_defs/stm32_switches.jinja b/radio/util/hw_defs/stm32_switches.jinja index f51361be7..7bacf5944 100644 --- a/radio/util/hw_defs/stm32_switches.jinja +++ b/radio/util/hw_defs/stm32_switches.jinja @@ -3,57 +3,42 @@ // This file has been generated from the target's JSON hardware description // -{% set regular_switches = switches | selectattr('type','!=','FSWITCH') | list %} -{% set function_switches = switches | selectattr('type','==','FSWITCH') | list %} +{% set regular_switches = switches | selectattr('is_cfs','==',False) | list %} +{% set display_switches = regular_switches | selectattr('display','!=',None) | list %} static const stm32_switch_t _switch_defs[] = { -{% for switch in regular_switches %} +{% for switch in switches %} {% if switch.type == '2POS' %} { "{{ switch.name }}", - {{ switch.gpio or "nullptr" }}, - {{ switch.pin or 0 }}, + {{ switch.gpio or "nullptr" }}, {{ switch.pin or 0 }}, nullptr, 0, - SWITCH_HW_2POS, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }} + SWITCH_HW_2POS, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }}, SWITCH_{{ switch.default }}, + {% if switch.is_cfs %} + true, {{ switch.cfs_idx }} + {% endif %} }, {% elif switch.type == '3POS' %} { "{{ switch.name }}", - {{ switch.gpio_high or "nullptr" }}, - {{ switch.pin_high or 0 }}, - {{ switch.gpio_low or "nullptr" }}, - {{ switch.pin_low or 0 }}, - SWITCH_HW_3POS, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }} + {{ switch.gpio_high or "nullptr" }}, {{ switch.pin_high or 0 }}, + {{ switch.gpio_low or "nullptr" }}, {{ switch.pin_low or 0 }}, + SWITCH_HW_3POS, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }}, SWITCH_{{ switch.default }}, }, {% elif switch.type == 'ADC' %} { "{{ switch.name }}", nullptr, {{ adc_index[switch.adc_input] }}, nullptr, 0, - SWITCH_HW_ADC, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }} + SWITCH_HW_ADC, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }}, SWITCH_{{ switch.default }}, }, {% endif %} {% endfor %} -{% for switch in function_switches %} - { - "{{ switch.name }}", - {{ switch.gpio or "nullptr" }}, - {{ switch.pin or 0 }}, - nullptr, 0, - SWITCH_HW_2POS, {{ 'SWITCH_HW_INVERTED' if switch.inverted else 0 }} - }, -{% endfor %} -}; - -static const stm32_switch_t* const _switch_offsets[] = { - _switch_defs, -{% if function_switches %} - _switch_defs + {{ regular_switches | count }}, -{% endif %} }; static inline void _init_switches() { +{% if switch_gpios|count > 0 %} LL_GPIO_InitTypeDef pinInit; LL_GPIO_StructInit(&pinInit); pinInit.Mode = LL_GPIO_MODE_INPUT; @@ -65,25 +50,19 @@ static inline void _init_switches() LL_GPIO_Init({{ sw_gpio }}, &pinInit); {% endif %} {% endfor %} +{% endif %} } -constexpr uint8_t n_switches = {{ regular_switches | count }}; -constexpr uint8_t n_fct_switches = {{ function_switches | count }}; - -constexpr swconfig_t _switch_default_config = (swconfig_t)0 -{% for sw in regular_switches %} - {% if sw.default %} - | ((swconfig_t)SWITCH_{{ sw.default }} << ({{ loop.index0 }} * SW_CFG_BITS)) - {% endif %} -{% endfor %} -; +constexpr uint8_t n_switches = {{ switches | count }}; +{% if display_switches | count > 0 %} const switch_display_pos_t _switch_display[] = { -{% for sw in regular_switches %} +{% for sw in switches %} {% if sw.display %} { {{ sw.display[0] }}, {{ sw.display[1] }} }, {% else %} { 0, 0 }, {% endif %} {% endfor %} -}; \ No newline at end of file +}; +{% endif %} \ No newline at end of file diff --git a/radio/util/hw_defs/switch_config.py b/radio/util/hw_defs/switch_config.py index cc4257ed2..5544cf476 100644 --- a/radio/util/hw_defs/switch_config.py +++ b/radio/util/hw_defs/switch_config.py @@ -15,15 +15,22 @@ SWITCH_CONFIG = { }, "gx12": { # left side - "SA": {"default": "TOGGLE", "display": [0, 0]}, - "SB": {"default": "3POS", "display": [0, 1]}, - "SE": {"default": "3POS", "display": [0, 2]}, - "SG": {"default": "TOGGLE", "display": [0, 3]}, + "SA": {"default": "TOGGLE"}, + "SB": {"default": "3POS", "display": [0, 0]}, + "SE": {"default": "3POS", "display": [0, 1]}, + "SG": {"default": "TOGGLE", "display": [0, 2]}, # right side - "SC": {"default": "3POS", "display": [1, 1]}, - "SD": {"default": "TOGGLE", "display": [1, 0]}, - "SF": {"default": "3POS", "display": [1, 2]}, - "SH": {"default": "TOGGLE", "display": [1, 3]}, + "SC": {"default": "3POS", "display": [1, 0]}, + "SD": {"default": "TOGGLE"}, + "SF": {"default": "3POS", "display": [1, 1]}, + "SH": {"default": "TOGGLE", "display": [1, 2]}, + # custom switches + "SI": {"default": "2POS"}, + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SN": {"default": "2POS"}, }, "commando8": { # left side @@ -90,6 +97,13 @@ SWITCH_CONFIG = { "SH": { "default": "TOGGLE" }, "SI": { "default": "TOGGLE" }, "SJ": { "default": "TOGGLE" }, + # custom switches + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SN": {"default": "2POS"}, + "SO": {"default": "2POS"}, + "SP": {"default": "2POS"}, }, "lr3pro": { # left side @@ -192,6 +206,13 @@ SWITCH_CONFIG = { "SD": {"default": "3POS"}, "SE": {"default": "2POS"}, "SF": {"default": "2POS"}, + # custom switches + "SG": {"default": "2POS"}, + "SH": {"default": "2POS"}, + "SI": {"default": "2POS"}, + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, }, "t16": { "SA": {"default": "3POS"}, @@ -238,6 +259,13 @@ SWITCH_CONFIG = { "SB": {"default": "3POS", "display": [1, 0]}, "SD": {"default": "TOGGLE", "display": [1, 1]}, "SF": {"default": "NONE", "display": [1, 2]}, + # custom switches + "SG": {"default": "2POS"}, + "SH": {"default": "2POS"}, + "SI": {"default": "2POS"}, + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, }, "tprov2": { # left side @@ -250,6 +278,13 @@ SWITCH_CONFIG = { "SD": {"default": "TOGGLE", "display": [1, 1]}, "SF": {"default": "2POS", "display": [1, 2]}, "SH": {"default": "NONE", "display": [1, 3]}, + # custom switches + "SI": {"default": "2POS"}, + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SN": {"default": "2POS"}, }, "tpros": { # left side @@ -272,6 +307,13 @@ SWITCH_CONFIG = { "SD": {"default": "TOGGLE", "display": [1, 1]}, "SF": {"default": "2POS", "display": [1, 2]}, "SH": {"default": "TOGGLE", "display": [1, 3]}, + # custom switches + "SJ": {"default": "2POS"}, + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SO": {"default": "2POS"}, + "SP": {"default": "2POS"}, }, "t20": { # left side @@ -285,7 +327,14 @@ SWITCH_CONFIG = { "SD": {"default": "3POS", "display": [1, 1]}, "SF": {"default": "2POS", "display": [1, 2]}, "SH": {"default": "TOGGLE", "display": [1, 3]}, - "SJ": {"default": "TOGGLE", "display": [1, 4]} + "SJ": {"default": "TOGGLE", "display": [1, 4]}, + # custom switches + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SN": {"default": "2POS"}, + "SO": {"default": "2POS"}, + "SP": {"default": "2POS"}, }, "t20v2": { # left side @@ -299,7 +348,14 @@ SWITCH_CONFIG = { "SD": {"default": "3POS", "display": [1, 1]}, "SF": {"default": "2POS", "display": [1, 2]}, "SH": {"default": "TOGGLE", "display": [1, 3]}, - "SJ": {"default": "TOGGLE", "display": [1, 4]} + "SJ": {"default": "TOGGLE", "display": [1, 4]}, + # custom switches + "SK": {"default": "2POS"}, + "SL": {"default": "2POS"}, + "SM": {"default": "2POS"}, + "SN": {"default": "2POS"}, + "SO": {"default": "2POS"}, + "SP": {"default": "2POS"}, }, "tx12": { # left side @@ -351,7 +407,10 @@ SWITCH_CONFIG = { # right side "SC": {"default": "3POS", "display": [1, 0]}, "SD": {"default": "3POS", "display": [1, 1]}, - "SH": {"default": "TOGGLE", "display": [1, 2]} + "SH": {"default": "TOGGLE", "display": [1, 2]}, + # optional + "SI": {"default": "NONE", "display": [0, 3]}, + "SJ": {"default": "NONE", "display": [0, 3]}, }, "x7access": { # left side @@ -361,7 +420,10 @@ SWITCH_CONFIG = { # right side "SC": {"default": "3POS", "display": [1, 0]}, "SD": {"default": "3POS", "display": [1, 1]}, - "SH": {"default": "TOGGLE", "display": [1, 2]} + "SH": {"default": "TOGGLE", "display": [1, 2]}, + # optional + "SI": {"default": "NONE", "display": [0, 3]}, + "SJ": {"default": "NONE", "display": [0, 3]}, }, "x9d": { # left side diff --git a/radio/util/yaml_parser.tmpl b/radio/util/yaml_parser.tmpl index f7e03dc97..9d13fc6a2 100644 --- a/radio/util/yaml_parser.tmpl +++ b/radio/util/yaml_parser.tmpl @@ -38,7 +38,7 @@ static const struct YamlNode {{ struct.name }}[] = { YAML_{{elmt.type|upper}}( "{{ max_len(elmt.name) }}", {{ elmt.bits }} ), {% endif %} {% elif elmt.type == 'enum' %} - YAML_ENUM("{{ max_len(elmt.name) }}", {{elmt.bits}}, {{elmt.var_type}}), + YAML_ENUM("{{ max_len(elmt.name) }}", {{elmt.bits}}, {{elmt.var_type}}, {{ elmt.func }}), {% elif elmt.type == 'struct' %} YAML_STRUCT("{{ max_len(elmt.name) }}", {{elmt.bits}}, {{elmt.var_type}}, {{ elmt.func }}), {% elif elmt.type == 'union' %}