diff --git a/companion/src/constants.h b/companion/src/constants.h index 10960074d..958134e07 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -25,7 +25,7 @@ enum BoardEnum { #define C9X_MAX_GVARS 9 #define C9X_MAX_ENCODERS 2 #define C9X_NUM_CHNOUT 32 // number of real output channels -#define C9X_NUM_CSW 32 // number of custom switches +#define C9X_NUM_CSW 64 // number of custom switches #define C9X_MAX_CUSTOM_FUNCTIONS 64 // number of functions assigned to switches #define C9X_NUM_MODULES 2 #define NUM_STICKS 4 diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index d9243255e..e619bd4b6 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -475,13 +475,6 @@ QString RawSource::toString(const ModelData * model) const QObject::tr("ACC"), QObject::tr("GPS Time"), }; - static const QString logicalSwitches[] = { - QObject::tr("L1"), QObject::tr("L2"), QObject::tr("L3"), QObject::tr("L4"), QObject::tr("L5"), QObject::tr("L6"), QObject::tr("L7"), QObject::tr("L8"), QObject::tr("L9"), QObject::tr("L10"), - QObject::tr("L11"), QObject::tr("L12"), QObject::tr("L13"), QObject::tr("L14"), QObject::tr("L15"), QObject::tr("L16"), QObject::tr("L17"), QObject::tr("L18"), QObject::tr("L19"), QObject::tr("L20"), - QObject::tr("L21"), QObject::tr("L22"), QObject::tr("L23"), QObject::tr("L24"), QObject::tr("L25"), QObject::tr("L26"), QObject::tr("L27"), QObject::tr("L28"), QObject::tr("L29"), QObject::tr("L30"), - QObject::tr("L31"), QObject::tr("L32") - }; - if (index<0) { return QObject::tr("----"); } @@ -508,7 +501,7 @@ QString RawSource::toString(const ModelData * model) const case SOURCE_TYPE_SWITCH: return (IS_TARANIS(GetEepromInterface()->getBoard()) ? CHECK_IN_ARRAY(switchesX9D, index) : CHECK_IN_ARRAY(switches9X, index)); case SOURCE_TYPE_CUSTOM_SWITCH: - return logicalSwitches[index]; + return QObject::tr("L%1").arg(index+1); case SOURCE_TYPE_CYC: return QObject::tr("CYC%1").arg(index+1); case SOURCE_TYPE_PPM: @@ -590,13 +583,6 @@ QString RawSwitch::toString() const SwitchUp('R'), QString::fromUtf8("SR-"), SwitchDn('R'), }; - static const QString logicalSwitches[] = { - QObject::tr("L1"), QObject::tr("L2"), QObject::tr("L3"), QObject::tr("L4"), QObject::tr("L5"), QObject::tr("L6"), QObject::tr("L7"), QObject::tr("L8"), QObject::tr("L9"), QObject::tr("L10"), - QObject::tr("L11"), QObject::tr("L12"), QObject::tr("L13"), QObject::tr("L14"), QObject::tr("L15"), QObject::tr("L16"), QObject::tr("L17"), QObject::tr("L18"), QObject::tr("L19"), QObject::tr("L20"), - QObject::tr("L21"), QObject::tr("L22"), QObject::tr("L23"), QObject::tr("L24"), QObject::tr("L25"), QObject::tr("L26"), QObject::tr("L27"), QObject::tr("L28"), QObject::tr("L29"), QObject::tr("L30"), - QObject::tr("L31"), QObject::tr("L32") - }; - static const QString flightModes[] = { QObject::tr("FM0"), QObject::tr("FM1"), QObject::tr("FM2"), QObject::tr("FM3"), QObject::tr("FM4"), QObject::tr("FM5"), QObject::tr("FM6"), QObject::tr("FM7"), QObject::tr("FM8") }; @@ -634,7 +620,7 @@ QString RawSwitch::toString() const else return CHECK_IN_ARRAY(switches9X, index-1); case SWITCH_TYPE_VIRTUAL: - return CHECK_IN_ARRAY(logicalSwitches, index-1); + return QObject::tr("L%1").arg(index); case SWITCH_TYPE_MULTIPOS_POT: return CHECK_IN_ARRAY(multiposPots, index-1); case SWITCH_TYPE_TRIM: diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 6d34cb994..a62d97025 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -22,12 +22,13 @@ #define MAX_MIXERS(board, version) (IS_ARM(board) ? 64 : 32) #define MAX_CHANNELS(board, version) (IS_ARM(board) ? 32 : 16) #define MAX_EXPOS(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 216) ? 64 : 32) : (IS_DBLRAM(board, version) ? 16 : 14)) -#define MAX_CUSTOM_SWITCHES(board, version) (IS_ARM(board) ? 32 : ((IS_DBLEEPROM(board, version) && version<217) ? 15 : 12)) +#define MAX_LOGICAL_SWITCHES(board, version) (IS_ARM(board) ? (version >= 218 ? 64 : 32) : ((IS_DBLEEPROM(board, version) && version<217) ? 15 : 12)) #define MAX_CUSTOM_FUNCTIONS(board, version) (IS_ARM(board) ? (version >= 216 ? 64 : 32) : (IS_DBLEEPROM(board, version) ? 24 : 16)) #define MAX_CURVES(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 216) ? 32 : 16) : 8) #define MAX_GVARS(board, version) ((IS_ARM(board) && version >= 216) ? 9 : 5) #define MAX_SENSORS(board, version) (32) #define NUM_PPM_INPUTS(board, version) ((IS_ARM(board) && version >= 216) ? 16 : 8) +#define ROTENC_COUNT(board, version) (IS_ARM(board) ? ((IS_TARANIS(board) && version >= 218) ? 0 : 1) : (IS_2560(board) ? 2 : 0)) #define IS_AFTER_RELEASE_21_MARCH_2013(board, version) (version >= 214 || (!IS_ARM(board) && version >= 213)) #define IS_AFTER_RELEASE_23_MARCH_2013(board, version) (version >= 214 || (board==BOARD_STOCK && version >= 213)) @@ -100,7 +101,7 @@ class SwitchesConversionTable: public ConversionTable { } } - for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { + for (int i=1; i<=MAX_LOGICAL_SWITCHES(board, version); i++) { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, -i), -val+offset); addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } @@ -125,7 +126,7 @@ class SwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val++); } - for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { + for (int i=1; i<=MAX_LOGICAL_SWITCHES(board, version); i++) { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } @@ -263,7 +264,7 @@ class SourcesConversionTable: public ConversionTable { addConversion(RawSource(SOURCE_TYPE_SWITCH, i), val++); } } - for (int i=0; i=215)) { // On stock we use 10bits per trim @@ -803,13 +804,21 @@ class FlightModeField: public TransformedField { internalField.Append(new SignedField<16>(trimBase[i])); } } - - internalField.Append(new SwitchField<8>(phase.swtch, board, version)); - if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<10>(phase.name)); - else - internalField.Append(new ZCharField<6>(phase.name)); - + if (IS_ARM(board) && version >= 218) { + if (HAS_LARGE_LCD(board)) + internalField.Append(new ZCharField<10>(phase.name)); + else + internalField.Append(new ZCharField<6>(phase.name)); + internalField.Append(new SwitchField<9>(phase.swtch, board, version)); + internalField.Append(new SpareBitsField<7>()); + } + else { + internalField.Append(new SwitchField<8>(phase.swtch, board, version)); + if (HAS_LARGE_LCD(board)) + internalField.Append(new ZCharField<10>(phase.name)); + else + internalField.Append(new ZCharField<6>(phase.name)); + } if (IS_ARM(board) && version >= 214) { internalField.Append(new UnsignedField<8>(phase.fadeIn)); internalField.Append(new UnsignedField<8>(phase.fadeOut)); @@ -922,7 +931,25 @@ class MixField: public TransformedField { version(version), model(model) { - if (IS_TARANIS(board) && version >= 217) { + if (IS_TARANIS(board) && version >= 218) { + internalField.Append(new SignedField<11>(_weight)); + internalField.Append(new UnsignedField<5>(_destCh)); + internalField.Append(new SourceField<10>(mix.srcRaw, board, version, FLAG_NOTELEMETRY)); + internalField.Append(new UnsignedField<1>((unsigned int &)mix.carryTrim)); + internalField.Append(new UnsignedField<2>(mix.mixWarn)); + internalField.Append(new UnsignedField<2>((unsigned int &)mix.mltpx)); + internalField.Append(new SpareBitsField<1>()); + internalField.Append(new SignedField<14>(_offset)); + internalField.Append(new SwitchField<9>(mix.swtch, board, version)); + internalField.Append(new UnsignedField<9>(mix.flightModes)); + internalField.Append(new CurveReferenceField(mix.curve, board, version)); + internalField.Append(new UnsignedField<8>(mix.delayUp)); + internalField.Append(new UnsignedField<8>(mix.delayDown)); + internalField.Append(new UnsignedField<8>(mix.speedUp)); + internalField.Append(new UnsignedField<8>(mix.speedDown)); + internalField.Append(new ZCharField<8>(mix.name)); + } + else if (IS_TARANIS(board) && version >= 217) { internalField.Append(new UnsignedField<8>(_destCh)); internalField.Append(new UnsignedField<9>(mix.flightModes)); internalField.Append(new UnsignedField<2>((unsigned int &)mix.mltpx)); @@ -1190,7 +1217,21 @@ class InputField: public TransformedField { board(board), version(version) { - if (IS_TARANIS(board) && version >= 217) { + if (IS_TARANIS(board) && version >= 218) { + internalField.Append(new UnsignedField<2>(expo.mode, "Mode")); + internalField.Append(new UnsignedField<14>(expo.scale, "Scale")); + internalField.Append(new SourceField<10>(expo.srcRaw, board, version, 0)); + internalField.Append(new SignedField<6>(expo.carryTrim, "CarryTrim")); + internalField.Append(new UnsignedField<5>(expo.chn, "Channel")); + internalField.Append(new SwitchField<9>(expo.swtch, board, version)); + internalField.Append(new UnsignedField<9>(expo.flightModes)); + internalField.Append(new SignedField<8>(_weight, "Weight")); + internalField.Append(new SpareBitsField<1>()); + internalField.Append(new ZCharField<8>(expo.name)); + internalField.Append(new SignedField<8>(_offset, "Offset")); + internalField.Append(new CurveReferenceField(expo.curve, board, version)); + } + else if (IS_TARANIS(board) && version >= 217) { internalField.Append(new SourceField<10>(expo.srcRaw, board, version, 0)); internalField.Append(new UnsignedField<14>(expo.scale, "Scale")); internalField.Append(new UnsignedField<8>(expo.chn, "Channel")); @@ -1595,7 +1636,7 @@ class AndSwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val); addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val++); } - for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { + for (int i=1; i<=MAX_LOGICAL_SWITCHES(board, version); i++) { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, -i), -val); addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } @@ -1606,7 +1647,7 @@ class AndSwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val); addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val++); } - for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { + for (int i=1; i<=MAX_LOGICAL_SWITCHES(board, version); i++) { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, -i), -val); addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } @@ -1671,7 +1712,16 @@ class LogicalSwitchField: public TransformedField { v2(0), v3(0) { - if (IS_ARM(board) && version >= 217) { + if (IS_ARM(board) && version >= 218) { + internalField.Append(new ConversionField< UnsignedField<8> >(csw.func, &functionsConversionTable, "Function")); + internalField.Append(new SignedField<10>(v1)); + internalField.Append(new SignedField<10>(v3)); + internalField.Append(new ConversionField< SignedField<9> >((int &)csw.andsw, andswitchesConversionTable, "AND switch")); + internalField.Append(new SpareBitsField<1>()); // TODO extra switch mode + internalField.Append(new SpareBitsField<2>()); + internalField.Append(new SignedField<16>(v2)); + } + else if (IS_ARM(board) && version >= 217) { internalField.Append(new ConversionField< UnsignedField<6> >(csw.func, &functionsConversionTable, "Function")); internalField.Append(new SignedField<10>(v1)); internalField.Append(new SignedField<16>(v2)); @@ -1706,7 +1756,7 @@ class LogicalSwitchField: public TransformedField { int scale = (version >= 216 ? 0 : 5); internalField.Append(new ConversionField< UnsignedField<8> >(csw.delay, 0, scale)); internalField.Append(new ConversionField< UnsignedField<8> >(csw.duration, 0, scale)); - if (version >= 214) { + if (version >= 214 && version <= 217) { internalField.Append(new ConversionField< SignedField<8> >((int &)csw.andsw, andswitchesConversionTable, "AND switch")); } } @@ -2029,8 +2079,14 @@ class ArmCustomFunctionField: public TransformedField { { memset(_param, 0, sizeof(_param)); - internalField.Append(new SwitchField<8>(fn.swtch, board, version)); - internalField.Append(new ConversionField< UnsignedField<8> >(_func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + if (version >= 218) { + internalField.Append(new SwitchField<9>(fn.swtch, board, version)); + internalField.Append(new ConversionField< UnsignedField<7> >(_func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + } + else { + internalField.Append(new SwitchField<8>(fn.swtch, board, version)); + internalField.Append(new ConversionField< UnsignedField<8> >(_func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + } if (IS_TARANIS(board) && version >= 216) internalField.Append(new CharField<8>(_param, false)); @@ -2905,8 +2961,21 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne } for (int i=0; i(modelData.timers[i].mode, board, version, true)); - if (IS_ARM(board) && version >= 217) { + if (IS_ARM(board) && version >= 218) { + internalField.Append(new SwitchField<9>(modelData.timers[i].mode, board, version, true)); + internalField.Append(new UnsignedField<23>(modelData.timers[i].val)); + internalField.Append(new SignedField<24>(modelData.timers[i].pvalue)); + internalField.Append(new UnsignedField<2>(modelData.timers[i].countdownBeep)); + internalField.Append(new BoolField<1>(modelData.timers[i].minuteBeep)); + internalField.Append(new UnsignedField<2>(modelData.timers[i].persistent)); + internalField.Append(new SpareBitsField<3>()); + if (IS_TARANIS(board)) + internalField.Append(new ZCharField<8>(modelData.timers[i].name)); + else + internalField.Append(new ZCharField<3>(modelData.timers[i].name)); + } + else if (IS_ARM(board) && version >= 217) { + internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, true)); internalField.Append(new UnsignedField<24>(modelData.timers[i].val)); internalField.Append(new SignedField<24>(modelData.timers[i].pvalue)); internalField.Append(new UnsignedField<2>(modelData.timers[i].countdownBeep)); @@ -2919,6 +2988,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne internalField.Append(new ZCharField<3>(modelData.timers[i].name)); } else if ((IS_ARM(board) || IS_2560(board)) && version >= 216) { + internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, true)); internalField.Append(new UnsignedField<16>(modelData.timers[i].val)); internalField.Append(new UnsignedField<2>(modelData.timers[i].countdownBeep)); internalField.Append(new BoolField<1>(modelData.timers[i].minuteBeep)); @@ -2927,6 +2997,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne internalField.Append(new SignedField<16>(modelData.timers[i].pvalue)); } else if (afterrelease21March2013) { + internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, true)); internalField.Append(new UnsignedField<12>(modelData.timers[i].val)); internalField.Append(new BoolField<1>((bool &)modelData.timers[i].countdownBeep)); internalField.Append(new BoolField<1>(modelData.timers[i].minuteBeep)); @@ -2940,6 +3011,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne } } else { + internalField.Append(new SwitchField<8>(modelData.timers[i].mode, board, version, true)); internalField.Append(new UnsignedField<16>(modelData.timers[i].val)); if (HAS_PERSISTENT_TIMERS(board)) { internalField.Append(new UnsignedField<1>(modelData.timers[i].persistent)); @@ -2999,7 +3071,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne for (int i=0; i(modelData.moduleData[0].ppmFrameLength)); diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index e74feb378..16b5d6f78 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -403,7 +403,7 @@ int OpenTxEepromInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t case BOARD_SKY9X: case BOARD_AR9X: case BOARD_9XRPRO: - version = 217; + version = 218; break; case BOARD_GRUVIN9X: case BOARD_MEGA2560: @@ -638,7 +638,7 @@ int OpenTxFirmware::getCapability(const Capability capability) return id.contains("nooverridech") ? 0 : 1; case LogicalSwitches: if (IS_ARM(board)) - return 32; + return 64; else return 12; case CustomAndSwitches: @@ -954,10 +954,10 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) // M128 revert because too much RAM used! case 216: // A lot of things (first github release) - return OLD_VERSION; - break; case 217: // 3 logical switches removed on M128 / gruvin9x boards + return OLD_VERSION; + case 218: break; default: return NOT_OPENTX; diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp index 19ccfb0c9..5d7fafbc6 100644 --- a/radio/src/eeprom_conversions.cpp +++ b/radio/src/eeprom_conversions.cpp @@ -109,7 +109,7 @@ enum Mix216Sources { MIXSRC216_SWA, MIXSRC216_SWB, MIXSRC216_SWC, - MIXSRC216_LAST_LOGICAL_SWITCH = MIXSRC216_FIRST_LOGICAL_SWITCH+NUM_LOGICAL_SWITCH-1, + MIXSRC216_LAST_LOGICAL_SWITCH = MIXSRC216_FIRST_LOGICAL_SWITCH+32-1, MIXSRC216_FIRST_TRAINER, MIXSRC216_LAST_TRAINER = MIXSRC216_FIRST_TRAINER+NUM_TRAINER-1, @@ -236,6 +236,19 @@ PACK(typedef struct { CurveRef curve; uint8_t spare; }) ExpoData_v216; +PACK(typedef struct { + uint32_t srcRaw:10; + uint32_t scale:14; + uint32_t chn:8; + int8_t swtch; + uint16_t flightModes; + int8_t weight; + int8_t carryTrim:6; + uint8_t mode:2; + char name[LEN_EXPOMIX_NAME]; + int8_t offset; + CurveRef curve; +}) ExpoData_v217; #else PACK(typedef struct { uint8_t mode; // 0=end, 1=pos, 2=neg, 3=both @@ -257,6 +270,7 @@ PACK(typedef struct { char name[LEN_EXPOMIX_NAME]; int8_t curveParam; }) ExpoData_v216; +typedef ExpoData_v216 ExpoData_v217; #endif #if defined(PCBTARANIS) @@ -333,6 +347,23 @@ PACK(typedef struct { char name[LEN_EXPOMIX_NAME]; uint8_t spare3; }) MixData_v216; +PACK(typedef struct { + uint8_t destCh; + uint16_t flightModes:9; + uint16_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := + uint16_t carryTrim:1; + uint16_t mixWarn:4; // mixer warning + int16_t weight; + uint32_t srcRaw:10; + int32_t offset:14; + int32_t swtch:8; + CurveRef curve; + uint8_t delayUp; + uint8_t delayDown; + uint8_t speedUp; + uint8_t speedDown; + char name[LEN_EXPOMIX_NAME]; +}) MixData_v217; #else PACK(typedef struct { uint8_t destCh; @@ -375,6 +406,7 @@ PACK(typedef struct { int16_t offset; char name[LEN_EXPOMIX_NAME]; }) MixData_v216; +typedef MixData MixData_v217; #endif PACK(typedef struct { @@ -397,14 +429,25 @@ PACK(typedef struct { uint16_t value; }) TimerData_v216; +PACK(typedef struct { + int32_t mode:8; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw + uint32_t start:24; + int32_t value:24; + uint32_t countdownBeep:2; + uint32_t minuteBeep:1; + uint32_t persistent:2; + uint32_t spare:3; + char name[LEN_TIMER_NAME]; +}) TimerData_v217; + PACK(typedef struct { int16_t trim[4]; int8_t swtch; // swtch of phase[0] is not used char name[LEN_FLIGHT_MODE_NAME]; uint8_t fadeIn; uint8_t fadeOut; - ROTARY_ENCODER_ARRAY; - gvar_t gvars[5]; + int16_t rotaryEncoders[1]; + gvar_t gvars[9]; }) FlightModeData_v215; PACK(typedef struct { @@ -426,6 +469,16 @@ PACK(typedef struct { // Logical Switches data int8_t andsw; }) LogicalSwitchData_v216; +PACK(typedef struct { // Logical Switches data + uint16_t func:6; + int16_t v1:10; + int16_t v2; + int16_t v3; + uint8_t delay; + uint8_t duration; + int8_t andsw; +}) LogicalSwitchData_v217; + #if defined(PCBTARANIS) PACK(typedef struct { int8_t swtch; @@ -441,6 +494,28 @@ PACK(typedef struct { uint8_t mode:2; uint8_t active:6; }) CustomFunctionData_v215; +PACK(typedef struct { + int8_t swtch; + uint8_t func; + PACK(union { + PACK(struct { + char name[8]; + }) play; + + PACK(struct { + int16_t val; + uint8_t mode; + uint8_t param; + int32_t spare2; + }) all; + + PACK(struct { + int32_t val1; + int32_t val2; + }) clear; + }); + uint8_t active; +}) CustomFunctionData_v216; #else PACK(typedef struct { int8_t swtch; @@ -456,6 +531,28 @@ PACK(typedef struct { uint8_t mode:2; uint8_t active:6; }) CustomFunctionData_v215; +PACK(typedef struct { + int8_t swtch; + uint8_t func; + PACK(union { + PACK(struct { + char name[6]; + }) play; + + PACK(struct { + int16_t val; + uint8_t mode; + uint8_t param; + int16_t spare2; + }) all; + + PACK(struct { + int32_t val1; + int16_t val2; + }) clear; + }); + uint8_t active; +}) CustomFunctionData_v216; #endif PACK(typedef struct { @@ -592,10 +689,10 @@ PACK(typedef struct { CURVDATA curves[MAX_CURVES]; int8_t points[NUM_POINTS]; - LogicalSwitchData_v216 logicalSw[NUM_LOGICAL_SWITCH]; - CustomFunctionData customFn[NUM_CFN]; + LogicalSwitchData_v216 logicalSw[32]; + CustomFunctionData_v216 customFn[NUM_CFN]; SwashRingData_v215 swashR; - FlightModeData flightModeData[MAX_FLIGHT_MODES]; + FlightModeData_v215 flightModeData[MAX_FLIGHT_MODES]; uint8_t thrTraceSrc; @@ -610,6 +707,49 @@ PACK(typedef struct { }) ModelData_v216; +PACK(typedef struct { + ModelHeader header; + TimerData_v217 timers[MAX_TIMERS]; + ARM_FIELD(uint8_t telemetryProtocol:3) + uint8_t thrTrim:1; // Enable Throttle Trim + ARM_FIELD(uint8_t noGlobalFunctions:1) + ARM_FIELD(uint8_t displayTrims:2) + ARM_FIELD(uint8_t ignoreSensorIds:1) + int8_t trimInc:3; // Trim Increments + uint8_t disableThrottleWarning:1; + ARM_FIELD(uint8_t displayChecklist:1) + uint8_t extendedLimits:1; + uint8_t extendedTrims:1; + uint8_t throttleReversed:1; + BeepANACenter beepANACenter; + MixData_v217 mixData[MAX_MIXERS]; + LimitData limitData[NUM_CHNOUT]; + ExpoData_v217 expoData[MAX_EXPOS]; + + CURVDATA curves[MAX_CURVES]; + int8_t points[NUM_POINTS]; + + LogicalSwitchData_v217 logicalSw[32]; + CustomFunctionData_v216 customFn[NUM_CFN]; + SwashRingData swashR; + FlightModeData_v215 flightModeData[MAX_FLIGHT_MODES]; + + uint8_t thrTraceSrc; + + swarnstate_t switchWarningState; + swarnenable_t switchWarningEnable; + + MODEL_GVARS_DATA + + TELEMETRY_DATA + + MODELDATA_EXTRA + + TelemetrySensor telemetrySensors[MAX_SENSORS]; + + TARANIS_REV9E_FIELD(uint8_t topLcdTimer) +}) ModelData_v217; + #if defined(PCBTARANIS) #define NUM_POTS_215 4 #else @@ -700,7 +840,7 @@ void ConvertGeneralSettings_215_to_216(EEGeneral &settings) settings.hapticStrength = 0; // Haptic strength reset } -void ConvertGeneralSettings_216_to_217(EEGeneral &settings) +void ConvertGeneralSettings_216_to_217(EEGeneral & settings) { settings.version = 217; #if defined(PCBTARANIS) @@ -709,6 +849,11 @@ void ConvertGeneralSettings_216_to_217(EEGeneral &settings) #endif } +void ConvertGeneralSettings_217_to_218(EEGeneral & settings) +{ + settings.version = 218; +} + int ConvertTelemetrySource_215_to_216(int source) { // TELEM_TX_TIME and 5 spare added @@ -845,6 +990,19 @@ int ConvertSwitch_216_to_217(int swtch) } #endif +int ConvertSwitch_217_to_218(int swtch) +{ + // 32 additional logical switches + + if (swtch < 0) + return -ConvertSwitch_217_to_218(-swtch); + + if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH+32) + return swtch+32; + + return swtch; +} + int ConvertSource_216_to_217(int source) { #if defined(PCBTARANIS) && defined(REV9E) @@ -890,8 +1048,8 @@ void ConvertModel_216_to_217(ModelData &model) ModelData_v216 oldModel; memcpy(&oldModel, &model, sizeof(oldModel)); - ModelData &newModel = model; - memset(&newModel, 0, sizeof(ModelData)); + ModelData_v217 & newModel = (ModelData_v217 &)model; + memset(&newModel, 0, sizeof(ModelData_v217)); char name[LEN_MODEL_NAME+1]; zchar2str(name, oldModel.header.name, LEN_MODEL_NAME); @@ -904,7 +1062,7 @@ void ConvertModel_216_to_217(ModelData &model) #endif for (uint8_t i=0; i<2; i++) { - TimerData & timer = newModel.timers[i]; + TimerData_v217 & timer = newModel.timers[i]; if (oldModel.timers[i].mode >= TMRMODE_COUNT) timer.mode = TMRMODE_COUNT + ConvertSwitch_216_to_217(oldModel.timers[i].mode - TMRMODE_COUNT + 1) - 1; else @@ -981,8 +1139,8 @@ void ConvertModel_216_to_217(ModelData &model) } memcpy(newModel.curves, oldModel.curves, sizeof(newModel.curves)); memcpy(newModel.points, oldModel.points, sizeof(newModel.points)); - for (int i=0; i= TMRMODE_COUNT) + newModel.timers[i].mode = TMRMODE_COUNT + ConvertSwitch_217_to_218(oldModel.timers[i].mode - TMRMODE_COUNT + 1) - 1; + else + newModel.timers[i].mode = ConvertSwitch_217_to_218(oldModel.timers[i].mode); + if (oldModel.timers[i].mode) + TRACE("timer mode %d => %d", oldModel.timers[i].mode, newModel.timers[i].mode); + newModel.timers[i].start = oldModel.timers[i].start; + newModel.timers[i].value = oldModel.timers[i].value; + newModel.timers[i].countdownBeep = oldModel.timers[i].countdownBeep; + newModel.timers[i].minuteBeep = oldModel.timers[i].minuteBeep; + newModel.timers[i].persistent = oldModel.timers[i].persistent; + memcpy(newModel.timers[i].name, oldModel.timers[i].name, sizeof(newModel.timers[i].name)); + } + newModel.telemetryProtocol = oldModel.telemetryProtocol; + newModel.thrTrim = oldModel.thrTrim; + newModel.noGlobalFunctions = oldModel.noGlobalFunctions; + newModel.displayTrims = oldModel.displayTrims; + newModel.ignoreSensorIds = oldModel.ignoreSensorIds; + newModel.trimInc = oldModel.trimInc; + newModel.disableThrottleWarning = oldModel.disableThrottleWarning; + newModel.displayChecklist = oldModel.displayChecklist; + newModel.extendedLimits = oldModel.extendedLimits; + newModel.extendedTrims = oldModel.extendedTrims; + newModel.throttleReversed = oldModel.throttleReversed; + newModel.beepANACenter = oldModel.beepANACenter; + for (int i=0; i