From 8d8a50ce74da5d204ab86775da128bae97c131c0 Mon Sep 17 00:00:00 2001 From: Neil Horne Date: Mon, 4 Sep 2023 19:46:33 +1000 Subject: [PATCH] feat(cpn): Trainer modes more closely mimic firmware (#3981) --- companion/src/firmwares/boards.cpp | 9 +++ companion/src/firmwares/boards.h | 5 +- .../src/firmwares/edgetx/yaml_modeldata.cpp | 2 +- companion/src/firmwares/modeldata.cpp | 60 ++++++++++++------- companion/src/firmwares/modeldata.h | 6 +- companion/src/modeledit/setup.cpp | 47 ++++++++++----- companion/src/modeledit/setup.h | 7 +++ 7 files changed, 95 insertions(+), 41 deletions(-) diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 87baaaa6a84..391ed93f4b2 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -574,6 +574,15 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) else return 250000; // less than 400K + case HasTrainerModuleCPPM: + return (getCapability(board, HasTrainerModuleSBUS) || IS_FAMILY_HORUS_OR_T16(board)); + + case HasTrainerModuleSBUS: + return ((IS_TARANIS_X9LITE(board) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_X9LITES(board)) || + IS_TARANIS_X9DP_2019(board) || IS_TARANIS_X7_ACCESS(board) || IS_RADIOMASTER_ZORRO(board) || + IS_RADIOMASTER_TX12_MK2(board) || IS_RADIOMASTER_BOXER(board)) || + (getCapability(board, HasExternalModuleSupport) && (IS_TARANIS(board) && !IS_FAMILY_T12(board)))); + default: return 0; } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index c38b106013f..f0274e74220 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -160,7 +160,10 @@ namespace Board { HasInternalModuleSupport, HasExternalModuleSupport, HasAudioMuteGPIO, - SportMaxBaudRate + SportMaxBaudRate, + HasIntModuleHeartbeatGPIO, + HasTrainerModuleCPPM, + HasTrainerModuleSBUS, }; struct SwitchInfo diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index 5ca2d5a5de4..0059bc92141 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -56,7 +56,7 @@ static const YamlLookupTable trainerModeLut = { { TRAINER_MODE_SLAVE_JACK, "SLAVE" }, { TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, "MASTER_SBUS_EXT" }, { TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, "MASTER_CPPM_EXT" }, - { TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, "MASTER_BATT_COMP" }, + { TRAINER_MODE_MASTER_SERIAL, "MASTER_BATT_COMP" }, { TRAINER_MODE_MASTER_BLUETOOTH, "MASTER_BT" }, { TRAINER_MODE_SLAVE_BLUETOOTH, "SLAVE_BT" }, { TRAINER_MODE_MULTI, "MASTER_MULTI" }, diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 855cd7f08f6..669ce84ea0a 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -1625,8 +1625,8 @@ QString ModelData::trainerModeToString(int value) 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_SERIAL: + return tr("Master/Serial"); case TRAINER_MODE_MASTER_BLUETOOTH: return tr("Master/Bluetooth"); case TRAINER_MODE_SLAVE_BLUETOOTH: @@ -1638,35 +1638,55 @@ QString ModelData::trainerModeToString(int value) } } -// static bool ModelData::isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value) { if (value < TRAINER_MODE_FIRST || value > TRAINER_MODE_LAST) 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.serialPort[GeneralSettings::SP_AUX1] != - UART_MODE_SBUS_TRAINER && - value == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) - ret = false; + if (value == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE && + IS_TARANIS_X9E(board) && + generalSettings.bluetoothMode) + return false; - if (generalSettings.bluetoothMode != - GeneralSettings::BLUETOOTH_MODE_TRAINER && - value >= TRAINER_MODE_MASTER_BLUETOOTH && - value <= TRAINER_MODE_SLAVE_BLUETOOTH) - ret = false; + if (value == TRAINER_MODE_MASTER_SERIAL && + (generalSettings.serialPort[GeneralSettings::SP_AUX1] != GeneralSettings::AUX_SERIAL_SBUS_TRAINER && + generalSettings.serialPort[GeneralSettings::SP_AUX2] != GeneralSettings::AUX_SERIAL_SBUS_TRAINER)) + return false; + + if ((value == TRAINER_MODE_MASTER_BLUETOOTH || value == TRAINER_MODE_SLAVE_BLUETOOTH) && + !IS_TARANIS_X9E(board) && + generalSettings.bluetoothMode != GeneralSettings::BLUETOOTH_MODE_TRAINER) + return false; + + if ((value == TRAINER_MODE_MASTER_JACK || value == TRAINER_MODE_SLAVE_JACK) && + ((IS_TARANIS_XLITE(board) && !IS_TARANIS_X9LITES(board)) || IS_IFLIGHT_COMMANDO8(board))) + return false; + + if (value == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE && + !Boards::getCapability(board, Board::HasTrainerModuleCPPM)) + return false; - return ret; + if (value == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE && + !Boards::getCapability(board, Board::HasTrainerModuleSBUS)) + return false; + + if ((value == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || value == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) && + (Boards::getCapability(board, Board::HasTrainerModuleCPPM) || + Boards::getCapability(board, Board::HasTrainerModuleSBUS)) && + moduleData[1].protocol != PULSES_OFF) + return false; + + if (value == TRAINER_MODE_MULTI && + ((!Boards::getCapability(board, Board::HasInternalModuleSupport) && + !Boards::getCapability(board, Board::HasExternalModuleSupport)) || + (moduleData[0].protocol != PULSES_MULTIMODULE && moduleData[1].protocol != PULSES_MULTIMODULE))) + return false; + + return true; } -// static AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware) { AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 975fb05e989..8df7a30f7c1 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -80,7 +80,7 @@ enum TrainerMode { TRAINER_MODE_SLAVE_JACK, TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, - TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, + TRAINER_MODE_MASTER_SERIAL, TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, TRAINER_MODE_MULTI, @@ -327,8 +327,8 @@ class ModelData { 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); + bool isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value); + AbstractStaticItemModel * trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware); unsigned int getFuncSwitchConfig(unsigned int index) const; void setFuncSwitchConfig(unsigned int index, unsigned int value); static QString funcSwitchConfigToString(unsigned int value); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 1d6f4f4177b..6cf44641f65 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -233,27 +233,27 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ModelPanel(parent, model, generalSettings, firmware), module(module), moduleIdx(moduleIdx), - ui(new Ui::Module) + ui(new Ui::Module), + trainerModeItemModel(nullptr) { lock = true; ui->setupUi(this); ui->label_module->setText(ModuleData::indexToString(moduleIdx, firmware)); - if (moduleIdx < 0) { + if (isTrainerModule(moduleIdx)) { ui->formLayout_col1->setSpacing(0); if (!IS_HORUS_OR_TARANIS(firmware->getBoard())) { ui->label_trainerMode->hide(); ui->trainerMode->hide(); } else { - if (panelFilteredItemModels) - ui->trainerMode->setModel(panelFilteredItemModels->getItemModel(FIM_TRAINERMODE)); + updateTrainerModeItemModel(); ui->trainerMode->setField(model.trainerMode); connect(ui->trainerMode, &AutoComboBox::currentDataChanged, this, [=] () { - update(); - emit updateItemModels(); - emit modified(); + update(); + emit updateItemModels(); + emit modified(); }); } } @@ -263,16 +263,16 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul } if (panelFilteredItemModels) { - if (moduleIdx >= 0) { + if (!isTrainerModule(moduleIdx)) { int id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(ModuleData::protocolItemModel(generalSettings), moduleIdx + 1/*flag cannot be 0*/), QString("Module Protocol %1").arg(moduleIdx)); panelFilteredItemModels->getItemModel(id)->setSortCaseSensitivity(Qt::CaseInsensitive); panelFilteredItemModels->getItemModel(id)->sort(0); ui->protocol->setModel(panelFilteredItemModels->getItemModel(id)); if (ui->protocol->findData(module.protocol) < 0) { - const QString moduleIdxDesc = moduleIdx == 0 ? tr("internal") : tr("external"); - const QString compareDesc = moduleIdx == 0 ? tr("hardware") : tr("profile"); - const QString intModuleDesc = moduleIdx == 0 ? ModuleData::typeToString(generalSettings.internalModule) : ""; + const QString moduleIdxDesc = isInternalModule(moduleIdx) ? tr("internal") : tr("external"); + const QString compareDesc = isInternalModule(moduleIdx) ? tr("hardware") : tr("profile"); + const QString intModuleDesc = isInternalModule(moduleIdx) ? ModuleData::typeToString(generalSettings.internalModule) : ""; QString msg = tr("Warning: The %1 module protocol %2 is incompatible with the %3 %1 module %4 and has been set to OFF!"); msg = msg.arg(moduleIdxDesc).arg(module.protocolToString(module.protocol)).arg(compareDesc).arg(intModuleDesc); @@ -291,7 +291,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->protocol->setField(module.protocol, this); } - if (moduleIdx == 0) { + if (isInternalModule(moduleIdx)) { int id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(GeneralSettings::antennaModeItemModel(true)), FIM_ANTENNAMODE); ui->antennaMode->setModel(panelFilteredItemModels->getItemModel(id)); } @@ -434,7 +434,7 @@ void ModulePanel::update() unsigned int mask = 0; unsigned int max_rx_num = 63; - if (moduleIdx >= 0) { + if (!isTrainerModule(moduleIdx)) { mask |= MASK_PROTOCOL; switch (protocol) { case PULSES_PXX_R9M: @@ -461,7 +461,7 @@ void ModulePanel::update() else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M || protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO) mask |= MASK_RX_NUMBER | MASK_ACCESS; - if (moduleIdx == 0 && + if (isInternalModule(moduleIdx) && (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_D8 || protocol==PULSES_PXX_XJT_LR12) && HAS_EXTERNAL_ANTENNA(board) && generalSettings.antennaMode == GeneralSettings::ANTENNA_MODE_PER_MODEL) @@ -553,7 +553,7 @@ void ModulePanel::update() mask |= MASK_FAILSAFES; } - if (moduleIdx > 0) + if (isExternalModule(moduleIdx)) ui->telemetryBaudrate->setVisible(mask & MASK_BAUDRATE); else ui->telemetryBaudrate->setVisible(false); @@ -814,6 +814,7 @@ void ModulePanel::onProtocolChanged(int index) } } + emit protocolChanged(); emit updateItemModels(); emit modified(); } @@ -1178,6 +1179,18 @@ void ModulePanel::onClearAccessRxClicked() } } +void ModulePanel::updateTrainerModeItemModel() +{ + if (isTrainerModule(moduleIdx)) { + if (trainerModeItemModel) + delete trainerModeItemModel; + + trainerModeItemModel = new FilteredItemModel(model->trainerModeItemModel(generalSettings, firmware)); + ui->trainerMode->setModel(trainerModeItemModel); + ui->trainerMode->updateValue(); + } +} + /******************************************************************************/ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): ModelPanel(parent, model, generalSettings, firmware), @@ -1409,7 +1422,6 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge panelItemModels->registerItemModel(TimerData::countdownStartItemModel()); panelItemModels->registerItemModel(TimerData::persistentItemModel()); panelItemModels->registerItemModel(TimerData::modeItemModel()); - panelFilteredModels->registerItemModel(new FilteredItemModel(ModelData::trainerModeItemModel(generalSettings, firmware)), FIM_TRAINERMODE); panelItemModels->registerItemModel(TimerData::showElapsedItemModel()); Board::Type board = firmware->getBoard(); @@ -1658,6 +1670,9 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]); connect(modules[CPN_MAX_MODULES], &ModulePanel::modified, this, &SetupPanel::modified); connect(modules[CPN_MAX_MODULES], &ModulePanel::updateItemModels, this, &SetupPanel::onModuleUpdateItemModels); + for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) { + connect(modules[i], &ModulePanel::protocolChanged, modules[CPN_MAX_MODULES], &ModulePanel::updateTrainerModeItemModel); + } } disableMouseScrolling(); diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index ae76a64a0fc..0f92d3eb281 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -35,6 +35,7 @@ namespace Ui { } class AutoLineEdit; +class FilteredItemModel; class TimerPanel : public ModelPanel { @@ -79,11 +80,13 @@ class ModulePanel : public ModelPanel public slots: void onExtendedLimitsToggled(); void onFailsafeModified(unsigned index); + void updateTrainerModeItemModel(); signals: void channelsRangeChanged(); void failsafeModified(unsigned index); void updateItemModels(); + void protocolChanged(); private slots: void setupFailsafes(); @@ -133,6 +136,10 @@ class ModulePanel : public ModelPanel QMap failsafeGroupsMap; static quint8 failsafesValueDisplayType; // FailsafeValueDisplayTypes void updateFailsafeUI(unsigned channel, quint8 updtSb); + FilteredItemModel *trainerModeItemModel; + static bool isTrainerModule(int index) { return index < 0; } + static bool isInternalModule(int index) { return index == 0; } + static bool isExternalModule(int index) { return index > 0; } }; class FunctionSwitchesPanel : public ModelPanel