diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 4968fe33c..0100a0175 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -78,7 +78,7 @@ jobs: - t16 - t18 - t8;zorro - - tlite + - tlite;tpro - tx12 - tx16s - x10;x10-access diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 6914f667c..9c98e519d 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -323,6 +323,8 @@ elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T12) set(FLAVOUR t12) elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TLITE) set(FLAVOUR tlite) +elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TPRO) + set(FLAVOUR tpro) elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12) set(FLAVOUR tx12) elseif(PCB STREQUAL X7 AND PCBREV STREQUAL ZORRO) diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index c34fcd295..9bdbdee8b 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -188,6 +188,10 @@ images/simulator/JumperTLITE/right_top.png images/simulator/JumperTLITE/right_bottom.png images/simulator/JumperTLITE/top.png + images/simulator/JumperTPRO/bottom.png + images/simulator/JumperTPRO/left.png + images/simulator/JumperTPRO/right.png + images/simulator/JumperTPRO/top.png images/simulator/TX12/left.png images/simulator/TX12/left-pageup.png images/simulator/TX12/left-pagedn.png diff --git a/companion/src/constants.h b/companion/src/constants.h index 63ba0a9b1..b06792a91 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -43,6 +43,7 @@ #define CPN_MAX_POTS (CPN_MAX_KNOBS + CPN_MAX_SLIDERS) #define CPN_MAX_CYC 3 #define CPN_MAX_SWITCHES 32 +#define CPN_MAX_FUNCTION_SWITCHES 6 #define CPN_MAX_MOUSE_ANALOGS 2 #define CPN_MAX_GYRO_ANALOGS 2 #define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_MOUSE_ANALOGS + CPN_MAX_GYRO_ANALOGS) diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 18605ea10..af164355c 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -82,6 +82,8 @@ uint32_t Boards::getFourCC(Type board) return 0x3D78746F; case BOARD_JUMPER_TLITE: return 0x4278746F; + case BOARD_JUMPER_TPRO: + return 0x4678746F; case BOARD_JUMPER_T16: return 0x3F78746F; case BOARD_JUMPER_T18: @@ -121,6 +123,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_TARANIS_X9E: case BOARD_JUMPER_T12: case BOARD_JUMPER_TLITE: + case BOARD_JUMPER_TPRO: case BOARD_RADIOMASTER_TX12: case BOARD_RADIOMASTER_T8: case BOARD_RADIOMASTER_ZORRO: @@ -160,6 +163,7 @@ int Boards::getFlashSize(Type board) case BOARD_TARANIS_X9E: case BOARD_JUMPER_T12: case BOARD_JUMPER_TLITE: + case BOARD_JUMPER_TPRO: case BOARD_RADIOMASTER_TX12: case BOARD_RADIOMASTER_ZORRO: case BOARD_RADIOMASTER_T8: @@ -196,7 +200,7 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index) if (index < DIM(switches)) return switches[index]; } - else if (IS_TARANIS_XLITE(board) || IS_JUMPER_TLITE(board)) { + else if (IS_TARANIS_XLITE(board) || IS_JUMPER_TLITE(board) || IS_JUMPER_TPRO(board)) { const Board::SwitchInfo switches[] = { {SWITCH_3POS, "SA"}, {SWITCH_3POS, "SB"}, @@ -365,7 +369,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 1; else if (IS_JUMPER_TLITE(board)) return 0; - else if (IS_TARANIS_SMALL(board)) + else if (IS_TARANIS_SMALL(board) || IS_JUMPER_TPRO(board)) return 2; else if (IS_TARANIS_X9E(board)) return 4; @@ -427,7 +431,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 7; else if (board == BOARD_TARANIS_X7) return 8; - else if (board == BOARD_JUMPER_TLITE) + else if (board == BOARD_JUMPER_TLITE || board == BOARD_JUMPER_TPRO) return 4; else if (board == BOARD_FLYSKY_NV14) return 8; @@ -447,7 +451,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case FactoryInstalledSwitches: if (IS_TARANIS_X9E(board)) return 8; - else if (IS_JUMPER_TLITE(board)) + else if (IS_JUMPER_TLITE(board) || IS_JUMPER_TPRO(board)) return 4; else if(IS_RADIOMASTER_ZORRO(board)) return 8; @@ -479,6 +483,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case HasColorLcd: return IS_FAMILY_HORUS_OR_T16(board); + case NumFunctionSwitches: + return IS_JUMPER_TPRO(board) ? 6 : 0; + default: return 0; } @@ -645,6 +652,8 @@ QString Boards::getBoardName(Board::Type board) return "Jumper T12"; case BOARD_JUMPER_TLITE: return "Jumper T-Lite"; + case BOARD_JUMPER_TPRO: + return "Jumper T-Pro"; case BOARD_JUMPER_T16: return "Jumper T16"; case BOARD_JUMPER_T18: diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 2bc37a458..ea0476bda 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -63,6 +63,7 @@ namespace Board { BOARD_JUMPER_TLITE, BOARD_FLYSKY_NV14, BOARD_RADIOMASTER_ZORRO, + BOARD_JUMPER_TPRO, BOARD_TYPE_COUNT, BOARD_TYPE_MAX = BOARD_TYPE_COUNT - 1 }; @@ -143,7 +144,8 @@ namespace Board { NumTrims, NumTrimSwitches, HasRTC, - HasColorLcd + HasColorLcd, + NumFunctionSwitches }; struct SwitchInfo @@ -237,6 +239,11 @@ inline bool IS_JUMPER_TLITE(Board::Type board) return board == Board::BOARD_JUMPER_TLITE; } +inline bool IS_JUMPER_TPRO(Board::Type board) +{ + return board == Board::BOARD_JUMPER_TPRO; +} + inline bool IS_JUMPER_T16(Board::Type board) { return board == Board::BOARD_JUMPER_T16; @@ -335,7 +342,7 @@ inline bool IS_TARANIS_X9E(Board::Type board) inline bool IS_TARANIS_SMALL(Board::Type board) { - return IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_FAMILY_T12(board); + return IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_FAMILY_T12(board) || IS_JUMPER_TPRO(board); } inline bool IS_TARANIS(Board::Type board) diff --git a/companion/src/firmwares/eepromimportexport.h b/companion/src/firmwares/eepromimportexport.h index 965810731..bcb66ab65 100644 --- a/companion/src/firmwares/eepromimportexport.h +++ b/companion/src/firmwares/eepromimportexport.h @@ -568,7 +568,7 @@ class TransformedField: public DataField { virtual void afterImport() = 0; - int dump(int level, int offset) override + int dump(int level=0, int offset=0) override { beforeExport(); return field.dump(level, offset); diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index 02ab4884d..099501c9d 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -162,7 +162,8 @@ enum Capability { HasAntennaChoice, HasADCJitterFilter, HasTelemetryBaudrate, - TopBarZones + TopBarZones, + FunctionSwitches }; class EEPROMInterface diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index e6b12ca5e..64e8879d6 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -212,6 +212,17 @@ void ModelData::setDefaultMixes(const GeneralSettings & settings) } } +void ModelData::setDefaultFunctionSwitches(int functionSwitchCount) +{ + if (functionSwitchCount == 0) + return; + + for (int i = 0; i < functionSwitchCount; i++) { + functionSwitchConfig |= (Board::SWITCH_2POS << 2 * i); + functionSwitchGroup |= (1 << 2 * i); + } +} + void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settings) { clear(); @@ -221,6 +232,7 @@ void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settin moduleData[i].modelId = id + 1; } setDefaultMixes(settings); + setDefaultFunctionSwitches(getCurrentFirmware()->getCapability(FunctionSwitches)); } int ModelData::getTrimValue(int phaseIdx, int trimIdx) @@ -1641,3 +1653,77 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings mdl->loadItemList(); return mdl; } + +QString ModelData::funcSwitchConfigToString(const int index) const +{ + if (index < CPN_MAX_FUNCTION_SWITCHES) + return funcSwitchConfigToString(index, (int)(functionSwitchConfig >> (2 * index)) & 0x03); + else + return CPN_STR_UNKNOWN_ITEM; +} + +// static +QString ModelData::funcSwitchConfigToString(const int index, const int value) +{ + switch (value) { + case FUNC_SWITCH_CONFIG_NONE: + return tr("NONE"); + case FUNC_SWITCH_CONFIG_TOGGLE: + return tr("TOGGLE"); + case FUNC_SWITCH_CONFIG_2POS: + return tr("2POS"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +AbstractStaticItemModel * ModelData::funcSwitchConfigItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_MODELDATA_FUNCSWITCHCONFIG); + + for (int i = FUNC_SWITCH_CONFIG_FIRST; i <= FUNC_SWITCH_CONFIG_LAST; i++) { + mdl->appendToItemList(funcSwitchConfigToString(0, i), i); + } + + mdl->loadItemList(); + return mdl; +} + +QString ModelData::funcSwitchStartToString(const int index) const +{ + if (index < CPN_MAX_FUNCTION_SWITCHES) + return funcSwitchStartToString(index, (int)(functionSwitchStartConfig >> (2 * index)) & 0x03); + else + return CPN_STR_UNKNOWN_ITEM; +} + +// static +QString ModelData::funcSwitchStartToString(const int index, const int value) +{ + switch (value) { + case FUNC_SWITCH_START_INACTIVE: + return CPN_STR_SW_INDICATOR_UP; + case FUNC_SWITCH_START_ACTIVE: + return CPN_STR_SW_INDICATOR_DN; + case FUNC_SWITCH_START_PREVIOUS: + return "="; + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +AbstractStaticItemModel * ModelData::funcSwitchStartItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_MODELDATA_FUNCSWITCHSTART); + + for (int i = FUNC_SWITCH_START_FIRST; i <= FUNC_SWITCH_START_LAST; i++) { + mdl->appendToItemList(funcSwitchStartToString(0, i), i); + } + + mdl->loadItemList(); + return mdl; +} diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index fbdd8f9c7..6a1443c12 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -35,6 +35,7 @@ #include "telem_data.h" #include "timerdata.h" #include "customisation_data.h" +#include "generalsettings.h" #include @@ -43,6 +44,8 @@ class RadioDataConversionState; class AbstractStaticItemModel; constexpr char AIM_MODELDATA_TRAINERMODE[] {"modeldata.trainermode"}; +constexpr char AIM_MODELDATA_FUNCSWITCHCONFIG[] {"modeldata.funcswitchconfig"}; +constexpr char AIM_MODELDATA_FUNCSWITCHSTART[] {"modeldata.funcswitchstart"}; #define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*" @@ -145,6 +148,7 @@ class ModelData { bool potsWarnEnabled[CPN_MAX_POTS]; int potsWarnPosition[CPN_MAX_POTS]; bool displayChecklist; + GVarData gvarData[CPN_MAX_GVARS]; MavlinkData mavlink; unsigned int telemetryProtocol; @@ -170,10 +174,34 @@ class ModelData { char registrationId[8+1]; + 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_INACTIVE, + FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_INACTIVE, + FUNC_SWITCH_START_ACTIVE, + 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_FUNCTION_SWITCHES][HARDWARE_NAME_LEN + 1]; + void clear(); bool isEmpty() const; void setDefaultInputs(const GeneralSettings & settings); void setDefaultMixes(const GeneralSettings & settings); + void setDefaultFunctionSwitches(int functionSwitchCount); void setDefaultValues(unsigned int id, const GeneralSettings & settings); int getTrimValue(int phaseIdx, int trimIdx); @@ -258,6 +286,12 @@ class ModelData { static QString trainerModeToString(const int value); static bool isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value); static AbstractStaticItemModel * trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware); + QString funcSwitchConfigToString(const int index) const; + static QString funcSwitchConfigToString(const int index, const int value); + static AbstractStaticItemModel * funcSwitchConfigItemModel(); + QString funcSwitchStartToString(const int index) const; + static QString funcSwitchStartToString(const int index, const int value); + static AbstractStaticItemModel * funcSwitchStartItemModel(); protected: void removeGlobalVar(int & var); diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index df8b9263a..421138999 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -51,6 +51,9 @@ inline int MAX_SWITCHES(Board::Type board, int version) if (IS_TARANIS_X7(board)) return 8; + if (IS_JUMPER_TPRO(board)) + return 10; + return Boards::getCapability(board, Board::Switches); } @@ -81,6 +84,13 @@ inline int MAX_POTS(Board::Type board, int version) return Boards::getCapability(board, Board::Pots); } +inline int MAX_FUNCTION_SWITCHES(Board::Type board, int version) +{ + if (IS_JUMPER_TPRO(board)) + return 6; + return 0; +} + inline int MAX_POTS_STORAGE(Board::Type board, int version) { if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) @@ -2630,17 +2640,17 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new LimitField(this, modelData.limitData[i], board, version)); for (int i=0; i(this, modelData.thrTraceSrc, "Throttle Source")); @@ -2836,6 +2846,16 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig else if (version >= 219) { internalField.Append(new ZCharField<8>(this, modelData.registrationId, "ACCESS Registration ID")); } + + if (IS_JUMPER_TPRO(board)) { + internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchConfig)); + internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchGroup)); + internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchStartConfig)); + internalField.Append(new UnsignedField<8>(this, modelData.functionSwitchLogicalState)); + for (int i=0; i < MAX_FUNCTION_SWITCHES(board, version); ++i) { + internalField.Append(new ZCharField<3>(this, modelData.functionSwitchNames[i], "Function switch name")); + } + } } void OpenTxModelData::beforeExport() diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h index c3f188eea..5ad907871 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.h +++ b/companion/src/firmwares/opentx/opentxeeprom.h @@ -40,6 +40,7 @@ #define JUMPER_TLITE_VARIANT 0x4003 #define RADIOMASTER_T8_VARIANT 0x4004 #define RADIOMASTER_ZORRO_VARIANT 0x4006 +#define JUMPER_TPRO_VARIANT 0x4005 class OpenTxGeneralData: public TransformedField { public: diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 59c6bab33..940d57456 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -62,6 +62,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for Jumper T12"; case BOARD_JUMPER_TLITE: return "OpenTX for Jumper T-Lite"; + case BOARD_JUMPER_TPRO: + return "OpenTX for Jumper T-Pro"; case BOARD_JUMPER_T16: return "OpenTX for Jumper T16"; case BOARD_JUMPER_T18: @@ -347,6 +349,9 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u else if (IS_JUMPER_TLITE(board)) { variant |= JUMPER_TLITE_VARIANT; } + else if (IS_JUMPER_TPRO(board)) { + variant |= JUMPER_TPRO_VARIANT; + } else if (IS_RADIOMASTER_TX12(board)) { variant |= RADIOMASTER_TX12_VARIANT; } @@ -752,6 +757,9 @@ int OpenTxFirmware::getCapability(::Capability capability) return IS_HORUS_OR_TARANIS(board) ? true : false; case TopBarZones: return getCapability(LcdWidth) > getCapability(LcdHeight) ? 4 : 2; + case FunctionSwitches: + return IS_JUMPER_TPRO(board) ? 6 : 0; + default: return 0; } @@ -1025,6 +1033,11 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari variantError = true; } } + else if (IS_JUMPER_TPRO(board)) { + if (variant != JUMPER_TPRO_VARIANT) { + variantError = true; + } + } else if (IS_RADIOMASTER_TX12(board)) { if (variant != RADIOMASTER_TX12_VARIANT) { variantError = true; @@ -1371,6 +1384,16 @@ void registerOpenTxFirmwares() registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, FLEX); + /* Jumper T-Pro board */ + firmware = new OpenTxFirmware("opentx-tpro", QCoreApplication::translate("Firmware", "Jumper T-Pro"), BOARD_JUMPER_TPRO); + addOpenTxCommonOptions(firmware); + firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support")); + firmware->addOption("nogvars", Firmware::tr("Disable Global variables")); + firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); + addOpenTxFontOptions(firmware); + registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); + /* Jumper T16 board */ firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); addOpenTxFrskyOptions(firmware); diff --git a/companion/src/images/simulator/JumperTPRO/bottom.png b/companion/src/images/simulator/JumperTPRO/bottom.png new file mode 100644 index 000000000..185b5ac36 Binary files /dev/null and b/companion/src/images/simulator/JumperTPRO/bottom.png differ diff --git a/companion/src/images/simulator/JumperTPRO/left.png b/companion/src/images/simulator/JumperTPRO/left.png new file mode 100644 index 000000000..efcfb5e98 Binary files /dev/null and b/companion/src/images/simulator/JumperTPRO/left.png differ diff --git a/companion/src/images/simulator/JumperTPRO/right.png b/companion/src/images/simulator/JumperTPRO/right.png new file mode 100644 index 000000000..e30e90a91 Binary files /dev/null and b/companion/src/images/simulator/JumperTPRO/right.png differ diff --git a/companion/src/images/simulator/JumperTPRO/top.png b/companion/src/images/simulator/JumperTPRO/top.png new file mode 100644 index 000000000..7cf5226ff Binary files /dev/null and b/companion/src/images/simulator/JumperTPRO/top.png differ diff --git a/companion/src/modeledit/CMakeLists.txt b/companion/src/modeledit/CMakeLists.txt index 73f0acf92..7404f821e 100644 --- a/companion/src/modeledit/CMakeLists.txt +++ b/companion/src/modeledit/CMakeLists.txt @@ -45,6 +45,7 @@ set(modeledit_HDRS set(modeledit_UIS setup_timer.ui setup_module.ui + setup_function_switches.ui flightmode.ui telemetry_customscreen.ui telemetry_sensor.ui diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 9b4222d50..f12d83a74 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -22,6 +22,7 @@ #include "ui_setup.h" #include "ui_setup_timer.h" #include "ui_setup_module.h" +#include "ui_setup_function_switches.h" #include "appdata.h" #include "modelprinter.h" #include "multiprotocols.h" @@ -982,6 +983,167 @@ void ModulePanel::onClearAccessRxClicked() } } +/******************************************************************************/ +FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): + ModelPanel(parent, model, generalSettings, firmware), + ui(new Ui::FunctionSwitches) +{ + ui->setupUi(this); + + AbstractStaticItemModel *fsConfig = ModelData::funcSwitchConfigItemModel(); + AbstractStaticItemModel *fsStart = ModelData::funcSwitchStartItemModel(); + + lock = true; + + QRegExp rx(CHAR_FOR_NAMES_REGEX); + + switchcnt = Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches); + + 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 QRegExpValidator(rx, this)); + aleName->setField((char *)model.functionSwitchNames[i], 3); + + QComboBox * cboConfig = new QComboBox(this); + cboConfig->setProperty("index", i); + cboConfig->setModel(fsConfig); + + QComboBox * cboStartPosn = new QComboBox(this); + cboStartPosn->setProperty("index", i); + cboStartPosn->setModel(fsStart); + + QSpinBox * sbGroup = new QSpinBox(this); + sbGroup->setProperty("index", i); + sbGroup->setMaximum(3); + + 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(sbGroup, row++, i + coloffset); + + connect(cboConfig, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_configCurrentIndexChanged); + connect(cboStartPosn, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_startPosnCurrentIndexChanged); + connect(sbGroup, QOverload::of(&QSpinBox::valueChanged), this, &FunctionSwitchesPanel::on_groupChanged); + + aleNames << aleName; + cboConfigs << cboConfig; + cboStartupPosns << cboStartPosn; + sbGroups << sbGroup; + } + + update(); + + lock = false; +} + +FunctionSwitchesPanel::~FunctionSwitchesPanel() +{ + delete ui; +} + +void FunctionSwitchesPanel::update() +{ + for (int i = 0; i < switchcnt; i++) { + update(i); + } +} + +void FunctionSwitchesPanel::update(int index) +{ + lock = true; + + for (int i = 0; i < switchcnt; i++) { + aleNames[i]->update(); + cboConfigs[i]->setCurrentIndex((model->functionSwitchConfig >> (2 * i)) & 0x03); + cboStartupPosns[i]->setCurrentIndex((model->functionSwitchStartConfig >> (2 * i)) & 0x03); + sbGroups[i]->setValue((model->functionSwitchGroup >> (2 * i)) & 0x03); + + if (cboConfigs[i]->currentIndex() < 2) + cboStartupPosns[i]->setEnabled(false); + else + cboStartupPosns[i]->setEnabled(true); + + if (cboConfigs[i]->currentIndex() < 1) + sbGroups[i]->setEnabled(false); + else + sbGroups[i]->setEnabled(true); + } + + lock = false; +} + +void FunctionSwitchesPanel::on_configCurrentIndexChanged(int index) +{ + if (!sender()) + return; + + QComboBox * cb = qobject_cast(sender()); + + if (cb && !lock) { + lock = true; + bool ok = false; + int i = sender()->property("index").toInt(&ok); + if (ok && ((model->functionSwitchConfig >> (2 * i)) & 0x03) != (unsigned int)index) { + unsigned int mask = ((unsigned int) 0x03 << (2 * i)); + model->functionSwitchConfig = (model->functionSwitchConfig & ~ mask) | ((unsigned int) index << (2 * i)); + if (index < 2) + model->functionSwitchStartConfig = (model->functionSwitchStartConfig & ~ mask) | ((unsigned int) 0 << (2 * i)); + if (index < 1) + model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) 0 << (2 * i)); + update(i); + emit modified(); + } + lock = false; + } +} + +void FunctionSwitchesPanel::on_startPosnCurrentIndexChanged(int index) +{ + if (!sender()) + return; + + QComboBox * cb = qobject_cast(sender()); + + if (cb && !lock) { + lock = true; + bool ok = false; + int i = sender()->property("index").toInt(&ok); + if (ok && ((model->functionSwitchStartConfig >> (2 * i)) & 0x03) != (unsigned int)index) { + unsigned int mask = ((unsigned int) 0x03 << (2 * i)); + model->functionSwitchStartConfig = (model->functionSwitchStartConfig & ~ mask) | ((unsigned int) index << (2 * i)); + emit modified(); + } + lock = false; + } +} + +void FunctionSwitchesPanel::on_groupChanged(int value) +{ + if (!sender()) + return; + + QSpinBox * sb = qobject_cast(sender()); + + if (sb && !lock) { + lock = true; + bool ok = false; + int i = sender()->property("index").toInt(&ok); + if (ok && ((model->functionSwitchGroup >> (2 * i)) & 0x03) != (unsigned int)value) { + unsigned int mask = ((unsigned int) 0x03 << (2 * i)); + model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) value << (2 * i)); + emit modified(); + } + lock = false; + } +} + /******************************************************************************/ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, @@ -1221,6 +1383,11 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge ui->trimsDisplay->setField(model.trimsDisplay, this); + if (Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches) > 0) + ui->functionSwitchesLayout->addWidget(new FunctionSwitchesPanel(this, model, generalSettings, firmware)); + //else + // ui->functionSwitchesLayout->hide(); + for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) { modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i); ui->modulesLayout->addWidget(modules[i]); diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 824b28acb..c63932237 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -31,8 +31,11 @@ namespace Ui { class Setup; class Timer; class Module; + class FunctionSwitches; } +class AutoLineEdit; + class TimerPanel : public ModelPanel { Q_OBJECT @@ -128,6 +131,31 @@ class ModulePanel : public ModelPanel void updateFailsafeUI(unsigned channel, quint8 updtSb); }; +class FunctionSwitchesPanel : public ModelPanel +{ + Q_OBJECT + + public: + FunctionSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + virtual ~FunctionSwitchesPanel(); + + virtual void update(); + void update(int index); + + private slots: + void on_configCurrentIndexChanged(int index); + void on_startPosnCurrentIndexChanged(int index); + void on_groupChanged(int value); + + private: + Ui::FunctionSwitches * ui; + QVector aleNames; + QVector cboConfigs; + QVector cboStartupPosns; + QVector sbGroups; + int switchcnt; +}; + class SetupPanel : public ModelPanel { Q_OBJECT diff --git a/companion/src/modeledit/setup.ui b/companion/src/modeledit/setup.ui index ee0ec28a3..51aae4f1e 100644 --- a/companion/src/modeledit/setup.ui +++ b/companion/src/modeledit/setup.ui @@ -7,7 +7,7 @@ 0 0 1007 - 405 + 435 @@ -630,6 +630,9 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi + + + diff --git a/companion/src/modeledit/setup_function_switches.ui b/companion/src/modeledit/setup_function_switches.ui new file mode 100644 index 000000000..acfd88e5d --- /dev/null +++ b/companion/src/modeledit/setup_function_switches.ui @@ -0,0 +1,121 @@ + + + FunctionSwitches + + + + 0 + 0 + 231 + 140 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + + + + + + 75 + true + + + + Function Switches + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + QLayout::SetMinimumSize + + + + + Type + + + + + + + + 0 + 0 + + + + Group + + + + + + + Start + + + + + + + Name + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/companion/src/multimodelprinter.cpp b/companion/src/multimodelprinter.cpp index 1cf0140e3..8c38776e5 100644 --- a/companion/src/multimodelprinter.cpp +++ b/companion/src/multimodelprinter.cpp @@ -277,6 +277,9 @@ QString MultiModelPrinter::print(QTextDocument * document) if (firmware->getCapability(Timers)) { str.append(printTimers()); } + if (Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches)) { + str.append(printFunctionSwitches()); + } str.append(printModules()); if (firmware->getCapability(Heli)) str.append(printHeliSetup()); @@ -938,3 +941,52 @@ QString MultiModelPrinter::printChecklist() } return str; } + +QString MultiModelPrinter::printFunctionSwitches() +{ + QString str; + MultiColumns columns(modelPrinterMap.size()); + columns.appendSectionTableStart(); + + int numFS = Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches); + int colwidth = 80 / numFS; + + QStringList headings = { tr("Function Switches") }; + for (int i = 0; i < numFS; i++) { + headings << tr("Switch %1").arg(i + 1); + } + columns.appendRowHeader(headings); + + columns.appendRowStart(tr("Name"), 20); + + for (int i = 0; i < numFS; i++) { + COMPARECELLWIDTH(model->functionSwitchNames[i], colwidth); + } + + columns.appendRowEnd(); + columns.appendRowStart(tr("Type"), 20); + + for (int i = 0; i < numFS; i++) { + COMPARECELLWIDTH(model->funcSwitchConfigToString((unsigned int)i), colwidth); + } + + columns.appendRowEnd(); + columns.appendRowStart(tr("Start"), 20); + + for (int i = 0; i < numFS; i++) { + COMPARECELLWIDTH(model->funcSwitchStartToString((unsigned int)i), colwidth); + } + + columns.appendRowEnd(); + columns.appendRowStart(tr("Group"), 20); + + for (int i = 0; i < numFS; i++) { + COMPARECELLWIDTH((model->functionSwitchGroup >> (2 * i)) & 0x03, colwidth); + } + + columns.appendRowEnd(); + + columns.appendTableEnd(); + str.append(columns.print()); + return str; +} diff --git a/companion/src/multimodelprinter.h b/companion/src/multimodelprinter.h index 4214bc45b..8cc48642c 100644 --- a/companion/src/multimodelprinter.h +++ b/companion/src/multimodelprinter.h @@ -95,6 +95,7 @@ class MultiModelPrinter: public QObject QString printTelemetryScreens(); QString printGlobalFunctions(); QString printChecklist(); + QString printFunctionSwitches(); }; #endif // _MULTIMODELPRINTER_H_ diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index cc605abbb..091867696 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -14,6 +14,7 @@ set(simulation_SRCS simulateduiwidgetX12.cpp simulateduiwidgetJumperT12.cpp simulateduiwidgetJumperTLITE.cpp + simulateduiwidgetJumperTPRO.cpp simulateduiwidgetJumperT16.cpp simulateduiwidgetJumperT18.cpp simulateduiwidgetTX12.cpp @@ -46,6 +47,7 @@ set(simulation_UIS simulateduiwidgetX12.ui simulateduiwidgetJumperT12.ui simulateduiwidgetJumperTLITE.ui + simulateduiwidgetJumperTPRO.ui simulateduiwidgetJumperT16.ui simulateduiwidgetJumperT18.ui simulateduiwidgetTX12.ui diff --git a/companion/src/simulation/simulateduiwidget.h b/companion/src/simulation/simulateduiwidget.h index 579ad567f..187a60660 100644 --- a/companion/src/simulation/simulateduiwidget.h +++ b/companion/src/simulation/simulateduiwidget.h @@ -113,6 +113,7 @@ namespace Ui { class SimulatedUIWidgetX12; class SimulatedUIWidgetJumperT12; class SimulatedUIWidgetJumperTLITE; + class SimulatedUIWidgetJumperTPRO; class SimulatedUIWidgetJumperT16; class SimulatedUIWidgetJumperT18; class SimulatedUIWidgetTX16S; @@ -258,6 +259,18 @@ class SimulatedUIWidgetJumperTLITE: public SimulatedUIWidget Ui::SimulatedUIWidgetJumperTLITE * ui; }; +class SimulatedUIWidgetJumperTPRO: public SimulatedUIWidget +{ + Q_OBJECT + + public: + explicit SimulatedUIWidgetJumperTPRO(SimulatorInterface * simulator, QWidget * parent = NULL); + virtual ~SimulatedUIWidgetJumperTPRO(); + + private: + Ui::SimulatedUIWidgetJumperTPRO * ui; +}; + class SimulatedUIWidgetJumperT16: public SimulatedUIWidget { Q_OBJECT diff --git a/companion/src/simulation/simulateduiwidgetJumperTPRO.cpp b/companion/src/simulation/simulateduiwidgetJumperTPRO.cpp new file mode 100644 index 000000000..e46c7fbad --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetJumperTPRO.cpp @@ -0,0 +1,54 @@ +#include "simulateduiwidget.h" +#include "ui_simulateduiwidgetJumperTPRO.h" + +// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h + +SimulatedUIWidgetJumperTPRO::SimulatedUIWidgetJumperTPRO(SimulatorInterface *simulator, QWidget * parent): + SimulatedUIWidget(simulator, parent), + ui(new Ui::SimulatedUIWidgetJumperTPRO) +{ + RadioUiAction * act; + + ui->setupUi(this); + + act = new RadioUiAction(0, QList() << Qt::Key_PageUp << Qt::Key_Up, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_MENU_ICN); + addRadioWidget(ui->leftbuttons->addArea(QRect(70, 85, 110, 90), "JumperTPRO/left.png", act)); + + act = new RadioUiAction(3, QList() << Qt::Key_PageDown << Qt::Key_Down, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_PAGE); + addRadioWidget(ui->leftbuttons->addArea(QRect(53, 174, 110, 90), "JumperTPRO/left.png", act)); + + act = new RadioUiAction(1, QList() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT); + addRadioWidget(ui->leftbuttons->addArea(QRect(11, 257, 110, 90), "JumperTPRO/left.png", act)); + + m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); + addRadioWidget(ui->rightbuttons->addArea(QRect(10, 96, 200, 220), "JumperTPRO/right.png", m_mouseMidClickAction)); + + //addRadioWidget(ui->leftbuttons->addArea(QRect(10, 65, 70, 50), "JumperTPRO/left_scrnshot.png", m_screenshotAction)); + + m_backlightColors << QColor(215, 243, 255); // X7 Blue + m_backlightColors << QColor(166,247,159); + m_backlightColors << QColor(247,159,166); + m_backlightColors << QColor(255,195,151); + m_backlightColors << QColor(247,242,159); + + setLcd(ui->lcd); + + QString css = "#radioUiWidget {" + "background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1," + "stop:0 rgba(255, 255, 255, 255)," + "stop:0.757062 rgba(241, 238, 238, 255)," + "stop:1 rgba(247, 245, 245, 255));" + "}"; + + QTimer * tim = new QTimer(this); + tim->setSingleShot(true); + connect(tim, &QTimer::timeout, [this, css]() { + emit customStyleRequest(css); + }); + tim->start(100); +} + +SimulatedUIWidgetJumperTPRO::~SimulatedUIWidgetJumperTPRO() +{ + delete ui; +} diff --git a/companion/src/simulation/simulateduiwidgetJumperTPRO.ui b/companion/src/simulation/simulateduiwidgetJumperTPRO.ui new file mode 100644 index 000000000..5a77f11ff --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetJumperTPRO.ui @@ -0,0 +1,258 @@ + + + SimulatedUIWidgetJumperTPRO + + + + 0 + 0 + 725 + 389 + + + + + 0 + 0 + + + + + 725 + 389 + + + + + 501 + 310 + + + + Jumper T-Pro Simulator + + + background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:0.757062 rgba(241, 238, 238, 255), stop:1 rgba(247, 245, 245, 255)); + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 234 + 368 + + + + + 234 + 368 + + + + background:url(:/images/simulator/JumperTPRO/left.png); + + + + + + + + 0 + 0 + + + + + 256 + 231 + + + + + 256 + 231 + + + + background-color: rgb(215, 243, 255); + + + + + + + + 0 + 0 + + + + + 236 + 368 + + + + + 236 + 368 + + + + background:url(:/images/simulator/JumperTPRO/right.png) + + + + + + + + 0 + 0 + + + + + 255 + 85 + + + + + 255 + 85 + + + + background:url(:/images/simulator/JumperTPRO/top.png) + + + + + + + + 0 + 0 + + + + + 255 + 131 + + + + + 255 + 131 + + + + background:url(:/images/simulator/JumperTPRO/bottom.png) + + + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + 16777215 + 12 + + + + + 0 + 12 + + + + background-color: rgb(255, 255, 255); + + + + + + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + 16777215 + 10 + + + + background-color: rgb(247, 245, 245); + + + + + + + + + + + LcdWidget + QWidget +
lcdwidget.h
+ 1 +
+ + ButtonsWidget + QWidget +
buttonswidget.h
+ 1 +
+
+ + +
diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index b087c7055..8f3ef08c2 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -94,6 +94,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato case Board::BOARD_JUMPER_TLITE: radioUiWidget = new SimulatedUIWidgetJumperTLITE(simulator, this); break; + case Board::BOARD_JUMPER_TPRO: + radioUiWidget = new SimulatedUIWidgetJumperTPRO(simulator, this); + break; case Board::BOARD_JUMPER_T16: radioUiWidget = new SimulatedUIWidgetJumperT16(simulator, this); break; diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index fd108bf56..5af5187c5 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -419,7 +419,12 @@ enum SwitchSources { SWSRC_SD2, #endif -#if defined(STORAGE_SWITCH_E) +#if defined(FUNCTION_SWITCHES) && defined(RADIO_TPRO) + SWSRC_FIRST_FUNCTION_SWITCH SKIP, + SWSRC_SE0 = SWSRC_FIRST_FUNCTION_SWITCH, + SWSRC_SE1, + SWSRC_SE2, +#elif defined(STORAGE_SWITCH_E) SWSRC_SE0, SWSRC_SE1, SWSRC_SE2, @@ -569,7 +574,7 @@ enum SwitchSources { SWSRC_INVERT SKIP = SWSRC_COUNT+1, }; -#if NUM_SWITCHES >= 8 +#if NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES >= 8 #define SWSRC_TRAINER SWSRC_SH2 #else #define SWSRC_TRAINER SWSRC_LAST_SWITCH, @@ -786,11 +791,15 @@ enum MixSources { static_assert(MIXSRC_FIRST_LOGICAL_SWITCH == MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES, "Wrong switches definition in MIXSRC list"); #endif -#define MIXSRC_FIRST (MIXSRC_NONE + 1) -#define MIXSRC_LAST MIXSRC_LAST_CH -#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES - 1) -#define INPUTSRC_FIRST MIXSRC_Rud -#define INPUTSRC_LAST MIXSRC_LAST_TELEM +#define MIXSRC_FIRST (MIXSRC_NONE + 1) +#define MIXSRC_LAST MIXSRC_LAST_CH +#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES - 1) +#define INPUTSRC_FIRST MIXSRC_Rud +#define INPUTSRC_LAST MIXSRC_LAST_TELEM +#if defined(FUNCTION_SWITCHES) +#define MIXSRC_LAST_REGULAR_SWITCH (MIXSRC_FIRST_SWITCH + NUM_REGULAR_SWITCHES - 1) +#define MIXSRC_FIRST_FS_SWITCH (MIXSRC_LAST_REGULAR_SWITCH + 1) +#endif enum BacklightMode { e_backlight_mode_off = 0, diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 5cc4c4319..8da911cf5 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -121,6 +121,9 @@ static inline void check_struct() #elif defined(PCBXLITE) CHKSIZE(RadioData, 858); CHKSIZE(ModelData, 6159); +#elif defined(RADIO_TPRO) + CHKSIZE(RadioData, 841); + CHKSIZE(ModelData, 6184); #elif defined(PCBX7) CHKSIZE(RadioData, 864); CHKSIZE(ModelData, 6159); diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index e062e926d..c4453ee69 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -616,6 +616,17 @@ PACK(struct CustomScreenData { #define SCRIPT_DATA #endif +#if defined(FUNCTION_SWITCHES) && NUM_FUNCTIONS_SWITCHES < 8 + #define FUNCTION_SWITCHS_FIELDS \ + uint16_t functionSwitchConfig; \ + uint16_t functionSwitchGroup; \ + uint16_t functionSwitchStartConfig; \ + uint8_t functionSwitchLogicalState; \ + char switchNames[NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME]; +#else + #define FUNCTION_SWITCHS_FIELDS +#endif + PACK(struct PartialModel { ModelHeader header; TimerData timers[MAX_TIMERS]; @@ -683,6 +694,8 @@ PACK(struct ModelData { char modelRegistrationID[PXX2_LEN_REGISTRATION_ID]; + FUNCTION_SWITCHS_FIELDS + bool isTrainerTraineeEnable() const { #if defined(PCBNV14) @@ -794,7 +807,7 @@ PACK(struct TrainerData { uint8_t backlightColor; \ CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \ swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \ - char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME] SKIP; \ + char switchNames[STORAGE_NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME] SKIP; \ char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP; \ BLUETOOTH_FIELDS #else diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index f6a6c6160..920647245 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -39,7 +39,7 @@ uint8_t g_moduleIdx; uint8_t getSwitchWarningsCount() { uint8_t count = 0; - for (int i=0; ipersistent = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_PERSISTENT, STR_VPERSISTENT, timer->persistent, 0, 2, attr, event); break; } +#if defined(FUNCTION_SWITCHES) + case ITEM_MODEL_SETUP_LABEL: + lcdDrawTextAlignedLeft(y, "Function Switches"); + break; + + case ITEM_MODEL_SETUP_SW1: + case ITEM_MODEL_SETUP_SW2: + case ITEM_MODEL_SETUP_SW3: + case ITEM_MODEL_SETUP_SW4: + case ITEM_MODEL_SETUP_SW5: + case ITEM_MODEL_SETUP_SW6: + { + int index = k - ITEM_MODEL_SETUP_SW1; + int config = FSWITCH_CONFIG(index); + lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH + NUM_REGULAR_SWITCHES - MIXSRC_Rud + index + 1, menuHorizontalPosition < 0 ? attr : 0); + if (ZEXIST(g_model.switchNames[index]) || (attr && s_editMode > 0 && menuHorizontalPosition == 0)) + editName(35, y, g_model.switchNames[index], LEN_SWITCH_NAME, event, menuHorizontalPosition == 0 ? attr : 0, 0, old_editMode); + else + lcdDrawMMM(35, y, menuHorizontalPosition == 0 ? attr : 0); + config = editChoice(30 + 5*FW, y, "", STR_SWTYPES, config, SWITCH_NONE, SWITCH_2POS, menuHorizontalPosition == 1 ? attr : 0, event); + if (attr && checkIncDec_Ret) { + swconfig_t mask = (swconfig_t)0x03 << (2*index); + g_model.functionSwitchConfig = (g_model.functionSwitchConfig & ~mask) | ((swconfig_t(config) & 0x03) << (2*index)); + } + + config = FSWITCH_GROUP(index); + config = editChoice(30 + 15*FW, y, "", STR_FSGROUPS, config, 0, 3, menuHorizontalPosition == 2 ? attr : 0, event); + if (attr && checkIncDec_Ret && menuHorizontalPosition == 2) { + swconfig_t mask = (swconfig_t) 0x03 << (2 * index); + g_model.functionSwitchGroup = (g_model.functionSwitchGroup & ~mask) | ((swconfig_t(config) & 0x03) << (2 * index)); + } + break; + } + + case ITEM_MODEL_SETUP_FS_STARTUP: + { + char c; + lcdDrawText(0, y, INDENT "Start", menuHorizontalPosition < 0 ? attr : 0); + for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { + uint8_t startPos = (g_model.functionSwitchStartConfig >> 2 * i) & 0x03; + c = STR_CHAR_UP STR_CHAR_DOWN "="[(g_model.functionSwitchStartConfig >> 2 * i) & 0x03]; + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN - (2 + FW) + i * 2 * FW, y, i + 1, 0); + lcdDrawChar(lcdNextPos, y, c, attr && (menuHorizontalPosition == i) ? (s_editMode ? INVERS + BLINK : INVERS) : 0); + if (attr && menuHorizontalPosition == i) { + CHECK_INCDEC_MODELVAR(event, startPos, 0, 2); + } + if (attr && checkIncDec_Ret) { + swconfig_t mask = (swconfig_t)0x03 << (2*i); + g_model.functionSwitchStartConfig = (g_model.functionSwitchStartConfig & ~mask) | ((swconfig_t(startPos) & 0x03) << (2*i)); + storageDirty(EE_MODEL); + } + } + break; + } +#endif case ITEM_MODEL_SETUP_EXTENDED_LIMITS: g_model.extendedLimits = editCheckBox(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, STR_ELIMITS, attr, event); break; @@ -724,7 +796,7 @@ void menuModelSetup(event_t event) } int current = 0; - for (int i = 0; i < NUM_SWITCHES; i++) { + for (int i = 0; i < NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES; i++) { if (SWITCH_WARNING_ALLOWED(i)) { div_t qr = div(current, MAX_SWITCH_PER_LINE); if (!READ_ONLY() && event == EVT_KEY_BREAK(KEY_ENTER) && attr && diff --git a/radio/src/gui/128x64/radio_diagkeys.cpp b/radio/src/gui/128x64/radio_diagkeys.cpp index 02f9b4b86..2452b900b 100644 --- a/radio/src/gui/128x64/radio_diagkeys.cpp +++ b/radio/src/gui/128x64/radio_diagkeys.cpp @@ -41,7 +41,7 @@ void menuRadioDiagKeys(event_t event) lcdDrawText(14*FW, MENU_HEADER_HEIGHT + 1, STR_VTRIM); - for (uint8_t i=0; i<9; i++) { + for (uint8_t i=0; i<10; i++) { coord_t y; if (i < NUM_TRIMS_KEYS) { @@ -69,10 +69,19 @@ void menuRadioDiagKeys(event_t event) drawSwitch(8*FW, y, i+1, 0); displaySwitchState(11*FW+2, y, i); } +#elif (NUM_SWITCHES > 6) + if (i < NUM_SWITCHES) { + if (SWITCH_EXISTS(i)) { + y = (i > 4) ? FH*(i-4) : MENU_HEADER_HEIGHT + FH*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); + } + } #else if (i < NUM_SWITCHES) { if (SWITCH_EXISTS(i)) { - y = (NUM_SWITCHES > 6 ? 0 : MENU_HEADER_HEIGHT) + FH*i; + y = (NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES > 6 ? 0 : MENU_HEADER_HEIGHT) + FH*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(8*FW+4, y, sw, 0); @@ -81,8 +90,18 @@ void menuRadioDiagKeys(event_t event) #endif } +#if defined(FUNCTION_SWITCHES) && defined(DEBUG) + lcdDrawText(LCD_W / 2 , LCD_H - 2 * FH, "Phys"); + lcdDrawText(LCD_W / 2 , LCD_H - 1 * FH, "Log"); + + for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { + lcdDrawNumber(LCD_W / 2 + 20 + (i + 1) * FW , LCD_H - 2 * FH, getFSPhysicalState(i)); + lcdDrawNumber(LCD_W / 2 + 20 + (i + 1) * FW , LCD_H - 1 * FH, getFSLogicalState(i)); + } +#endif + #if defined(ROTARY_ENCODER_NAVIGATION) - coord_t y = MENU_HEADER_HEIGHT + 1 + FH*KEY_COUNT; + coord_t y = LCD_H - FH - 1; lcdDrawText(0, y, STR_ROTARY_ENCODER); lcdDrawNumber(5*FW+FWNUM+2, y, rotencValue / ROTARY_ENCODER_GRANULARITY, RIGHT); #endif diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 471dc7168..35039c4a7 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -660,7 +660,7 @@ void menuMainView(event_t event) } } #elif defined(PCBTARANIS) - uint8_t switches = min(NUM_SWITCHES, 6); + uint8_t switches = min(NUM_SWITCHES- NUM_FUNCTIONS_SWITCHES, 6); for (int i = 0; i < switches; ++i) { if (SWITCH_EXISTS(i)) { uint8_t x = 2 * FW - 2, y = 4 * FH + i * FH + 1; diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index 48bb47246..67de15c46 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -55,6 +55,7 @@ enum { ITEM_RADIO_HARDWARE_SB, ITEM_RADIO_HARDWARE_SC, ITEM_RADIO_HARDWARE_SD, +#if !defined(RADIO_TPRO) #if defined(HARDWARE_SWITCH_E) ITEM_RADIO_HARDWARE_SE, #endif @@ -73,6 +74,7 @@ enum { #if defined(HARDWARE_SWITCH_J) ITEM_RADIO_HARDWARE_SJ, #endif +#endif #if defined(HARDWARE_SWITCH_K) ITEM_RADIO_HARDWARE_SK, ITEM_RADIO_HARDWARE_SL, @@ -154,6 +156,8 @@ enum { #if defined(PCBX9E) #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 +#elif defined(RADIO_TPRO) + #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif defined(RADIO_T12) #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|HIDDEN_ROW, NAVIGATION_LINE_BY_LINE|HIDDEN_ROW #elif NUM_SWITCHES == 9 @@ -432,6 +436,7 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_HARDWARE_SB: case ITEM_RADIO_HARDWARE_SC: case ITEM_RADIO_HARDWARE_SD: +#if !defined(RADIO_TPRO) #if defined(HARDWARE_SWITCH_E) case ITEM_RADIO_HARDWARE_SE: #endif @@ -450,6 +455,7 @@ void menuRadioHardware(event_t event) #if defined(HARDWARE_SWITCH_J) case ITEM_RADIO_HARDWARE_SJ: #endif +#endif #if defined(HARDWARE_SWITCH_K) case ITEM_RADIO_HARDWARE_SK: case ITEM_RADIO_HARDWARE_SL: diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp index a7e5dc6c9..a02c3a78b 100644 --- a/radio/src/hal/adc_driver.cpp +++ b/radio/src/hal/adc_driver.cpp @@ -59,6 +59,8 @@ const etx_hal_adc_driver_t* etx_hal_adc_driver = nullptr; const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, -1,-1, 1, 1}; #elif defined(RADIO_ZORRO) const int8_t adcDirection[NUM_ANALOGS] = {-1, 1, 1, -1, -1, 1, 1, 1}; +#elif defined(RADIO_TPRO) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1, 1, 1}; #elif defined(PCBX7) const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1, 1}; #elif defined(PCBX9LITE) diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt index 8a75d379c..685778108 100644 --- a/radio/src/lua/CMakeLists.txt +++ b/radio/src/lua/CMakeLists.txt @@ -30,6 +30,7 @@ if(PYTHONINTERP_FOUND) add_lua_export_target(x12s ${LUA_INCLUDES} -DPCBHORUS -DPCBX12S) add_lua_export_target(t12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T12) add_lua_export_target(tlite ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_TLITE) + add_lua_export_target(tpro ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_TPRO) add_lua_export_target(tx12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_TX12) add_lua_export_target(zorro ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_ZORRO) add_lua_export_target(t8 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T8) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 8ac29f153..354cdd1c8 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -50,6 +50,8 @@ #include "lua/lua_exports_t12.inc" #elif defined(RADIO_TLITE) #include "lua/lua_exports_tlite.inc" +#elif defined(RADIO_TPRO) + #include "lua/lua_exports_tpro.inc" #elif defined(RADIO_TX12) #include "lua/lua_exports_tx12.inc" #elif defined(RADIO_ZORRO) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 92214f605..cdb90e6df 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -348,6 +348,20 @@ getvalue_t getValue(mixsrc_t i) // TODO : find a better define #if defined(PCBFRSKY) || defined(PCBFLYSKY) +#if defined(FUNCTION_SWITCHES) + else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_REGULAR_SWITCH) { + mixsrc_t sw = i - MIXSRC_FIRST_SWITCH; + if (SWITCH_EXISTS(sw)) { + return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024)); + } + else { + return 0; + } + } + else if (i >= MIXSRC_FIRST_FS_SWITCH && i <= MIXSRC_LAST_SWITCH) { + return getFSLogicalState(i - MIXSRC_FIRST_SWITCH - NUM_REGULAR_SWITCHES) ? +1024 : -1024; + } +#else else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_SWITCH) { mixsrc_t sw = i - MIXSRC_FIRST_SWITCH; if (SWITCH_EXISTS(sw)) { @@ -357,6 +371,7 @@ getvalue_t getValue(mixsrc_t i) return 0; } } +#endif #else else if (i == MIXSRC_3POS) { return (getSwitch(SW_ID0+1) ? -1024 : (getSwitch(SW_ID1+1) ? 0 : 1024)); diff --git a/radio/src/model_init.cpp b/radio/src/model_init.cpp index 492ccb190..ce3b3cf7b 100644 --- a/radio/src/model_init.cpp +++ b/radio/src/model_init.cpp @@ -114,6 +114,13 @@ 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; +#endif + #if defined(COLORLCD) //TODO: not sure yet we need it here loadDefaultLayout(); diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 958e529a3..a8117e792 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -83,9 +83,18 @@ #if defined(PCBFRSKY) || defined(PCBNV14) #define SWITCH_CONFIG(x) (bfGet(g_eeGeneral.switchConfig, 2*(x), 2)) +#if defined(FUNCTION_SWITCHES) + #define FSWITCH_CONFIG(x) (bfGet(g_model.functionSwitchConfig, 2*(x), 2)) + #define FSWITCH_GROUP(x) (bfGet(g_model.functionSwitchGroup, 2*(x), 2)) + #define IS_SWITCH_FS(x) (x >= NUM_REGULAR_SWITCHES) + #define SWITCH_EXISTS(x) (IS_SWITCH_FS(x) ? true : (FSWITCH_CONFIG(x) != SWITCH_NONE)) + #define IS_CONFIG_3POS(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - NUM_REGULAR_SWITCHES) == SWITCH_3POS) : (SWITCH_CONFIG(x) == SWITCH_3POS)) + #define IS_CONFIG_TOGGLE(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - NUM_REGULAR_SWITCHES) == 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) +#endif #define SWITCH_WARNING_ALLOWED(x) (SWITCH_EXISTS(x) && !IS_CONFIG_TOGGLE(x)) #else #define IS_CONFIG_3POS(x) IS_3POS(x) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index f358af4a4..16895d2c6 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -171,6 +171,10 @@ void per10ms() readKeysAndTrims(); +#if defined(FUNCTION_SWITCHES) + evalFunctionSwitches(); +#endif + #if defined(ROTARY_ENCODER_NAVIGATION) if (IS_ROTARY_ENCODER_NAVIGATION_ENABLE()) { static rotenc_t rePreviousValue; @@ -372,7 +376,6 @@ uint16_t evalChkSum() return sum; } - bool isInputRecursive(int index) { ExpoData * line = expoAddress(0); @@ -1414,6 +1417,12 @@ void opentxStart(const uint8_t startOptions = OPENTX_START_DEFAULT_ARGS) ALERT(STR_TEST_WARNING, TR_TEST_NOTSAFE, AU_ERROR); #endif +#if defined(FUNCTION_SWITCHES) + if (!UNEXPECTED_SHUTDOWN()) { + setFSStartupPosition(); + } +#endif + #if defined(GUI) if (calibration_needed) { #if defined(LIBOPENUI) diff --git a/radio/src/opentx_constants.h b/radio/src/opentx_constants.h index 4b6559a65..bcb934df5 100644 --- a/radio/src/opentx_constants.h +++ b/radio/src/opentx_constants.h @@ -41,6 +41,12 @@ enum SliderConfig { SLIDER_WITH_DETENT, }; +enum fsStartPositionType { + FS_START_UP, + FS_START_DOWN, + FS_START_PREVIOUS +}; + enum CalibrationState { CALIB_START, CALIB_SET_MIDPOINT, diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 2ac4f5dc6..43896b690 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -152,6 +152,8 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3D78746F // otx for Jumper T12 #elif defined(RADIO_TLITE) #define OTX_FOURCC 0x4278746F // otx for Jumper TLite +#elif defined(RADIO_TPRO) + #define OTX_FOURCC 0x4678746F // otx for Jumper TPro #elif defined(RADIO_TX12) #define OTX_FOURCC 0x4178746F // otx for Radiomaster TX12 #elif defined(RADIO_ZORRO) diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index 53410cb2e..e88309434 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -445,7 +445,14 @@ void OpenTxSim::updateKeysAndSwitches(bool start) SWITCH_KEY(C, 2, 3); SWITCH_KEY(D, 3, 3); - #if defined(HARDWARE_SWITCH_G) && defined(HARDWARE_SWITCH_H) + #if defined(RADIO_TPRO) + SWITCH_KEY(1, 4, 2); + SWITCH_KEY(2, 5, 2); + SWITCH_KEY(3, 6, 2); + SWITCH_KEY(4, 7, 2); + SWITCH_KEY(5, 8, 2); + SWITCH_KEY(6, 9, 2); + #elif defined(HARDWARE_SWITCH_G) && defined(HARDWARE_SWITCH_H) SWITCH_KEY(E, 4, 3); SWITCH_KEY(F, 5, 2); SWITCH_KEY(G, 6, 3); diff --git a/radio/src/storage/conversions/CMakeLists.txt b/radio/src/storage/conversions/CMakeLists.txt index 601482530..75ec49ad2 100644 --- a/radio/src/storage/conversions/CMakeLists.txt +++ b/radio/src/storage/conversions/CMakeLists.txt @@ -1,8 +1,11 @@ set(STORAGE_CONVERSIONS 219) -if(PCB STREQUAL X7 AND PCBREV STREQUAL ZORRO) - set(STORAGE_CONVERSIONS 221) +if(PCB STREQUAL X7) + if(PCBREV STREQUAL ZORRO OR PCBREV STREQUAL TPRO) + set(STORAGE_CONVERSIONS 221) + endif() endif() +message("Storage conversion: ${STORAGE_CONVERSIONS}") if(STORAGE_CONVERSIONS) add_definitions(-DSTORAGE_CONVERSIONS=${STORAGE_CONVERSIONS}) diff --git a/radio/src/storage/conversions/conversions_219_220.cpp b/radio/src/storage/conversions/conversions_219_220.cpp index d65d528af..efbaaa7c7 100644 --- a/radio/src/storage/conversions/conversions_219_220.cpp +++ b/radio/src/storage/conversions/conversions_219_220.cpp @@ -35,6 +35,8 @@ #include #endif +#if STORAGE_CONVERSIONS < 220 + // // Summary of all changes between 219 & 220 // @@ -349,3 +351,5 @@ const char* convertRadioData_219_to_220() return nullptr; } #endif + +#endif diff --git a/radio/src/storage/conversions/conversions_220_221.cpp b/radio/src/storage/conversions/conversions_220_221.cpp index 634f8b960..7a1981c82 100644 --- a/radio/src/storage/conversions/conversions_220_221.cpp +++ b/radio/src/storage/conversions/conversions_220_221.cpp @@ -44,6 +44,8 @@ namespace yaml_conv_220 { const YamlNode* get_partialmodel_nodes(); }; +#if STORAGE_CONVERSIONS < 221 + #if defined(STORAGE_MODELSLIST) void patchFilenameToYaml(char* str); @@ -184,3 +186,5 @@ const char* convertRadioData_220_to_221() } #endif + +#endif diff --git a/radio/src/storage/conversions/yaml/dataconstants_220.h b/radio/src/storage/conversions/yaml/dataconstants_220.h index aefde174c..a520dd2d2 100644 --- a/radio/src/storage/conversions/yaml/dataconstants_220.h +++ b/radio/src/storage/conversions/yaml/dataconstants_220.h @@ -92,6 +92,8 @@ #if defined(PCBXLITES) || defined(PCBXLITE) #define STORAGE_NUM_SWITCHES 6 +#elif defined(RADIO_TPRO) +#define STORAGE_NUM_SWITCHES 10 #elif defined(RADIO_TLITE) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_TX12) || defined(RADIO_T8) || defined(PCBX7ACCESS) || defined(PCBX7) #define STORAGE_NUM_SWITCHES 8 #elif defined(PCBX9LITES) diff --git a/radio/src/storage/conversions/yaml/datastructs_220.h b/radio/src/storage/conversions/yaml/datastructs_220.h index 2e5392317..b99edaf6e 100644 --- a/radio/src/storage/conversions/yaml/datastructs_220.h +++ b/radio/src/storage/conversions/yaml/datastructs_220.h @@ -999,6 +999,9 @@ static inline void check_struct() #elif defined(PCBXLITE) CHKSIZE(RadioData, 859); CHKSIZE(ModelData, 6157); +#elif defined(RADIO_TPRO) + CHKSIZE(RadioData, 860); + CHKSIZE(ModelData, 6157); #elif defined(PCBX7) CHKSIZE(RadioData, 865); CHKSIZE(ModelData, 6157); diff --git a/radio/src/storage/yaml/CMakeLists.txt b/radio/src/storage/yaml/CMakeLists.txt index f6ca45fc6..0611d5334 100644 --- a/radio/src/storage/yaml/CMakeLists.txt +++ b/radio/src/storage/yaml/CMakeLists.txt @@ -29,6 +29,8 @@ elseif(PCB STREQUAL X7) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_zorro.cpp) elseif(PCBREV STREQUAL T8) set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_t8.cpp) + elseif(PCBREV STREQUAL TPRO) + set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp) else() set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_x7.cpp) endif() diff --git a/radio/src/storage/yaml/yaml_datastructs.cpp b/radio/src/storage/yaml/yaml_datastructs.cpp index 11ae7730f..f7d3d1fa1 100644 --- a/radio/src/storage/yaml/yaml_datastructs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs.cpp @@ -44,6 +44,8 @@ #include "yaml_datastructs_zorro.cpp" #elif defined(RADIO_T8) #include "yaml_datastructs_t8.cpp" + #elif defined(RADIO_TPRO) + #include "yaml_datastructs_tpro.cpp" #else #include "yaml_datastructs_x7.cpp" #endif diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp new file mode 100644 index 000000000..bbc59e22c --- /dev/null +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -0,0 +1,880 @@ +// generated by generate_yaml.py + +// +// Enums first +// + +const struct YamlIdStr enum_BacklightMode[] = { + { e_backlight_mode_off, "backlight_mode_off" }, + { e_backlight_mode_keys, "backlight_mode_keys" }, + { e_backlight_mode_sticks, "backlight_mode_sticks" }, + { e_backlight_mode_all, "backlight_mode_all" }, + { e_backlight_mode_on, "backlight_mode_on" }, + { 0, NULL } +}; +const struct YamlIdStr enum_AntennaModes[] = { + { ANTENNA_MODE_INTERNAL, "MODE_INTERNAL" }, + { ANTENNA_MODE_ASK, "MODE_ASK" }, + { ANTENNA_MODE_PER_MODEL, "MODE_PER_MODEL" }, + { ANTENNA_MODE_EXTERNAL, "MODE_EXTERNAL" }, + { ANTENNA_MODE_FIRST, "MODE_FIRST" }, + { ANTENNA_MODE_LAST, "MODE_LAST" }, + { 0, NULL } +}; +const struct YamlIdStr enum_ModuleType[] = { + { MODULE_TYPE_NONE, "TYPE_NONE" }, + { MODULE_TYPE_PPM, "TYPE_PPM" }, + { MODULE_TYPE_XJT_PXX1, "TYPE_XJT_PXX1" }, + { MODULE_TYPE_ISRM_PXX2, "TYPE_ISRM_PXX2" }, + { MODULE_TYPE_DSM2, "TYPE_DSM2" }, + { MODULE_TYPE_CROSSFIRE, "TYPE_CROSSFIRE" }, + { MODULE_TYPE_MULTIMODULE, "TYPE_MULTIMODULE" }, + { MODULE_TYPE_R9M_PXX1, "TYPE_R9M_PXX1" }, + { MODULE_TYPE_R9M_PXX2, "TYPE_R9M_PXX2" }, + { MODULE_TYPE_R9M_LITE_PXX1, "TYPE_R9M_LITE_PXX1" }, + { MODULE_TYPE_R9M_LITE_PXX2, "TYPE_R9M_LITE_PXX2" }, + { MODULE_TYPE_GHOST, "TYPE_GHOST" }, + { MODULE_TYPE_R9M_LITE_PRO_PXX2, "TYPE_R9M_LITE_PRO_PXX2" }, + { MODULE_TYPE_SBUS, "TYPE_SBUS" }, + { MODULE_TYPE_XJT_LITE_PXX2, "TYPE_XJT_LITE_PXX2" }, + { MODULE_TYPE_FLYSKY, "TYPE_FLYSKY" }, + { MODULE_TYPE_COUNT, "TYPE_COUNT" }, + { MODULE_TYPE_MAX, "TYPE_MAX" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TrainerMultiplex[] = { + { TRAINER_OFF, "OFF" }, + { TRAINER_ADD, "ADD" }, + { TRAINER_REPL, "REPL" }, + { 0, NULL } +}; +const struct YamlIdStr enum_BeeperMode[] = { + { e_mode_quiet, "mode_quiet" }, + { e_mode_alarms, "mode_alarms" }, + { e_mode_nokeys, "mode_nokeys" }, + { e_mode_all, "mode_all" }, + { 0, NULL } +}; +const struct YamlIdStr enum_BluetoothModes[] = { + { BLUETOOTH_OFF, "OFF" }, + { BLUETOOTH_TELEMETRY, "TELEMETRY" }, + { BLUETOOTH_TRAINER, "TRAINER" }, + { 0, NULL } +}; +const struct YamlIdStr enum_Functions[] = { + { FUNC_OVERRIDE_CHANNEL, "OVERRIDE_CHANNEL" }, + { FUNC_TRAINER, "TRAINER" }, + { FUNC_INSTANT_TRIM, "INSTANT_TRIM" }, + { FUNC_RESET, "RESET" }, + { FUNC_SET_TIMER, "SET_TIMER" }, + { FUNC_ADJUST_GVAR, "ADJUST_GVAR" }, + { FUNC_VOLUME, "VOLUME" }, + { FUNC_SET_FAILSAFE, "SET_FAILSAFE" }, + { FUNC_RANGECHECK, "RANGECHECK" }, + { FUNC_BIND, "BIND" }, + { FUNC_PLAY_SOUND, "PLAY_SOUND" }, + { FUNC_PLAY_TRACK, "PLAY_TRACK" }, + { FUNC_PLAY_VALUE, "PLAY_VALUE" }, + { FUNC_RESERVE4, "RESERVE4" }, + { FUNC_PLAY_SCRIPT, "PLAY_SCRIPT" }, + { FUNC_RESERVE5, "RESERVE5" }, + { FUNC_BACKGND_MUSIC, "BACKGND_MUSIC" }, + { FUNC_BACKGND_MUSIC_PAUSE, "BACKGND_MUSIC_PAUSE" }, + { FUNC_VARIO, "VARIO" }, + { FUNC_HAPTIC, "HAPTIC" }, + { FUNC_LOGS, "LOGS" }, + { FUNC_BACKLIGHT, "BACKLIGHT" }, + { FUNC_SCREENSHOT, "SCREENSHOT" }, + { FUNC_RACING_MODE, "RACING_MODE" }, + { 0, NULL } +}; +const struct YamlIdStr enum_UartModes[] = { + { UART_MODE_NONE, "MODE_NONE" }, + { UART_MODE_TELEMETRY_MIRROR, "MODE_TELEMETRY_MIRROR" }, + { UART_MODE_TELEMETRY, "MODE_TELEMETRY" }, + { UART_MODE_SBUS_TRAINER, "MODE_SBUS_TRAINER" }, + { UART_MODE_LUA, "MODE_LUA" }, + { UART_MODE_COUNT, "MODE_COUNT" }, + { UART_MODE_MAX, "MODE_MAX" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TimerModes[] = { + { TMRMODE_OFF, "OFF" }, + { TMRMODE_ON, "ON" }, + { TMRMODE_START, "START" }, + { TMRMODE_THR, "THR" }, + { TMRMODE_THR_REL, "THR_REL" }, + { TMRMODE_THR_START, "THR_START" }, + { 0, NULL } +}; +const struct YamlIdStr enum_MixerMultiplex[] = { + { MLTPX_ADD, "ADD" }, + { MLTPX_MUL, "MUL" }, + { MLTPX_REPL, "REPL" }, + { 0, NULL } +}; +const struct YamlIdStr enum_MixSources[] = { + { MIXSRC_NONE, "NONE" }, + { MIXSRC_Rud, "Rud" }, + { MIXSRC_Ele, "Ele" }, + { MIXSRC_Thr, "Thr" }, + { MIXSRC_Ail, "Ail" }, + { MIXSRC_POT1, "POT1" }, + { MIXSRC_POT2, "POT2" }, + { MIXSRC_MAX, "MAX" }, + { MIXSRC_CYC1, "CYC1" }, + { MIXSRC_CYC2, "CYC2" }, + { MIXSRC_CYC3, "CYC3" }, + { MIXSRC_TrimRud, "TrimRud" }, + { MIXSRC_TrimEle, "TrimEle" }, + { MIXSRC_TrimThr, "TrimThr" }, + { MIXSRC_TrimAil, "TrimAil" }, + { MIXSRC_SA, "SA" }, + { MIXSRC_SB, "SB" }, + { MIXSRC_SC, "SC" }, + { MIXSRC_SD, "SD" }, + { MIXSRC_SE, "SE" }, + { MIXSRC_SF, "SF" }, + { MIXSRC_SG, "SG" }, + { MIXSRC_SH, "SH" }, + { MIXSRC_SI, "SI" }, + { MIXSRC_SJ, "SJ" }, + { MIXSRC_SW1, "SW1" }, + { MIXSRC_CH1, "CH1" }, + { MIXSRC_CH2, "CH2" }, + { MIXSRC_CH3, "CH3" }, + { MIXSRC_CH4, "CH4" }, + { MIXSRC_CH5, "CH5" }, + { MIXSRC_CH6, "CH6" }, + { MIXSRC_CH7, "CH7" }, + { MIXSRC_CH8, "CH8" }, + { MIXSRC_CH9, "CH9" }, + { MIXSRC_CH10, "CH10" }, + { MIXSRC_CH11, "CH11" }, + { MIXSRC_CH12, "CH12" }, + { MIXSRC_CH13, "CH13" }, + { MIXSRC_CH14, "CH14" }, + { MIXSRC_CH15, "CH15" }, + { MIXSRC_CH16, "CH16" }, + { MIXSRC_GVAR1, "GVAR1" }, + { MIXSRC_TX_VOLTAGE, "TX_VOLTAGE" }, + { MIXSRC_TX_TIME, "TX_TIME" }, + { MIXSRC_TX_GPS, "TX_GPS" }, + { MIXSRC_TIMER1, "TIMER1" }, + { MIXSRC_TIMER2, "TIMER2" }, + { MIXSRC_TIMER3, "TIMER3" }, + { 0, NULL } +}; +const struct YamlIdStr enum_LogicalSwitchesFunctions[] = { + { LS_FUNC_NONE, "FUNC_NONE" }, + { LS_FUNC_VEQUAL, "FUNC_VEQUAL" }, + { LS_FUNC_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL" }, + { LS_FUNC_VPOS, "FUNC_VPOS" }, + { LS_FUNC_VNEG, "FUNC_VNEG" }, + { LS_FUNC_RANGE, "FUNC_RANGE" }, + { LS_FUNC_APOS, "FUNC_APOS" }, + { LS_FUNC_ANEG, "FUNC_ANEG" }, + { LS_FUNC_AND, "FUNC_AND" }, + { LS_FUNC_OR, "FUNC_OR" }, + { LS_FUNC_XOR, "FUNC_XOR" }, + { LS_FUNC_EDGE, "FUNC_EDGE" }, + { LS_FUNC_EQUAL, "FUNC_EQUAL" }, + { LS_FUNC_GREATER, "FUNC_GREATER" }, + { LS_FUNC_LESS, "FUNC_LESS" }, + { LS_FUNC_DIFFEGREATER, "FUNC_DIFFEGREATER" }, + { LS_FUNC_ADIFFEGREATER, "FUNC_ADIFFEGREATER" }, + { LS_FUNC_TIMER, "FUNC_TIMER" }, + { LS_FUNC_STICKY, "FUNC_STICKY" }, + { LS_FUNC_COUNT, "FUNC_COUNT" }, + { LS_FUNC_MAX, "FUNC_MAX" }, + { 0, NULL } +}; +const struct YamlIdStr enum_SwashType[] = { + { SWASH_TYPE_NONE, "TYPE_NONE" }, + { SWASH_TYPE_120, "TYPE_120" }, + { SWASH_TYPE_120X, "TYPE_120X" }, + { SWASH_TYPE_140, "TYPE_140" }, + { SWASH_TYPE_90, "TYPE_90" }, + { 0, NULL } +}; +const struct YamlIdStr enum_SwitchSources[] = { + { SWSRC_NONE, "NONE" }, + { SWSRC_SA0, "SA0" }, + { SWSRC_SA1, "SA1" }, + { SWSRC_SA2, "SA2" }, + { SWSRC_SB0, "SB0" }, + { SWSRC_SB1, "SB1" }, + { SWSRC_SB2, "SB2" }, + { SWSRC_SC0, "SC0" }, + { SWSRC_SC1, "SC1" }, + { SWSRC_SC2, "SC2" }, + { SWSRC_SD0, "SD0" }, + { SWSRC_SD1, "SD1" }, + { SWSRC_SD2, "SD2" }, + { SWSRC_SE0, "SE0" }, + { SWSRC_SE1, "SE1" }, + { SWSRC_SE2, "SE2" }, + { SWSRC_SF0, "SF0" }, + { SWSRC_SF1, "SF1" }, + { SWSRC_SF2, "SF2" }, + { SWSRC_SG0, "SG0" }, + { SWSRC_SG1, "SG1" }, + { SWSRC_SG2, "SG2" }, + { SWSRC_SH0, "SH0" }, + { SWSRC_SH1, "SH1" }, + { SWSRC_SH2, "SH2" }, + { SWSRC_SI0, "SI0" }, + { SWSRC_SI1, "SI1" }, + { SWSRC_SI2, "SI2" }, + { SWSRC_SJ0, "SJ0" }, + { SWSRC_SJ1, "SJ1" }, + { SWSRC_SJ2, "SJ2" }, + { SWSRC_TrimRudLeft, "TrimRudLeft" }, + { SWSRC_TrimRudRight, "TrimRudRight" }, + { SWSRC_TrimEleDown, "TrimEleDown" }, + { SWSRC_TrimEleUp, "TrimEleUp" }, + { SWSRC_TrimThrDown, "TrimThrDown" }, + { SWSRC_TrimThrUp, "TrimThrUp" }, + { SWSRC_TrimAilLeft, "TrimAilLeft" }, + { SWSRC_TrimAilRight, "TrimAilRight" }, + { SWSRC_SW1, "SW1" }, + { SWSRC_SW2, "SW2" }, + { SWSRC_ON, "ON" }, + { SWSRC_ONE, "ONE" }, + { SWSRC_TELEMETRY_STREAMING, "TELEMETRY_STREAMING" }, + { SWSRC_RADIO_ACTIVITY, "RADIO_ACTIVITY" }, + { SWSRC_OFF, "OFF" }, + { 0, NULL } +}; +const struct YamlIdStr enum_PotsWarnMode[] = { + { POTS_WARN_OFF, "WARN_OFF" }, + { POTS_WARN_MANUAL, "WARN_MANUAL" }, + { POTS_WARN_AUTO, "WARN_AUTO" }, + { 0, NULL } +}; +const struct YamlIdStr enum_FailsafeModes[] = { + { FAILSAFE_NOT_SET, "NOT_SET" }, + { FAILSAFE_HOLD, "HOLD" }, + { FAILSAFE_CUSTOM, "CUSTOM" }, + { FAILSAFE_NOPULSES, "NOPULSES" }, + { FAILSAFE_RECEIVER, "RECEIVER" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TelemetrySensorFormula[] = { + { TELEM_FORMULA_ADD, "FORMULA_ADD" }, + { TELEM_FORMULA_AVERAGE, "FORMULA_AVERAGE" }, + { TELEM_FORMULA_MIN, "FORMULA_MIN" }, + { TELEM_FORMULA_MAX, "FORMULA_MAX" }, + { TELEM_FORMULA_MULTIPLY, "FORMULA_MULTIPLY" }, + { TELEM_FORMULA_TOTALIZE, "FORMULA_TOTALIZE" }, + { TELEM_FORMULA_CELL, "FORMULA_CELL" }, + { TELEM_FORMULA_CONSUMPTION, "FORMULA_CONSUMPTION" }, + { TELEM_FORMULA_DIST, "FORMULA_DIST" }, + { 0, NULL } +}; +const struct YamlIdStr enum_TelemetrySensorType[] = { + { TELEM_TYPE_CUSTOM, "TYPE_CUSTOM" }, + { TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" }, + { 0, NULL } +}; + +// +// Structs last +// + +static const struct YamlNode struct_CalibData[] = { + YAML_IDX_CUST("calib",r_calib,w_calib), + YAML_SIGNED( "mid", 16 ), + YAML_SIGNED( "spanNeg", 16 ), + YAML_SIGNED( "spanPos", 16 ), + YAML_END +}; +static const struct YamlNode struct_signed_16[] = { + YAML_IDX, + YAML_SIGNED( "val", 16 ), + YAML_END +}; +static const struct YamlNode struct_TrainerMix[] = { + YAML_IDX, + YAML_UNSIGNED( "srcChn", 6 ), + YAML_ENUM("mode", 2, enum_TrainerMultiplex), + YAML_SIGNED( "studWeight", 8 ), + YAML_END +}; +static const struct YamlNode struct_TrainerData[] = { + YAML_ARRAY("calib", 16, 4, struct_signed_16, NULL), + YAML_ARRAY("mix", 16, 4, struct_TrainerMix, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_1[] = { + YAML_STRING("name", 6), + YAML_END +}; +static const struct YamlNode struct_anonymous_2[] = { + YAML_SIGNED( "val", 16 ), + YAML_UNSIGNED( "mode", 8 ), + YAML_UNSIGNED( "param", 8 ), + YAML_SIGNED( "spare", 32 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_3[] = { + YAML_SIGNED( "val1", 32 ), + YAML_SIGNED( "val2", 32 ), + YAML_END +}; +static const struct YamlNode union_anonymous_0_elmts[] = { + YAML_STRUCT("play", 48, struct_anonymous_1, NULL), + YAML_STRUCT("all", 64, struct_anonymous_2, NULL), + YAML_STRUCT("clear", 64, struct_anonymous_3, NULL), + YAML_END +}; +static const struct YamlNode struct_CustomFunctionData[] = { + YAML_IDX, + YAML_SIGNED_CUST( "swtch", 9, r_swtchSrc, w_swtchSrc ), + YAML_ENUM("func", 7, enum_Functions), + YAML_CUSTOM("def",r_customFn,w_customFn), + YAML_PADDING( 64 ), + YAML_PADDING( 8 ), + YAML_END +}; +static const struct YamlNode struct_string_24[] = { + YAML_IDX, + YAML_STRING("val", 3), + YAML_END +}; +static const struct YamlNode struct_RadioData[] = { + YAML_UNSIGNED( "version", 8 ), + YAML_PADDING( 16 ), + YAML_ARRAY("calib", 48, 6, struct_CalibData, NULL), + YAML_PADDING( 16 ), + YAML_SIGNED( "currModel", 8 ), + 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_UNSIGNED( "disableRtcWarning", 1 ), + YAML_UNSIGNED( "keysBacklight", 1 ), + YAML_PADDING( 1 ), + YAML_ENUM("internalModule", 8, enum_ModuleType), + YAML_STRUCT("trainer", 128, struct_TrainerData, NULL), + YAML_UNSIGNED( "view", 8 ), + YAML_PADDING( 2 ), + YAML_UNSIGNED( "fai", 1 ), + YAML_SIGNED_CUST( "beepMode", 2, r_beeperMode, w_beeperMode ), + YAML_UNSIGNED( "alarmsFlash", 1 ), + YAML_UNSIGNED( "disableMemoryWarning", 1 ), + YAML_UNSIGNED( "disableAlarmWarning", 1 ), + YAML_UNSIGNED( "stickMode", 2 ), + YAML_SIGNED( "timezone", 5 ), + YAML_UNSIGNED( "adjustRTC", 1 ), + YAML_UNSIGNED( "inactivityTimer", 8 ), + YAML_UNSIGNED( "telemetryBaudrate", 3 ), + YAML_SIGNED( "splashMode", 3 ), + YAML_SIGNED_CUST( "hapticMode", 2, r_beeperMode, w_beeperMode ), + YAML_SIGNED( "switchesDelay", 8 ), + YAML_UNSIGNED( "lightAutoOff", 8 ), + YAML_UNSIGNED( "templateSetup", 8 ), + YAML_SIGNED( "PPM_Multiplier", 8 ), + YAML_SIGNED_CUST( "hapticLength", 8, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "beepLength", 3, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "hapticStrength", 3, r_5pos, w_5pos ), + YAML_UNSIGNED( "gpsFormat", 1 ), + YAML_UNSIGNED( "unexpectedShutdown", 1 ), + YAML_UNSIGNED_CUST( "speakerPitch", 8, r_spPitch, w_spPitch ), + YAML_SIGNED_CUST( "speakerVolume", 8, r_vol, w_vol ), + YAML_SIGNED_CUST( "vBatMin", 8, r_vbat_min, w_vbat_min ), + YAML_SIGNED_CUST( "vBatMax", 8, r_vbat_max, w_vbat_max ), + YAML_UNSIGNED( "backlightBright", 8 ), + YAML_UNSIGNED( "globalTimer", 32 ), + YAML_UNSIGNED( "bluetoothBaudrate", 4 ), + YAML_ENUM("bluetoothMode", 4, enum_BluetoothModes), + YAML_UNSIGNED( "countryCode", 2 ), + YAML_SIGNED( "pwrOnSpeed", 3 ), + YAML_SIGNED( "pwrOffSpeed", 3 ), + YAML_UNSIGNED( "imperial", 1 ), + YAML_UNSIGNED( "jitterFilter", 1 ), + YAML_UNSIGNED( "disableRssiPoweroffAlarm", 1 ), + YAML_UNSIGNED( "USBMode", 2 ), + YAML_UNSIGNED( "jackMode", 2 ), + YAML_PADDING( 1 ), + YAML_STRING("ttsLanguage", 2), + YAML_SIGNED_CUST( "beepVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "wavVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "varioVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "backgroundVolume", 4, r_5pos, w_5pos ), + YAML_SIGNED_CUST( "varioPitch", 8, r_vPitch, w_vPitch ), + YAML_SIGNED_CUST( "varioRange", 8, r_vPitch, w_vPitch ), + YAML_SIGNED( "varioRepeat", 8 ), + YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_ENUM("auxSerialMode", 4, enum_UartModes), + YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr), + YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr), + YAML_UNSIGNED( "backlightColor", 8 ), + YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid), + YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr), + YAML_PADDING( 96 ), + YAML_PADDING( 144 ), + YAML_STRING("ownerRegistrationID", 8), + YAML_SIGNED( "uartSampleMode", 2 ), + YAML_END +}; +static const struct YamlNode struct_unsigned_8[] = { + YAML_IDX, + YAML_UNSIGNED( "val", 8 ), + YAML_END +}; +static const struct YamlNode struct_ModelHeader[] = { + YAML_STRING("name", 10), + YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL), + YAML_END +}; +static const struct YamlNode struct_TimerData[] = { + YAML_IDX, + YAML_UNSIGNED( "start", 22 ), + YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ), + YAML_SIGNED( "value", 22 ), + YAML_ENUM("mode", 3, enum_TimerModes), + YAML_UNSIGNED( "countdownBeep", 2 ), + YAML_UNSIGNED( "minuteBeep", 1 ), + YAML_UNSIGNED( "persistent", 2 ), + YAML_SIGNED( "countdownStart", 2 ), + YAML_STRING("name", 3), + YAML_END +}; +static const struct YamlNode struct_CurveRef[] = { + YAML_UNSIGNED( "type", 8 ), + YAML_SIGNED( "value", 8 ), + YAML_END +}; +static const struct YamlNode struct_MixData[] = { + YAML_SIGNED_CUST( "weight", 11, in_read_weight, in_write_weight ), + YAML_UNSIGNED( "destCh", 5 ), + YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), + YAML_UNSIGNED( "carryTrim", 1 ), + YAML_UNSIGNED( "mixWarn", 2 ), + YAML_ENUM("mltpx", 2, enum_MixerMultiplex), + YAML_PADDING( 1 ), + YAML_SIGNED( "offset", 14 ), + YAML_SIGNED_CUST( "swtch", 9, r_swtchSrc, w_swtchSrc ), + YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), + YAML_STRUCT("curve", 16, struct_CurveRef, NULL), + YAML_UNSIGNED( "delayUp", 8 ), + YAML_UNSIGNED( "delayDown", 8 ), + YAML_UNSIGNED( "speedUp", 8 ), + YAML_UNSIGNED( "speedDown", 8 ), + YAML_STRING("name", 6), + YAML_END +}; +static const struct YamlNode struct_LimitData[] = { + YAML_IDX, + YAML_SIGNED( "min", 11 ), + YAML_SIGNED( "max", 11 ), + YAML_SIGNED( "ppmCenter", 10 ), + YAML_SIGNED( "offset", 11 ), + YAML_UNSIGNED( "symetrical", 1 ), + YAML_UNSIGNED( "revert", 1 ), + YAML_PADDING( 3 ), + YAML_SIGNED( "curve", 8 ), + YAML_STRING("name", 4), + YAML_END +}; +static const struct YamlNode struct_ExpoData[] = { + YAML_UNSIGNED( "mode", 2 ), + YAML_UNSIGNED( "scale", 14 ), + YAML_UNSIGNED_CUST( "srcRaw", 10, r_mixSrcRaw, w_mixSrcRaw ), + YAML_SIGNED( "carryTrim", 6 ), + YAML_UNSIGNED( "chn", 5 ), + YAML_SIGNED_CUST( "swtch", 9, r_swtchSrc, w_swtchSrc ), + YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ), + YAML_SIGNED_CUST( "weight", 8, in_read_weight, in_write_weight ), + YAML_PADDING( 1 ), + YAML_STRING("name", 6), + YAML_SIGNED( "offset", 8 ), + YAML_STRUCT("curve", 16, struct_CurveRef, NULL), + YAML_END +}; +static const struct YamlNode struct_CurveHeader[] = { + YAML_IDX, + YAML_UNSIGNED( "type", 1 ), + YAML_UNSIGNED( "smooth", 1 ), + YAML_SIGNED( "points", 6 ), + YAML_STRING("name", 3), + YAML_END +}; +static const struct YamlNode struct_signed_8[] = { + YAML_IDX, + YAML_SIGNED( "val", 8 ), + YAML_END +}; +static const struct YamlNode struct_LogicalSwitchData[] = { + YAML_IDX, + YAML_ENUM("func", 8, enum_LogicalSwitchesFunctions), + YAML_CUSTOM("def",r_logicSw,w_logicSw), + YAML_PADDING( 10 ), + YAML_PADDING( 10 ), + YAML_SIGNED_CUST( "andsw", 9, r_swtchSrc, w_swtchSrc ), + YAML_PADDING( 1 ), + YAML_PADDING( 2 ), + YAML_PADDING( 16 ), + YAML_UNSIGNED( "delay", 8 ), + YAML_UNSIGNED( "duration", 8 ), + YAML_END +}; +static const struct YamlNode struct_SwashRingData[] = { + YAML_ENUM("type", 8, enum_SwashType), + YAML_UNSIGNED( "value", 8 ), + YAML_UNSIGNED_CUST( "collectiveSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_UNSIGNED_CUST( "aileronSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_UNSIGNED_CUST( "elevatorSource", 8, r_mixSrcRaw, w_mixSrcRaw ), + YAML_SIGNED( "collectiveWeight", 8 ), + YAML_SIGNED( "aileronWeight", 8 ), + YAML_SIGNED( "elevatorWeight", 8 ), + YAML_END +}; +static const struct YamlNode struct_trim_t[] = { + YAML_IDX, + YAML_SIGNED( "value", 11 ), + YAML_UNSIGNED( "mode", 5 ), + YAML_END +}; +static const struct YamlNode struct_FlightModeData[] = { + YAML_IDX, + YAML_ARRAY("trim", 16, 4, struct_trim_t, NULL), + YAML_STRING("name", 6), + YAML_SIGNED_CUST( "swtch", 9, r_swtchSrc, w_swtchSrc ), + YAML_PADDING( 7 ), + YAML_UNSIGNED( "fadeIn", 8 ), + YAML_UNSIGNED( "fadeOut", 8 ), + YAML_ARRAY("gvars", 16, 9, struct_signed_16, gvar_is_active), + YAML_END +}; +static const struct YamlNode struct_GVarData[] = { + YAML_IDX, + YAML_STRING("name", 3), + YAML_UNSIGNED( "min", 12 ), + YAML_UNSIGNED( "max", 12 ), + YAML_UNSIGNED( "popup", 1 ), + YAML_UNSIGNED( "prec", 1 ), + YAML_UNSIGNED( "unit", 2 ), + YAML_PADDING( 4 ), + YAML_END +}; +static const struct YamlNode struct_VarioData[] = { + YAML_UNSIGNED_CUST( "source", 7, r_tele_sensor, w_tele_sensor ), + YAML_UNSIGNED( "centerSilent", 1 ), + YAML_SIGNED( "centerMax", 8 ), + YAML_SIGNED( "centerMin", 8 ), + YAML_SIGNED( "min", 8 ), + YAML_SIGNED( "max", 8 ), + YAML_END +}; +static const struct YamlNode struct_RssiAlarmData[] = { + YAML_SIGNED( "disabled", 1 ), + YAML_PADDING( 1 ), + YAML_SIGNED( "warning", 6 ), + YAML_PADDING( 2 ), + YAML_SIGNED( "critical", 6 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_5[] = { + YAML_SIGNED( "delay", 6 ), + YAML_UNSIGNED( "pulsePol", 1 ), + YAML_UNSIGNED( "outputType", 1 ), + YAML_SIGNED( "frameLength", 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_6[] = { + YAML_PADDING( 3 ), + YAML_UNSIGNED( "disableTelemetry", 1 ), + YAML_UNSIGNED( "disableMapping", 1 ), + YAML_PADDING( 1 ), + YAML_UNSIGNED( "autoBindMode", 1 ), + YAML_UNSIGNED( "lowPowerMode", 1 ), + YAML_SIGNED( "optionValue", 8 ), + YAML_UNSIGNED( "receiverTelemetryOff", 1 ), + YAML_UNSIGNED( "receiverHigherChannels", 1 ), + YAML_PADDING( 6 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_7[] = { + YAML_UNSIGNED( "power", 2 ), + YAML_PADDING( 2 ), + YAML_UNSIGNED( "receiverTelemetryOff", 1 ), + YAML_UNSIGNED( "receiverHigherChannels", 1 ), + YAML_SIGNED( "antennaMode", 2 ), + YAML_PADDING( 8 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_8[] = { + YAML_PADDING( 6 ), + YAML_UNSIGNED( "noninverted", 1 ), + YAML_PADDING( 1 ), + YAML_SIGNED( "refreshRate", 8 ), + YAML_END +}; +static const struct YamlNode struct_string_64[] = { + YAML_IDX, + YAML_STRING("val", 8), + YAML_END +}; +static const struct YamlNode struct_anonymous_9[] = { + YAML_UNSIGNED( "receivers", 7 ), + YAML_UNSIGNED( "racingMode", 1 ), + YAML_ARRAY("receiverName", 64, 3, struct_string_64, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_10[] = { + YAML_ARRAY("rx_id", 8, 4, struct_unsigned_8, NULL), + YAML_UNSIGNED( "mode", 3 ), + YAML_UNSIGNED( "rfPower", 1 ), + YAML_UNSIGNED( "reserved", 4 ), + YAML_ARRAY("rx_freq", 8, 2, struct_unsigned_8, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_11[] = { + YAML_UNSIGNED( "bindPower", 3 ), + YAML_UNSIGNED( "runPower", 3 ), + YAML_UNSIGNED( "emi", 1 ), + YAML_UNSIGNED( "telemetry", 1 ), + YAML_UNSIGNED( "failsafeTimeout", 16 ), + YAML_ARRAY("rx_freq", 8, 2, struct_unsigned_8, NULL), + YAML_UNSIGNED( "mode", 2 ), + YAML_UNSIGNED( "reserved", 6 ), + YAML_END +}; +static const struct YamlNode union_anonymous_4_elmts[] = { + YAML_ARRAY("raw", 8, 25, struct_unsigned_8, NULL), + YAML_STRUCT("ppm", 16, struct_anonymous_5, NULL), + YAML_STRUCT("multi", 24, struct_anonymous_6, NULL), + YAML_STRUCT("pxx", 16, struct_anonymous_7, NULL), + YAML_STRUCT("sbus", 16, struct_anonymous_8, NULL), + YAML_STRUCT("pxx2", 200, struct_anonymous_9, NULL), + YAML_STRUCT("flysky", 56, struct_anonymous_10, NULL), + YAML_STRUCT("afhds3", 64, struct_anonymous_11, NULL), + YAML_END +}; +static const struct YamlNode struct_ModuleData[] = { + YAML_IDX, + YAML_ENUM("type", 4, enum_ModuleType), + YAML_PADDING( 4 ), + 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_PADDING( 3 ), + YAML_PADDING( 1 ), + YAML_UNION("mod", 200, union_anonymous_4_elmts, select_mod_type), + YAML_END +}; +static const struct YamlNode struct_TrainerModuleData[] = { + YAML_UNSIGNED_CUST( "mode", 8, r_trainerMode, w_trainerMode ), + YAML_UNSIGNED( "channelsStart", 8 ), + YAML_SIGNED( "channelsCount", 8 ), + YAML_SIGNED( "frameLength", 8 ), + YAML_SIGNED( "delay", 6 ), + YAML_UNSIGNED( "pulsePol", 1 ), + YAML_PADDING( 1 ), + YAML_END +}; +static const struct YamlNode union_ScriptDataInput_elmts[] = { + YAML_SIGNED( "value", 16 ), + YAML_UNSIGNED_CUST( "source", 16, r_mixSrcRaw, w_mixSrcRaw ), + YAML_END +}; +static const struct YamlNode union_ScriptDataInput[] = { + YAML_IDX, + YAML_UNION("u", 16, union_ScriptDataInput_elmts, select_script_input), + YAML_END +}; +static const struct YamlNode struct_ScriptData[] = { + YAML_IDX, + YAML_STRING("file", 6), + YAML_STRING("name", 6), + YAML_ARRAY("inputs", 16, 6, union_ScriptDataInput, NULL), + YAML_END +}; +static const struct YamlNode union_anonymous_12_elmts[] = { + YAML_UNSIGNED( "id", 16 ), + YAML_UNSIGNED( "persistentValue", 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_14[] = { + YAML_UNSIGNED( "physID", 5 ), + YAML_UNSIGNED( "rxIndex", 3 ), + YAML_END +}; +static const struct YamlNode union_anonymous_13_elmts[] = { + YAML_STRUCT("frskyInstance", 8, struct_anonymous_14, NULL), + YAML_UNSIGNED( "instance", 8 ), + YAML_ENUM("formula", 8, enum_TelemetrySensorFormula), + YAML_END +}; +static const struct YamlNode struct_anonymous_16[] = { + YAML_UNSIGNED( "ratio", 16 ), + YAML_SIGNED( "offset", 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_17[] = { + YAML_UNSIGNED( "source", 8 ), + YAML_UNSIGNED( "index", 8 ), + YAML_PADDING( 16 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_18[] = { + YAML_ARRAY("sources", 8, 4, struct_signed_8, NULL), + YAML_END +}; +static const struct YamlNode struct_anonymous_19[] = { + YAML_UNSIGNED( "source", 8 ), + YAML_PADDING( 24 ), + YAML_END +}; +static const struct YamlNode struct_anonymous_20[] = { + YAML_UNSIGNED( "gps", 8 ), + YAML_UNSIGNED( "alt", 8 ), + YAML_PADDING( 16 ), + YAML_END +}; +static const struct YamlNode union_anonymous_15_elmts[] = { + YAML_STRUCT("custom", 32, struct_anonymous_16, NULL), + YAML_STRUCT("cell", 32, struct_anonymous_17, NULL), + YAML_STRUCT("calc", 32, struct_anonymous_18, NULL), + YAML_STRUCT("consumption", 32, struct_anonymous_19, NULL), + YAML_STRUCT("dist", 32, struct_anonymous_20, NULL), + YAML_UNSIGNED( "param", 32 ), + YAML_END +}; +static const struct YamlNode struct_TelemetrySensor[] = { + YAML_IDX, + YAML_UNION("id1", 16, union_anonymous_12_elmts, select_id1), + YAML_UNION("id2", 8, union_anonymous_13_elmts, select_id2), + YAML_STRING("label", 4), + YAML_UNSIGNED( "subId", 8 ), + YAML_ENUM("type", 1, enum_TelemetrySensorType), + YAML_PADDING( 1 ), + YAML_UNSIGNED( "unit", 6 ), + YAML_UNSIGNED( "prec", 2 ), + YAML_UNSIGNED( "autoOffset", 1 ), + YAML_UNSIGNED( "filter", 1 ), + YAML_UNSIGNED( "logs", 1 ), + YAML_UNSIGNED( "persistent", 1 ), + YAML_UNSIGNED( "onlyPositive", 1 ), + YAML_PADDING( 1 ), + YAML_UNION("cfg", 32, union_anonymous_15_elmts, select_sensor_cfg), + YAML_END +}; +static const struct YamlNode struct_FrSkyBarData[] = { + YAML_IDX, + YAML_UNSIGNED_CUST( "source", 16, r_mixSrcRaw, w_mixSrcRaw ), + YAML_SIGNED( "barMin", 16 ), + YAML_SIGNED( "barMax", 16 ), + YAML_END +}; +static const struct YamlNode struct_LineDataSource[] = { + YAML_IDX, + YAML_UNSIGNED_CUST( "val", 16, r_mixSrcRaw, w_mixSrcRaw ), + YAML_END +}; +static const struct YamlNode struct_FrSkyLineData[] = { + YAML_IDX, + YAML_ARRAY("sources", 16, 2, struct_LineDataSource, NULL), + YAML_END +}; +static const struct YamlNode struct_TelemetryScriptData[] = { + YAML_STRING("file", 6), + YAML_ARRAY("inputs", 16, 8, struct_signed_16, NULL), + YAML_END +}; +static const struct YamlNode union_TelemetryScreenData_u_elmts[] = { + YAML_ARRAY("bars", 48, 4, struct_FrSkyBarData, NULL), + YAML_ARRAY("lines", 32, 4, struct_FrSkyLineData, NULL), + YAML_STRUCT("script", 176, struct_TelemetryScriptData, NULL), + YAML_END +}; +static const struct YamlNode struct_TelemetryScreenData[] = { + YAML_IDX, + YAML_CUSTOM("type",r_tele_screen_type,w_tele_screen_type), + YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data), + YAML_END +}; +static const struct YamlNode struct_ModelData[] = { + YAML_STRUCT("header", 96, struct_ModelHeader, NULL), + YAML_ARRAY("timers", 88, 3, struct_TimerData, NULL), + YAML_UNSIGNED( "telemetryProtocol", 3 ), + YAML_UNSIGNED( "thrTrim", 1 ), + YAML_UNSIGNED( "noGlobalFunctions", 1 ), + YAML_UNSIGNED( "displayTrims", 2 ), + YAML_UNSIGNED( "ignoreSensorIds", 1 ), + YAML_SIGNED( "trimInc", 3 ), + YAML_UNSIGNED( "disableThrottleWarning", 1 ), + YAML_UNSIGNED( "displayChecklist", 1 ), + YAML_UNSIGNED( "extendedLimits", 1 ), + YAML_UNSIGNED( "extendedTrims", 1 ), + YAML_UNSIGNED( "throttleReversed", 1 ), + YAML_UNSIGNED( "beepANACenter", 16 ), + YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), + YAML_ARRAY("limitData", 88, 32, struct_LimitData, NULL), + YAML_ARRAY("expoData", 136, 64, struct_ExpoData, NULL), + YAML_ARRAY("curves", 32, 32, struct_CurveHeader, NULL), + YAML_ARRAY("points", 8, 512, struct_signed_8, NULL), + YAML_ARRAY("logicalSw", 72, 64, struct_LogicalSwitchData, NULL), + YAML_ARRAY("customFn", 88, 64, struct_CustomFunctionData, cfn_is_active), + YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active), + YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active), + YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ), + YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn), + YAML_PADDING( 32 ), + 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", 16, struct_RssiAlarmData, NULL), + YAML_PADDING( 3 ), + YAML_UNSIGNED( "thrTrimSw", 3 ), + YAML_ENUM("potsWarnMode", 2, enum_PotsWarnMode), + YAML_ARRAY("moduleData", 232, 2, struct_ModuleData, NULL), + YAML_ARRAY("failsafeChannels", 16, 32, struct_signed_16, NULL), + YAML_STRUCT("trainerData", 40, struct_TrainerModuleData, NULL), + YAML_ARRAY("scriptsData", 192, 7, struct_ScriptData, NULL), + YAML_ARRAY("inputNames", 24, 32, struct_string_24, NULL), + YAML_UNSIGNED( "potsWarnEnabled", 16 ), + YAML_ARRAY("potsWarnPosition", 8, 2, struct_signed_8, NULL), + YAML_ARRAY("telemetrySensors", 112, 40, struct_TelemetrySensor, NULL), + YAML_PADDING( 8 ), + 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_END +}; +static const struct YamlNode struct_PartialModel[] = { + YAML_STRUCT("header", 96, struct_ModelHeader, NULL), + YAML_ARRAY("timers", 88, 3, struct_TimerData, NULL), + YAML_END +}; + +#define MAX_RADIODATA_MODELDATA_PARTIALMODEL_STR_LEN 26 + +static const struct YamlNode __RadioData_root_node = YAML_ROOT( struct_RadioData ); + +const YamlNode* get_radiodata_nodes() +{ + return &__RadioData_root_node; +} +static const struct YamlNode __ModelData_root_node = YAML_ROOT( struct_ModelData ); + +const YamlNode* get_modeldata_nodes() +{ + return &__ModelData_root_node; +} +static const struct YamlNode __PartialModel_root_node = YAML_ROOT( struct_PartialModel ); + +const YamlNode* get_partialmodel_nodes() +{ + return &__PartialModel_root_node; +} + diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index 291e109ae..885201f86 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -444,20 +444,20 @@ int getRawSwitchIdx(char sw) char getRawSwitchFromIdx(int idx) { -#if defined(PCBX7) && !defined(RADIO_TX12) && !defined(RADIO_ZORRO) +#if defined(PCBX7) && !defined(RADIO_TX12) && !defined(RADIO_ZORRO) && !defined(RADIO_TPRO) if (idx >= 5) return 'H' + idx - 5; else if (idx == 4) -#if defined(RADIO_T12) + #if defined(RADIO_T12) return 'G'; -#else + #else return 'F'; -#endif + #endif else return 'A' + idx; #else return 'A' + idx; -#endif +#endif } char *getSwitchName(char *dest, swsrc_t idx) @@ -467,6 +467,13 @@ char *getSwitchName(char *dest, swsrc_t idx) dest = strAppend(dest, g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME); } else { +#if defined(FUNCTIONS_SWITCHES) + if (swinfo.quot >= NUM_REGULAR_SWITCHES) { + *dest++ = 'W'; + *dest++ = '1' + swinfo.quot - 4; + return dest; + } +#endif *dest++ = 'S'; *dest++ = getRawSwitchFromIdx(swinfo.quot); } diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 5d77bb168..d8f5b8819 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -70,6 +70,85 @@ uint8_t potsPos[NUM_XPOTS]; #define SWITCH_POSITION(sw) (switchesPos & ((MASK_CFN_TYPE)1<<(sw))) #define POT_POSITION(sw) ((potsPos[(sw)/XPOTS_MULTIPOS_COUNT] & 0x0f) == ((sw) % XPOTS_MULTIPOS_COUNT)) +#if defined(FUNCTION_SWITCHES) +// Non pushed : SWSRC_Sx0 = -1024 = Sx(up) = state 0 +// Pushed : SWSRC_Sx2 = +1024 = Sx(down) = state 1 + +uint8_t fsPreviousState = 0; + +void setFSStartupPosition() +{ + for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { + uint8_t startPos = (g_model.functionSwitchStartConfig >> 2 * i) & 0x03; + switch(startPos) { + case FS_START_DOWN: + g_model.functionSwitchLogicalState &= ~(1 << i); // clear state + break; + + case FS_START_UP: + g_model.functionSwitchLogicalState |= 1 << i; + break; + + case FS_START_PREVIOUS: + default: + // Do nothing, use existing g_model.functionSwitchLogicalState value + break; + } + } +} + +uint8_t getFSLogicalState(uint8_t index) +{ + return (uint8_t )(bfSingleBitGet(g_model.functionSwitchLogicalState, index) >> (index)); +} + +uint8_t getFSPhysicalState(uint8_t index) +{ + return switchState(((index + NUM_REGULAR_SWITCHES) * 3) + 2) ? 1 : 0; +} + +uint8_t getFSPreviousPhysicalState(uint8_t index) +{ + return (uint8_t )(bfSingleBitGet(fsPreviousState, index) >> (index)); +} + +void evalFunctionSwitches() +{ + for (uint8_t i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { + if (FSWITCH_CONFIG(i) == SWITCH_NONE) { + fsLedOff(i); + continue; + } + + uint8_t physicalState = getFSPhysicalState(i); + if (physicalState != getFSPreviousPhysicalState(i)) { // FS was moved + if (FSWITCH_CONFIG(i) == SWITCH_2POS && physicalState == 1) { + g_model.functionSwitchLogicalState ^= 1 << i; // Toggle bit + } + else if (FSWITCH_CONFIG(i) == SWITCH_TOGGLE) { + g_model.functionSwitchLogicalState ^= (physicalState ^ g_model.functionSwitchLogicalState) & (1 << i); // Set bit to switch value + } + 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 + } + } + } + fsPreviousState ^= 1 << i; // Toggle state + storageDirty(EE_MODEL); + } + + if (getFSLogicalState(i)) + fsLedOn(i); + else + fsLedOff(i); + } +} +#endif + div_t switchInfo(int switchPosition) { return div(switchPosition-SWSRC_FIRST_SWITCH, 3); @@ -133,6 +212,11 @@ void getSwitchesPosition(bool startup) CHECK_2POS(SW_SA); CHECK_3POS(0, SW_SB); CHECK_3POS(1, SW_SC); +#elif defined(RADIO_TPRO) + CHECK_3POS(0, SW_SA); + CHECK_3POS(1, SW_SB); + CHECK_2POS(SW_SC); + CHECK_2POS(SW_SD); #else CHECK_3POS(0, SW_SA); CHECK_3POS(1, SW_SB); @@ -165,14 +249,24 @@ void getSwitchesPosition(bool startup) CHECK_2POS(SW_SD); CHECK_3POS(2, SW_SE); CHECK_3POS(3, SW_SF); +#elif defined(RADIO_TPRO) + CHECK_2POS(SW_SE); + CHECK_2POS(SW_SF); + CHECK_2POS(SW_SG); + CHECK_2POS(SW_SH); + CHECK_2POS(SW_SI); + CHECK_2POS(SW_SJ); #elif defined(PCBX7) CHECK_3POS(3, SW_SD); - #if defined(RADIO_T12) - CHECK_2POS(SW_SG); - #else + #if defined(HARDWARE_SWITCH_F) CHECK_2POS(SW_SF); #endif - CHECK_2POS(SW_SH); + #if defined(HARDWARE_SWITCH_G) + CHECK_2POS(SW_SG); + #endif + #if defined(HARDWARE_SWITCH_H) + CHECK_2POS(SW_SH); + #endif #else CHECK_3POS(3, SW_SD); CHECK_3POS(4, SW_SE); @@ -456,8 +550,8 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) result = latencyToggleSwitch; } #endif - else if (cs_idx <= SWSRC_LAST_SWITCH) { -#if defined(PCBFRSKY) + else if (cs_idx <= (SWSRC_LAST_SWITCH - 3 * NUM_FUNCTIONS_SWITCHES)) { +#if defined(PCBFRSKY) || defined(PCBFLYSKY) if (flags & GETSWITCH_MIDPOS_DELAY) result = SWITCH_POSITION(cs_idx-SWSRC_FIRST_SWITCH); else @@ -465,8 +559,14 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) #else result = switchState(cs_idx-SWSRC_FIRST_SWITCH); #endif - } +#if defined(FUNCTION_SWITCHES) + else if (cs_idx <= SWSRC_LAST_SWITCH) { + div_t qr = div(cs_idx - 3 * NUM_FUNCTIONS_SWITCHES, 3); + auto value = getFSLogicalState(qr.quot + 1); + result = qr.rem == -2 ? 1 - value : value; + } +#endif #if NUM_XPOTS > 0 else if (cs_idx <= SWSRC_LAST_MULTIPOS_SWITCH) { result = POT_POSITION(cs_idx-SWSRC_FIRST_MULTIPOS_SWITCH); @@ -526,13 +626,14 @@ void evalLogicalSwitches(bool isCurrentFlightmode) } swarnstate_t switches_states = 0; +uint8_t fsswitches_states = 0; swsrc_t getMovedSwitch() { static tmr10ms_t s_move_last_time = 0; swsrc_t result = 0; // Switches - for (int i = 0; i < NUM_SWITCHES; i++) { + for (int i = 0; i < NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES; i++) { if (SWITCH_EXISTS(i)) { swarnstate_t mask = ((swarnstate_t) 0x07 << (i * 3)); uint8_t prev = (switches_states & mask) >> (i * 3); @@ -544,6 +645,20 @@ swsrc_t getMovedSwitch() } } } + +#if defined(FUNCTION_SWITCHES) + for (int i = 0; i < NUM_FUNCTIONS_SWITCHES; i++) { + if (FSWITCH_CONFIG(i) != SWITCH_NONE) { + auto prev = (uint8_t )(bfSingleBitGet(fsswitches_states, i) >> (i)); + uint8_t next = getFSLogicalState(i); + if (prev != next) { + switches_states ^= (-next ^ switches_states) & (1 << i); + result = 2 + (3 * (i + NUM_REGULAR_SWITCHES)) + next; + } + } + } +#endif + // Multipos for (int i = 0; i < NUM_XPOTS; i++) { if (IS_POT_MULTIPOS(POT1 + i)) { diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index f9e1873f3..7450b124a 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -304,6 +304,10 @@ enum EnumSwitchesPositions #define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3) +#if !defined(NUM_FUNCTIONS_SWITCHES) +#define NUM_FUNCTIONS_SWITCHES 0 +#endif + void keysInit(); uint32_t switchState(uint8_t index); uint32_t readKeys(); diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index c70100315..0677593b3 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -235,6 +235,10 @@ enum EnumSwitchesPositions #define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3) +#if !defined(NUM_FUNCTIONS_SWITCHES) +#define NUM_FUNCTIONS_SWITCHES 0 +#endif + void monitorInit(); void keysInit(); uint8_t keyState(uint8_t index); diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index e12be5f6d..7ac83b00b 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -57,6 +57,10 @@ void rotaryEncoderEnd(); #define STORAGE_NUM_SWITCHES NUM_SWITCHES #define NUM_SWITCHES_POSITIONS 9 +#if !defined(NUM_FUNCTIONS_SWITCHES) +#define NUM_FUNCTIONS_SWITCHES 0 +#endif + enum EnumKeys { KEY_MENU, diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 15ff14c05..599d77188 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -138,6 +138,20 @@ elseif(PCB STREQUAL X7) add_definitions(-DRADIO_FAMILY_JUMPER_T12) add_definitions(-DEEPROM_VARIANT=0x4001) add_definitions(-DMANUFACTURER_JUMPER) + elseif(PCBREV STREQUAL TPRO) + set(DEFAULT_INTERNAL_MODULE MULTIMODULE CACHE STRING "Default internal module") + set(INTERNAL_MODULE_SERIAL YES) + set(FLAVOUR tpro) + set(NAVIGATION_TYPE x7) + set(CPU_TYPE STM32F2) + set(ROTARY_ENCODER YES) + set(CPU_TYPE_FULL STM32F205xE) # for size report + set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) + set(LUA_EXPORT lua_export_tpro) + add_definitions(-DFUNCTION_SWITCHES) + add_definitions(-DRADIO_TPRO) + add_definitions(-DEEPROM_VARIANT=0x4005) + add_definitions(-DMANUFACTURER_JUMPER) elseif(PCBREV STREQUAL TLITE) set(DEFAULT_INTERNAL_MODULE MULTIMODULE CACHE STRING "Default internal module") set(INTERNAL_MODULE_SERIAL YES) diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 01df37927..7688a76a5 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -38,7 +38,7 @@ void rotaryEncoderInit(); void rotaryEncoderCheck(); #endif -#if defined(RADIO_ZORRO) +#if defined(RADIO_ZORRO) || defined(RADIO_TPRO) #define ROTARY_ENCODER_INVERT #endif @@ -330,7 +330,16 @@ enum EnumSwitches SW_SE, SW_SF, SW_SG, - SW_SH + SW_SH, + SW_SI, + SW_SJ, + SW_SK, + SW_SL, + SW_SM, + SW_SO, + SW_SP, + SW_SQ, + SW_SR, }; #if defined(RADIO_TX12) #define IS_3POS(x) ((x) != SW_SA && (x) != SW_SD) @@ -353,22 +362,22 @@ enum EnumSwitchesPositions SW_SD0, SW_SD1, SW_SD2, -#if defined(PCBX9) || defined(PCBXLITES) || defined(PCBX9LITES) || defined(RADIO_TX12) || defined(RADIO_ZORRO) +#if defined(HARDWARE_SWITCH_E) SW_SE0, SW_SE1, SW_SE2, #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || (defined(PCBX7) && !defined(RADIO_T12)) || defined(PCBXLITES) || defined(PCBX9LITES) || defined(RADIO_T8) || defined(RADIO_ZORRO) +#if defined(HARDWARE_SWITCH_F) SW_SF0, SW_SF1, SW_SF2, #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX9LITES) || defined(RADIO_T12) || defined(RADIO_ZORRO) +#if defined(HARDWARE_SWITCH_G) SW_SG0, SW_SG1, SW_SG2, #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || (defined(PCBX7) && !defined(RADIO_TX12)) || defined(RADIO_T8) || defined(RADIO_ZORRO) +#if defined(HARDWARE_SWITCH_H) SW_SH0, SW_SH1, SW_SH2, @@ -440,6 +449,16 @@ enum EnumSwitchesPositions #define STORAGE_NUM_SWITCHES 8 #define DEFAULT_SWITCH_CONFIG (SWITCH_2POS << 6) + (SWITCH_2POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); #define DEFAULT_POTS_CONFIG (0) +#elif defined(RADIO_TPRO) + #define NUM_SWITCHES 10 + #define NUM_FUNCTIONS_SWITCHES 6 + #define NUM_REGULAR_SWITCHES (NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES) + #define STORAGE_NUM_SWITCHES 10 + #define DEFAULT_SWITCH_CONFIG (SWITCH_TOGGLE << 6) + (SWITCH_TOGGLE << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); + #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 + #define DEFAULT_POTS_CONFIG (POT_WITHOUT_DETENT << 0) + (POT_WITH_DETENT << 2); // S1 = pot without detent, S2 = pot with detent #elif defined(RADIO_FAMILY_JUMPER_T12) #define NUM_SWITCHES 8 #define STORAGE_NUM_SWITCHES NUM_SWITCHES @@ -500,17 +519,24 @@ enum EnumSwitchesPositions #define DEFAULT_SLIDERS_CONFIG (SLIDER_WITH_DETENT << 1) + (SLIDER_WITH_DETENT << 0) #endif +#if !defined(NUM_FUNCTIONS_SWITCHES) + #define NUM_FUNCTIONS_SWITCHES 0 +#endif + #define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3) void keysInit(); uint32_t switchState(uint8_t index); -#if defined(RADIO_ZORRO) -static const uint8_t switchReOrder[] = {1, 0, 4, 2, 3, 5}; -#else -static const uint8_t switchReOrder[] = {0, 1, 2, 3, 4, 5}; -#endif uint32_t readKeys(); uint32_t readTrims(); +#if defined(FUNCTION_SWITCHES) +extern uint8_t fsPreviousState; +void evalFunctionSwitches(); +void setFSStartupPosition(); +uint8_t getFSLogicalState(uint8_t index); +uint8_t getFSPhysicalState(uint8_t index); +#endif + #define TRIMS_PRESSED() (readTrims()) #define KEYS_PRESSED() (readKeys()) @@ -757,6 +783,10 @@ uint8_t isBacklightEnabled(); #define USB_NAME "Jumper TLite" #define USB_MANUFACTURER 'J', 'U', 'M', 'P', 'E', 'R', ' ', ' ' /* 8 bytes */ #define USB_PRODUCT 'T', '-', 'L', 'I', 'T', 'E', ' ', ' ' /* 8 Bytes */ +#elif defined(RADIO_TPRO) + #define USB_NAME "Jumper TPro" + #define USB_MANUFACTURER 'J', 'U', 'M', 'P', 'E', 'R', ' ', ' ' /* 8 bytes */ + #define USB_PRODUCT 'T', '-', 'P', 'R', 'O', ' ', ' ', ' ' /* 8 Bytes */ #else #define USB_NAME "FrSky Taranis" #define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */ @@ -926,6 +956,10 @@ void ledOff(); void ledRed(); void ledGreen(); void ledBlue(); +#if defined(FUNCTION_SWITCHES) +void fsLedOff(uint8_t); +void fsLedOn(uint8_t); +#endif // LCD driver #if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) @@ -942,7 +976,7 @@ void ledBlue(); #define IS_LCD_RESET_NEEDED() true #define LCD_CONTRAST_MIN 10 #define LCD_CONTRAST_MAX 30 -#if defined(RADIO_TX12) || defined(RADIO_FAMILY_JUMPER_T12) +#if defined(RADIO_TX12) || defined(RADIO_TPRO) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_TPRO) #define LCD_CONTRAST_DEFAULT 25 #else #define LCD_CONTRAST_DEFAULT 15 diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 4db84712d..ea2bec79b 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -53,7 +53,7 @@ #define KEYS_GPIO_PIN_LEFT GPIO_Pin_12 // PE.12 #define KEYS_GPIO_REG_RIGHT GPIOE->IDR #define KEYS_GPIO_PIN_RIGHT GPIO_Pin_13 // PE.13 -#elif defined(RADIO_FAMILY_JUMPER_T12) +#elif defined(RADIO_FAMILY_JUMPER_T12) && !defined(RADIO_TPRO) #define KEYS_GPIO_REG_EXIT GPIOD->IDR #define KEYS_GPIO_PIN_EXIT GPIO_Pin_2 // PD.02 #define KEYS_GPIO_REG_ENTER GPIOE->IDR @@ -174,7 +174,7 @@ #define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOE #define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource10 #define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource11 -#elif defined(RADIO_X7) || defined(RADIO_X7ACCESS) +#elif defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TPRO) #define ROTARY_ENCODER_NAVIGATION #define ROTARY_ENCODER_GPIO GPIOE #define ROTARY_ENCODER_GPIO_PIN_A GPIO_Pin_9 // PE.09 @@ -368,6 +368,13 @@ #define HARDWARE_SWITCH_A #define SWITCHES_GPIO_REG_A GPIOE->IDR #define SWITCHES_GPIO_PIN_A GPIO_Pin_14 // PE.14 +#elif defined(RADIO_TPRO) + #define STORAGE_SWITCH_A + #define HARDWARE_SWITCH_A + #define SWITCHES_GPIO_REG_A_L GPIOE->IDR + #define SWITCHES_GPIO_PIN_A_L GPIO_Pin_13 // PE.13 + #define SWITCHES_GPIO_REG_A_H GPIOE->IDR + #define SWITCHES_GPIO_PIN_A_H GPIO_Pin_7 // PE.07 #elif defined(PCBX7) #define STORAGE_SWITCH_A #define HARDWARE_SWITCH_A @@ -405,7 +412,7 @@ #define SWITCHES_GPIO_PIN_B_L GPIO_Pin_7 // PE.07 #define SWITCHES_GPIO_REG_B_H GPIOE->IDR #define SWITCHES_GPIO_PIN_B_H GPIO_Pin_13 // PE.13 -#elif defined(RADIO_TLITE) +#elif defined(RADIO_TLITE) || defined(RADIO_TPRO) #define STORAGE_SWITCH_B #define HARDWARE_SWITCH_B #define SWITCHES_GPIO_REG_B_L GPIOE->IDR @@ -470,7 +477,7 @@ #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_2 // PE.02 #define SWITCHES_GPIO_REG_C_H GPIOE->IDR #define SWITCHES_GPIO_PIN_C_H GPIO_Pin_1 // PE.01 -#elif defined(RADIO_TLITE) +#elif defined(RADIO_TLITE) || defined(RADIO_TPRO) #define STORAGE_SWITCH_C #define HARDWARE_SWITCH_C #define SWITCHES_GPIO_REG_C GPIOE->IDR @@ -527,7 +534,7 @@ #define HARDWARE_SWITCH_D #define SWITCHES_GPIO_REG_D GPIOE->IDR #define SWITCHES_GPIO_PIN_D GPIO_Pin_8 // PE.08 -#elif defined(RADIO_TLITE) +#elif defined(RADIO_TLITE) || defined(RADIO_TPRO) #define STORAGE_SWITCH_D #define HARDWARE_SWITCH_D #define SWITCHES_GPIO_REG_D GPIOD->IDR @@ -585,6 +592,12 @@ #define SWITCHES_GPIO_PIN_E_H GPIO_Pin_13 // PE.13 #define SWITCHES_GPIO_REG_E_L GPIOE->IDR #define SWITCHES_GPIO_PIN_E_L GPIO_Pin_7 // PE.07 +#elif defined(RADIO_TPRO) + // SW1 + #define STORAGE_SWITCH_E + #define HARDWARE_SWITCH_E + #define SWITCHES_GPIO_REG_E GPIOG->IDR + #define SWITCHES_GPIO_PIN_E GPIO_Pin_7 // PG.07 #elif defined(PCBX7) // no SWE #else @@ -628,7 +641,13 @@ #define SWITCHES_GPIO_PIN_F_L GPIO_Pin_1 // PE.01 #define SWITCHES_GPIO_REG_F_H GPIOE->IDR #define SWITCHES_GPIO_PIN_F_H GPIO_Pin_2 // PE.02 -#elif defined(RADIO_T8) || defined(RADIO_TLITE) +#elif defined(RADIO_TPRO) + // SW2 + #define STORAGE_SWITCH_F + #define HARDWARE_SWITCH_F + #define SWITCHES_GPIO_REG_F GPIOG->IDR + #define SWITCHES_GPIO_PIN_F GPIO_Pin_6 // PG.06 +#elif defined(RADIO_T8) || defined(RADIO_TLITE) || defined(RADIO_TPRO) // no SWF #define STORAGE_SWITCH_F #elif defined(RADIO_T12) @@ -662,6 +681,12 @@ #define HARDWARE_SWITCH_G #define SWITCHES_GPIO_REG_G GPIOE->IDR #define SWITCHES_GPIO_PIN_G GPIO_Pin_14 // PE.14 +#elif defined(RADIO_TPRO) + // SW3 + #define STORAGE_SWITCH_G + #define HARDWARE_SWITCH_G + #define SWITCHES_GPIO_REG_G GPIOG->IDR + #define SWITCHES_GPIO_PIN_G GPIO_Pin_5 // PG.05 #elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_T8) // no SWG #else @@ -689,7 +714,13 @@ #define STORAGE_SWITCH_H // no SWH #elif defined(RADIO_TX12) -#elif defined(RADIO_TLITE) +#elif defined(RADIO_TPRO) + // SW4 + #define STORAGE_SWITCH_H + #define HARDWARE_SWITCH_H + #define SWITCHES_GPIO_REG_H GPIOG->IDR + #define SWITCHES_GPIO_PIN_H GPIO_Pin_4 // PG.04 +#elif defined(RADIO_TLITE) || defined(RADIO_TPRO) // no SWH #define STORAGE_SWITCH_H #elif defined(PCBX7) @@ -740,6 +771,17 @@ #define STORAGE_SWITCH_J #elif defined(RADIO_ZORRO) // No I/J +#elif defined(RADIO_TPRO) + // SW5 + #define STORAGE_SWITCH_I + #define HARDWARE_SWITCH_I + #define SWITCHES_GPIO_REG_I GPIOG->IDR + #define SWITCHES_GPIO_PIN_I GPIO_Pin_3 // PG.03 + // SW6 + #define STORAGE_SWITCH_J + #define HARDWARE_SWITCH_J + #define SWITCHES_GPIO_REG_J GPIOG->IDR + #define SWITCHES_GPIO_PIN_J GPIO_Pin_2 // PG.02 #elif defined(PCBX7) #define STORAGE_SWITCH_I #define HARDWARE_SWITCH_I @@ -849,6 +891,13 @@ #define KEYS_GPIOB_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5) #define KEYS_GPIOC_PINS (GPIO_Pin_4 | GPIO_Pin_5) #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14) +#elif defined(RADIO_TPRO) + #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG) + #define KEYS_GPIOA_PINS (GPIO_Pin_5) + #define KEYS_GPIOC_PINS (GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3) + #define KEYS_GPIOD_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15) + #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15) + #define KEYS_GPIOG_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7) #elif defined(RADIO_FAMILY_JUMPER_T12) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS GPIO_Pin_5 @@ -1067,6 +1116,30 @@ #define ADC_GPIOC_PINS ADC_GPIO_PIN_BATT #define ADC_CHANNEL_BATT ADC_Channel_10 #define ADC_VREF_PREC2 330 +#elif defined(RADIO_TPRO) + #define HARDWARE_POT1 + #define HARDWARE_POT2 + #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2) + #define ADC_RCC_APB1Periph 0 + #define ADC_RCC_APB2Periph RCC_APB2Periph_ADC1 + #define ADC_GPIO_PIN_STICK_RV GPIO_Pin_0 // PA.00 + #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_1 // PA.01 + #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_2 // PA.02 + #define ADC_GPIO_PIN_STICK_LH GPIO_Pin_3 // PA.03 + #define ADC_CHANNEL_STICK_RV ADC_Channel_0 // ADC1_IN0 + #define ADC_CHANNEL_STICK_RH ADC_Channel_1 // ADC1_IN1 + #define ADC_CHANNEL_STICK_LV ADC_Channel_2 // ADC1_IN2 + #define ADC_CHANNEL_STICK_LH ADC_Channel_3 // ADC1_IN3 + #define ADC_GPIO_PIN_POT1 GPIO_Pin_0 // PB.00 + #define ADC_GPIO_PIN_POT2 GPIO_Pin_6 // PA.06 + #define ADC_GPIO_PIN_BATT GPIO_Pin_0 // PC.00 + #define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_POT2) + #define ADC_GPIOB_PINS ADC_GPIO_PIN_POT1 + #define ADC_GPIOC_PINS ADC_GPIO_PIN_BATT + #define ADC_CHANNEL_POT1 ADC_Channel_6 + #define ADC_CHANNEL_POT2 ADC_Channel_8 + #define ADC_CHANNEL_BATT ADC_Channel_10 + #define ADC_VREF_PREC2 330 #elif defined(PCBX7) #define HARDWARE_POT1 #define HARDWARE_POT2 @@ -1244,6 +1317,19 @@ #define LED_BLUE_GPIO_PIN GPIO_Pin_6 // PE.06 #endif +#if defined(FUNCTION_SWITCHES) + #define FS_RCC_AHB1Periph RCC_AHB1Periph_GPIOF + #define GPIO_FSLED_GPIO_ON GPIO_SetBits + #define GPIO_FSLED_GPIO_OFF GPIO_ResetBits + #define FSLED_GPIO GPIOF + #define FSLED_GPIO_PIN_1 GPIO_Pin_5 + #define FSLED_GPIO_PIN_2 GPIO_Pin_4 + #define FSLED_GPIO_PIN_3 GPIO_Pin_3 + #define FSLED_GPIO_PIN_4 GPIO_Pin_2 + #define FSLED_GPIO_PIN_5 GPIO_Pin_1 + #define FSLED_GPIO_PIN_6 GPIO_Pin_0 +#endif + // Internal Module #if defined(PCBXLITE) #define EXTERNAL_ANTENNA @@ -1362,7 +1448,7 @@ #define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream5_IRQHandler #define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF5 #define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) -#elif (defined(RADIO_FAMILY_JUMPER_T12) && defined(HARDWARE_INTERNAL_MODULE)) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) +#elif (defined(RADIO_FAMILY_JUMPER_T12) && defined(HARDWARE_INTERNAL_MODULE)) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_TPRO) #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_USART3 | RCC_APB1Periph_TIM2) #define INTMODULE_RCC_APB2Periph 0 @@ -1612,7 +1698,7 @@ #define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn #define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising -#if defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) +#if defined(RADIO_X7) || defined(RADIO_X7ACCESS) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_TPRO) #define TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER #elif defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019) #define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler @@ -1724,7 +1810,7 @@ #define INTMODULE_HEARTBEAT_EXTI_IRQHandler EXTI1_IRQHandler #elif defined(RADIO_ZORRO) #define INTMODULE_HEARTBEAT_RCC_AHB1Periph 0 -#elif defined(RADIO_X7) || defined(RADIO_TX12) +#elif defined(RADIO_X7) || defined(RADIO_TX12) || defined(RADIO_TPRO) #define INTMODULE_HEARTBEAT #define INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER #define INTMODULE_HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC @@ -1912,7 +1998,7 @@ #define KEYS_BACKLIGHT_RCC_AHB1Periph 0 // LCD driver -#if defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_T8) +#if defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_T8) || defined(RADIO_TPRO) #define LCD_VERTICAL_INVERT #endif #if defined(PCBX9E) @@ -2116,12 +2202,12 @@ #define AUDIO_SPEAKER_ENABLE_GPIO_PIN GPIO_Pin_14 // PD.14 #define HEADPHONE_TRAINER_SWITCH_GPIO GPIOD #define HEADPHONE_TRAINER_SWITCH_GPIO_PIN GPIO_Pin_9 // PD.09 -#elif defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_TLITE) +#elif defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_TLITE) || defined(RADIO_TPRO) #define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1) #define AUDIO_MUTE_GPIO GPIOE #define AUDIO_MUTE_GPIO_PIN GPIO_Pin_12 // PE.12 #define AUDIO_MUTE_DELAY 500 // ms -#if defined(RADIO_TLITE) +#if defined(RADIO_TLITE) || defined(RADIO_TPRO) #define AUDIO_UNMUTE_DELAY 250 // ms #else #define AUDIO_UNMUTE_DELAY 150 // ms diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp index 3dc4260eb..1d5d3fccf 100644 --- a/radio/src/targets/taranis/keys_driver.cpp +++ b/radio/src/targets/taranis/keys_driver.cpp @@ -210,7 +210,7 @@ uint32_t switchState(uint8_t index) ADD_2POS_CASE(A); ADD_3POS_CASE(B, 1); ADD_3POS_CASE(C, 2); -#elif defined(RADIO_TLITE) +#elif defined(RADIO_TLITE) || defined(RADIO_TPRO) ADD_3POS_CASE(A, 0); ADD_3POS_CASE(B, 1); ADD_2POS_CASE(C); @@ -256,6 +256,13 @@ uint32_t switchState(uint8_t index) ADD_2POS_CASE(D); #elif defined(RADIO_TLITE) // Only 4 switches +#elif defined(RADIO_TPRO) + ADD_2POS_CASE(E); + ADD_2POS_CASE(F); + ADD_2POS_CASE(G); + ADD_2POS_CASE(H); + ADD_2POS_CASE(I); + ADD_2POS_CASE(J); #elif defined(PCBX7) ADD_3POS_CASE(D, 3); #if defined(RADIO_T12) diff --git a/radio/src/targets/taranis/lcd_driver_spi.cpp b/radio/src/targets/taranis/lcd_driver_spi.cpp index 53ac9ac25..e3f9069c8 100644 --- a/radio/src/targets/taranis/lcd_driver_spi.cpp +++ b/radio/src/targets/taranis/lcd_driver_spi.cpp @@ -21,7 +21,7 @@ #include "opentx.h" -#if defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) +#if defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_TX12) || defined(RADIO_ZORRO) || defined(RADIO_T8) || defined(RADIO_TPRO) #define LCD_CONTRAST_OFFSET -10 #else #define LCD_CONTRAST_OFFSET 160 diff --git a/radio/src/targets/taranis/led_driver.cpp b/radio/src/targets/taranis/led_driver.cpp index 04033c655..0b6824cf0 100644 --- a/radio/src/targets/taranis/led_driver.cpp +++ b/radio/src/targets/taranis/led_driver.cpp @@ -43,8 +43,32 @@ void ledInit() GPIO_InitStructure.GPIO_Pin = LED_BLUE_GPIO_PIN; GPIO_Init(LED_BLUE_GPIO, &GPIO_InitStructure); #endif + +#if defined(FUNCTION_SWITCHES) + RCC_AHB1PeriphClockCmd(FS_RCC_AHB1Periph, ENABLE); + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = FSLED_GPIO_PIN_1 | FSLED_GPIO_PIN_2 | FSLED_GPIO_PIN_3 | FSLED_GPIO_PIN_4 | FSLED_GPIO_PIN_5 | FSLED_GPIO_PIN_6; + GPIO_Init(FSLED_GPIO, &GPIO_InitStructure); +#endif } +#if defined(FUNCTION_SWITCHES) +constexpr uint32_t fsLeds[] = {FSLED_GPIO_PIN_1, FSLED_GPIO_PIN_2, FSLED_GPIO_PIN_3, FSLED_GPIO_PIN_4, FSLED_GPIO_PIN_5, FSLED_GPIO_PIN_6}; + +void fsLedOff(uint8_t index) +{ + GPIO_FSLED_GPIO_OFF(FSLED_GPIO, fsLeds[index]); +} + +void fsLedOn(uint8_t index) +{ + GPIO_FSLED_GPIO_ON(FSLED_GPIO, fsLeds[index]); +} +#endif + void ledOff() { #if defined(LED_RED_GPIO) diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 418d4b639..d54529847 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -94,6 +94,7 @@ ISTR(CRSF_BAUDRATE); ISTR(PPM_POL); ISTR(SBUS_INVERSION_VALUES); ISTR(SPORT_MODES); +ISTR(FSGROUPS); #if defined(PCBSKY9X) && defined(REVX) ISTR(VOUTPUT_TYPE); diff --git a/radio/src/translations.h b/radio/src/translations.h index f1c16e9a2..e37110dbb 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -178,6 +178,7 @@ extern const char STR_MULTI_POWER[]; extern const char STR_MULTI_TELEMETRY_MODE[]; extern const char STR_MULTI_WBUS_MODE[]; extern const char STR_SPORT_MODES[]; +extern const char STR_FSGROUPS[]; extern const char STR_AFHDS3_ONE_TO_ONE_TELEMETRY[]; extern const char STR_AFHDS3_ONE_TO_MANY[]; diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index fca9c7ecd..2d3936df5 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -40,9 +40,20 @@ #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW STR_CHAR_POT"S1\0" STR_CHAR_POT"S2\0" #define TR_SW_VSRCRAW STR_CHAR_SWITCH"SA\0" STR_CHAR_SWITCH"SB\0" STR_CHAR_SWITCH"SC\0" STR_CHAR_SWITCH"SD\0" STR_CHAR_SWITCH"SE\0" STR_CHAR_SWITCH"SF\0" -#elif defined(RADIO_FAMILY_JUMPER_T12) +#elif defined(RADIO_TPRO) #define TR_POTS_VSRCRAW STR_CHAR_POT"S1\0" STR_CHAR_POT"S2\0" - #define TR_SW_VSRCRAW STR_CHAR_SWITCH"SA\0" STR_CHAR_SWITCH"SB\0" STR_CHAR_SWITCH"SC\0" STR_CHAR_SWITCH"SD\0" STR_CHAR_SWITCH"SG\0" STR_CHAR_SWITCH"SH\0" STR_CHAR_SWITCH"SI\0" STR_CHAR_SWITCH"SJ\0" +#define TR_SW_VSRCRAW \ + STR_CHAR_SWITCH \ + "SA\0" STR_CHAR_SWITCH "SB\0" STR_CHAR_SWITCH "SC\0" STR_CHAR_SWITCH \ + "SD\0" STR_CHAR_SWITCH "SW1" STR_CHAR_SWITCH "SW2" STR_CHAR_SWITCH \ + "SW3" STR_CHAR_SWITCH "SW4" STR_CHAR_SWITCH "SW5" STR_CHAR_SWITCH "SW6" +#elif defined(RADIO_FAMILY_JUMPER_T12) +#define TR_POTS_VSRCRAW STR_CHAR_POT "S1\0" STR_CHAR_POT "S2\0" +#define TR_SW_VSRCRAW \ + STR_CHAR_SWITCH "SA\0" STR_CHAR_SWITCH "SB\0" STR_CHAR_SWITCH \ + "SC\0" STR_CHAR_SWITCH "SD\0" STR_CHAR_SWITCH \ + "SG\0" STR_CHAR_SWITCH "SH\0" STR_CHAR_SWITCH \ + "SI\0" STR_CHAR_SWITCH "SJ\0" #elif defined(RADIO_TX12) #define TR_POTS_VSRCRAW STR_CHAR_POT "S1\0" STR_CHAR_POT "S2\0" #define TR_SW_VSRCRAW STR_CHAR_SWITCH "SA\0" STR_CHAR_SWITCH "SB\0" STR_CHAR_SWITCH "SC\0" STR_CHAR_SWITCH "SD\0" STR_CHAR_SWITCH "SE\0" STR_CHAR_SWITCH "SF\0" STR_CHAR_SWITCH "SI\0" STR_CHAR_SWITCH "SJ\0" @@ -372,3 +383,7 @@ #define TR_EDIT_THEME "EDIT THEME" #define TR_DETAILS "Details" #define TR_THEME_EDITOR "THEMES" + +#define LEN_FSGROUPS "\001" +#define TR_FSGROUPS "-""1""2""3" + diff --git a/tools/build-companion-nightly-win32.sh b/tools/build-companion-nightly-win32.sh index 0ca9d2edf..8d21395d7 100644 --- a/tools/build-companion-nightly-win32.sh +++ b/tools/build-companion-nightly-win32.sh @@ -81,6 +81,10 @@ cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=TLITE ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt +cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=TPRO ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt + cmake ${COMMON_OPTIONS} -DPCB=X9D ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt diff --git a/tools/build-companion-nightly.sh b/tools/build-companion-nightly.sh index eef3aef73..c342da9f4 100755 --- a/tools/build-companion-nightly.sh +++ b/tools/build-companion-nightly.sh @@ -81,6 +81,10 @@ cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=TLITE ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt +cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=TPRO ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt + cmake ${COMMON_OPTIONS} -DPCB=X9D ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt diff --git a/tools/build-gh.sh b/tools/build-gh.sh index 89dc53ea8..097357516 100755 --- a/tools/build-gh.sh +++ b/tools/build-gh.sh @@ -99,6 +99,9 @@ do tlite) BUILD_OPTIONS+="-DPCB=X7 -DPCBREV=TLITE" ;; + tpro) + BUILD_OPTIONS+="-DPCB=X7 -DPCBREV=TPRO" + ;; xlite) BUILD_OPTIONS+="-DPCB=XLITE" ;; diff --git a/tools/build-jumper.py b/tools/build-jumper.py index cfce0920c..8e7d9e171 100755 --- a/tools/build-jumper.py +++ b/tools/build-jumper.py @@ -14,6 +14,11 @@ boards = { "PCBREV": "TLITE", "DEFAULT_MODE": "2", }, + "TPRO": { + "PCB": "X7", + "PCBREV": "TPRO", + "DEFAULT_MODE": "2", + }, "T12": { "PCB": "X7", "PCBREV": "T12", diff --git a/tools/generate-yaml.sh b/tools/generate-yaml.sh index dbaea4f2e..c4f7e150b 100755 --- a/tools/generate-yaml.sh +++ b/tools/generate-yaml.sh @@ -9,7 +9,7 @@ if [[ -n ${GCC_ARM} ]] ; then export PATH=${GCC_ARM}:$PATH fi -: ${FLAVOR:="t12;t8;tlite;tx12;zorro;tx16s;x12s;nv14;x7;x9d;x9dp;x9e;x9lite;x9lites;xlite;xlites"} +: ${FLAVOR:="t12;t8;tlite;tpro;tx12;zorro;tx16s;x12s;nv14;x7;x9d;x9dp;x9e;x9lite;x9lites;xlite;xlites"} : ${SRCDIR:=$(dirname $(pwd)/"$0")/..} : ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -DDISABLE_COMPANION=YES -Wno-dev -DYAML_STORAGE=YES "} @@ -53,6 +53,9 @@ do tlite) BUILD_OPTIONS+="-DPCB=X7 -DPCBREV=TLITE" ;; + tpro) + BUILD_OPTIONS+="-DPCB=X7 -DPCBREV=TPRO" + ;; xlite) BUILD_OPTIONS+="-DPCB=XLITE" ;;