From dd7ca0aad78f11ce13979632bccafdaee8d8f89f Mon Sep 17 00:00:00 2001 From: elecpower Date: Mon, 7 Jun 2021 21:53:23 +1000 Subject: [PATCH] Fixes 8541 and other trainer mode enhancements --- companion/src/firmwares/modeldata.cpp | 70 +++++++++++++++++++ companion/src/firmwares/modeldata.h | 15 +++- companion/src/firmwares/moduledata.h | 8 --- .../src/firmwares/opentx/opentxeeprom.cpp | 18 +++++ companion/src/modeledit/setup.cpp | 49 ++++--------- companion/src/modeledit/setup.h | 4 +- companion/src/modeledit/setup_module.ui | 42 +---------- companion/src/modelprinter.cpp | 29 +------- companion/src/modelprinter.h | 1 - radio/src/dataconstants.h | 4 ++ radio/src/datastructs.h | 4 +- 11 files changed, 126 insertions(+), 118 deletions(-) diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 679e90f5f..c6159f1e8 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -26,6 +26,7 @@ #include "radiodataconversionstate.h" #include "helpers.h" #include "adjustmentreference.h" +#include "compounditemmodels.h" ModelData::ModelData() { @@ -1550,3 +1551,72 @@ void ModelData::limitsSet(const int index, const QByteArray & data) memcpy(&limitData[index], data.constData(), sizeof(LimitData)); } + +QString ModelData::trainerModeToString() const +{ + return trainerModeToString(trainerMode); +} + +// static +QString ModelData::trainerModeToString(int value) +{ + switch (value) { + case TRAINER_MODE_MASTER_JACK: + return tr("Master/Jack"); + case TRAINER_MODE_SLAVE_JACK: + return tr("Slave/Jack"); + case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: + return tr("Master/SBUS Module"); + case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: + return tr("Master/CPPM Module"); + case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: + return tr("Master/Battery"); + case TRAINER_MODE_MASTER_BLUETOOTH: + return tr("Master/Bluetooth"); + case TRAINER_MODE_SLAVE_BLUETOOTH: + return tr("Slave/Bluetooth"); + case TRAINER_MODE_MULTI: + return tr("Master/Multi"); + default: + return CPN_STR_UNKNOWN_ITEM; + } +} + +// static +bool ModelData::isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value) +{ + if (value < 0 || value >= TRAINER_MODE_COUNT) + return false; + + bool ret = true; + const Board::Type board = firmware->getBoard(); + + if (!IS_TARANIS(board) || IS_ACCESS_RADIO(board, Firmware::getCurrentVariant()->getId())) { + if (value >= TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE && value <= TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) + ret = false; + } + else if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER && value == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) + ret = false; + + if (generalSettings.bluetoothMode != GeneralSettings::BLUETOOTH_MODE_TRAINER && value >= TRAINER_MODE_MASTER_BLUETOOTH && value <= TRAINER_MODE_SLAVE_BLUETOOTH) + ret = false; + + if (!IS_RADIOMASTER_TX16S(board) && value == TRAINER_MODE_MULTI) + ret = false; + + return ret; +} + +// static +AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware) +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_MODELDATA_TRAINERMODE); + + for (int i = 0; i < TRAINER_MODE_COUNT; i++) { + mdl->appendToItemList(trainerModeToString(i), i, isTrainerModeAvailable(generalSettings, firmware, i)); + } + + mdl->loadItemList(); + return mdl; +} diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index f834a0779..1a3854714 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -39,6 +39,9 @@ class GeneralSettings; class RadioDataConversionState; +class AbstractStaticItemModel; + +constexpr char AIM_MODELDATA_TRAINERMODE[] {"modeldata.trainermode"}; #define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*" @@ -96,14 +99,15 @@ typedef char TopbarData[216+1]; #endif enum TrainerMode { - TRAINER_MODE_MASTER_TRAINER_JACK, - TRAINER_MODE_SLAVE, + TRAINER_MODE_MASTER_JACK, + TRAINER_MODE_SLAVE_JACK, TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, - TRAINER_MODE_MULTI + TRAINER_MODE_MULTI, + TRAINER_MODE_COUNT }; #define INPUT_NAME_LEN 4 @@ -274,6 +278,11 @@ class ModelData { void limitsMove(const int index, const int offset); void limitsSet(const int index, const QByteArray & data); + QString trainerModeToString() const; + 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); + protected: void removeGlobalVar(int & var); diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index 8acec18b0..04e936758 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -146,14 +146,6 @@ enum MultiModuleRFProtocols { MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2 }; -enum TrainerProtocol { - TRAINER_MASTER_JACK, - TRAINER_SLAVE_JACK, - TRAINER_MASTER_SBUS_MODULE, - TRAINER_MASTER_CPPM_MODULE, - TRAINER_MASTER_SBUS_BATT_COMPARTMENT -}; - enum ModuleSubtypeR9M { MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_EU, diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index b82e76795..e43a4014e 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -2556,6 +2556,15 @@ void OpenTxModelData::beforeExport() } modelData.switchWarningStates = newSwitchWarningStates; } + + // TODO remove when enum not radio specific requires eeprom change and conversion + if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) { + if (!IS_TARANIS(board)) { + modelData.trainerMode -= 2; + if (!IS_RADIOMASTER_TX16S(board)) + modelData.trainerMode -= 1; + } + } } void OpenTxModelData::afterImport() @@ -2577,6 +2586,15 @@ void OpenTxModelData::afterImport() if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3) { modelData.thrTraceSrc += 2; } + + // TODO remove when enum not radio specific requires eeprom change and conversion + if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) { + if (!IS_TARANIS(board)) { + modelData.trainerMode += 2; + if (!IS_RADIOMASTER_TX16S(board)) + modelData.trainerMode += 1; + } + } } OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant): diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index de6609591..0eec2a206 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -32,6 +32,7 @@ constexpr char FIM_TIMERSWITCH[] {"Timer Switch"}; constexpr char FIM_THRSOURCE[] {"Throttle Source"}; +constexpr char FIM_TRAINERMODE[] {"Trainer Mode"}; TimerPanel::TimerPanel(QWidget * parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, FilteredItemModelFactory * panelFilteredModels, CompoundItemModelFactory * panelItemModels): @@ -186,7 +187,8 @@ void TimerPanel::onCountdownBeepChanged(int index) quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT; -ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx): +ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx, + FilteredItemModelFactory * panelFilteredItemModels): ModelPanel(parent, model, generalSettings, firmware), module(module), moduleIdx(moduleIdx), @@ -198,30 +200,17 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->label_module->setText(ModuleData::indexToString(moduleIdx, firmware)); if (moduleIdx < 0) { - if (!IS_TARANIS(firmware->getBoard()) || IS_ACCESS_RADIO(firmware->getBoard(), Firmware::getCurrentVariant()->getId())) { - ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1); - ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1); - ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1); - } - else if (generalSettings.auxSerialMode != UART_MODE_SBUS_TRAINER) { - ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1); - } - - if (generalSettings.bluetoothMode != 2) { - ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BLUETOOTH, 0, Qt::UserRole - 1); - ui->trainerMode->setItemData(TRAINER_MODE_SLAVE_BLUETOOTH, 0, Qt::UserRole - 1); - } - - if (!IS_FAMILY_T16(firmware->getBoard())) { - ui->trainerMode->setItemData(TRAINER_MODE_MULTI, 0, Qt::UserRole - 1); - } - - ui->trainerMode->setCurrentIndex(model.trainerMode); + ui->formLayout_col1->setSpacing(0); if (!IS_HORUS_OR_TARANIS(firmware->getBoard())) { ui->label_trainerMode->hide(); ui->trainerMode->hide(); } - ui->formLayout_col1->setSpacing(0); + else { + if (panelFilteredItemModels) + ui->trainerMode->setModel(panelFilteredItemModels->getItemModel(FIM_TRAINERMODE)); + ui->trainerMode->setField(model.trainerMode); + connect(ui->trainerMode, SIGNAL(currentDataChanged(int)), this, SLOT(update())); + } } else { ui->label_trainerMode->hide(); @@ -455,11 +444,11 @@ void ModulePanel::update() } } else if (IS_HORUS_OR_TARANIS(board)) { - if (model->trainerMode == TRAINER_SLAVE_JACK) { - mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT; + if (model->trainerMode == TRAINER_MODE_SLAVE_JACK) { + mask |= MASK_PPM_FIELDS | MASK_SBUSPPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT; } } - else if (model->trainerMode != TRAINER_MASTER_JACK) { + else if (model->trainerMode != TRAINER_MODE_MASTER_JACK) { mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT; } @@ -651,15 +640,6 @@ void ModulePanel::update() ui->rxFreq->setVisible((mask & MASK_RX_FREQ)); } -void ModulePanel::on_trainerMode_currentIndexChanged(int index) -{ - if (!lock && model->trainerMode != (unsigned)index) { - model->trainerMode = index; - update(); - emit modified(); - } -} - void ModulePanel::onProtocolChanged(int index) { if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) { @@ -1010,6 +990,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge panelItemModels->registerItemModel(TimerData::countdownBeepItemModel()); panelItemModels->registerItemModel(TimerData::countdownStartItemModel()); panelItemModels->registerItemModel(TimerData::persistentItemModel()); + panelFilteredModels->registerItemModel(new FilteredItemModel(ModelData::trainerModeItemModel(generalSettings, firmware)), FIM_TRAINERMODE); Board::Type board = firmware->getBoard(); @@ -1249,7 +1230,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge } if (firmware->getCapability(ModelTrainerEnable)) { - modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1); + modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1, panelFilteredModels); ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]); connect(modules[CPN_MAX_MODULES], &ModulePanel::modified, this, &SetupPanel::modified); } diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 955f2189b..d2c5391ac 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -66,7 +66,8 @@ class ModulePanel : public ModelPanel Q_OBJECT public: - ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx); + ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx, + FilteredItemModelFactory * panelFilteredItemModels = nullptr); virtual ~ModulePanel(); virtual void update(); @@ -81,7 +82,6 @@ class ModulePanel : public ModelPanel private slots: void setupFailsafes(); - void on_trainerMode_currentIndexChanged(int index); void onProtocolChanged(int index); void on_ppmDelay_editingFinished(); void on_channelsCount_editingFinished(); diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui index 652975acd..f78bd2772 100644 --- a/companion/src/modeledit/setup_module.ui +++ b/companion/src/modeledit/setup_module.ui @@ -1019,7 +1019,7 @@ - + 0 @@ -1035,46 +1035,6 @@ QComboBox::AdjustToContents - - - Master/Jack - - - - - Slave/Jack - - - - - Master/SBUS Module - - - - - Master/CPPM Module - - - - - Master/SBUS in battery compartment - - - - - Master/Bluetooth - - - - - Slave/Bluetooth - - - - - Master/Multi - - diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 1d7df4f93..25bee2498 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -190,9 +190,9 @@ QString ModelPrinter::printModule(int idx) QString result; ModuleData module = model.moduleData[(idx<0 ? CPN_MAX_MODULES : idx)]; if (idx < 0) { - str << printLabelValue(tr("Mode"), printTrainerMode()); + str << printLabelValue(tr("Mode"), model.trainerModeToString()); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - if (model.trainerMode == TRAINER_SLAVE_JACK) { + if (model.trainerMode == TRAINER_MODE_SLAVE_JACK) { str << printLabelValue(tr("Channels"), QString("%1-%2").arg(module.channelsStart + 1).arg(module.channelsStart + module.channelsCount)); str << printLabelValue(tr("Frame length"), QString("%1ms").arg(printPPMFrameLength(module.ppm.frameLength))); str << printLabelValue(tr("PPM delay"), QString("%1us").arg(module.ppm.delay)); @@ -239,31 +239,6 @@ QString ModelPrinter::printModule(int idx) return result; } -QString ModelPrinter::printTrainerMode() -{ - QString result; - switch (model.trainerMode) { - case TRAINER_MASTER_JACK: - result = tr("Master/Jack"); - break; - case TRAINER_SLAVE_JACK: - result = tr("Slave/Jack"); - break; - case TRAINER_MASTER_SBUS_MODULE: - result = tr("Master/SBUS Module"); - break; - case TRAINER_MASTER_CPPM_MODULE: - result = tr("Master/CPPM Module"); - break; - case TRAINER_MASTER_SBUS_BATT_COMPARTMENT: - result = tr("Master/SBUS in battery compartment"); - break; - default: - result = CPN_STR_UNKNOWN_ITEM; - } - return result; -} - QString ModelPrinter::printHeliSwashType () { switch (model.swashRingData.type) { diff --git a/companion/src/modelprinter.h b/companion/src/modelprinter.h index 8be56bd64..6cc63a85f 100644 --- a/companion/src/modelprinter.h +++ b/companion/src/modelprinter.h @@ -61,7 +61,6 @@ class ModelPrinter: public QObject QString printFlightModes(unsigned int flightModes); QString printInputFlightModes(unsigned int flightModes); QString printModule(int idx); - QString printTrainerMode(); QString printCenterBeep(); QString printHeliSwashType(); QString printTrim(int flightModeIndex, int stickIndex); diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 1c5fdc1ea..66ab681b5 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -186,6 +186,9 @@ enum ModuleIndex { EXTERNAL_MODULE, SPORT_MODULE, }; + +// TODO: simplify at an eeprom change to a single master list and use ui filters. Simplies radio conversions and both radio and companion code +// Companion opentxeeprom.cpp will require after import and before export manipulation removed enum TrainerMode { TRAINER_MODE_MASTER_TRAINER_JACK, TRAINER_MODE_SLAVE, @@ -208,6 +211,7 @@ enum TrainerMode { }; #endif +// TODO: simplify at an eeprom change to a single master list and use ui filters #define TRAINER_MODE_MIN() TRAINER_MODE_MASTER_TRAINER_JACK #if !defined(HARDWARE_EXTERNAL_MODULE) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 765245b3e..992066203 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -390,7 +390,7 @@ PACK(struct TelemetrySensor { */ PACK(struct TrainerModuleData { - uint8_t mode:3; + uint8_t mode:3; // TODO: simplify value at an eeprom change refer compile driven enum handling in dataconstants.h uint8_t spare1:5; uint8_t channelsStart; int8_t channelsCount; // 0=8 channels @@ -970,4 +970,4 @@ static inline void check_struct() #undef CHKSIZE } -#endif /* BACKUP */ +#endif /* BACKUP */