diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index f6bea20af..e313a6057 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -390,6 +390,8 @@ QString CustomSwData::funcToString() return QObject::tr("Timer"); case CS_FN_STICKY: return QObject::tr("Sticky"); + case CS_FN_STAY: + return QObject::tr("Stay"); default: return QObject::tr("Unknown"); } @@ -406,11 +408,14 @@ QString CustomSwData::toString(const ModelData & model) result +="( "; } switch (getFunctionFamily()) { + case CS_FAMILY_STAY: + result = QObject::tr("STAY(%1, [%2:%3])").arg(RawSwitch(val1).toString()).arg(ValToTim(val2)).arg(ValToTim(val2+val3)); + break; case CS_FAMILY_STICKY: - result = QObject::tr("STICKY(%1 , %2)").arg(RawSwitch(val1).toString()).arg(RawSwitch(val2).toString()); + result = QObject::tr("STICKY(%1, %2)").arg(RawSwitch(val1).toString()).arg(RawSwitch(val2).toString()); break; case CS_FAMILY_TIMER: - result = QObject::tr("TIMER(%1 , %2)").arg(ValToTim(val1)).arg(ValToTim(val2)); + result = QObject::tr("TIMER(%1, %2)").arg(ValToTim(val1)).arg(ValToTim(val2)); break; case CS_FAMILY_VOFS: { RawSource source = RawSource(val1, &model); @@ -873,11 +878,7 @@ void ModelData::clear() phaseData[i].clear(); clearInputs(); clearMixes(); - for(int i=0; i<4; i++){ - mixData[i].destCh = i+1; - mixData[i].srcRaw = RawSource(SOURCE_TYPE_STICK, i); - mixData[i].weight = 100; - } + for (int i=0; ifunc = func; } unsigned int func; - int val1; - int val2; + int val1; + int val2; + int val3; unsigned int delay; unsigned int duration; int andsw; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 60996f68f..779012861 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -1140,7 +1140,12 @@ class CustomSwitchField: public TransformedField { switchesConversionTable(SwitchesConversionTable::getInstance(board, version)), andswitchesConversionTable(AndSwitchesConversionTable::getInstance(board, version)) { - if (IS_ARM(board) && version >= 215) { + if (IS_ARM(board) && version >= 216) { + internalField.Append(new SignedField<8>(v1)); + internalField.Append(new SignedField<16>(v2)); + internalField.Append(new SignedField<16>(v3)); + } + else if (IS_ARM(board) && version >= 215) { internalField.Append(new SignedField<16>(v1)); internalField.Append(new SignedField<16>(v2)); } @@ -1170,7 +1175,12 @@ class CustomSwitchField: public TransformedField { virtual void beforeExport() { - if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { + if (csw.func == CS_FN_STAY) { + switchesConversionTable->exportValue(csw.val1, v1); + v2 = csw.val2; + v3 = csw.val3; + } + else if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { switchesConversionTable->exportValue(csw.val1, v1); switchesConversionTable->exportValue(csw.val2, v2); } @@ -1189,7 +1199,12 @@ class CustomSwitchField: public TransformedField { virtual void afterImport() { - if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { + if (csw.func == CS_FN_STAY) { + switchesConversionTable->importValue(v1, csw.val1); + csw.val2 = v2; + csw.val3 = v3; + } + else if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { switchesConversionTable->importValue(v1, csw.val1); switchesConversionTable->importValue(v2, csw.val2); } @@ -1218,6 +1233,7 @@ class CustomSwitchField: public TransformedField { ConversionTable * andswitchesConversionTable; int v1; int v2; + int v3; }; class CustomFunctionsConversionTable: public ConversionTable { diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp index 58c07b74f..9bbf8fe55 100644 --- a/radio/src/eeprom_conversions.cpp +++ b/radio/src/eeprom_conversions.cpp @@ -381,13 +381,13 @@ void ConvertModel_215_to_216(ModelData &model) #if defined(PCBTARANIS) CustomSwData * cs = &g_model.customSw[i]; uint8_t cstate = cswFamily(cs->func); - if (cstate == CS_VOFS || cstate == CS_VCOMP || cstate == CS_VDIFF) { + if (cstate == CS_FAMILY_OFS || cstate == CS_FAMILY_COMP || cstate == CS_FAMILY_DIFF) { if (cs->v1 > 0) cs->v1 += MAX_INPUTS + MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS; if (cs->v1 > MIXSRC_GVAR1+4) cs->v1 += 4; } - if (cstate == CS_VOFS || cstate == CS_VDIFF) { + if (cstate == CS_FAMILY_OFS || cstate == CS_FAMILY_DIFF) { if (cs->v1 >= MIXSRC_FIRST_TELEM) { - switch (cs->v1) { + switch ((uint8_t)cs->v1) { case MIXSRC_FIRST_TELEM + TELEM_TM1-1: case MIXSRC_FIRST_TELEM + TELEM_TM2-1: cs->v2 = (cs->v2+128) * 3; @@ -429,7 +429,7 @@ void ConvertModel_215_to_216(ModelData &model) } } } - if (cstate == CS_VCOMP) { + if (cstate == CS_FAMILY_COMP) { if (cs->v2 > 0) cs->v2 += MAX_INPUTS + MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS; if (cs->v2 > MIXSRC_GVAR1+4) cs->v2 += 4; } diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index 01ee2766d..f310407cb 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -4174,6 +4174,9 @@ enum CustomSwitchFields { CSW_FIELD_FUNCTION, CSW_FIELD_V1, CSW_FIELD_V2, +#if defined(PCBTARANIS) + CSW_FIELD_V3, +#endif CSW_FIELD_ANDSW, #if defined(CPUARM) CSW_FIELD_DURATION, @@ -4208,7 +4211,8 @@ void menuModelCustomSwitchOne(uint8_t event) CustomSwData * cs = cswAddress(s_currIdx); uint8_t sw = SWSRC_SW1+s_currIdx; putsSwitches(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0)); - SIMPLE_SUBMENU_NOTITLE(CSW_FIELD_COUNT); + + SUBMENU_NOTITLE(CSW_FIELD_COUNT, {0, 0, 1, 0 /*, 0...*/}); int8_t sub = m_posVert; @@ -4222,10 +4226,18 @@ void menuModelCustomSwitchOne(uint8_t event) lcd_putsLeft(y, STR_FUNC); lcd_putsiAtt(CSWONE_2ND_COLUMN, y, STR_VCSWFUNC, cs->func, attr); if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, cs->func, CS_MAXF); - if (cstate != cswFamily(cs->func)) { - cs->v1 = 0; - cs->v2 = 0; + cs->func = checkIncDec(event, cs->func, 0, CS_MAXF, EE_MODEL, isFunctionAvailable); + uint8_t new_cstate = cswFamily(cs->func); + if (cstate != new_cstate) { + if (new_cstate == CS_FAMILY_TIMER) { + cs->v1 = cs->v2 = -119; + } + else if (new_cstate == CS_FAMILY_STAY) { + cs->v1 = 0; cs->v2 = -129; cs->v3 = 0; + } + else { + cs->v1 = cs->v2 = 0; + } } } break; @@ -4233,11 +4245,11 @@ void menuModelCustomSwitchOne(uint8_t event) { lcd_putsLeft(y, STR_V1); int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM; - if (cstate == CS_VBOOL || cstate == CS_VSTICKY) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY || cstate == CS_FAMILY_STAY) { putsSwitches(CSWONE_2ND_COLUMN, y, cs->v1, attr); v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cs->v1+1, LEFT|attr); v1_max = 99; } @@ -4252,16 +4264,32 @@ void menuModelCustomSwitchOne(uint8_t event) case CSW_FIELD_V2: { lcd_putsLeft(y, STR_V2); - int8_t v2_min=0, v2_max=MIXSRC_LAST_TELEM; - if (cstate == CS_VBOOL || cstate == CS_VSTICKY) { + int16_t v2_min=0, v2_max=MIXSRC_LAST_TELEM; + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSWONE_2ND_COLUMN, y, cs->v2, attr); v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1; } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cs->v2+1, LEFT|attr); v2_max = 99; } - else if (cstate == CS_VCOMP) { + else if (cstate == CS_FAMILY_STAY) { + lcd_putc(CSWONE_2ND_COLUMN-4, y, '['); + lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|(m_posHorz==0 ? attr : 0)); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_putsAtt(lcdLastPos+3, y, "--", (m_posHorz==1 ? attr : 0)); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(m_posHorz==1 ? attr : 0)); + lcd_putc(lcdLastPos, y, ']'); + if (s_editMode <= 0) continue; + if (attr && m_posHorz==1) { + CHECK_INCDEC_MODELVAR(event, cs->v3, 0, 222 - cs->v2); + break; + } + v2_min=-129; v2_max = 122; + } + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr); } else { @@ -4269,7 +4297,7 @@ void menuModelCustomSwitchOne(uint8_t event) if (cs->v1 >= MIXSRC_FIRST_TELEM) { putsTelemetryChannel(CSWONE_2ND_COLUMN, y, cs->v1 - MIXSRC_FIRST_TELEM, convertCswTelemValue(cs), attr|LEFT); v2_max = maxTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1); - if (cstate == CS_VOFS) { + if (cstate == CS_FAMILY_OFS) { v2_min = -128; v2_max -= 128; } @@ -4358,15 +4386,26 @@ void menuModelCustomSwitches(uint8_t event) // CSW params uint8_t cstate = cswFamily(cs->func); - if (cstate == CS_VBOOL || cstate == CS_VSTICKY) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); putsSwitches(CSW_3RD_COLUMN, y, cs->v2, 0); } - else if (cstate == CS_VCOMP) { + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, 0); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, 0); } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_STAY) { + putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); + lcd_putc(CSW_3RD_COLUMN-4, y, '['); + lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_puts(lcdLastPos+3, y, "--"); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1); + lcd_putc(lcdLastPos-1, y, ']'); + } + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSW_2ND_COLUMN, y, cs->v1+1, LEFT); lcd_outdezAtt(CSW_3RD_COLUMN, y, cs->v2+1, LEFT); } @@ -4473,11 +4512,12 @@ void menuModelCustomSwitches(uint8_t event) uint8_t cstate = cswFamily(cs->func); #if defined(CPUARM) int16_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; + int16_t v3_min=0, v3_max=100; #else int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; #endif - if (cstate == CS_VBOOL || cstate == CS_VSTICKY) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; @@ -4485,13 +4525,31 @@ void menuModelCustomSwitches(uint8_t event) INCDEC_SET_FLAG(INCDEC_SWITCH); INCDEC_ENABLE_CHECK(isSwitchAvailableInCustomSwitches); } - else if (cstate == CS_VCOMP) { +#if defined(CPUARM) + else if (cstate == CS_FAMILY_STAY) { + putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); + lcd_putc(CSW_3RD_COLUMN-4, y, '['); + lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|attr2); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_putsAtt(lcdLastPos+3, y, "--", (horz==CSW_FIELD_V3 ? attr : 0)); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(horz==CSW_FIELD_V3 ? attr : 0)); + lcd_putc(lcdLastPos, y, ']'); + v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; + v2_min=-129; v2_max = 122; + v3_max = 222 - cs->v2; + INCDEC_SET_FLAG(0); + INCDEC_ENABLE_CHECK(NULL); + } +#endif + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, attr1); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); INCDEC_SET_FLAG(INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSW_2ND_COLUMN, y, cswTimerValue(cs->v1), LEFT|PREC1|attr1); lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|attr2); v1_min = v2_min = -128; @@ -4520,7 +4578,7 @@ void menuModelCustomSwitches(uint8_t event) eeDirty(EE_MODEL); } #else - if (cstate == CS_VOFS) { + if (cstate == CS_FAMILY_OFS) { v2_min = -128; v2_max -= 128; } @@ -4552,37 +4610,59 @@ void menuModelCustomSwitches(uint8_t event) // CSW AND switch #if defined(CPUARM) - putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==3 ? attr : 0); + putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==CSW_FIELD_ANDSW ? attr : 0); #else uint8_t andsw = cs->andsw; if (andsw > SWSRC_LAST_SWITCH) { andsw += SWSRC_SW1-SWSRC_LAST_SWITCH-1; } - putsSwitches(CSW_4TH_COLUMN, y, andsw, horz==3 ? attr : 0); + putsSwitches(CSW_4TH_COLUMN, y, andsw, horz==CSW_FIELD_ANDSW ? attr : 0); #endif #if defined(CPUARM) // CSW duration if (cs->duration > 0) - lcd_outdezAtt(CSW_5TH_COLUMN, y, 5*cs->duration, (horz==4 ? attr : 0)|PREC1|LEFT); + lcd_outdezAtt(CSW_5TH_COLUMN, y, 5*cs->duration, (horz==CSW_FIELD_DURATION ? attr : 0)|PREC1|LEFT); else - lcd_putsiAtt(CSW_5TH_COLUMN, y, STR_MMMINV, 0, horz==4 ? attr : 0); + lcd_putsiAtt(CSW_5TH_COLUMN, y, STR_MMMINV, 0, horz==CSW_FIELD_DURATION ? attr : 0); // CSW delay if (cs->delay > 0) - lcd_outdezAtt(CSW_6TH_COLUMN, y, 5*cs->delay, (horz==5 ? attr : 0)|PREC1|LEFT); + lcd_outdezAtt(CSW_6TH_COLUMN, y, 5*cs->delay, (horz==CSW_FIELD_DELAY ? attr : 0)|PREC1|LEFT); else - lcd_putsiAtt(CSW_6TH_COLUMN, y, STR_MMMINV, 0, horz==5 ? attr : 0); + lcd_putsiAtt(CSW_6TH_COLUMN, y, STR_MMMINV, 0, horz==CSW_FIELD_DELAY ? attr : 0); + + if (attr && horz == CSW_FIELD_V3 && cstate != CS_FAMILY_STAY) { + REPEAT_LAST_CURSOR_MOVE(); + } #endif + if ((s_editMode>0 || p1valdiff) && attr) { switch (horz) { case CSW_FIELD_FUNCTION: { +#if defined(CPUARM) + cs->func = checkIncDec(event, cs->func, 0, CS_MAXF, EE_MODEL, isFunctionAvailable); +#else CHECK_INCDEC_MODELVAR_ZERO(event, cs->func, CS_MAXF); +#endif uint8_t new_cstate = cswFamily(cs->func); - if (cstate != new_cstate) - cs->v1 = cs->v2 = (new_cstate==CS_VTIMER ? -119/*1.0*/ : 0); + if (cstate != new_cstate) { +#if defined(CPUARM) + if (new_cstate == CS_FAMILY_TIMER) { + cs->v1 = cs->v2 = -119; + } + else if (new_cstate == CS_FAMILY_STAY) { + cs->v1 = 0; cs->v2 = -129; cs->v3 = 0; + } + else { + cs->v1 = cs->v2 = 0; + } +#else + cs->v1 = cs->v2 = (new_cstate==CS_FAMILY_TIMER ? -119/*1.0*/ : 0); +#endif + } break; } case CSW_FIELD_V1: @@ -4591,7 +4671,7 @@ void menuModelCustomSwitches(uint8_t event) case CSW_FIELD_V2: cs->v2 = CHECK_INCDEC_PARAM(event, cs->v2, v2_min, v2_max); #if defined(PCBTARANIS) - if (cstate==CS_VOFS && cs->v1!=0 && event==EVT_KEY_LONG(KEY_ENTER)) { + if (cstate==CS_FAMILY_OFS && cs->v1!=0 && event==EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); getvalue_t x = getValue(cs->v1); if (cs->v1 < MIXSRC_GVAR1) @@ -4602,6 +4682,11 @@ void menuModelCustomSwitches(uint8_t event) } #endif break; +#if defined(CPUARM) + case CSW_FIELD_V3: + cs->v3 = CHECK_INCDEC_PARAM(event, cs->v3, v3_min, v3_max); + break; +#endif case CSW_FIELD_ANDSW: #if defined(CPUARM) INCDEC_SET_FLAG(INCDEC_SWITCH); diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp index 455ac0a57..e6cbfccee 100644 --- a/radio/src/gui/menus.cpp +++ b/radio/src/gui/menus.cpp @@ -1291,5 +1291,10 @@ bool isSwitchAvailable(int16_t swtch) return true; } +// Not available yet, will be needed if we implement the Range function later... +bool isFunctionAvailable(int16_t function) +{ + return function != CS_RANGE; +} #endif diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h index 3b4e44e59..eed58fd97 100644 --- a/radio/src/gui/menus.h +++ b/radio/src/gui/menus.h @@ -190,6 +190,7 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max); var = checkIncDecModelZero(event,var,max) #if defined(CPUARM) + bool isFunctionAvailable(int16_t function); bool isSwitchAvailable(int16_t swtch); bool isSwitchAvailableInCustomSwitches(int16_t swtch); #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 7fd0183d8..c74a12f76 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -668,14 +668,42 @@ PACK( union u_int8int16_t { #endif +enum CswFunctions { + CS_OFF, + CS_VEQUAL, // v==offset + CS_VPOS, // v>offset + CS_VNEG, // voffset + CS_ANEG, // |v|srcRaw = i+1; - if (!isSourceAvailable(mix->srcRaw)) { - mix->srcRaw = MIXSRC_Rud - 1 + stick_index; - } #else mix->srcRaw = MIXSRC_Rud - 1 + channel_order(i+1); #endif @@ -573,9 +583,9 @@ void modelDefault(uint8_t id) g_model.frsky.channels[0].ratio = 132; #endif -#ifdef MAVLINK - g_model.mavlink.rc_rssi_scale = 15; - g_model.mavlink.pc_rssi_en = 1; +#if defined(MAVLINK) + g_model.mavlink.rc_rssi_scale = 15; + g_model.mavlink.pc_rssi_en = 1; #endif } @@ -1426,7 +1436,7 @@ bool getSwitch(int8_t swtch) csLastValue[cs_idx] = CS_LAST_VALUE_INIT; result = false; } - else if ((s=cswFamily(cs->func)) == CS_VBOOL) { + else if ((s=cswFamily(cs->func)) == CS_FAMILY_BOOL) { bool res1 = getSwitch(cs->v1); bool res2 = getSwitch(cs->v2); switch (cs->func) { @@ -1442,16 +1452,21 @@ bool getSwitch(int8_t swtch) break; } } - else if (s == CS_VTIMER) { + else if (s == CS_FAMILY_TIMER) { result = (csLastValue[cs_idx] <= 0); } - else if (s == CS_VSTICKY) { + else if (s == CS_FAMILY_STICKY) { result = (csLastValue[cs_idx] & (1<<0)); } +#if defined(CPUARM) + else if (s == CS_FAMILY_STAY) { + result = (csLastValue[cs_idx] & (1<<0)); + } +#endif else { getvalue_t x = getValue(cs->v1); getvalue_t y; - if (s == CS_VCOMP) { + if (s == CS_FAMILY_COMP) { y = getValue(cs->v2); switch (cs->func) { @@ -1476,7 +1491,7 @@ bool getSwitch(int8_t swtch) y = convertCswTelemValue(cs); #if defined(FRSKY_HUB) && defined(GAUGES) - if (s == CS_VOFS) { + if (s == CS_FAMILY_OFS) { uint8_t idx = cs->v1-MIXSRC_FIRST_TELEM+1-TELEM_ALT; if (idx < THLD_MAX) { // Fill the threshold array @@ -1563,6 +1578,9 @@ bool getSwitch(int8_t swtch) if (cswDurations[cs_idx] > get_tmr10ms()) { result = true; } + else if (s == CS_FAMILY_STICKY) { + csLastValue[cs_idx] &= ~(1<<0); + } } #endif @@ -1980,7 +1998,7 @@ getvalue_t convertCswTelemValue(CustomSwData * cs) #if defined(CPUARM) val = convert16bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, cs->v2); #else - if (cswFamily(cs->func)==CS_VOFS) + if (cswFamily(cs->func)==CS_FAMILY_OFS) val = convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128+cs->v2); else val = convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128+cs->v2) - convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128); @@ -3995,27 +4013,54 @@ void doMixerCalculations() } } else if (cs->func == CS_STICKY) { - uint16_t & lastValue = (uint16_t &)csLastValue[i]; - bool before = (lastValue & (1<<15)); - if (lastValue & (1<<0)) { + PACK(typedef struct { + bool state; + bool last; + }) cs_sticky_struct; + cs_sticky_struct & lastValue = (cs_sticky_struct &)csLastValue[i]; + bool before = lastValue.last & 0x01; + if (lastValue.state) { bool now = getSwitch(cs->v2); if (now != before) { - lastValue ^= (1<<15); + lastValue.last ^= true; if (!before) { - lastValue &= ~(1<<0); + lastValue.state = false; } } } else { bool now = getSwitch(cs->v1); if (before != now) { - lastValue ^= (1<<15); + lastValue.last ^= true; if (!before) { - lastValue |= (1<<0); + lastValue.state = true; } } } } +#if defined(CPUARM) + else if (cs->func == CS_STAY) { + PACK(typedef struct { + uint8_t state:1; + uint16_t duration:15; + }) cs_stay_struct; + + cs_stay_struct & lastValue = (cs_stay_struct &)csLastValue[i]; + lastValue.state = false; + bool state = getSwitch(cs->v1); + if (state) { + if (cs->v3 == 0 && lastValue.duration == cswTimerValue(cs->v2)) + lastValue.state = true; + if (lastValue.duration < 1000) + lastValue.duration++; + } + else { + if (lastValue.duration > cswTimerValue(cs->v2) && lastValue.duration <= cswTimerValue(cs->v2+cs->v3)) + lastValue.state = true; + lastValue.duration = 0; + } + } +#endif } if (s_cnt_1s >= 10) { // 1sec diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 765a56c2d..82f8aca72 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -622,37 +622,6 @@ enum BaseCurves { #define SWASH_TYPE_90 4 #define SWASH_TYPE_NUM 4 -enum CswFunctions { - CS_OFF, - CS_VEQUAL, // v==offset - CS_VPOS, // v>offset - CS_VNEG, // voffset - CS_ANEG, // |v|x\0 ""ax""|a|b\0 ""ax\0 ""ax""|a|b\0 ""a