/* * Copyright (C) OpenTX * * Based on code named * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include "opentx.h" enum Mix216Sources { MIXSRC216_NONE, #if defined(PCBTARANIS) MIXSRC216_FIRST_INPUT, MIXSRC216_LAST_INPUT = MIXSRC216_FIRST_INPUT+MAX_INPUTS-1, MIXSRC216_FIRST_LUA, MIXSRC216_LAST_LUA = MIXSRC216_FIRST_LUA+(MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS)-1, #endif MIXSRC216_Rud, MIXSRC216_Ele, MIXSRC216_Thr, MIXSRC216_Ail, MIXSRC216_FIRST_POT, #if defined(PCBTARANIS) MIXSRC216_POT1 = MIXSRC216_FIRST_POT, MIXSRC216_POT2, MIXSRC216_POT3, MIXSRC216_SLIDER1, MIXSRC216_SLIDER2, MIXSRC216_LAST_POT = MIXSRC216_SLIDER2, #else MIXSRC216_P1 = MIXSRC216_FIRST_POT, MIXSRC216_P2, MIXSRC216_P3, MIXSRC216_LAST_POT = MIXSRC216_P3, #endif #if defined(PCBSKY9X) MIXSRC216_REa, MIXSRC216_LAST_ROTARY_ENCODER = MIXSRC216_REa, #endif MIXSRC216_MAX, MIXSRC216_CYC1, MIXSRC216_CYC2, MIXSRC216_CYC3, MIXSRC216_TrimRud, MIXSRC216_TrimEle, MIXSRC216_TrimThr, MIXSRC216_TrimAil, MIXSRC216_FIRST_SWITCH, #if defined(PCBTARANIS) MIXSRC216_SA = MIXSRC216_FIRST_SWITCH, MIXSRC216_SB, MIXSRC216_SC, MIXSRC216_SD, MIXSRC216_SE, MIXSRC216_SF, MIXSRC216_SG, MIXSRC216_SH, #else MIXSRC216_3POS = MIXSRC216_FIRST_SWITCH, MIXSRC216_THR, MIXSRC216_RUD, MIXSRC216_ELE, MIXSRC216_AIL, MIXSRC216_GEA, MIXSRC216_TRN, #endif MIXSRC216_FIRST_LOGICAL_SWITCH, MIXSRC216_SW1 = MIXSRC216_FIRST_LOGICAL_SWITCH, MIXSRC216_SW9 = MIXSRC216_SW1 + 8, MIXSRC216_SWA, MIXSRC216_SWB, MIXSRC216_SWC, MIXSRC216_LAST_LOGICAL_SWITCH = MIXSRC216_FIRST_LOGICAL_SWITCH+32-1, MIXSRC216_FIRST_TRAINER, MIXSRC216_LAST_TRAINER = MIXSRC216_FIRST_TRAINER+NUM_TRAINER-1, MIXSRC216_FIRST_CH, MIXSRC216_CH1 = MIXSRC216_FIRST_CH, MIXSRC216_CH2, MIXSRC216_CH3, MIXSRC216_CH4, MIXSRC216_CH5, MIXSRC216_CH6, MIXSRC216_CH7, MIXSRC216_CH8, MIXSRC216_CH9, MIXSRC216_CH10, MIXSRC216_CH11, MIXSRC216_CH12, MIXSRC216_CH13, MIXSRC216_CH14, MIXSRC216_CH15, MIXSRC216_CH16, MIXSRC216_LAST_CH = MIXSRC216_CH1+NUM_CHNOUT-1, MIXSRC216_GVAR1, MIXSRC216_LAST_GVAR = MIXSRC216_GVAR1+MAX_GVARS-1, MIXSRC216_FIRST_TELEM, }; enum Telemetry216Source { TELEM216_NONE, TELEM216_TX_VOLTAGE, TELEM216_TX_TIME, TELEM216_RESERVE1, TELEM216_RESERVE2, TELEM216_RESERVE3, TELEM216_RESERVE4, TELEM216_RESERVE5, TELEM216_TIMER1, TELEM216_TIMER2, TELEM216_SWR, TELEM216_RSSI_TX, TELEM216_RSSI_RX, TELEM216_RESERVE0, TELEM216_A1, TELEM216_A2, TELEM216_A3, TELEM216_A4, TELEM216_ALT, TELEM216_RPM, TELEM216_FUEL, TELEM216_T1, TELEM216_T2, TELEM216_SPEED, TELEM216_DIST, TELEM216_GPSALT, TELEM216_CELL, TELEM216_CELLS_SUM, TELEM216_VFAS, TELEM216_CURRENT, TELEM216_CONSUMPTION, TELEM216_POWER, TELEM216_ACCx, TELEM216_ACCy, TELEM216_ACCz, TELEM216_HDG, TELEM216_VSPEED, TELEM216_ASPEED, TELEM216_DTE, TELEM216_RESERVE6, TELEM216_RESERVE7, TELEM216_RESERVE8, TELEM216_RESERVE9, TELEM216_RESERVE10, TELEM216_MIN_A1, TELEM216_MIN_A2, TELEM216_MIN_A3, TELEM216_MIN_A4, TELEM216_MIN_ALT, TELEM216_MAX_ALT, TELEM216_MAX_RPM, TELEM216_MAX_T1, TELEM216_MAX_T2, TELEM216_MAX_SPEED, TELEM216_MAX_DIST, TELEM216_MAX_ASPEED, TELEM216_MIN_CELL, TELEM216_MIN_CELLS_SUM, TELEM216_MIN_VFAS, TELEM216_MAX_CURRENT, TELEM216_MAX_POWER, TELEM216_RESERVE11, TELEM216_RESERVE12, TELEM216_RESERVE13, TELEM216_RESERVE14, TELEM216_RESERVE15, TELEM216_ACC, TELEM216_GPS_TIME, }; #if defined(XCURVES) PACK(typedef struct { uint8_t type:3; uint8_t smooth:1; uint8_t spare:4; int8_t points; }) CurveData_v216; #else typedef int16_t CurveData_v216; #endif #if defined(PCBTARANIS) PACK(typedef struct { uint8_t srcRaw; uint16_t scale; uint8_t chn; 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; 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:2; // 0=end, 1=pos, 2=neg, 3=both uint8_t chn:4; uint8_t curveMode:2; int8_t swtch; uint16_t flightModes; int8_t weight; char name[LEN_EXPOMIX_NAME]; int8_t curveParam; }) ExpoData_v216; typedef ExpoData_v216 ExpoData_v217; #endif #if defined(PCBTARANIS) PACK(typedef struct { int16_t min; int16_t max; int8_t ppmCenter; int16_t offset:14; uint16_t symetrical:1; uint16_t revert:1; char name[LEN_CHANNEL_NAME]; int8_t curve; }) LimitData_v216; #else #define LimitData_v216 LimitData #endif #if defined(PCBTARANIS) PACK(typedef struct { uint8_t destCh; uint16_t flightModes; uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := uint8_t carryTrim:1; uint8_t spare1:5; int16_t weight; int8_t swtch; CurveRef curve; uint8_t mixWarn:4; // mixer warning uint8_t spare2:4; uint8_t delayUp; uint8_t delayDown; uint8_t speedUp; uint8_t speedDown; uint8_t srcRaw; int16_t offset; 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:5; uint8_t mixWarn:3; // mixer warning uint16_t flightModes; uint8_t curveMode:1; uint8_t noExpo:1; int8_t carryTrim:3; uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means := uint8_t spare:1; int16_t weight; int8_t swtch; int8_t curveParam; uint8_t delayUp; uint8_t delayDown; uint8_t speedUp; uint8_t speedDown; uint8_t srcRaw; int16_t offset; char name[LEN_EXPOMIX_NAME]; }) MixData_v216; typedef MixData MixData_v217; #endif PACK(typedef struct { int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw uint16_t start; uint8_t countdownBeep:2; uint8_t minuteBeep:1; uint8_t persistent:2; uint8_t spare:3; 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[NUM_STICKS]; int8_t swtch; // swtch of phase[0] is not used char name[LEN_FLIGHT_MODE_NAME]; uint8_t fadeIn; uint8_t fadeOut; int16_t rotaryEncoders[1]; gvar_t gvars[9]; }) FlightModeData_v216; PACK(typedef struct { // Logical Switches data int8_t v1; int16_t v2; int16_t v3; uint8_t func; uint8_t delay; uint8_t duration; 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; 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; 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 { uint8_t source; uint8_t barMin; // minimum for bar display uint8_t barMax; // ditto for max display (would usually = ratio) }) FrSkyBarData_v216; PACK(typedef struct { uint8_t sources[NUM_LINE_ITEMS]; }) FrSkyLineData_v216; typedef union { FrSkyBarData_v216 bars[4]; FrSkyLineData_v216 lines[4]; } FrSkyScreenData_v216; PACK(typedef struct { FrSkyChannelData channels[4]; uint8_t usrProto; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh, 3=Halcyon uint8_t voltsSource:7; uint8_t altitudeDisplayed:1; int8_t blades; // How many blades for RPMs, 0=2 blades uint8_t currentSource; uint8_t screensType; // 2bits per screen (None/Gauges/Numbers/Script) FrSkyScreenData_v216 screens[3]; uint8_t varioSource; int8_t varioCenterMax; int8_t varioCenterMin; int8_t varioMin; int8_t varioMax; FrSkyRSSIAlarm rssiAlarms[2]; uint16_t mAhPersistent:1; uint16_t storedMah:15; int8_t fasOffset; }) FrSkyData_v216; PACK(typedef struct { char file[10]; char name[10]; int8_t inputs[10]; }) ScriptData_v216; PACK(typedef struct { // Swash Ring data uint8_t invertELE:1; uint8_t invertAIL:1; uint8_t invertCOL:1; uint8_t type:5; uint8_t collectiveSource; uint8_t value; }) SwashRingData_v216; PACK(typedef struct { int8_t rfProtocol; uint8_t channelsStart; int8_t channelsCount; // 0=8 channels uint8_t failsafeMode; int16_t failsafeChannels[NUM_CHNOUT]; int8_t ppmDelay; int8_t ppmFrameLength; uint8_t ppmPulsePol; }) ModuleData_v216; #if defined(PCBTARANIS) #define MODELDATA_EXTRA_216 \ uint8_t externalModule; \ uint8_t trainerMode; \ ModuleData_v216 moduleData[NUM_MODULES+1]; \ char curveNames[MAX_CURVES][6]; \ ScriptData_v216 scriptsData[MAX_SCRIPTS]; \ char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; \ uint8_t nPotsToWarn; \ int8_t potPosition[NUM_POTS]; \ uint8_t spare[2]; #elif defined(PCBSKY9X) #define MODELDATA_EXTRA_216 \ uint8_t externalModule; \ ModuleData_v216 moduleData[NUM_MODULES+1]; \ uint8_t nPotsToWarn; \ int8_t potPosition[NUM_POTS]; \ uint8_t rxBattAlarms[2]; #endif #if defined(PCBTARANIS) #define MODELDATA_EXTRA_217 \ uint8_t spare:3; \ uint8_t trainerMode:3; \ uint8_t potsWarnMode:2; \ ModuleData moduleData[NUM_MODULES+1]; \ char curveNames[MAX_CURVES][6]; \ ScriptData scriptsData[MAX_SCRIPTS]; \ char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; \ uint8_t potsWarnEnabled; \ int8_t potsWarnPosition[NUM_POTS]; #else #define MODELDATA_EXTRA_217 \ uint8_t spare:6; \ uint8_t potsWarnMode:2; \ ModuleData moduleData[NUM_MODULES+1]; \ uint8_t potsWarnEnabled; \ int8_t potsWarnPosition[NUM_POTS]; \ uint8_t rxBattAlarms[2]; #endif #if defined(PCBTARANIS) PACK(typedef struct { char name[LEN_MODEL_NAME]; uint8_t modelId; char bitmap[LEN_BITMAP_NAME]; }) ModelHeader_v216; #else PACK(typedef struct { char name[LEN_MODEL_NAME]; uint8_t modelId; }) ModelHeader_v216; #endif PACK(typedef struct { ModelHeader_v216 header; TimerData_v216 timers[2]; AVR_FIELD(uint8_t protocol:3) ARM_FIELD(uint8_t telemetryProtocol:3) uint8_t thrTrim:1; // Enable Throttle Trim AVR_FIELD(int8_t ppmNCH:4) ARM_FIELD(int8_t spare2:4) int8_t trimInc:3; // Trim Increments uint8_t disableThrottleWarning:1; ARM_FIELD(uint8_t displayChecklist:1) AVR_FIELD(uint8_t pulsePol:1) uint8_t extendedLimits:1; uint8_t extendedTrims:1; uint8_t throttleReversed:1; AVR_FIELD(int8_t ppmDelay) BeepANACenter beepANACenter; // 1<<0->A1.. 1<<6->A7 MixData_v216 mixData[MAX_MIXERS]; LimitData_v216 limitData[NUM_CHNOUT]; ExpoData_v216 expoData[MAX_EXPOS]; CurveData_v216 curves[MAX_CURVES]; int8_t points[NUM_POINTS]; LogicalSwitchData_v216 logicalSw[32]; CustomFunctionData_v216 customFn[NUM_CFN]; SwashRingData_v216 swashR; FlightModeData_v216 flightModeData[MAX_FLIGHT_MODES]; uint8_t thrTraceSrc; uint16_t switchWarningState; uint8_t switchWarningEnable; GVarData gvars[MAX_GVARS]; FrSkyData_v216 frsky; MODELDATA_EXTRA_216 }) 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]; CurveData_v216 curves[MAX_CURVES]; int8_t points[NUM_POINTS]; LogicalSwitchData_v217 logicalSw[32]; CustomFunctionData_v216 customFn[NUM_CFN]; SwashRingData swashR; FlightModeData_v216 flightModeData[MAX_FLIGHT_MODES]; uint8_t thrTraceSrc; swarnstate_t switchWarningState; swarnenable_t switchWarningEnable; GVarData gvars[MAX_GVARS]; FrSkyTelemetryData frsky; MODELDATA_EXTRA_217 TelemetrySensor telemetrySensors[MAX_SENSORS]; TARANIS_REV9E_FIELD(uint8_t toplcdTimer) }) ModelData_v217; int ConvertTelemetrySource_216_to_217(int source) { // TELEM_TIMER3 added // if (source >= TELEM_TIMER3) // source += 1; return source; } #if defined(PCBTARANIS) int ConvertSwitch_216_to_217(int swtch) { if (swtch < 0) return -ConvertSwitch_216_to_217(-swtch); if (swtch > SWSRC_SF0) swtch += 1; if (swtch > SWSRC_SH0) swtch += 1; return swtch; } #else int ConvertSwitch_216_to_217(int swtch) { return 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) // SI to SR switches added if (source >= MIXSRC_SI) source += 10; #endif // Telemetry conversions if (source >= MIXSRC_FIRST_TELEM) source = 0; return source; } int ConvertSource_217_to_218(int source) { #if defined(PCBTARANIS) if (source >= MIXSRC_FIRST_LOGICAL_SWITCH + 32) source += 32; #endif return source; } int ConvertGVar_216_to_217(int value) { if (value < -4096 + 9) value += 4096 - 1024; else if (value > 4095 - 9) value -= 4095 - 1023; return value; } PACK(typedef struct { uint8_t version; uint16_t variant; CalibData calib[NUM_STICKS+NUM_POTS]; uint16_t chkSum; int8_t currModel; uint8_t contrast; uint8_t vBatWarn; int8_t txVoltageCalibration; int8_t backlightMode; TrainerData trainer; uint8_t view; // index of view in main screen int8_t buzzerMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all uint8_t fai:1; int8_t beepMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all uint8_t alarmsFlash:1; uint8_t disableMemoryWarning:1; uint8_t disableAlarmWarning:1; uint8_t stickMode:2; int8_t timezone:5; uint8_t adjustRTC:1; uint8_t inactivityTimer; uint8_t mavbaud:3; int8_t splashMode:3; int8_t hapticMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all int8_t switchesDelay; uint8_t lightAutoOff; uint8_t templateSetup; // RETA order for receiver channels int8_t PPM_Multiplier; int8_t hapticLength; uint8_t reNavigation; N_TARANIS_FIELD(uint8_t stickReverse) int8_t beepLength:3; int8_t hapticStrength:3; uint8_t gpsFormat:1; uint8_t unexpectedShutdown:1; uint8_t speakerPitch; int8_t speakerVolume; int8_t vBatMin; int8_t vBatMax; uint8_t backlightBright; int8_t txCurrentCalibration; int8_t temperatureWarn; uint8_t mAhWarn; uint16_t mAhUsed; uint32_t globalTimer; int8_t temperatureCalib; uint8_t btBaudrate; uint8_t optrexDisplay; uint8_t sticksGain; uint8_t rotarySteps; uint8_t countryCode; uint8_t imperial; char ttsLanguage[2]; int8_t beepVolume; int8_t wavVolume; int8_t varioVolume; int8_t varioPitch; int8_t varioRange; int8_t varioRepeat; int8_t backgroundVolume; #if defined(PCBTARANIS) uint8_t serial2Mode:6; uint8_t slidersConfig:2; uint8_t potsConfig; uint8_t backlightColor; swarnstate_t switchUnlockStates; CustomFunctionData_v216 customFn[NUM_CFN]; swconfig_t switchConfig; char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; char anaNames[NUM_STICKS+NUM_POTS][LEN_ANA_NAME]; #else CustomFunctionData_v216 customFn[NUM_CFN]; #endif #if defined(PCBTARANIS) && defined(REV9E) uint8_t bluetoothEnable; char bluetoothName[LEN_BLUETOOTH_NAME]; #endif }) RadioData_v216; void ConvertRadioData_216_to_217(RadioData & settings) { RadioData_v216 * settings_v216 = (RadioData_v216 *)&settings; settings_v216->version = 217; #if defined(PCBTARANIS) settings_v216->potsConfig = 0x05; // S1 and S2 = pots with detent settings_v216->switchConfig = 0x00007bff; // 6x3POS, 1x2POS, 1xTOGGLE #endif } void ConvertSpecialFunctions_217_to_218(CustomFunctionData * cf218, CustomFunctionData_v216 * cf216) { for (int i=0; istickReverse; #endif settings.beepLength = settings_v217->beepLength; settings.hapticStrength = settings_v217->hapticStrength; settings.gpsFormat = settings_v217->gpsFormat; settings.unexpectedShutdown = settings_v217->unexpectedShutdown; settings.speakerPitch = settings_v217->speakerPitch; settings.speakerVolume = settings_v217->speakerVolume; settings.vBatMin = settings_v217->vBatMin; settings.vBatMax = settings_v217->vBatMax; settings.backlightBright = settings_v217->backlightBright; settings.globalTimer = settings_v217->globalTimer; settings.btBaudrate = settings_v217->btBaudrate; settings.countryCode = settings_v217->countryCode; settings.imperial = settings_v217->imperial; settings.ttsLanguage[0] = settings_v217->ttsLanguage[0]; settings.ttsLanguage[1] = settings_v217->ttsLanguage[1]; settings.beepVolume = settings_v217->beepVolume; settings.wavVolume = settings_v217->wavVolume; settings.varioVolume = settings_v217->varioVolume; settings.backgroundVolume = settings_v217->backgroundVolume; settings.varioPitch = settings_v217->varioPitch; settings.varioRange = settings_v217->varioRange; settings.varioRepeat = settings_v217->varioRepeat; ConvertSpecialFunctions_217_to_218(settings.customFn, settings_v217->customFn); #if defined(PCBTARANIS) settings.serial2Mode = settings_v217->serial2Mode; settings.slidersConfig = settings_v217->slidersConfig; settings.potsConfig = settings_v217->potsConfig; settings.backlightColor = settings_v217->backlightColor; settings.switchUnlockStates = settings_v217->switchUnlockStates; settings.switchConfig = settings_v217->switchConfig; memcpy(settings.switchNames, settings_v217->switchNames, sizeof(settings.switchNames)); memcpy(settings.anaNames, settings_v217->anaNames, sizeof(settings.anaNames)); #endif #if defined(PCBTARANIS) && defined(REV9E) settings.bluetoothEnable = settings_v217->bluetoothEnable; memcpy(settings.bluetoothName, settings_v217->bluetoothName, sizeof(settings.bluetoothName)); #endif #if defined(PCBSKY9X) settings.txCurrentCalibration = settings_v217->txCurrentCalibration; settings.temperatureWarn = settings_v217->temperatureWarn; settings.mAhWarn = settings_v217->mAhWarn; settings.mAhUsed = settings_v217->mAhUsed; settings.temperatureCalib = settings_v217->temperatureCalib; settings.optrexDisplay = settings_v217->optrexDisplay; settings.sticksGain = settings_v217->sticksGain; settings.rotarySteps = settings_v217->rotarySteps; #endif } void ConvertModel_216_to_217(ModelData & model) { // Timer3 added // 32bits Timers // MixData reduction // PPM center range // Telemetry custom screens assert(sizeof(ModelData_v216) <= sizeof(ModelData)); ModelData_v216 oldModel; memcpy(&oldModel, &model, sizeof(oldModel)); 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); TRACE("Model %s conversion from v216 to v217", name); newModel.header.modelId[0] = oldModel.header.modelId; memcpy(newModel.header.name, oldModel.header.name, LEN_MODEL_NAME); #if defined(PCBTARANIS) memcpy(newModel.header.bitmap, oldModel.header.bitmap, LEN_BITMAP_NAME); #endif for (uint8_t i=0; i<2; 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 timer.mode = ConvertSwitch_216_to_217(oldModel.timers[i].mode); timer.start = oldModel.timers[i].start; timer.countdownBeep = oldModel.timers[i].countdownBeep; timer.minuteBeep = oldModel.timers[i].minuteBeep; timer.persistent = oldModel.timers[i].persistent; timer.value = oldModel.timers[i].value; } newModel.telemetryProtocol = oldModel.telemetryProtocol; newModel.thrTrim = oldModel.thrTrim; 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> 6; newModel.potsWarnEnabled = oldModel.nPotsToWarn & 0x1f; memcpy(newModel.potsWarnPosition, oldModel.potPosition, sizeof(newModel.potsWarnPosition)); } void ConvertModel_217_to_218(ModelData & model) { assert(sizeof(ModelData_v217) <= sizeof(ModelData)); ModelData_v217 oldModel; memcpy(&oldModel, &model, sizeof(oldModel)); ModelData & newModel = model; memset(&newModel, 0, sizeof(ModelData)); char name[LEN_MODEL_NAME+1]; zchar2str(name, oldModel.header.name, LEN_MODEL_NAME); TRACE("Model %s conversion from v217 to v218", name); newModel.header = oldModel.header; for (uint8_t 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 UNIT_WATTS) newModel.telemetrySensors[i].unit += 1; } #if defined(PCBTARANIS) && defined(REV9E) newModel.toplcdTimer = oldModel.toplcdTimer; #endif } void ConvertModel(int id, int version) { eeLoadModelData(id); if (version == 216) { version = 217; ConvertModel_216_to_217(g_model); } if (version == 217) { version = 218; ConvertModel_217_to_218(g_model); } uint8_t currModel = g_eeGeneral.currModel; g_eeGeneral.currModel = id; storageDirty(EE_MODEL); storageCheck(true); g_eeGeneral.currModel = currModel; } bool eeConvert() { const char *msg = NULL; if (g_eeGeneral.version == 216) { msg = PSTR("EEprom Data v216"); } else if (g_eeGeneral.version == 217) { msg = PSTR("EEprom Data v217"); } else { return false; } int conversionVersionStart = g_eeGeneral.version; // Information to the user and wait for key press #if defined(PCBSKY9X) g_eeGeneral.optrexDisplay = 0; #endif g_eeGeneral.backlightMode = e_backlight_mode_on; g_eeGeneral.backlightBright = 0; g_eeGeneral.contrast = 25; ALERT(STR_STORAGE_WARNING, msg, AU_BAD_RADIODATA); // Message MESSAGE(STR_STORAGE_WARNING, STR_EEPROM_CONVERTING, NULL, AU_NONE); // General Settings conversion eeLoadGeneralSettingsData(); int version = conversionVersionStart; if (version == 216) { version = 217; ConvertRadioData_216_to_217(g_eeGeneral); } if (version == 217) { version = 218; ConvertRadioData_217_to_218(g_eeGeneral); } storageDirty(EE_GENERAL); storageCheck(true); #if defined(COLORLCD) #elif LCD_W >= 212 lcdDrawRect(60, 6*FH+4, 132, 3); #else lcdDrawRect(10, 6*FH+4, 102, 3); #endif // Models conversion for (uint8_t id=0; id= 212 lcdDrawSolidHorizontalLine(61, 6*FH+5, 10+id*2, FORCE); #else lcdDrawSolidHorizontalLine(11, 6*FH+5, 10+(id*3)/2, FORCE); #endif lcdRefresh(); if (eeModelExists(id)) { ConvertModel(id, conversionVersionStart); } } return true; }