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
27 #include "dataconstants.h"
28 #include "definitions.h"
31 #define ARM_FIELD(x) x;
35 #define AVR_FIELD(x) x;
39 #define N_PCBSTD_FIELD(x)
41 #define N_PCBSTD_FIELD(x) x;
44 #if defined(PCBTARANIS)
45 #define N_TARANIS_FIELD(x)
46 #define TARANIS_FIELD(x) x;
48 #define N_TARANIS_FIELD(x) x;
49 #define TARANIS_FIELD(x)
53 #define TARANIS_PCBX9E_FIELD(x) x;
55 #define TARANIS_PCBX9E_FIELD(x)
59 #define N_HORUS_FIELD(x)
60 #define HORUS_FIELD(x) x;
62 #define N_HORUS_FIELD(x) x;
63 #define HORUS_FIELD(x)
69 #define NOBACKUP(...) __VA_ARGS__
72 #if defined(PCBTARANIS) || defined(PCBHORUS)
73 typedef uint16_t source_t
;
75 typedef uint8_t source_t
;
83 PACK(struct CurveRef
{
89 int16_t weight
:11; // GV1=-1024, -GV1=1023
91 uint16_t srcRaw
:10; // srcRaw=0 means not used
93 uint16_t mixWarn
:2; // mixer warning
94 uint16_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
98 uint32_t flightModes
:9;
104 NOBACKUP(char name
[LEN_EXPOMIX_NAME
]);
106 #elif defined(CPUM2560) || defined(CPUM2561)
107 PACK(struct MixData
{
108 uint8_t destCh
:4; // 0, 1..MAX_OUTPUT_CHANNELS
109 uint8_t curveMode
:1; // O=curve, 1=differential
111 uint8_t weightMode
:1;
112 uint8_t offsetMode
:1;
117 uint8_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
119 uint8_t mixWarn
:2; // mixer warning
129 PACK(struct MixData
{
130 uint8_t destCh
:4; // 0, 1..MAX_OUTPUT_CHANNELS
131 uint8_t curveMode
:1; // O=curve, 1=differential
133 uint8_t weightMode
:1;
134 uint8_t offsetMode
:1;
137 uint8_t mltpx
:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
138 uint8_t flightModes
:5;
141 uint8_t mixWarn
:2; // mixer warning
152 * Expo/Input structure
156 PACK(struct ExpoData
{
163 uint32_t flightModes
:9;
166 NOBACKUP(char name
[LEN_EXPOMIX_NAME
]);
170 #elif defined(CPUM2560) || defined(CPUM2561)
171 PACK(struct ExpoData
{
172 uint8_t mode
:2; // 0=end, 1=pos, 2=neg, 3=both
182 PACK(struct ExpoData
{
183 uint8_t mode
:2; // 0=end, 1=pos, 2=neg, 3=both
186 uint8_t flightModes
:5;
188 uint8_t weight
; // One spare bit here (used for GVARS)
198 PACK(struct LimitData
{
201 int32_t ppmCenter
:10;
203 uint16_t symetrical
:1;
207 NOBACKUP(char name
[LEN_CHANNEL_NAME
]);
210 PACK(struct LimitData
{
215 uint16_t symetrical
:1;
221 * LogicalSwitch structure
225 PACK(struct LogicalSwitchData
{
229 int32_t andsw
:9; // TODO rename to xswtch
230 uint32_t andswtype
:1; // TODO rename to xswtchType (AND / OR)
231 uint32_t spare
:2; // anything else needed?
237 PACK(struct LogicalSwitchData
{
246 * SpecialFunction structure
251 #if defined(PCBTARANIS)
252 #define CFN_SPARE_TYPE int32_t
254 #define CFN_SPARE_TYPE int16_t
257 PACK(struct CustomFunctionData
{
261 NOBACKUP(PACK(struct {
262 char name
[LEN_FUNCTION_NAME
];
269 NOBACKUP(CFN_SPARE_TYPE spare
);
272 NOBACKUP(PACK(struct {
274 NOBACKUP(CFN_SPARE_TYPE val2
);
279 #elif defined(CPUM2560)
280 PACK(struct CustomFunctionData
{
290 PACK(struct CustomFunctionData
{
313 * FlightMode structure
322 typedef int16_t trim_t
;
325 typedef int16_t gvar_t
;
327 #if MAX_ROTARY_ENCODERS > 0
328 #define FLIGHT_MODE_ROTARY_ENCODERS_FIELD int16_t rotaryEncoders[MAX_ROTARY_ENCODERS];
330 #define FLIGHT_MODE_ROTARY_ENCODERS_FIELD
334 PACK(struct FlightModeData
{
335 trim_t trim
[NUM_TRIMS
];
336 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
337 int16_t swtch
:9; // swtch of phase[0] is not used
341 FLIGHT_MODE_ROTARY_ENCODERS_FIELD
342 gvar_t gvars
[MAX_GVARS
];
344 #elif !defined(PCBSTD)
345 PACK(struct FlightModeData
{
346 trim_t trim
[NUM_STICKS
];
347 int8_t swtch
; // swtch of phase[0] is not used
348 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
351 FLIGHT_MODE_ROTARY_ENCODERS_FIELD
352 gvar_t gvars
[MAX_GVARS
];
355 PACK(struct FlightModeData
{
356 int8_t trim
[NUM_STICKS
];
357 int8_t trim_ext
; // 2 extra bits per trim (10bits)
358 int8_t swtch
; // swtch of phase[0] is not used
359 NOBACKUP(char name
[LEN_FLIGHT_MODE_NAME
]);
370 PACK(struct CurveData
{
373 int8_t points
:6; // describes number of points - 5
374 NOBACKUP(char name
[LEN_CURVE_NAME
]);
377 typedef int8_t CurveData
;
385 PACK(struct GVarData
{
386 NOBACKUP(char name
[LEN_GVAR_NAME
]);
401 PACK(struct TimerData
{
402 int32_t mode
:9; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
405 uint32_t countdownBeep
:2;
406 uint32_t minuteBeep
:1;
407 uint32_t persistent
:2;
408 int32_t countdownStart
:2;
409 uint32_t direction
:1;
410 NOBACKUP(char name
[LEN_TIMER_NAME
]);
412 #elif defined(CPUM2560)
413 PACK(struct TimerData
{
414 int8_t mode
; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
416 uint8_t countdownBeep
:2;
417 uint8_t minuteBeep
:1;
418 uint8_t persistent
:2;
419 uint8_t countdownStart
:3;
423 PACK(struct TimerData
{
424 int8_t mode
; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
426 uint16_t countdownBeep
:1;
427 uint16_t minuteBeep
:1;
433 * Swash Ring structure
436 #if defined(VIRTUAL_INPUTS)
437 PACK(struct SwashRingData
{
440 uint8_t collectiveSource
;
441 uint8_t aileronSource
;
442 uint8_t elevatorSource
;
443 int8_t collectiveWeight
;
444 int8_t aileronWeight
;
445 int8_t elevatorWeight
;
448 PACK(struct SwashRingData
{
453 uint8_t collectiveSource
;
459 union ScriptDataInput
{
464 PACK(struct ScriptData
{
465 char file
[LEN_SCRIPT_FILENAME
];
466 char name
[LEN_SCRIPT_NAME
];
467 ScriptDataInput inputs
[MAX_SCRIPT_INPUTS
];
472 * Frsky Telemetry structure
475 PACK(struct RssiAlarmData
{
481 inline int8_t getWarningRssi() {return 45 + warning
;}
482 inline int8_t getCriticalRssi() {return 42 + critical
;}
485 PACK(struct FrSkyRSSIAlarm
{
492 typedef int16_t ls_telemetry_value_t
;
494 typedef uint8_t ls_telemetry_value_t
;
497 #if !defined(COLORLCD)
498 PACK(struct FrSkyBarData
{
500 ls_telemetry_value_t barMin
; // minimum for bar display
501 ls_telemetry_value_t barMax
; // ditto for max display (would usually = ratio)
504 PACK(struct FrSkyLineData
{
505 source_t sources
[NUM_LINE_ITEMS
];
508 #if defined(PCBTARANIS)
509 PACK(struct TelemetryScriptData
{
510 char file
[LEN_SCRIPT_FILENAME
];
511 int16_t inputs
[MAX_TELEM_SCRIPT_INPUTS
];
515 union FrSkyScreenData
{
516 FrSkyBarData bars
[4];
517 FrSkyLineData lines
[4];
518 #if defined(PCBTARANIS)
519 TelemetryScriptData script
;
524 #if defined(COLORLCD)
525 PACK(struct FrSkyTelemetryData
{ // TODO EEPROM change, rename to VarioData
526 uint8_t varioSource
:7;
527 uint8_t varioCenterSilent
:1;
528 int8_t varioCenterMax
;
529 int8_t varioCenterMin
;
533 #elif defined(CPUARM)
534 // TODO remove this also on Taranis
535 PACK(struct FrSkyTelemetryData
{
537 uint8_t altitudeSource
;
538 uint8_t screensType
; // 2bits per screen (None/Gauges/Numbers/Script)
539 FrSkyScreenData screens
[MAX_TELEMETRY_SCREENS
]; // TODO EEPROM change should not be here anymore
540 uint8_t varioSource
:7;
541 uint8_t varioCenterSilent
:1;
542 int8_t varioCenterMax
;
543 int8_t varioCenterMin
;
548 PACK(struct FrSkyChannelData
{
549 uint8_t ratio
; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
551 uint16_t type
:4; // channel unit (0=volts, ...)
552 uint8_t alarms_value
[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
553 uint8_t alarms_level
:4;
554 uint8_t alarms_greater
:2; // 0=LT(<), 1=GT(>)
555 uint8_t multiplier
:2; // 0=no multiplier, 1=*2 multiplier
558 PACK(struct FrSkyTelemetryData
{
559 FrSkyChannelData channels
[MAX_FRSKY_A_CHANNELS
];
560 uint8_t usrProto
:2; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh, 3=Halcyon
561 uint8_t blades
:2; // How many blades for RPMs, 0=2 blades
562 uint8_t screensType
:2;
563 uint8_t voltsSource
:2;
566 FrSkyRSSIAlarm rssiAlarms
[2];
567 FrSkyScreenData screens
[MAX_TELEMETRY_SCREENS
];
568 uint8_t varioSource
:3;
569 int8_t varioCenterMin
:5;
570 uint8_t currentSource
:3;
571 int8_t varioCenterMax
:5;
577 * MAVLINK Telemetry structure
580 #if defined(TELEMETRY_MAVLINK)
581 PACK(struct MavlinkTelemetryData
{
582 uint8_t rc_rssi_scale
:4;
583 uint8_t pc_rssi_en
:1;
590 * Telemetry Sensor structure
594 PACK(struct TelemetrySensor
{
596 uint16_t id
; // data identifier, for FrSky we can reuse existing ones. Source unit is derived from type.
597 NOBACKUP(uint16_t persistentValue
);
600 uint8_t instance
; // instance ID to allow handling multiple instances of same value type, for FrSky can be the physical ID of the sensor
601 NOBACKUP(uint8_t formula
);
603 char label
[TELEM_LABEL_LEN
]; // user defined label
604 uint8_t type
:1; // 0=custom / 1=calculated
605 uint8_t unit
:5; // user can choose what unit to display each value in
607 uint8_t autoOffset
:1;
610 uint8_t persistent
:1;
611 uint8_t onlyPositive
:1;
614 NOBACKUP(PACK(struct {
618 NOBACKUP(PACK(struct {
623 NOBACKUP(PACK(struct {
626 NOBACKUP(PACK(struct {
630 NOBACKUP(PACK(struct {
638 void init(const char *label
, uint8_t unit
=UNIT_RAW
, uint8_t prec
=0);
639 void init(uint16_t id
);
640 bool isAvailable() const;
641 int32_t getValue(int32_t value
, uint8_t unit
, uint8_t prec
) const;
642 bool isConfigurable() const;
643 bool isPrecConfigurable() const;
644 int32_t getPrecMultiplier() const;
645 int32_t getPrecDivisor() const);
653 // Only used in case switch and if statements as "virtual" protocol
654 #define MM_RF_CUSTOM_SELECTED 0xff
655 PACK(struct ModuleData
{
658 uint8_t channelsStart
;
659 int8_t channelsCount
; // 0=8 channels
660 uint8_t failsafeMode
:4; // only 3 bits used
662 uint8_t invertedSerial
:1; // telemetry serial inverted from standard
663 int16_t failsafeChannels
[MAX_OUTPUT_CHANNELS
];
668 uint8_t outputType
:1; // false = open drain, true = push pull
672 uint8_t rfProtocolExtra
:2;
674 uint8_t customProto
:1;
675 uint8_t autoBindMode
:1;
676 uint8_t lowPowerMode
:1;
680 uint8_t power
:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
682 uint8_t receiver_telem_off
:1; // false = receiver telem enabled
683 uint8_t receiver_channel_9_16
:1; // false = pwm out 1-8, true 9-16
684 uint8_t external_antenna
:1; // false = internal antenna, true = external antenna
685 uint8_t fast
:1; // TODO: to be used later by external module (fast means serial @ high speed)
690 uint8_t noninverted
:1;
692 int8_t refreshRate
; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)
696 // Helper functions to set both of the rfProto protocol at the same time
697 NOBACKUP(inline uint8_t getMultiProtocol(bool returnCustom
) {
698 if (returnCustom
&& multi
.customProto
)
699 return MM_RF_CUSTOM_SELECTED
;
700 return ((uint8_t) (rfProtocol
& 0x0f)) + (multi
.rfProtocolExtra
<< 4);
703 NOBACKUP(inline void setMultiProtocol(uint8_t proto
)
705 rfProtocol
= (uint8_t) (proto
& 0x0f);
706 multi
.rfProtocolExtra
= (proto
& 0x30) >> 4;
715 #if defined(CPUARM) || defined(CPUM2560)
716 typedef uint16_t BeepANACenter
;
718 typedef uint8_t BeepANACenter
;
721 #if LEN_BITMAP_NAME > 0
722 #define MODEL_HEADER_BITMAP_FIELD NOBACKUP(char bitmap[LEN_BITMAP_NAME]);
724 #define MODEL_HEADER_BITMAP_FIELD
728 PACK(struct ModelHeader
{
729 char name
[LEN_MODEL_NAME
]; // must be first for eeLoadModelName
730 uint8_t modelId
[NUM_MODULES
];
731 MODEL_HEADER_BITMAP_FIELD
734 #if defined(COLORLCD)
735 typedef uint16_t swconfig_t
;
736 typedef uint32_t swarnstate_t
;
737 #elif defined(PCBX9E)
738 typedef uint64_t swconfig_t
;
739 typedef uint64_t swarnstate_t
;
740 typedef uint32_t swarnenable_t
;
741 #elif defined(PCBTARANIS)
742 typedef uint16_t swconfig_t
;
743 typedef uint16_t swarnstate_t
;
744 typedef uint8_t swarnenable_t
;
746 typedef uint8_t swarnstate_t
;
747 typedef uint8_t swarnenable_t
;
750 #if defined(COLORLCD)
751 #define SWITCHES_WARNING_DATA \
752 NOBACKUP(swarnstate_t switchWarningState);
754 #define SWITCHES_WARNING_DATA \
755 swarnstate_t switchWarningState; \
756 swarnenable_t switchWarningEnable;
759 #if defined(PCBSTD) && defined(GVARS)
760 #define MODEL_GVARS_DATA gvar_t gvars[MAX_GVARS];
761 #elif defined(PCBSTD)
762 #define MODEL_GVARS_DATA
764 #define MODEL_GVARS_DATA GVarData gvars[MAX_GVARS];
768 #define TELEMETRY_DATA NOBACKUP(FrSkyTelemetryData frsky); NOBACKUP(RssiAlarmData rssiAlarms);
769 #elif defined(TELEMETRY_MAVLINK)
770 #define TELEMETRY_DATA MavlinkTelemetryData mavlink;
771 #elif defined(TELEMETRY_FRSKY) || !defined(PCBSTD)
772 #define TELEMETRY_DATA NOBACKUP(FrSkyTelemetryData frsky);
774 #define TELEMETRY_DATA
777 #if defined(PCBHORUS)
778 #include "gui/480x272/layout.h"
779 #include "gui/480x272/topbar.h"
780 PACK(struct CustomScreenData
{
782 Layout::PersistentData layoutData
;
784 #define CUSTOM_SCREENS_DATA \
785 NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]); \
786 NOBACKUP(Topbar::PersistentData topbarData); \
787 NOBACKUP(uint8_t view);
788 #elif defined(PCBTARANIS)
789 #define CUSTOM_SCREENS_DATA \
790 NOBACKUP(uint8_t view);
792 #define CUSTOM_SCREENS_DATA
793 // TODO other boards could have their custom screens here as well
797 #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]);
798 #elif defined(PCBX10)
799 #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]);
800 #elif defined(PCBTARANIS)
801 #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];
802 #elif defined(PCBSKY9X)
803 #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];
805 #define MODELDATA_EXTRA
808 PACK(struct ModelData
{
810 TimerData timers
[MAX_TIMERS
];
811 AVR_FIELD(uint8_t protocol
:3)
812 ARM_FIELD(uint8_t telemetryProtocol
:3)
813 uint8_t thrTrim
:1; // Enable Throttle Trim
814 AVR_FIELD(int8_t ppmNCH
:4)
815 ARM_FIELD(uint8_t noGlobalFunctions
:1)
816 ARM_FIELD(uint8_t displayTrims
:2)
817 ARM_FIELD(uint8_t ignoreSensorIds
:1)
818 int8_t trimInc
:3; // Trim Increments
819 uint8_t disableThrottleWarning
:1;
820 ARM_FIELD(uint8_t displayChecklist
:1)
821 AVR_FIELD(uint8_t pulsePol
:1)
822 uint8_t extendedLimits
:1;
823 uint8_t extendedTrims
:1;
824 uint8_t throttleReversed
:1;
825 AVR_FIELD(int8_t ppmDelay
)
826 BeepANACenter beepANACenter
;
827 MixData mixData
[MAX_MIXERS
];
828 LimitData limitData
[MAX_OUTPUT_CHANNELS
];
829 ExpoData expoData
[MAX_EXPOS
];
831 CurveData curves
[MAX_CURVES
];
832 int8_t points
[MAX_CURVE_POINTS
];
834 LogicalSwitchData logicalSw
[MAX_LOGICAL_SWITCHES
];
835 CustomFunctionData customFn
[MAX_SPECIAL_FUNCTIONS
];
836 SwashRingData swashR
;
837 FlightModeData flightModeData
[MAX_FLIGHT_MODES
];
839 AVR_FIELD(int8_t ppmFrameLength
) // 0=22.5ms (10ms-30ms) 0.5ms increments
841 NOBACKUP(uint8_t thrTraceSrc
);
843 SWITCHES_WARNING_DATA
851 ARM_FIELD(NOBACKUP(TelemetrySensor telemetrySensors
[MAX_TELEMETRY_SENSORS
]))
853 TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer
)
863 #if XPOTS_MULTIPOS_COUNT > 0
864 PACK(struct StepsCalibData
{
866 uint8_t steps
[XPOTS_MULTIPOS_COUNT
-1];
870 PACK(struct CalibData
{
876 PACK(struct TrainerMix
{
877 uint8_t srcChn
:6; // 0-7 = ch1-8
878 uint8_t mode
:2; // off,add-mode,subst-mode
882 PACK(struct TrainerData
{
884 NOBACKUP(TrainerMix mix
[4]);
887 #if defined(PCBHORUS)
888 #define SPLASH_MODE uint8_t splashSpares:3
889 #elif defined(FSPLASH)
890 #define SPLASH_MODE uint8_t splashMode:3
891 #elif defined(CPUARM)
892 #define SPLASH_MODE int8_t splashMode:3
894 #define SPLASH_MODE uint8_t splashMode:1; uint8_t splashSpare:2
898 #define EXTRA_GENERAL_FIELDS_ARM \
899 NOBACKUP(uint8_t backlightBright); \
900 NOBACKUP(uint32_t globalTimer); \
901 NOBACKUP(uint8_t bluetoothBaudrate:4); \
902 NOBACKUP(uint8_t bluetoothMode:4); \
903 NOBACKUP(uint8_t countryCode); \
904 NOBACKUP(uint8_t imperial:1); \
905 NOBACKUP(uint8_t jitterFilter:1); /* 0 - active */\
906 uint8_t disableRssiPoweroffAlarm:1; \
907 NOBACKUP(uint8_t USBMode:2); \
908 NOBACKUP(uint8_t spareExtraArm:3); \
909 NOBACKUP(char ttsLanguage[2]); \
910 NOBACKUP(int8_t beepVolume:4); \
911 NOBACKUP(int8_t wavVolume:4); \
912 NOBACKUP(int8_t varioVolume:4); \
913 NOBACKUP(int8_t backgroundVolume:4); \
914 NOBACKUP(int8_t varioPitch); \
915 NOBACKUP(int8_t varioRange); \
916 NOBACKUP(int8_t varioRepeat); \
917 CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS];
920 #if defined(PCBHORUS)
921 #define EXTRA_GENERAL_FIELDS \
922 EXTRA_GENERAL_FIELDS_ARM \
923 NOBACKUP(uint8_t serial2Mode:4); \
924 uint8_t slidersConfig:4; \
925 uint32_t switchConfig; \
926 uint8_t potsConfig; /* two bits per pot */ \
927 NOBACKUP(char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]); \
928 NOBACKUP(char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS+NUM_DUMMY_ANAS][LEN_ANA_NAME]); \
929 NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
930 NOBACKUP(uint8_t spare:1); \
931 NOBACKUP(uint8_t blOffBright:7); \
932 NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]);
933 #elif defined(PCBTARANIS)
934 #if defined(BLUETOOTH)
935 #define BLUETOOTH_FIELDS \
937 char bluetoothName[LEN_BLUETOOTH_NAME];
939 #define BLUETOOTH_FIELDS
941 #define EXTRA_GENERAL_FIELDS \
942 EXTRA_GENERAL_FIELDS_ARM \
943 uint8_t serial2Mode:4; \
944 uint8_t slidersConfig:4; \
945 uint8_t potsConfig; /* two bits per pot */\
946 uint8_t backlightColor; \
947 swarnstate_t switchUnlockStates; \
948 swconfig_t switchConfig; \
949 char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
950 char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; \
952 #elif defined(PCBSKY9X)
953 #define EXTRA_GENERAL_FIELDS \
954 EXTRA_GENERAL_FIELDS_ARM \
955 int8_t txCurrentCalibration; \
956 int8_t temperatureWarn; \
959 int8_t temperatureCalib; \
960 uint8_t optrexDisplay; \
961 uint8_t sticksGain; \
962 uint8_t rotarySteps; \
963 char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
964 char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME];
965 #elif defined(CPUARM)
966 #define EXTRA_GENERAL_FIELDS EXTRA_GENERAL_FIELDS_ARM
968 #define EXTRA_GENERAL_FIELDS uint8_t countryCode;
970 #define EXTRA_GENERAL_FIELDS
973 #if defined(PCBHORUS)
974 #include "gui/480x272/theme.h"
976 NOBACKUP(char themeName[8]); \
977 NOBACKUP(Theme::PersistentData themeData);
983 #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)
985 #define BUZZER_FIELD NOBACKUP(int8_t spareRadio:2);
988 PACK(struct RadioData
{
989 NOBACKUP(uint8_t version
);
990 NOBACKUP(uint16_t variant
);
991 CalibData calib
[NUM_STICKS
+NUM_POTS
+NUM_SLIDERS
+NUM_MOUSE_ANALOGS
+NUM_DUMMY_ANAS
];
992 NOBACKUP(uint16_t chkSum
);
993 N_HORUS_FIELD(int8_t currModel
);
994 N_HORUS_FIELD(uint8_t contrast
);
995 NOBACKUP(uint8_t vBatWarn
);
996 NOBACKUP(int8_t txVoltageCalibration
);
997 NOBACKUP(int8_t backlightMode
);
998 NOBACKUP(TrainerData trainer
);
999 NOBACKUP(uint8_t view
); // index of view in main screen
1001 NOBACKUP(uint8_t fai
:1);
1002 NOBACKUP(int8_t beepMode
:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all
1003 NOBACKUP(uint8_t alarmsFlash
:1);
1004 NOBACKUP(uint8_t disableMemoryWarning
:1);
1005 NOBACKUP(uint8_t disableAlarmWarning
:1);
1006 uint8_t stickMode
:2;
1007 NOBACKUP(int8_t timezone
:5);
1008 NOBACKUP(uint8_t adjustRTC
:1);
1009 NOBACKUP(uint8_t inactivityTimer
);
1010 AVR_FIELD(uint8_t mavbaud
:3)
1011 ARM_FIELD(uint8_t telemetryBaudrate
:3)
1012 SPLASH_MODE
; /* 3bits */
1013 NOBACKUP(int8_t hapticMode
:2); // -2=quiet, -1=only alarms, 0=no keys, 1=all
1014 AVR_FIELD(uint8_t blOffBright
:4)
1015 AVR_FIELD(uint8_t blOnBright
:4)
1016 ARM_FIELD(int8_t switchesDelay
)
1017 NOBACKUP(uint8_t lightAutoOff
);
1018 NOBACKUP(uint8_t templateSetup
); // RETA order for receiver channels
1019 NOBACKUP(int8_t PPM_Multiplier
);
1020 NOBACKUP(int8_t hapticLength
);
1021 N_HORUS_FIELD(N_TARANIS_FIELD(N_PCBSTD_FIELD(uint8_t reNavigation
)));
1022 N_HORUS_FIELD(N_TARANIS_FIELD(uint8_t stickReverse
));
1023 NOBACKUP(int8_t beepLength
:3);
1024 NOBACKUP(int8_t hapticStrength
:3);
1025 NOBACKUP(uint8_t gpsFormat
:1);
1026 NOBACKUP(uint8_t unexpectedShutdown
:1);
1027 NOBACKUP(uint8_t speakerPitch
);
1028 NOBACKUP(int8_t speakerVolume
);
1029 NOBACKUP(int8_t vBatMin
);
1030 NOBACKUP(int8_t vBatMax
);
1032 EXTRA_GENERAL_FIELDS
1038 #undef SWITCHES_WARNING_DATA
1039 #undef MODEL_GVARS_DATA
1040 #undef TELEMETRY_DATA
1041 #undef MODELDATA_EXTRA
1042 #undef CUSTOM_SCREENS_DATA
1044 #undef EXTRA_GENERAL_FIELDS
1049 #if !defined(BACKUP)
1050 /* Compile time check to test structure size has not changed *
1051 Changing the size of one of the eeprom structs may cause wrong data to
1052 be loaded. Error out if the struct size changes.
1053 This function tries not avoid checking or using the defines
1054 other than the CPU arch and board type so changes in other
1055 defines also trigger the struct size changes */
1057 template <typename ToCheck
, size_t expectedSize
, size_t realSize
= sizeof(ToCheck
)>
1059 static_assert(expectedSize
== realSize
, "struct size changed");
1062 static inline void check_struct()
1064 #define CHKSIZE(x, y) check_size<struct x, y>()
1065 #define CHKTYPE(x, y) check_size<x, y>()
1068 CHKSIZE(CurveRef
, 2);
1071 /* Difference between Taranis/Horus is LEN_EXPOMIX_NAME */
1072 /* LEN_FUNCTION_NAME is the difference in CustomFunctionData */
1074 #if defined(PCBX7) || defined(PCBXLITE)
1075 CHKSIZE(MixData
, 20);
1076 CHKSIZE(ExpoData
, 17);
1077 CHKSIZE(LimitData
, 11);
1078 CHKSIZE(LogicalSwitchData
, 9);
1079 CHKSIZE(CustomFunctionData
, 11);
1080 CHKSIZE(FlightModeData
, 28 + 2*NUM_TRIMS
);
1081 CHKSIZE(TimerData
, 11);
1082 CHKSIZE(SwashRingData
, 8);
1083 CHKSIZE(FrSkyBarData
, 6);
1084 CHKSIZE(FrSkyLineData
, 4);
1085 CHKTYPE(union FrSkyScreenData
, 24);
1086 CHKSIZE(FrSkyTelemetryData
, 104);
1087 CHKSIZE(ModelHeader
, 12);
1088 CHKSIZE(CurveData
, 4);
1089 #elif defined(PCBTARANIS)
1090 CHKSIZE(MixData
, 22);
1091 CHKSIZE(ExpoData
, 19);
1092 CHKSIZE(LimitData
, 13);
1093 CHKSIZE(LogicalSwitchData
, 9);
1094 CHKSIZE(CustomFunctionData
, 11);
1095 CHKSIZE(FlightModeData
, 40);
1096 CHKSIZE(TimerData
, 16);
1097 CHKSIZE(SwashRingData
, 8);
1098 CHKSIZE(FrSkyBarData
, 6);
1099 CHKSIZE(FrSkyLineData
, 6);
1100 CHKTYPE(union FrSkyScreenData
, 24);
1101 CHKSIZE(FrSkyTelemetryData
, 104);
1102 CHKSIZE(ModelHeader
, 24);
1103 CHKSIZE(CurveData
, 4);
1104 #elif defined(PCBHORUS)
1105 CHKSIZE(MixData
, 20);
1106 CHKSIZE(ExpoData
, 17);
1107 CHKSIZE(LimitData
, 13);
1108 CHKSIZE(CustomFunctionData
, 9);
1109 CHKSIZE(FlightModeData
, 44);
1110 CHKSIZE(TimerData
, 16);
1111 CHKSIZE(SwashRingData
, 8);
1112 CHKSIZE(FrSkyTelemetryData
, 5);
1113 CHKSIZE(ModelHeader
, 27);
1114 CHKSIZE(CurveData
, 4);
1115 CHKSIZE(CustomScreenData
, 610);
1116 CHKSIZE(Topbar::PersistentData
, 216);
1117 #elif defined(PCBSKY9X)
1118 CHKSIZE(MixData
, 20);
1119 CHKSIZE(ExpoData
, 17);
1120 CHKSIZE(LimitData
, 11);
1121 CHKSIZE(CustomFunctionData
, 9);
1122 CHKSIZE(FlightModeData
, 38);
1123 CHKSIZE(TimerData
, 11);
1124 CHKSIZE(SwashRingData
, 8);
1125 CHKSIZE(FrSkyBarData
, 5);
1126 CHKSIZE(FrSkyLineData
, 2);
1127 CHKSIZE(FrSkyTelemetryData
, 88);
1128 CHKSIZE(ModelHeader
, 12);
1129 CHKTYPE(CurveData
, 4);
1131 // Common for all variants
1132 CHKSIZE(LimitData
, 5);
1133 CHKSIZE(SwashRingData
, 3);
1134 CHKSIZE(FrSkyBarData
, 3);
1135 CHKSIZE(FrSkyLineData
, 2);
1136 CHKSIZE(FrSkyTelemetryData
, 43);
1137 CHKSIZE(ModelHeader
, 11);
1138 CHKTYPE(CurveData
, 1);
1141 #if defined(CPUM2560) || defined(CPUM2561)
1142 CHKSIZE(ExpoData
, 5);
1143 CHKSIZE(MixData
, 10);
1145 CHKSIZE(MixData
, 9);
1146 CHKSIZE(ExpoData
, 4);
1149 #if defined(CPUM2560)
1150 CHKSIZE(CustomFunctionData
, 4);
1151 CHKSIZE(TimerData
, 6);
1153 CHKSIZE(CustomFunctionData
, 3);
1154 CHKSIZE(TimerData
, 3);
1158 CHKSIZE(FlightModeData
, 13);
1159 CHKSIZE(RadioData
, 84);
1161 CHKSIZE(FlightModeData
, 30);
1162 CHKSIZE(RadioData
, 85);
1165 #endif /* board specific ifdefs*/
1168 CHKSIZE(LogicalSwitchData
, 9);
1169 CHKSIZE(TelemetrySensor
, 13);
1170 CHKSIZE(ModuleData
,70);
1172 CHKSIZE(LogicalSwitchData
, 3);
1173 CHKSIZE(FrSkyChannelData
, 6);
1174 CHKSIZE(ModuleData
, 38);
1177 #if !defined(PCBSTD)
1178 CHKSIZE(GVarData
, 7);
1182 CHKSIZE(RssiAlarmData
, 2);
1184 CHKSIZE(FrSkyRSSIAlarm
, 1);
1186 CHKSIZE(TrainerData
, 16);
1188 #if defined(PCBXLITE)
1189 CHKSIZE(RadioData
, 844);
1190 CHKSIZE(ModelData
, 6025);
1191 #elif defined(PCBX7)
1192 CHKSIZE(RadioData
, 850);
1193 CHKSIZE(ModelData
, 6025);
1194 #elif defined(PCBX9E)
1195 CHKSIZE(RadioData
, 952);
1196 CHKSIZE(ModelData
, 6520);
1197 #elif defined(PCBX9D)
1198 CHKSIZE(RadioData
, 872);
1199 CHKSIZE(ModelData
, 6507);
1200 #elif defined(PCBSKY9X)
1201 CHKSIZE(RadioData
, 727);
1202 CHKSIZE(ModelData
, 5188);
1203 #elif defined(PCBHORUS)
1204 CHKSIZE(RadioData
, 847);
1205 CHKSIZE(ModelData
, 9380);