From d7190493d598e51de5a56f44a3b28aebcc913aa8 Mon Sep 17 00:00:00 2001 From: elecpower Date: Sun, 2 Jan 2022 00:23:27 +1100 Subject: [PATCH] Add Internal Module to companion --- companion/src/firmwares/boards.cpp | 3 + companion/src/firmwares/boards.h | 5 +- companion/src/firmwares/generalsettings.h | 1 + companion/src/firmwares/moduledata.cpp | 279 +++++++++++++++++++++- companion/src/firmwares/moduledata.h | 38 ++- companion/src/generaledit/hardware.cpp | 28 ++- companion/src/modeledit/setup.cpp | 19 +- companion/src/modeledit/setup_module.ui | 2 +- 8 files changed, 348 insertions(+), 27 deletions(-) diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 4332f32d8..0378b95c7 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -489,6 +489,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case HasSDCard: return IS_STM32(board); + case HasInternalModuleSupport: + return (IS_STM32(board) && !IS_TARANIS_SMALL(board)); + default: return 0; } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index f3a836963..844ea7502 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -147,7 +147,8 @@ namespace Board { HasRTC, HasColorLcd, NumFunctionSwitches, - HasSDCard + HasSDCard, + HasInternalModuleSupport }; struct SwitchInfo @@ -211,9 +212,11 @@ class Boards static QString potTypeToString(int value); static QString sliderTypeToString(int value); static QString switchTypeToString(int value); + static QString intModuleTypeToString(int value); static AbstractStaticItemModel * potTypeItemModel(); static AbstractStaticItemModel * sliderTypeItemModel(); static AbstractStaticItemModel * switchTypeItemModel(); + static AbstractStaticItemModel * intModuleTypeItemModel(); static StringTagMappingTable getTrimSwitchesLookupTable(Board::Type board); static StringTagMappingTable getTrimSourcesLookupTable(Board::Type board); diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index f7115cc46..bf334c63a 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -161,6 +161,7 @@ class GeneralSettings { int vBatMin; int vBatMax; int backlightMode; + unsigned int internalModule; // Introducted in EdgeTX 2.6 yaml only TrainerData trainer; unsigned int view; // main screen view // TODO enum bool disableThrottleWarning; diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index 37bf5be4c..5b2a84192 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -23,6 +23,12 @@ #include "multiprotocols.h" #include "afhds3.h" #include "radiodataconversionstate.h" +#include "compounditemmodels.h" +#include "generalsettings.h" +#include "datahelpers.h" + +#include +#include void ModuleData::convert(RadioDataConversionState & cstate) { @@ -149,7 +155,7 @@ QString ModuleData::indexToString(int index, Firmware * fw) } // static -QString ModuleData::protocolToString(unsigned protocol) +QString ModuleData::protocolToString(unsigned int protocol) { static const char * strings[] = { "OFF", @@ -262,3 +268,274 @@ int ModuleData::getMaxChannelCount() } return 8; } + +/* + If Companion did not combine the /radio/src/datastructs type and sub-type fields + this would be so much cleaner and, modules and protocols generally easier to maintain + Another case for refactoring ModuleData as a whole! +*/ + +// static +int ModuleData::getTypeFromProtocol(unsigned int protocol) +{ + const QVector>ProtocolTypeTable = { + + { PULSES_OFF, MODULE_TYPE_NONE }, + { PULSES_PPM, MODULE_TYPE_PPM }, + + { PULSES_PXX_XJT_X16, MODULE_TYPE_XJT_PXX1 }, + { PULSES_PXX_XJT_D8, MODULE_TYPE_XJT_PXX1 }, + { PULSES_PXX_XJT_LR12, MODULE_TYPE_XJT_PXX1 }, + + { PULSES_ACCESS_ISRM, MODULE_TYPE_ISRM_PXX2 }, + { PULSES_ACCST_ISRM_D16, MODULE_TYPE_ISRM_PXX2 }, + + { PULSES_LP45, MODULE_TYPE_DSM2 }, + { PULSES_DSM2, MODULE_TYPE_DSM2 }, + { PULSES_DSMX, MODULE_TYPE_DSM2 }, + + { PULSES_CROSSFIRE, MODULE_TYPE_CROSSFIRE }, + { PULSES_MULTIMODULE, MODULE_TYPE_MULTIMODULE }, + { PULSES_PXX_R9M, MODULE_TYPE_R9M_PXX1 }, + { PULSES_ACCESS_R9M, MODULE_TYPE_R9M_PXX2 }, + { PULSES_PXX_R9M_LITE, MODULE_TYPE_R9M_LITE_PXX1 }, + { PULSES_ACCESS_R9M_LITE, MODULE_TYPE_R9M_LITE_PXX2 }, + { PULSES_GHOST, MODULE_TYPE_GHOST }, + { PULSES_ACCESS_R9M_LITE_PRO, MODULE_TYPE_R9M_LITE_PRO_PXX2 }, + { PULSES_SBUS, MODULE_TYPE_SBUS }, + + { PULSES_XJT_LITE_X16, MODULE_TYPE_XJT_LITE_PXX2 }, + { PULSES_XJT_LITE_D8, MODULE_TYPE_XJT_LITE_PXX2 }, + { PULSES_XJT_LITE_LR12, MODULE_TYPE_XJT_LITE_PXX2 }, + + { PULSES_AFHDS3, MODULE_TYPE_FLYSKY } + }; + + QPairelmt; + + foreach (elmt, ProtocolTypeTable) { + if (elmt.first == (int)protocol) + return elmt.second; + } + + return -1; +} + +// static +int ModuleData::getSubTypeFromProtocol(unsigned int protocol) +{ + if (protocol == PULSES_ACCST_ISRM_D16 || protocol == PULSES_ACCESS_ISRM) + return protocol - PULSES_ACCESS_ISRM; + else if (protocol >= PULSES_PXX_XJT_X16 && protocol <= PULSES_PXX_XJT_LR12) + return protocol - PULSES_PXX_XJT_X16; + else + return 0; +} + +// static +QString ModuleData::typeToString(int type) +{ + static const char * strings[] = { + "OFF", + "PPM", + "FrSky XJT", + "ISRM", + "DSM2", + "TBS Crossfire", + "DIY Multiprotocol Module", + "FrSky R9M", + "FrSky R9M ACCESS", + "FrSky R9MLite", + "FrSky R9ML ACCESS", + "ImmersionRC Ghost", + "FrSky R9MLP ACCESS", + "SBUS output at VBat", + "FrSky XJT Lite", + "FlySky" + }; + + return CHECK_IN_ARRAY(strings, type); +} + +// static +bool ModuleData::isInternalModuleAvailable(int moduleType) +{ + if (moduleType == MODULE_TYPE_NONE) + return true; + + Firmware *fw = getCurrentFirmware(); + Board::Type board = fw->getBoard(); + QString id = fw->getId(); + + if (!Boards::getCapability(board, Board::HasInternalModuleSupport)) + return false; + + //=================================== + // TODO: this is not finished!!!!!!! + //=================================== + + switch(moduleType) { + case MODULE_TYPE_MULTIMODULE: + return id.contains("internalmulti") || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board) || IS_RADIOMASTER_TX12(board) || IS_JUMPER_TLITE(board); + break; + case MODULE_TYPE_CROSSFIRE: + break; + case MODULE_TYPE_XJT_PXX1: + if(IS_TARANIS(board)) + return true; + break; + case MODULE_TYPE_ISRM_PXX2: + if(IS_ACCESS_RADIO(board, id)) + return true; + break; + case MODULE_TYPE_PPM: + break; + case MODULE_TYPE_FLYSKY: + if (IS_FLYSKY_NV14(board)) + return true; + break; + default: + return false; + } + + return false; +} + +// static +AbstractStaticItemModel * ModuleData::internalModuleItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("moduledata.internalmodule"); + + for (int i = 0; i < MODULE_TYPE_COUNT; i++) { + mdl->appendToItemList(typeToString(i), i, isInternalModuleAvailable(i)); + } + + mdl->loadItemList(); + return mdl; +} + +// static +bool ModuleData::isProtocolAvailable(int moduleidx, unsigned int protocol, GeneralSettings & settings) +{ + if (protocol == PULSES_OFF) + return true; + + Firmware *fw = getCurrentFirmware(); + Board::Type board = fw->getBoard(); + + if (moduleidx == 0 && Boards::getCapability(board, Board::HasInternalModuleSupport)) + return (int)settings.internalModule == getTypeFromProtocol(protocol); + + QString id = fw->getId(); + + if (IS_HORUS_OR_TARANIS(board)) { + switch (moduleidx) { + case 1: + switch (protocol) { + case PULSES_OFF: + case PULSES_PPM: + return true; + case PULSES_PXX_XJT_X16: + case PULSES_PXX_XJT_D8: + case PULSES_PXX_XJT_LR12: + return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); + case PULSES_PXX_R9M: + case PULSES_LP45: + case PULSES_DSM2: + case PULSES_DSMX: + case PULSES_SBUS: + case PULSES_MULTIMODULE: + case PULSES_CROSSFIRE: + case PULSES_AFHDS3: + case PULSES_GHOST: + return true; + case PULSES_ACCESS_R9M: + return IS_ACCESS_RADIO(board, id) || (IS_FAMILY_HORUS_OR_T16(board) && id.contains("externalaccessmod")); + case PULSES_PXX_R9M_LITE: + case PULSES_ACCESS_R9M_LITE: + case PULSES_ACCESS_R9M_LITE_PRO: + case PULSES_XJT_LITE_X16: + case PULSES_XJT_LITE_D8: + case PULSES_XJT_LITE_LR12: + return (IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_TLITE(board)); + default: + return false; + } + + case -1: + switch (protocol) { + case PULSES_PPM: + return true; + default: + return false; + } + + default: + return false; + } + } + else if (IS_SKY9X(board)) { + switch (moduleidx) { + case 0: + switch (protocol) { + case PULSES_PPM: + case PULSES_PXX_XJT_X16: + case PULSES_PXX_XJT_D8: + case PULSES_PXX_XJT_LR12: + case PULSES_PXX_R9M: + case PULSES_LP45: + case PULSES_DSM2: + case PULSES_DSMX: + case PULSES_SBUS: + case PULSES_MULTIMODULE: + return true; + default: + return false; + } + break; + case 1: + switch (protocol) { + case PULSES_PPM: + return true; + default: + return false; + } + break; + default: + return false; + } + } + else { + switch (protocol) { + case PULSES_PPM: + case PULSES_DSMX: + case PULSES_LP45: + case PULSES_DSM2: + // case PULSES_PXX_DJT: // Unavailable for now + case PULSES_PPM16: + case PULSES_PPMSIM: + return true; + default: + return false; + } + } + + return false; // to avoid compiler warning +} + +// static +AbstractStaticItemModel * ModuleData::protocolItemModel(GeneralSettings & settings) +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("moduledata.protocol"); + + for (int i = 0; i <= 1; i++) { + for (unsigned int j = 0; j < PULSES_PROTOCOL_LAST; j++) { + mdl->appendToItemList(protocolToString(j), j, isProtocolAvailable(i, j, settings), 0, i + 1/*flag cannot be 0*/); + } + } + + mdl->loadItemList(); + return mdl; +} diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index 04e936758..49dc594c8 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef MODULEDATA_H -#define MODULEDATA_H +#pragma once #include "constants.h" @@ -27,6 +26,30 @@ class Firmware; class RadioDataConversionState; +class AbstractStaticItemModel; +class GeneralSettings; + +// from radio/src/pulses/module_constants.h +enum ModuleType { + MODULE_TYPE_NONE = 0, + MODULE_TYPE_PPM, + MODULE_TYPE_XJT_PXX1, + MODULE_TYPE_ISRM_PXX2, + MODULE_TYPE_DSM2, + MODULE_TYPE_CROSSFIRE, + MODULE_TYPE_MULTIMODULE, + MODULE_TYPE_R9M_PXX1, // R9M + MODULE_TYPE_R9M_PXX2, // R9M ACCESS + MODULE_TYPE_R9M_LITE_PXX1, //R9MLite + MODULE_TYPE_R9M_LITE_PXX2, //R9MLP + MODULE_TYPE_GHOST, // Replaces MODULE_TYPE_R9M_LITE_PRO_PXX1 which doesn't exist + MODULE_TYPE_R9M_LITE_PRO_PXX2, + MODULE_TYPE_SBUS, + MODULE_TYPE_XJT_LITE_PXX2, + MODULE_TYPE_FLYSKY, //no more protocols possible because of 4 bits value + MODULE_TYPE_COUNT, + MODULE_TYPE_MAX = MODULE_TYPE_COUNT - 1 +}; enum PulsesProtocol { PULSES_OFF, @@ -219,10 +242,15 @@ class ModuleData { QString subTypeToString(int type = -1) const; QString powerValueToString(Firmware * fw) const; static QString indexToString(int index, Firmware * fw); - static QString protocolToString(unsigned protocol); + static QString protocolToString(unsigned int protocol); static QStringList powerValueStrings(enum PulsesProtocol protocol, int subType, Firmware * fw); bool hasFailsafes(Firmware * fw) const; int getMaxChannelCount(); + static int getTypeFromProtocol(unsigned int protocol); + static int getSubTypeFromProtocol(unsigned int protocol); + static QString typeToString(int type); + static bool isInternalModuleAvailable(int type); + static AbstractStaticItemModel * internalModuleItemModel(); + static bool isProtocolAvailable(int moduleidx, unsigned int protocol, GeneralSettings & settings); + static AbstractStaticItemModel * protocolItemModel(GeneralSettings & settings); }; - -#endif // MODULEDATA_H diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 69a2a6de4..95e4d1284 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -33,6 +33,7 @@ constexpr char FIM_SWITCHTYPE2POS[] {"Switch Type 2 Pos"}; constexpr char FIM_SWITCHTYPE3POS[] {"Switch Type 3 Pos"}; +constexpr char FIM_INTERNALMODULES[] {"Internal Modules"}; HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels): GeneralPanel(parent, generalSettings, firmware), @@ -52,6 +53,9 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings int auxmodelid = editorItemModels->registerItemModel(GeneralSettings::auxSerialModeItemModel()); int baudmodelid = editorItemModels->registerItemModel(GeneralSettings::telemetryBaudrateItemModel()); + id = editorItemModels->registerItemModel(ModuleData::internalModuleItemModel()); + tabFilteredModels->registerItemModel(new FilteredItemModel(editorItemModels->getItemModel(id)), FIM_INTERNALMODULES); + grid = new QGridLayout(this); int count; int row = 0; @@ -127,6 +131,22 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings addParams(row, antennaMode); } + if (Boards::getCapability(board, Board::HasInternalModuleSupport)) { + addLabel(tr("Internal module"), row, 0); + AutoComboBox *internalModule = new AutoComboBox(this); + internalModule->setModel(tabFilteredModels->getItemModel(FIM_INTERNALMODULES)); + internalModule->setField(generalSettings.internalModule, this); + addParams(row, internalModule); + } + + if (firmware->getCapability(HasTelemetryBaudrate)) { + addLabel(tr("Maximum Baud"), row, 0); + AutoComboBox *maxBaudRate = new AutoComboBox(this); + maxBaudRate->setModel(editorItemModels->getItemModel(baudmodelid)); + maxBaudRate->setField(generalSettings.telemetryBaudrate, this); + addParams(row, maxBaudRate); + } + if (firmware->getCapability(HasAuxSerialMode)) { QString lbl = "Serial Port"; if (IS_RADIOMASTER_TX16S(board)) @@ -163,14 +183,6 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings addParams(row, sportPower); } - if (firmware->getCapability(HasTelemetryBaudrate)) { - addLabel(tr("Maximum Baud"), row, 0); - AutoComboBox *maxBaudRate = new AutoComboBox(this); - maxBaudRate->setModel(editorItemModels->getItemModel(baudmodelid)); - maxBaudRate->setField(generalSettings.telemetryBaudrate, this); - addParams(row, maxBaudRate); - } - if (firmware->getCapability(HastxCurrentCalibration)) { addLabel(tr("Current Offset"), row, 0); AutoSpinBox *txCurrentCalibration = new AutoSpinBox(this); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index c611aa1f5..b838fc4b0 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -237,14 +237,12 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->trainerMode->hide(); } - // The protocols available on this board - for (unsigned int i = 0; i < PULSES_PROTOCOL_LAST; i++) { - if (firmware->isAvailable((PulsesProtocol) i, moduleIdx)) { - ui->protocol->addItem(ModuleData::protocolToString(i), i); - if (i == module.protocol) - ui->protocol->setCurrentIndex(ui->protocol->count() - 1); - } + if (panelFilteredItemModels && moduleIdx >= 0) { + int id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(ModuleData::protocolItemModel(generalSettings), moduleIdx + 1/*flag cannot be 0*/), QString("Module Protocol %1").arg(moduleIdx)); + ui->protocol->setModel(panelFilteredItemModels->getItemModel(id)); + ui->protocol->setField(module.protocol, this); } + for (int i = 0; i <= MODULE_SUBTYPE_MULTI_LAST; i++) { if (i == MODULE_SUBTYPE_MULTI_SCANNER) continue; @@ -266,7 +264,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul update(); - connect(ui->protocol, static_cast(&QComboBox::currentIndexChanged), this, &ModulePanel::onProtocolChanged); + connect(ui->protocol, &AutoComboBox::currentDataChanged, this, &ModulePanel::onProtocolChanged); connect(ui->multiSubType, static_cast(&QComboBox::currentIndexChanged), this, &ModulePanel::onSubTypeChanged); connect(ui->multiProtocol, static_cast(&QComboBox::currentIndexChanged), this, &ModulePanel::onMultiProtocolChanged); connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes); @@ -662,8 +660,7 @@ void ModulePanel::update() void ModulePanel::onProtocolChanged(int index) { - if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) { - module.protocol = ui->protocol->itemData(index).toInt(); + if (!lock) { module.channelsCount = module.getMaxChannelCount(); update(); emit updateItemModels(); @@ -1391,7 +1388,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge // 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); + modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i, panelFilteredModels); ui->modulesLayout->addWidget(modules[i]); connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified); connect(modules[i], &ModulePanel::updateItemModels, this, &SetupPanel::onModuleUpdateItemModels); diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui index f78bd2772..4689f6a8d 100644 --- a/companion/src/modeledit/setup_module.ui +++ b/companion/src/modeledit/setup_module.ui @@ -805,7 +805,7 @@ - + 0