From d1ef6f866c0012a4bd3c73d854fae791ae9d79f9 Mon Sep 17 00:00:00 2001 From: Peter Feerick Date: Sun, 23 Jan 2022 18:42:31 +1000 Subject: [PATCH] [tpro] fix function switch behaviours and add always on capability (#1479) * fix: tpro function switch toggle mode * feat: Function switches now have alway on option * Companion support for function switch always on * Fix nasty eeprom error * Update fs startup item model * Fix Tpro SWITCH_EXISTS Co-authored-by: 3djc Co-authored-by: elecpower --- companion/src/firmwares/modeldata.cpp | 6 +-- .../src/firmwares/opentx/opentxeeprom.cpp | 4 +- companion/src/modeledit/setup.cpp | 41 +++++++++++++++++- companion/src/modeledit/setup.h | 2 + .../src/modeledit/setup_function_switches.ui | 43 +++++++++++-------- radio/src/gui/128x64/model_setup.cpp | 16 ++++++- radio/src/myeeprom.h | 3 +- radio/src/switches.cpp | 16 ++++--- 8 files changed, 98 insertions(+), 33 deletions(-) diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 64e8879d6..70ca16810 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -1704,11 +1704,11 @@ QString ModelData::funcSwitchStartToString(const int index, const int value) { switch (value) { case FUNC_SWITCH_START_INACTIVE: - return CPN_STR_SW_INDICATOR_UP; + return tr("Inactive"); case FUNC_SWITCH_START_ACTIVE: - return CPN_STR_SW_INDICATOR_DN; + return tr("Active"); case FUNC_SWITCH_START_PREVIOUS: - return "="; + return tr("Restore"); default: return CPN_STR_UNKNOWN_ITEM; } diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 7724497c8..2636be39f 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -2659,7 +2659,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version)); else if (IS_TARANIS_X9E(board)) internalField.Append(new SwitchesWarningField<64>(this, modelData.switchWarningStates, board, version)); - else if (version >= 219 && IS_TARANIS_X9D(board)) + else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version)); else if (IS_TARANIS(board)) internalField.Append(new SwitchesWarningField<16>(this, modelData.switchWarningStates, board, version)); @@ -2668,7 +2668,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig if (IS_TARANIS_X9E(board)) internalField.Append(new UnsignedField<32>(this, modelData.switchWarningEnable)); - else if (version >= 219 && IS_TARANIS_X9D(board)) + else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) internalField.Append(new UnsignedField<16>(this, modelData.switchWarningEnable)); else if (!IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new UnsignedField<8>(this, modelData.switchWarningEnable)); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 98b555c3b..b6a05946c 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -1034,6 +1034,10 @@ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model QSpinBox * sbGroup = new QSpinBox(this); sbGroup->setProperty("index", i); sbGroup->setMaximum(3); + sbGroup->setSpecialValueText("-"); + + QCheckBox * cbAlwaysOnGroup = new QCheckBox(this); + cbAlwaysOnGroup->setProperty("index", i); int row = 0; int coloffset = 1; @@ -1042,15 +1046,18 @@ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model ui->gridSwitches->addWidget(cboConfig, row++, i + coloffset); ui->gridSwitches->addWidget(cboStartPosn, row++, i + coloffset); ui->gridSwitches->addWidget(sbGroup, row++, i + coloffset); + ui->gridSwitches->addWidget(cbAlwaysOnGroup, row++, i + coloffset); connect(cboConfig, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_configCurrentIndexChanged); connect(cboStartPosn, QOverload::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_startPosnCurrentIndexChanged); connect(sbGroup, QOverload::of(&QSpinBox::valueChanged), this, &FunctionSwitchesPanel::on_groupChanged); + connect(cbAlwaysOnGroup, &QCheckBox::toggled, this, &FunctionSwitchesPanel::on_alwaysOnGroupChanged); aleNames << aleName; cboConfigs << cboConfig; cboStartupPosns << cboStartPosn; sbGroups << sbGroup; + cbAlwaysOnGroups << cbAlwaysOnGroup; } update(); @@ -1078,7 +1085,9 @@ void FunctionSwitchesPanel::update(int index) aleNames[i]->update(); cboConfigs[i]->setCurrentIndex((model->functionSwitchConfig >> (2 * i)) & 0x03); cboStartupPosns[i]->setCurrentIndex((model->functionSwitchStartConfig >> (2 * i)) & 0x03); - sbGroups[i]->setValue((model->functionSwitchGroup >> (2 * i)) & 0x03); + const int grp = (model->functionSwitchGroup >> (2 * i)) & 0x03; + sbGroups[i]->setValue(grp); + cbAlwaysOnGroups[i]->setChecked((model->functionSwitchGroup >> (2 * switchcnt + grp)) & 0x01); if (cboConfigs[i]->currentIndex() < 2) cboStartupPosns[i]->setEnabled(false); @@ -1089,6 +1098,11 @@ void FunctionSwitchesPanel::update(int index) sbGroups[i]->setEnabled(false); else sbGroups[i]->setEnabled(true); + + if (!(sbGroups[i]->isEnabled()) || grp < 1) + cbAlwaysOnGroups[i]->setEnabled(false); + else + cbAlwaysOnGroups[i]->setEnabled(true); } lock = false; @@ -1153,12 +1167,37 @@ void FunctionSwitchesPanel::on_groupChanged(int value) if (ok && ((model->functionSwitchGroup >> (2 * i)) & 0x03) != (unsigned int)value) { unsigned int mask = ((unsigned int) 0x03 << (2 * i)); model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) value << (2 * i)); + update(i); emit modified(); } lock = false; } } +void FunctionSwitchesPanel::on_alwaysOnGroupChanged(int value) +{ + if (!sender()) + return; + + QCheckBox * cb = qobject_cast(sender()); + + if (cb && !lock) { + lock = true; + bool ok = false; + int i = sender()->property("index").toInt(&ok); + + if (ok) { + const int grp = (model->functionSwitchGroup >> (2 * i)) & 0x03; + unsigned int mask = ((unsigned int) 0x01 << (2 * switchcnt + grp)); + model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) value << (2 * switchcnt + grp)); + update(); + emit modified(); + } + + lock = false; + } +} + /******************************************************************************/ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index c63932237..015ed491c 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -146,6 +146,7 @@ class FunctionSwitchesPanel : public ModelPanel void on_configCurrentIndexChanged(int index); void on_startPosnCurrentIndexChanged(int index); void on_groupChanged(int value); + void on_alwaysOnGroupChanged(int value); private: Ui::FunctionSwitches * ui; @@ -153,6 +154,7 @@ class FunctionSwitchesPanel : public ModelPanel QVector cboConfigs; QVector cboStartupPosns; QVector sbGroups; + QVector cbAlwaysOnGroups; int switchcnt; }; diff --git a/companion/src/modeledit/setup_function_switches.ui b/companion/src/modeledit/setup_function_switches.ui index acfd88e5d..3e272ce27 100644 --- a/companion/src/modeledit/setup_function_switches.ui +++ b/companion/src/modeledit/setup_function_switches.ui @@ -7,7 +7,7 @@ 0 0 231 - 140 + 145 @@ -56,6 +56,13 @@ QLayout::SetMinimumSize + + + + + + + @@ -63,6 +70,20 @@ + + + + Name + + + + + + + Start + + + @@ -76,24 +97,10 @@ - - + + - Start - - - - - - - Name - - - - - - - + Always On diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index ceceb045f..5fc591d22 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -256,7 +256,7 @@ inline uint8_t MODULE_SUBTYPE_ROWS(int moduleIdx) #endif #if defined(FUNCTION_SWITCHES) - #define FUNCTION_SWITCHES_ROWS READONLY_ROW, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|2, NAVIGATION_LINE_BY_LINE|(NUM_FUNCTIONS_SWITCHES-1), + #define FUNCTION_SWITCHES_ROWS READONLY_ROW, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|3, NAVIGATION_LINE_BY_LINE|(NUM_FUNCTIONS_SWITCHES-1), #else #define FUNCTION_SWITCHES_ROWS #endif @@ -631,11 +631,23 @@ void menuModelSetup(event_t event) } config = FSWITCH_GROUP(index); - config = editChoice(30 + 15*FW, y, "", STR_FSGROUPS, config, 0, 3, menuHorizontalPosition == 2 ? attr : 0, event); + config = editChoice(30 + 13 * FW, y, "", STR_FSGROUPS, config, 0, 3, menuHorizontalPosition == 2 ? attr : 0, event); if (attr && checkIncDec_Ret && menuHorizontalPosition == 2) { swconfig_t mask = (swconfig_t) 0x03 << (2 * index); g_model.functionSwitchGroup = (g_model.functionSwitchGroup & ~mask) | ((swconfig_t(config) & 0x03) << (2 * index)); } + + if (FSWITCH_GROUP(index)) { + uint8_t groupeAlwaysOn = IS_FSWITCH_GROUP_ON(config); + groupeAlwaysOn = editCheckBox(groupeAlwaysOn, 30 + 15 * FW, y, "", menuHorizontalPosition == 3 ? attr : 0, event); + if (attr && checkIncDec_Ret && menuHorizontalPosition == 3) { + swconfig_t mask = (swconfig_t) 0x01 << (2 * NUM_FUNCTIONS_SWITCHES + config); + g_model.functionSwitchGroup = (g_model.functionSwitchGroup & ~mask) | (groupeAlwaysOn << (2 * NUM_FUNCTIONS_SWITCHES + config)); + } + } + else if (attr && menuHorizontalPosition == 3) { // Non visible checkbox + REPEAT_LAST_CURSOR_MOVE(); + } break; } diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index aaa74a634..402021ca8 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -86,8 +86,9 @@ #if defined(FUNCTION_SWITCHES) #define FSWITCH_CONFIG(x) (bfGet(g_model.functionSwitchConfig, 2*(x), 2)) #define FSWITCH_GROUP(x) (bfGet(g_model.functionSwitchGroup, 2*(x), 2)) + #define IS_FSWITCH_GROUP_ON(x) (bfGet(g_model.functionSwitchGroup, 2 * NUM_FUNCTIONS_SWITCHES + x, 1)) #define IS_SWITCH_FS(x) (x >= NUM_REGULAR_SWITCHES) - #define SWITCH_EXISTS(x) (IS_SWITCH_FS(x) ? true : (FSWITCH_CONFIG(x) != SWITCH_NONE)) + #define SWITCH_EXISTS(x) (IS_SWITCH_FS(x) ? true : (SWITCH_CONFIG(x) != SWITCH_NONE)) #define IS_CONFIG_3POS(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - NUM_REGULAR_SWITCHES) == SWITCH_3POS) : (SWITCH_CONFIG(x) == SWITCH_3POS)) #define IS_CONFIG_TOGGLE(x) (IS_SWITCH_FS(x) ? (FSWITCH_CONFIG(x - NUM_REGULAR_SWITCHES) == SWITCH_TOGGLE) : (SWITCH_CONFIG(x) == SWITCH_TOGGLE)) #else diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index c5d43867c..9a8fc7182 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -122,21 +122,25 @@ void evalFunctionSwitches() uint8_t physicalState = getFSPhysicalState(i); if (physicalState != getFSPreviousPhysicalState(i)) { // FS was moved - if (FSWITCH_CONFIG(i) == SWITCH_2POS && physicalState == 1) { - g_model.functionSwitchLogicalState ^= 1 << i; // Toggle bit - } - else if (FSWITCH_CONFIG(i) == SWITCH_TOGGLE) { - g_model.functionSwitchLogicalState ^= (physicalState ^ g_model.functionSwitchLogicalState) & (1 << i); // Set bit to switch value + if ((FSWITCH_CONFIG(i) == SWITCH_2POS && physicalState == 1) || (FSWITCH_CONFIG(i) == SWITCH_TOGGLE)) { + if (IS_FSWITCH_GROUP_ON(FSWITCH_GROUP(i)) != 0) { // In an always on group + g_model.functionSwitchLogicalState |= 1 << i; // Set bit + } + else { + g_model.functionSwitchLogicalState ^= 1 << i; // Toggle bit + } } + if (FSWITCH_GROUP(i) && physicalState == 1) { // switch is in a group, other in group need to be turned off for (uint8_t j = 0; j < NUM_FUNCTIONS_SWITCHES; j++) { - if (i == j) + if (i == j) continue; if (FSWITCH_GROUP(j) == FSWITCH_GROUP(i)) { g_model.functionSwitchLogicalState &= ~(1 << j); // clear state } } } + fsPreviousState ^= 1 << i; // Toggle state storageDirty(EE_MODEL); }