5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 // No include guards here, this file may be included many times in different namespaces
22 // i.e. BACKUP RAM Backup/Restore functions
25 #include "dataconstants.h"
28 #define ARM_FIELD(x) x;
32 #define AVR_FIELD(x) x;
36 #define N_PCBSTD_FIELD(x)
38 #define N_PCBSTD_FIELD(x) x;
41 #if defined(PCBTARANIS)
42 #define N_TARANIS_FIELD(x)
43 #define TARANIS_FIELD(x) x;
45 #define N_TARANIS_FIELD(x) x;
46 #define TARANIS_FIELD(x)
50 #define TARANIS_PCBX9E_FIELD(x) x;
52 #define TARANIS_PCBX9E_FIELD(x)
56 #define N_HORUS_FIELD(x)
57 #define HORUS_FIELD(x) x;
59 #define N_HORUS_FIELD(x) x;
60 #define HORUS_FIELD(x)
66 #define NOBACKUP(...) __VA_ARGS__
69 #if defined(PCBTARANIS) || defined(PCBHORUS)
70 typedef uint16_t source_t
;
72 typedef uint8_t source_t
;
80 PACK(struct CurveRef
{
86 int16_t weight
:11; // GV1=-1024, -GV1=1023
88 uint16_t srcRaw
:10; // srcRaw=0 means not used
90 uint16_t mixWarn
:2; // mixer warning
91 uint16_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
95 uint32_t flightModes
:9;
101 NOBACKUP(char name
[LEN_EXPOMIX_NAME
]);
103 #elif defined(CPUM2560) || defined(CPUM2561)
104 PACK(struct MixData
{
105 uint8_t destCh
:4; // 0, 1..MAX_OUTPUT_CHANNELS
106 uint8_t curveMode
:1; // O=curve, 1=differential
108 uint8_t weightMode
:1;
109 uint8_t offsetMode
:1;
114 uint8_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
116 uint8_t mixWarn
:2; // mixer warning
126 PACK(struct MixData
{
127 uint8_t destCh
:4; // 0, 1..MAX_OUTPUT_CHANNELS
128 uint8_t curveMode
:1; // O=curve, 1=differential
130 uint8_t weightMode
:1;
131 uint8_t offsetMode
:1;
134 uint8_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
135 uint8_t flightModes
:5;
138 uint8_t mixWarn
:2; // mixer warning
149 * Expo/Input structure
153 PACK(struct ExpoData
{
160 uint32_t flightModes
:9;
163 NOBACKUP(char name
[LEN_EXPOMIX_NAME
]);
167 #elif defined(CPUM2560) || defined(CPUM2561)
168 PACK(struct ExpoData
{
169 uint8_t mode
:2; // 0=end, 1=pos, 2=neg, 3=both
179 PACK(struct ExpoData
{
180 uint8_t mode
:2; // 0=end, 1=pos, 2=neg, 3=both
183 uint8_t flightModes
:5;
185 uint8_t weight
; // One spare bit here (used for GVARS)
195 PACK(struct LimitData
{
198 int32_t ppmCenter
:10;
200 uint16_t symetrical
:1;
204 NOBACKUP(char name
[LEN_CHANNEL_NAME
]);
207 PACK(struct LimitData
{
212 uint16_t symetrical
:1;
218 * LogicalSwitch structure
222 PACK(struct LogicalSwitchData
{
226 int32_t andsw
:9; // TODO rename to xswtch
227 uint32_t andswtype
:1; // TODO rename to xswtchType (AND / OR)
228 uint32_t spare
:2; // anything else needed?
234 PACK(struct LogicalSwitchData
{
243 * SpecialFunction structure
248 #if defined(PCBTARANIS)
249 #define CFN_SPARE_TYPE int32_t
251 #define CFN_SPARE_TYPE int16_t
254 PACK(struct CustomFunctionData
{
258 NOBACKUP(PACK(struct {
259 char name
[LEN_FUNCTION_NAME
];
266 NOBACKUP(CFN_SPARE_TYPE spare
);
271 NOBACKUP(CFN_SPARE_TYPE val2
);
276 #elif defined(CPUM2560)
277 PACK(struct CustomFunctionData
{
287 PACK(struct CustomFunctionData
{
310 * FlightMode structure
319 typedef int16_t trim_t
;
322 typedef int16_t gvar_t
;
324 #if MAX_ROTARY_ENCODERS > 0
325 #define FLIGHT_MODE_ROTARY_ENCODERS_FIELD int16_t rotaryEncoders[MAX_ROTARY_ENCODERS];
327 #define FLIGHT_MODE_ROTARY_ENCODERS_FIELD
331 PACK(struct FlightModeData
{
332 trim_t trim
[NUM_STICKS
+NUM_AUX_TRIMS
];
333 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
334 int16_t swtch
:9; // swtch of phase[0] is not used
338 FLIGHT_MODE_ROTARY_ENCODERS_FIELD
339 gvar_t gvars
[MAX_GVARS
];
341 #elif !defined(PCBSTD)
342 PACK(struct FlightModeData
{
343 trim_t trim
[NUM_STICKS
];
344 int8_t swtch
; // swtch of phase[0] is not used
345 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
348 FLIGHT_MODE_ROTARY_ENCODERS_FIELD
349 gvar_t gvars
[MAX_GVARS
];
352 PACK(struct FlightModeData
{
353 int8_t trim
[NUM_STICKS
];
354 int8_t trim_ext
; // 2 extra bits per trim (10bits)
355 int8_t swtch
; // swtch of phase[0] is not used
356 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
367 PACK(struct CurveData
{
370 int8_t points
:6; // describes number of points - 5
371 NOBACKUP(char name
[LEN_CURVE_NAME
]);
374 typedef int8_t CurveData
;
382 PACK(struct GVarData
{
383 NOBACKUP(char name
[LEN_GVAR_NAME
]);
398 PACK(struct TimerData
{
399 int32_t mode
:9; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
402 uint32_t countdownBeep
:2;
403 uint32_t minuteBeep
:1;
404 uint32_t persistent
:2;
405 int32_t countdownStart
:2;
406 uint32_t direction
:1;
407 NOBACKUP(char name
[LEN_TIMER_NAME
]);
409 #elif defined(CPUM2560)
410 PACK(struct TimerData
{
411 int8_t mode
; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
413 uint8_t countdownBeep
:2;
414 uint8_t minuteBeep
:1;
415 uint8_t persistent
:2;
416 uint8_t countdownStart
:3;
420 PACK(struct TimerData
{
421 int8_t mode
; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
423 uint16_t countdownBeep
:1;
424 uint16_t minuteBeep
:1;
430 * Swash Ring structure
433 #if defined(VIRTUAL_INPUTS)
434 PACK(struct SwashRingData
{
437 uint8_t collectiveSource
;
438 uint8_t aileronSource
;
439 uint8_t elevatorSource
;
440 int8_t collectiveWeight
;
441 int8_t aileronWeight
;
442 int8_t elevatorWeight
;
445 PACK(struct SwashRingData
{
450 uint8_t collectiveSource
;
456 union ScriptDataInput
{
461 PACK(struct ScriptData
{
462 char file
[LEN_SCRIPT_FILENAME
];
463 char name
[LEN_SCRIPT_NAME
];
464 ScriptDataInput inputs
[MAX_SCRIPT_INPUTS
];
469 * Frsky Telemetry structure
472 PACK(struct RssiAlarmData
{
478 inline int8_t getWarningRssi() {return 45 + warning
;}
479 inline int8_t getCriticalRssi() {return 42 + critical
;}
482 PACK(struct FrSkyRSSIAlarm
{
489 typedef int16_t ls_telemetry_value_t
;
491 typedef uint8_t ls_telemetry_value_t
;
494 #if !defined(COLORLCD)
495 PACK(struct FrSkyBarData
{
497 ls_telemetry_value_t barMin
; // minimum for bar display
498 ls_telemetry_value_t barMax
; // ditto for max display (would usually = ratio)
501 PACK(struct FrSkyLineData
{
502 source_t sources
[NUM_LINE_ITEMS
];
505 #if defined(PCBTARANIS)
506 PACK(struct TelemetryScriptData
{
507 char file
[LEN_SCRIPT_FILENAME
];
508 int16_t inputs
[MAX_TELEM_SCRIPT_INPUTS
];
512 union FrSkyScreenData
{
513 FrSkyBarData bars
[4];
514 FrSkyLineData lines
[4];
515 #if defined(PCBTARANIS)
516 TelemetryScriptData script
;
521 #if defined(COLORLCD)
522 PACK(struct FrSkyTelemetryData
{ // TODO EEPROM change, rename to VarioData
523 uint8_t varioSource
:7;
524 uint8_t varioCenterSilent
:1;
525 int8_t varioCenterMax
;
526 int8_t varioCenterMin
;
530 #elif defined(CPUARM)
531 // TODO remove this also on Taranis
532 PACK(struct FrSkyTelemetryData
{
534 uint8_t altitudeSource
;
535 uint8_t screensType
; // 2bits per screen (None/Gauges/Numbers/Script)
536 FrSkyScreenData screens
[MAX_TELEMETRY_SCREENS
]; // TODO EEPROM change should not be here anymore
537 uint8_t varioSource
:7;
538 uint8_t varioCenterSilent
:1;
539 int8_t varioCenterMax
;
540 int8_t varioCenterMin
;
545 PACK(struct FrSkyChannelData
{
546 uint8_t ratio
; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
548 uint16_t type
:4; // channel unit (0=volts, ...)
549 uint8_t alarms_value
[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
550 uint8_t alarms_level
:4;
551 uint8_t alarms_greater
:2; // 0=LT(<), 1=GT(>)
552 uint8_t multiplier
:2; // 0=no multiplier, 1=*2 multiplier
555 PACK(struct FrSkyTelemetryData
{
556 FrSkyChannelData channels
[MAX_FRSKY_A_CHANNELS
];
557 uint8_t usrProto
:2; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh, 3=Halcyon
558 uint8_t blades
:2; // How many blades for RPMs, 0=2 blades
559 uint8_t screensType
:2;
560 uint8_t voltsSource
:2;
563 FrSkyRSSIAlarm rssiAlarms
[2];
564 FrSkyScreenData screens
[MAX_TELEMETRY_SCREENS
];
565 uint8_t varioSource
:3;
566 int8_t varioCenterMin
:5;
567 uint8_t currentSource
:3;
568 int8_t varioCenterMax
:5;
574 * MAVLINK Telemetry structure
577 #if defined(TELEMETRY_MAVLINK)
578 PACK(struct MavlinkTelemetryData
{
579 uint8_t rc_rssi_scale
:4;
580 uint8_t pc_rssi_en
:1;
587 * Telemetry Sensor structure
591 PACK(struct TelemetrySensor
{
593 uint16_t id
; // data identifier, for FrSky we can reuse existing ones. Source unit is derived from type.
594 uint16_t persistentValue
;
597 uint8_t instance
; // instance ID to allow handling multiple instances of same value type, for FrSky can be the physical ID of the sensor
600 char label
[TELEM_LABEL_LEN
]; // user defined label
601 uint8_t type
:1; // 0=custom / 1=calculated
602 uint8_t unit
:5; // user can choose what unit to display each value in
604 uint8_t autoOffset
:1;
607 uint8_t persistent
:1;
608 uint8_t onlyPositive
:1;
635 void init(const char *label
, uint8_t unit
=UNIT_RAW
, uint8_t prec
=0);
636 void init(uint16_t id
);
637 bool isAvailable() const;
638 int32_t getValue(int32_t value
, uint8_t unit
, uint8_t prec
) const;
639 bool isConfigurable() const;
640 bool isPrecConfigurable() const;
641 int32_t getPrecMultiplier() const;
642 int32_t getPrecDivisor() const);
650 // Only used in case switch and if statements as "virtual" protocol
651 #define MM_RF_CUSTOM_SELECTED 0xff
652 PACK(struct ModuleData
{
655 uint8_t channelsStart
;
656 int8_t channelsCount
; // 0=8 channels
657 uint8_t failsafeMode
:4; // only 3 bits used
659 uint8_t invertedSerial
:1; // telemetry serial inverted from standard
660 int16_t failsafeChannels
[MAX_OUTPUT_CHANNELS
];
665 uint8_t outputType
:1; // false = open drain, true = push pull
669 uint8_t rfProtocolExtra
:2;
671 uint8_t customProto
:1;
672 uint8_t autoBindMode
:1;
673 uint8_t lowPowerMode
:1;
677 uint8_t power
:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
679 uint8_t receiver_telem_off
:1; // false = receiver telem enabled
680 uint8_t receiver_channel_9_16
:1; // false = pwm out 1-8, true 9-16
681 uint8_t external_antenna
:1; // false = internal antenna, true = external antenna
687 uint8_t noninverted
:1;
689 int8_t refreshRate
; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)
693 // Helper functions to set both of the rfProto protocol at the same time
694 NOBACKUP(inline uint8_t getMultiProtocol(bool returnCustom
) {
695 if (returnCustom
&& multi
.customProto
)
696 return MM_RF_CUSTOM_SELECTED
;
697 return ((uint8_t) (rfProtocol
& 0x0f)) + (multi
.rfProtocolExtra
<< 4);
700 NOBACKUP(inline void setMultiProtocol(uint8_t proto
)
702 rfProtocol
= (uint8_t) (proto
& 0x0f);
703 multi
.rfProtocolExtra
= (proto
& 0x30) >> 4;
712 #if defined(CPUARM) || defined(CPUM2560)
713 typedef uint16_t BeepANACenter
;
715 typedef uint8_t BeepANACenter
;
718 #if LEN_BITMAP_NAME > 0
719 #define MODEL_HEADER_BITMAP_FIELD NOBACKUP(char bitmap[LEN_BITMAP_NAME]);
721 #define MODEL_HEADER_BITMAP_FIELD
725 PACK(struct ModelHeader
{
726 char name
[LEN_MODEL_NAME
]; // must be first for eeLoadModelName
727 uint8_t modelId
[NUM_MODULES
];
728 MODEL_HEADER_BITMAP_FIELD
731 #if defined(COLORLCD)
732 typedef uint16_t swconfig_t
;
733 typedef uint32_t swarnstate_t
;
734 #elif defined(PCBX9E)
735 typedef uint64_t swconfig_t
;
736 typedef uint64_t swarnstate_t
;
737 typedef uint32_t swarnenable_t
;
738 #elif defined(PCBTARANIS)
739 typedef uint16_t swconfig_t
;
740 typedef uint16_t swarnstate_t
;
741 typedef uint8_t swarnenable_t
;
743 typedef uint8_t swarnstate_t
;
744 typedef uint8_t swarnenable_t
;
747 #if defined(COLORLCD)
748 #define SWITCHES_WARNING_DATA \
749 NOBACKUP(swarnstate_t switchWarningState);
751 #define SWITCHES_WARNING_DATA \
752 swarnstate_t switchWarningState; \
753 swarnenable_t switchWarningEnable;
756 #if defined(PCBSTD) && defined(GVARS)
757 #define MODEL_GVARS_DATA gvar_t gvars[MAX_GVARS];
758 #elif defined(PCBSTD)
759 #define MODEL_GVARS_DATA
761 #define MODEL_GVARS_DATA GVarData gvars[MAX_GVARS];
765 #define TELEMETRY_DATA NOBACKUP(FrSkyTelemetryData frsky); NOBACKUP(RssiAlarmData rssiAlarms);
766 #elif defined(TELEMETRY_MAVLINK)
767 #define TELEMETRY_DATA MavlinkTelemetryData mavlink;
768 #elif defined(TELEMETRY_FRSKY) || !defined(PCBSTD)
769 #define TELEMETRY_DATA NOBACKUP(FrSkyTelemetryData frsky);
771 #define TELEMETRY_DATA
774 #if defined(PCBHORUS)
775 #include "gui/480x272/layout.h"
776 #include "gui/480x272/topbar.h"
777 PACK(struct CustomScreenData
{
779 Layout::PersistentData layoutData
;
781 #define CUSTOM_SCREENS_DATA \
782 NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]); \
783 NOBACKUP(Topbar::PersistentData topbarData); \
784 NOBACKUP(uint8_t view);
785 #elif defined(PCBTARANIS)
786 #define CUSTOM_SCREENS_DATA \
787 NOBACKUP(uint8_t view);
789 #define CUSTOM_SCREENS_DATA
790 // TODO other boards could have their custom screens here as well
794 #define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]);
795 #elif defined(PCBX10)
796 #define MODELDATA_EXTRA NOBACKUP(uint8_t spare:3); NOBACKUP(uint8_t trainerMode:3); NOBACKUP(uint8_t potsWarnMode:2); ModuleData moduleData[NUM_MODULES+1]; NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]); NOBACKUP(uint8_t potsWarnEnabled); NOBACKUP(int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]); NOBACKUP(uint8_t potsWarnSpares[NUM_DUMMY_ANAS]);
797 #elif defined(PCBTARANIS)
798 #define MODELDATA_EXTRA uint8_t spare:3; uint8_t trainerMode:3; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; ScriptData scriptsData[MAX_SCRIPTS]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS];
799 #elif defined(PCBSKY9X)
800 #define MODELDATA_EXTRA uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; char inputNames[MAX_INPUTS][LEN_INPUT_NAME]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS+NUM_SLIDERS]; uint8_t rxBattAlarms[2];
802 #define MODELDATA_EXTRA
805 PACK(struct ModelData
{
807 TimerData timers
[MAX_TIMERS
];
808 AVR_FIELD(uint8_t protocol
:3)
809 ARM_FIELD(uint8_t telemetryProtocol
:3)
810 uint8_t thrTrim
:1; // Enable Throttle Trim
811 AVR_FIELD(int8_t ppmNCH
:4)
812 ARM_FIELD(uint8_t noGlobalFunctions
:1)
813 ARM_FIELD(uint8_t displayTrims
:2)
814 ARM_FIELD(uint8_t ignoreSensorIds
:1)
815 int8_t trimInc
:3; // Trim Increments
816 uint8_t disableThrottleWarning
:1;
817 ARM_FIELD(uint8_t displayChecklist
:1)
818 AVR_FIELD(uint8_t pulsePol
:1)
819 uint8_t extendedLimits
:1;
820 uint8_t extendedTrims
:1;
821 uint8_t throttleReversed
:1;
822 AVR_FIELD(int8_t ppmDelay
)
823 BeepANACenter beepANACenter
;
824 MixData mixData
[MAX_MIXERS
];
825 LimitData limitData
[MAX_OUTPUT_CHANNELS
];
826 ExpoData expoData
[MAX_EXPOS
];
828 CurveData curves
[MAX_CURVES
];
829 int8_t points
[MAX_CURVE_POINTS
];
831 LogicalSwitchData logicalSw
[MAX_LOGICAL_SWITCHES
];
832 CustomFunctionData customFn
[MAX_SPECIAL_FUNCTIONS
];
833 SwashRingData swashR
;
834 FlightModeData flightModeData
[MAX_FLIGHT_MODES
];
836 AVR_FIELD(int8_t ppmFrameLength
) // 0=22.5ms (10ms-30ms) 0.5ms increments
838 NOBACKUP(uint8_t thrTraceSrc
);
840 SWITCHES_WARNING_DATA
848 ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors
[MAX_TELEMETRY_SENSORS
]))
850 TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer
)
860 #if XPOTS_MULTIPOS_COUNT > 0
861 PACK(struct StepsCalibData
{
863 uint8_t steps
[XPOTS_MULTIPOS_COUNT
-1];
867 PACK(struct CalibData
{
873 PACK(struct TrainerMix
{
874 uint8_t srcChn
:6; // 0-7 = ch1-8
875 uint8_t mode
:2; // off,add-mode,subst-mode
879 PACK(struct TrainerData
{
881 NOBACKUP(TrainerMix mix
[4]);
884 #if defined(PCBHORUS)
885 #define SPLASH_MODE uint8_t splashSpares:3
886 #elif defined(FSPLASH)
887 #define SPLASH_MODE uint8_t splashMode:3
888 #elif defined(CPUARM)
889 #define SPLASH_MODE int8_t splashMode:3
891 #define SPLASH_MODE uint8_t splashMode:1; uint8_t splashSpare:2
895 #define EXTRA_GENERAL_FIELDS_ARM \
896 NOBACKUP(uint8_t backlightBright); \
897 NOBACKUP(uint32_t globalTimer); \
898 NOBACKUP(uint8_t bluetoothBaudrate:4); \
899 NOBACKUP(uint8_t bluetoothMode:4); \
900 NOBACKUP(uint8_t countryCode); \
901 NOBACKUP(uint8_t imperial:1); \
902 NOBACKUP(uint8_t jitterFilter:1); /* 0 - active */\
903 NOBACKUP(uint8_t disableRssiPoweroffAlarm:1); \
904 NOBACKUP(uint8_t USBMode:2); \
905 NOBACKUP(uint8_t spareExtraArm:3); \
906 NOBACKUP(char ttsLanguage[2]); \
907 NOBACKUP(int8_t beepVolume:4); \
908 NOBACKUP(int8_t wavVolume:4); \
909 NOBACKUP(int8_t varioVolume:4); \
910 NOBACKUP(int8_t backgroundVolume:4); \
911 NOBACKUP(int8_t varioPitch); \
912 NOBACKUP(int8_t varioRange); \
913 NOBACKUP(int8_t varioRepeat); \
914 CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
917 #if defined(PCBHORUS)
918 #define EXTRA_GENERAL_FIELDS \
919 EXTRA_GENERAL_FIELDS_ARM \
920 NOBACKUP(uint8_t serial2Mode:4); \
921 uint8_t slidersConfig:4; \
922 uint32_t switchConfig; \
923 uint8_t potsConfig; /* two bits per pot */ \
924 NOBACKUP(char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]); \
925 NOBACKUP(char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_DUMMY_ANAS][LEN_ANA_NAME]); \
926 NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
927 NOBACKUP(uint8_t spare:1); \
928 NOBACKUP(uint8_t blOffBright:7); \
929 NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]);
930 #elif defined(PCBTARANIS)
931 #if defined(PCBX9E) || defined(PCBX7)
932 #define BLUETOOTH_FIELDS \
934 char bluetoothName[LEN_BLUETOOTH_NAME];
936 #define BLUETOOTH_FIELDS
938 #define EXTRA_GENERAL_FIELDS \
939 EXTRA_GENERAL_FIELDS_ARM \
940 uint8_t serial2Mode:4; \
941 uint8_t slidersConfig:4; \
942 uint8_t potsConfig; /* two bits per pot */\
943 uint8_t backlightColor; \
944 swarnstate_t switchUnlockStates; \
945 swconfig_t switchConfig; \
946 char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
947 char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; \
949 #elif defined(PCBSKY9X)
950 #define EXTRA_GENERAL_FIELDS \
951 EXTRA_GENERAL_FIELDS_ARM \
952 int8_t txCurrentCalibration; \
953 int8_t temperatureWarn; \
956 int8_t temperatureCalib; \
957 uint8_t optrexDisplay; \
958 uint8_t sticksGain; \
959 uint8_t rotarySteps; \
960 char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
961 char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME];
962 #elif defined(CPUARM)
963 #define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM
965 #define EXTRA_GENERAL_FIELDS uint8_t countryCode;
967 #define EXTRA_GENERAL_FIELDS
970 #if defined(PCBHORUS)
971 #include "gui/480x272/theme.h"
973 NOBACKUP(char themeName[8]); \
974 NOBACKUP(Theme::PersistentData themeData);
980 #define BUZZER_FIELD NOBACKUP(int8_t buzzerMode:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware)
982 #define BUZZER_FIELD NOBACKUP(int8_t spareRadio:2);
985 PACK(struct RadioData
{
986 NOBACKUP(uint8_t version
);
987 NOBACKUP(uint16_t variant
);
988 CalibData calib
[NUM_STICKS
+NUM_POTS
+NUM_SLIDERS
+NUM_MOUSE_ANALOGS
+NUM_DUMMY_ANAS
];
989 NOBACKUP(uint16_t chkSum
);
990 N_HORUS_FIELD(int8_t currModel
);
991 N_HORUS_FIELD(uint8_t contrast
);
992 NOBACKUP(uint8_t vBatWarn
);
993 NOBACKUP(int8_t txVoltageCalibration
);
994 NOBACKUP(int8_t backlightMode
);
995 NOBACKUP(TrainerData trainer
);
996 NOBACKUP(uint8_t view
); // index of view in main screen
998 NOBACKUP(uint8_t fai
:1);
999 NOBACKUP(int8_t beepMode
:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all
1000 NOBACKUP(uint8_t alarmsFlash
:1);
1001 NOBACKUP(uint8_t disableMemoryWarning
:1);
1002 NOBACKUP(uint8_t disableAlarmWarning
:1);
1003 uint8_t stickMode
:2;
1004 NOBACKUP(int8_t timezone
:5);
1005 NOBACKUP(uint8_t adjustRTC
:1);
1006 NOBACKUP(uint8_t inactivityTimer
);
1007 AVR_FIELD(uint8_t mavbaud
:3)
1008 ARM_FIELD(uint8_t telemetryBaudrate
:3)
1009 SPLASH_MODE
; /* 3bits */
1010 NOBACKUP(int8_t hapticMode
:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all
1011 AVR_FIELD(uint8_t blOffBright
:4)
1012 AVR_FIELD(uint8_t blOnBright
:4)
1013 ARM_FIELD(int8_t switchesDelay
)
1014 NOBACKUP(uint8_t lightAutoOff
);
1015 NOBACKUP(uint8_t templateSetup
); // RETA order for receiver channels
1016 NOBACKUP(int8_t PPM_Multiplier
);
1017 NOBACKUP(int8_t hapticLength
);
1018 N_HORUS_FIELD(N_TARANIS_FIELD(N_PCBSTD_FIELD(uint8_t reNavigation
)));
1019 N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t stickReverse
));
1020 NOBACKUP(int8_t beepLength
:3);
1021 NOBACKUP(int8_t hapticStrength
:3);
1022 NOBACKUP(uint8_t gpsFormat
:1);
1023 NOBACKUP(uint8_t unexpectedShutdown
:1);
1024 NOBACKUP(uint8_t speakerPitch
);
1025 NOBACKUP(int8_t speakerVolume
);
1026 NOBACKUP(int8_t vBatMin
);
1027 NOBACKUP(int8_t vBatMax
);
1029 EXTRA_GENERAL_FIELDS
1035 #undef SWITCHES_WARNING_DATA
1036 #undef MODEL_GVARS_DATA
1037 #undef TELEMETRY_DATA
1038 #undef MODELDATA_EXTRA
1039 #undef CUSTOM_SCREENS_DATA
1041 #undef EXTRA_GENERAL_FIELDS
1046 #if !defined(BACKUP)
1047 /* Compile time check to test structure size has not changed *
1048 Changing the size of one of the eeprom structs may cause wrong data to
1049 be loaded. Error out if the struct size changes.
1050 This function tries not avoid checking or using the defines
1051 other than the CPU arch and board type so changes in other
1052 defines also trigger the struct size changes */
1054 template <typename ToCheck
, size_t expectedSize
, size_t realSize
= sizeof(ToCheck
)>
1056 static_assert(expectedSize
== realSize
, "struct size changed");
1059 static inline void check_struct()
1061 #define CHKSIZE(x, y) check_size<struct x, y>()
1062 #define CHKTYPE(x, y) check_size<x, y>()
1065 CHKSIZE(CurveRef
, 2);
1068 /* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */
1069 /* LEN_FUNCTION_NAME is the difference in CustomFunctionData */
1072 CHKSIZE(MixData
, 20);
1073 CHKSIZE(ExpoData
, 17);
1074 CHKSIZE(LimitData
, 11);
1075 CHKSIZE(LogicalSwitchData
, 9);
1076 CHKSIZE(CustomFunctionData
, 11);
1077 CHKSIZE(FlightModeData
, 36);
1078 CHKSIZE(TimerData
, 11);
1079 CHKSIZE(SwashRingData
, 8);
1080 CHKSIZE(FrSkyBarData
, 6);
1081 CHKSIZE(FrSkyLineData
, 4);
1082 CHKTYPE(union FrSkyScreenData
, 24);
1083 CHKSIZE(FrSkyTelemetryData
, 104);
1084 CHKSIZE(ModelHeader
, 12);
1085 CHKSIZE(CurveData
, 4);
1087 CHKSIZE(RadioData
, 850);
1088 CHKSIZE(ModelData
, 6025);
1090 #elif defined(PCBTARANIS)
1091 CHKSIZE(MixData
, 22);
1092 CHKSIZE(ExpoData
, 19);
1093 CHKSIZE(LimitData
, 13);
1094 CHKSIZE(LogicalSwitchData
, 9);
1095 CHKSIZE(CustomFunctionData
, 11);
1096 CHKSIZE(FlightModeData
, 40);
1097 CHKSIZE(TimerData
, 16);
1098 CHKSIZE(SwashRingData
, 8);
1099 CHKSIZE(FrSkyBarData
, 6);
1100 CHKSIZE(FrSkyLineData
, 6);
1101 CHKTYPE(union FrSkyScreenData
, 24);
1102 CHKSIZE(FrSkyTelemetryData
, 104);
1103 CHKSIZE(ModelHeader
, 24);
1104 CHKSIZE(CurveData
, 4);
1106 CHKSIZE(RadioData
, 952);
1107 CHKSIZE(ModelData
, 6520);
1109 CHKSIZE(RadioData
, 872);
1110 CHKSIZE(ModelData
, 6507);
1113 #elif defined(PCBHORUS)
1114 CHKSIZE(MixData
, 20);
1115 CHKSIZE(ExpoData
, 17);
1116 CHKSIZE(LimitData
, 13);
1117 CHKSIZE(CustomFunctionData
, 9);
1118 CHKSIZE(FlightModeData
, 44);
1119 CHKSIZE(TimerData
, 16);
1120 CHKSIZE(SwashRingData
, 8);
1122 CHKSIZE(FrSkyTelemetryData
, 5);
1123 CHKSIZE(ModelHeader
, 27);
1124 CHKSIZE(CurveData
, 4);
1125 CHKSIZE(RadioData
, 847);
1126 CHKSIZE(ModelData
, 9380);
1127 CHKSIZE(CustomScreenData
, 610);
1128 CHKSIZE(Topbar::PersistentData
, 216);
1129 #elif defined(PCBSKY9X)
1130 CHKSIZE(MixData
, 20);
1131 CHKSIZE(ExpoData
, 17);
1132 CHKSIZE(LimitData
, 11);
1133 CHKSIZE(CustomFunctionData
, 9);
1134 CHKSIZE(FlightModeData
, 38);
1135 CHKSIZE(TimerData
, 11);
1136 CHKSIZE(SwashRingData
, 8);
1137 CHKSIZE(FrSkyBarData
, 5);
1138 CHKSIZE(FrSkyLineData
, 2);
1139 CHKSIZE(FrSkyTelemetryData
, 88);
1140 CHKSIZE(ModelHeader
, 12);
1141 CHKTYPE(CurveData
, 4);
1142 CHKSIZE(RadioData
, 727);
1143 CHKSIZE(ModelData
, 5188);
1145 // Common for all variants
1146 CHKSIZE(LimitData
, 5);
1147 CHKSIZE(SwashRingData
, 3);
1148 CHKSIZE(FrSkyBarData
, 3);
1149 CHKSIZE(FrSkyLineData
, 2);
1150 CHKSIZE(FrSkyTelemetryData
, 43);
1151 CHKSIZE(ModelHeader
, 11);
1152 CHKTYPE(CurveData
, 1);
1155 #if defined(CPUM2560) || defined(CPUM2561)
1156 CHKSIZE(ExpoData
, 5);
1157 CHKSIZE(MixData
, 10);
1159 CHKSIZE(MixData
, 9);
1160 CHKSIZE(ExpoData
, 4);
1163 #if defined(CPUM2560)
1164 CHKSIZE(CustomFunctionData
, 4);
1165 CHKSIZE(TimerData
, 6);
1167 CHKSIZE(CustomFunctionData
, 3);
1168 CHKSIZE(TimerData
, 3);
1172 CHKSIZE(FlightModeData
, 13);
1173 CHKSIZE(RadioData
, 84);
1175 CHKSIZE(FlightModeData
, 30);
1176 CHKSIZE(RadioData
, 85);
1179 #endif /* board specific ifdefs*/
1182 CHKSIZE(LogicalSwitchData
, 9);
1183 CHKSIZE(TelemetrySensor
, 13);
1184 CHKSIZE(ModuleData
,70);
1186 CHKSIZE(LogicalSwitchData
, 3);
1187 CHKSIZE(FrSkyChannelData
, 6);
1188 CHKSIZE(ModuleData
, 38);
1191 #if !defined(PCBSTD)
1192 CHKSIZE(GVarData
, 7);
1196 CHKSIZE(RssiAlarmData
, 2);
1198 CHKSIZE(FrSkyRSSIAlarm
, 1);
1200 CHKSIZE(TrainerData
, 16);