Add Internal Module to companion

This commit is contained in:
elecpower
2022-01-02 13:05:09 +01:00
committed by Raphael Coeffic
parent 85a184f15e
commit d7190493d5
8 changed files with 348 additions and 27 deletions
+3
View File
@@ -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;
}
+4 -1
View File
@@ -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);
@@ -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;
+278 -1
View File
@@ -23,6 +23,12 @@
#include "multiprotocols.h"
#include "afhds3.h"
#include "radiodataconversionstate.h"
#include "compounditemmodels.h"
#include "generalsettings.h"
#include "datahelpers.h"
#include <QPair>
#include <QVector>
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<QPair<int, int>>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 }
};
QPair<int, int>elmt;
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;
}
+33 -5
View File
@@ -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
+20 -8
View File
@@ -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);
+8 -11
View File
@@ -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<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onProtocolChanged);
connect(ui->protocol, &AutoComboBox::currentDataChanged, this, &ModulePanel::onProtocolChanged);
connect(ui->multiSubType, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onSubTypeChanged);
connect(ui->multiProtocol, static_cast<void(QComboBox::*)(int)>(&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);
+1 -1
View File
@@ -805,7 +805,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="protocol">
<widget class="AutoComboBox" name="protocol">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>