Skip to content

Commit

Permalink
feat(cpn): Trainer modes more closely mimic firmware (#3981)
Browse files Browse the repository at this point in the history
  • Loading branch information
Neil Horne authored Sep 4, 2023
1 parent f55f9c4 commit 8d8a50c
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 41 deletions.
9 changes: 9 additions & 0 deletions companion/src/firmwares/boards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 4 additions & 1 deletion companion/src/firmwares/boards.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ namespace Board {
HasInternalModuleSupport,
HasExternalModuleSupport,
HasAudioMuteGPIO,
SportMaxBaudRate
SportMaxBaudRate,
HasIntModuleHeartbeatGPIO,
HasTrainerModuleCPPM,
HasTrainerModuleSBUS,
};

struct SwitchInfo
Expand Down
2 changes: 1 addition & 1 deletion companion/src/firmwares/edgetx/yaml_modeldata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down
60 changes: 40 additions & 20 deletions companion/src/firmwares/modeldata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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();
Expand Down
6 changes: 3 additions & 3 deletions companion/src/firmwares/modeldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
47 changes: 31 additions & 16 deletions companion/src/modeledit/setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
}
}
Expand All @@ -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 <b>%2</b> is incompatible with the <b>%3 %1 module %4</b> and has been set to <b>OFF</b>!");
msg = msg.arg(moduleIdxDesc).arg(module.protocolToString(module.protocol)).arg(compareDesc).arg(intModuleDesc);

Expand All @@ -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));
}
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -814,6 +814,7 @@ void ModulePanel::onProtocolChanged(int index)
}
}

emit protocolChanged();
emit updateItemModels();
emit modified();
}
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions companion/src/modeledit/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Ui {
}

class AutoLineEdit;
class FilteredItemModel;

class TimerPanel : public ModelPanel
{
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -133,6 +136,10 @@ class ModulePanel : public ModelPanel
QMap<int, ChannelFailsafeWidgetsGroup> 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
Expand Down

0 comments on commit 8d8a50c

Please sign in to comment.