Add "hardware_defs" target to dump hardware defines from hal.h per target Fixed hal.h definitions for switches & ADC inputs Tools to generate hardware definitions from current hal.h generator: add support for EXTx and analog switches WiP Add generated header to hardware_defs target Add support for ADC input direction and index per GPIO port Incredible: it compiles Removed StdPeriph ADC driver Works on QX7 Works on TX16S (VBat missing) Switch driver using generated switches for stm32 targets Switch driver with generated switches for simu Use switch names from switch driver Fixed single conversion handling Fixed horus VBat reading Added switch name Fix warnings about bitfield offsets and GCC 4.4 This is caused by bitfields that cross type boundaries. In this particular case, it happens as the bitfield is not defined the same in `rtc_backup.cpp`. Switches has already been moved to generic driver Jitter measurement for each sample, not just for oversampled values Moved periph clock init to the ADC driver ADC & GPIOs. Add switchInit() to init pins Fix NV14 CMake Fix taranis target Fix NV14 (again) Model audio files: use new interface for switch index Fix X9-lite Fix simu headers Fix getSwitchName() Add support for ADC switches Fix switch warning YAML Test only switches which are defined Conversions tests for QX7 only on QX7 Fix X12S Fix function switch names Enable ADC periph clock before initialising channels NV14: offset inputs for the sticks & fix switches WiP: get rid of VSRCRAW and some more Simu shall use normal ADC driver fix x7 fix nv14 Fix 9x nav fix 212x64 fix xlite fix x9e fix simu lib fix unit tests fix x7 tests PWM stick values should be written directly into adcValues ... just like FlySky sticks. fix x12s fix nv14 Add some support for SPI ADC (only unit tests) Remove `jq` usage fix generate_yaml.py for newer libclang fix pot config fix stick names Some YAML generator improvements Max 16 Pots on COLORLCD Fix some source names Use 10 bits for switches to prevent overflow Removed horus constants for switches & ADC inputs Fix unit tests Fix curve edit Fix libsimulator Fix function switches (tpro) Refine ADC & analog API Moved hardware definitions scripts and templates into own dir cleanup API refine Fix unit tests Mixer: apply calibration only on required inputs Place ADC switches after all other ADC inputs Fix X12S Remove useless TR_POTS_VSRCRAW, TR_SW_VSRCRAW, and TR_VSRCRAW Cleanup redundant generated YAML parsers Fixes Boxer rebase Add boxer to generate-hw-defs.sh Obsolete LUA exports Add boxer ADC_DIRECTION Split generate_hw_defs.py into multiple files Some cleanup (+ LUA switches) Fix AXIS definitions Fixed translation strings declarations Some rebase fixes Remove some useless StdPeriph drivers fix: set pin mode to reset state on usart deinit fix: use canonical names for calibration data fix: ADC driver does not care about unconfigured inputs fix X12S ADC Add support for ADC conversion chaining Better X12S ADC implem Moved X12S ADC driver to HAL/LL Improve ADC driver separation Fixed taranis & nv14 Moved PWM gimbals to HAL/LL Removed useless TR_EXTRA_VSRCRAW Fixed include guards Small fixes Renamed control inputs Moved internal and external module pulse driver def to boards Move more things to the generic_stm32 board Remove STR_VMIXTRIMS Added analog labels Generate main control names Misuse labels / short labels for main controls Backward compatibility: sliders and legacy names New keys driver Let's get rid of StdPeriph headers in simu Add jinja2 to CI workflows Use `grep` instead of `sed` chore: add python jinja2 oto msys setup script Removed more static definitions and use dynamic ones instead Fixes X9E Fix x7 nav too 212 switch display Fix default sliders Removed NUM_STICKS 212 switch display working nicely Surface radio 'stick' replacements fix: switch, trim & rotary pin init Remove old key drivers Removed VKEYS Removed ETX_FOURCC Fixed SURFACE_NAME Removed TR_VSWITCHES & TR_TRIMS_SWITCHES Fix xpot switches Store calibrated analogs in physical order Use getSourceString in drawSource Implement missing YAML read/write Fix isSourceAvailableInInputs() Fix isSourceAvailable() Some surface fixes Fix CLI debug Ported colour UI of analog diagnostics to new ADC API Small fixes Better input mapping Minor tpro fixes Fix trims available Remove TX mode choice on surface radio Rename surface controls Channel order alignement Fix throttle warning Fix checkTrims() Fix pot config casting issue Fix IS_SWITCH_FS() Fixed input mapping Fix fswitch auto-switch Fixed storing / reading function switches in YAML Fix enableVBatBridge() / disableVBatBridge() Fix interesting mode conversion Fix sources issues Fix special funnction list Proper function switch handling 128 GUI improvements Fix compilation Boxer cosmetics 128 hardware screen cosmetic Fix TX12 switches More switches fixes Simplify CPU type handling Fix flash size Fixed page-up / page-down in libopenui
992 lines
26 KiB
C
992 lines
26 KiB
C
/*
|
|
* Copyright (C) EdgeTX
|
|
*
|
|
* Based on code named
|
|
* opentx - https://github.com/opentx/opentx
|
|
* 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.
|
|
*/
|
|
|
|
// No include guards here, this file may be included many times in different namespaces
|
|
// i.e. BACKUP RAM Backup/Restore functions
|
|
|
|
#include <inttypes.h>
|
|
#include "board.h"
|
|
#include "dataconstants.h"
|
|
#include "definitions.h"
|
|
#include "opentx_types.h"
|
|
#include "globals.h"
|
|
#include "serial.h"
|
|
#include "usb_joystick.h"
|
|
#include "input_mapping.h"
|
|
|
|
#if defined(PCBTARANIS)
|
|
#define N_TARANIS_FIELD(x)
|
|
#define TARANIS_FIELD(x) x;
|
|
#else
|
|
#define N_TARANIS_FIELD(x) x;
|
|
#define TARANIS_FIELD(x)
|
|
#endif
|
|
|
|
#if defined(PCBX9E)
|
|
#define TARANIS_PCBX9E_FIELD(x) x;
|
|
#else
|
|
#define TARANIS_PCBX9E_FIELD(x)
|
|
#endif
|
|
|
|
#if defined(PCBHORUS)
|
|
#define N_HORUS_FIELD(x)
|
|
#define HORUS_FIELD(x) x;
|
|
#else
|
|
#define N_HORUS_FIELD(x) x;
|
|
#define HORUS_FIELD(x)
|
|
#endif
|
|
|
|
#if defined(BACKUP)
|
|
#define NOBACKUP(...)
|
|
#else
|
|
#define NOBACKUP(...) __VA_ARGS__
|
|
#endif
|
|
|
|
#include "storage/yaml/yaml_defs.h"
|
|
|
|
/*
|
|
* Mixer structure
|
|
*/
|
|
|
|
PACK(struct CurveRef {
|
|
uint8_t type;
|
|
int8_t value CUST(in_read_weight,in_write_weight);
|
|
});
|
|
|
|
PACK(struct MixData {
|
|
int16_t weight:11 CUST(in_read_weight,in_write_weight); // GV1=-1024, -GV1=1023
|
|
uint16_t destCh:5;
|
|
uint16_t srcRaw:10 CUST(r_mixSrcRaw,w_mixSrcRaw); // srcRaw=0 means not used
|
|
uint16_t carryTrim:1;
|
|
uint16_t mixWarn:2; // mixer warning
|
|
uint16_t mltpx:2 ENUM(MixerMultiplex);
|
|
uint16_t spare:1 SKIP;
|
|
int32_t offset:13 CUST(in_read_weight,in_write_weight);
|
|
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
|
uint32_t flightModes:9 CUST(r_flightModes, w_flightModes);
|
|
CurveRef curve;
|
|
uint8_t delayUp;
|
|
uint8_t delayDown;
|
|
uint8_t speedUp;
|
|
uint8_t speedDown;
|
|
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
|
|
});
|
|
|
|
/*
|
|
* Expo/Input structure
|
|
*/
|
|
|
|
PACK(struct ExpoData {
|
|
uint16_t mode:2;
|
|
uint16_t scale:14;
|
|
CUST_ATTR(carryTrim, r_carryTrim, nullptr); //pre 2.9
|
|
int16_t trimSource:6;
|
|
uint16_t srcRaw:10 ENUM(MixSources) CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
uint32_t chn:5;
|
|
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
|
uint32_t flightModes:9 CUST(r_flightModes, w_flightModes);
|
|
int32_t weight:8 CUST(in_read_weight,in_write_weight);
|
|
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
|
|
int8_t offset CUST(in_read_weight,in_write_weight);
|
|
CurveRef curve;
|
|
});
|
|
|
|
/*
|
|
* Limit structure
|
|
*/
|
|
|
|
PACK(struct LimitData {
|
|
int32_t min:11 CUST(in_read_weight,in_write_weight);
|
|
int32_t max:11 CUST(in_read_weight,in_write_weight);
|
|
int32_t ppmCenter:10; // TODO can be reduced to 8 bits
|
|
int16_t offset:11 CUST(in_read_weight,in_write_weight);
|
|
uint16_t symetrical:1;
|
|
uint16_t revert:1;
|
|
uint16_t spare:3 SKIP;
|
|
int8_t curve;
|
|
NOBACKUP(char name[LEN_CHANNEL_NAME]);
|
|
});
|
|
|
|
/*
|
|
* LogicalSwitch structure
|
|
*/
|
|
|
|
PACK(struct LogicalSwitchData {
|
|
uint8_t func ENUM(LogicalSwitchesFunctions);
|
|
CUST_ATTR(def,r_logicSw,w_logicSw);
|
|
int32_t v1:10 SKIP;
|
|
int32_t v3:10 SKIP;
|
|
int32_t andsw:10 CUST(r_swtchSrc,w_swtchSrc); // TODO rename to xswtch
|
|
uint32_t andswtype:1 SKIP; // TODO rename to xswtchType (AND / OR)
|
|
uint32_t spare:1 SKIP; // anything else needed?
|
|
int16_t v2 SKIP;
|
|
uint8_t delay;
|
|
uint8_t duration;
|
|
});
|
|
|
|
/*
|
|
* SpecialFunction structure
|
|
*/
|
|
|
|
|
|
#if defined(PCBTARANIS)
|
|
#define CFN_SPARE_TYPE int32_t
|
|
#else
|
|
#define CFN_SPARE_TYPE int16_t
|
|
#endif
|
|
|
|
PACK(struct CustomFunctionData {
|
|
int16_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
|
uint16_t func:6 ENUM(Functions); // TODO: 6 bits for Functions?
|
|
CUST_ATTR(def,r_customFn,w_customFn);
|
|
PACK(union {
|
|
NOBACKUP(PACK(struct {
|
|
char name[LEN_FUNCTION_NAME];
|
|
}) play);
|
|
|
|
PACK(struct {
|
|
int16_t val;
|
|
uint8_t mode;
|
|
uint8_t param;
|
|
NOBACKUP(CFN_SPARE_TYPE spare);
|
|
}) all;
|
|
|
|
NOBACKUP(PACK(struct {
|
|
int32_t val1;
|
|
NOBACKUP(CFN_SPARE_TYPE val2);
|
|
}) clear);
|
|
}) NAME(fp) SKIP;
|
|
uint8_t active SKIP;
|
|
|
|
bool isEmpty() const
|
|
{
|
|
return swtch == 0;
|
|
}
|
|
});
|
|
|
|
/*
|
|
* FlightMode structure
|
|
*/
|
|
|
|
PACK(struct trim_t {
|
|
int16_t value:11;
|
|
uint16_t mode:5;
|
|
});
|
|
|
|
PACK(struct FlightModeData {
|
|
trim_t trim[MAX_TRIMS];
|
|
NOBACKUP(char name[LEN_FLIGHT_MODE_NAME]);
|
|
// swtch of phase[0] is not used
|
|
int16_t swtch:10 ENUM(SwitchSources) CUST(r_swtchSrc,w_swtchSrc);
|
|
int16_t spare:6 SKIP;
|
|
uint8_t fadeIn;
|
|
uint8_t fadeOut;
|
|
gvar_t gvars[MAX_GVARS] FUNC(gvar_is_active);
|
|
});
|
|
|
|
/*
|
|
* Curve structure
|
|
*/
|
|
|
|
PACK(struct CurveHeader {
|
|
uint8_t type:1;
|
|
uint8_t smooth:1;
|
|
int8_t points:6; // describes number of points - 5
|
|
NOBACKUP(char name[LEN_CURVE_NAME]);
|
|
});
|
|
|
|
/*
|
|
* GVar structure
|
|
*/
|
|
|
|
PACK(struct GVarData {
|
|
NOBACKUP(char name[LEN_GVAR_NAME]);
|
|
uint32_t min:12;
|
|
uint32_t max:12;
|
|
uint32_t popup:1;
|
|
uint32_t prec:1;
|
|
uint32_t unit:2;
|
|
uint32_t spare:4 SKIP;
|
|
});
|
|
|
|
/*
|
|
* Timer structure
|
|
*/
|
|
|
|
PACK(struct TimerData {
|
|
uint32_t start:22;
|
|
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
|
|
int32_t value:22;
|
|
uint32_t mode:3 ENUM(TimerModes);
|
|
uint32_t countdownBeep:2;
|
|
uint32_t minuteBeep:1;
|
|
uint32_t persistent:2;
|
|
int32_t countdownStart:2;
|
|
uint8_t showElapsed:1;
|
|
uint8_t extraHaptic:1;
|
|
uint8_t spare:6 SKIP;
|
|
NOBACKUP(char name[LEN_TIMER_NAME]);
|
|
});
|
|
|
|
/*
|
|
* Swash Ring structure
|
|
*/
|
|
|
|
PACK(struct SwashRingData {
|
|
uint8_t type ENUM(SwashType);
|
|
uint8_t value;
|
|
uint8_t collectiveSource CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
uint8_t aileronSource CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
uint8_t elevatorSource CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
int8_t collectiveWeight;
|
|
int8_t aileronWeight;
|
|
int8_t elevatorWeight;
|
|
});
|
|
|
|
#if MAX_SCRIPTS > 0
|
|
union ScriptDataInput {
|
|
int16_t value;
|
|
source_t source CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
} FUNC(select_script_input);
|
|
|
|
PACK(struct ScriptData {
|
|
char file[LEN_SCRIPT_FILENAME];
|
|
char name[LEN_SCRIPT_NAME];
|
|
ScriptDataInput inputs[MAX_SCRIPT_INPUTS];
|
|
});
|
|
#endif
|
|
|
|
/*
|
|
* Frsky Telemetry structure (legacy read-only)
|
|
*/
|
|
PACK(struct RssiAlarmData {
|
|
// int8_t disabled:1;
|
|
CUST_ATTR(disabled,r_rssiDisabled,nullptr);
|
|
// int8_t warning:6; + 45
|
|
CUST_ATTR(warning,r_rssiWarning,nullptr);
|
|
// int8_t critical:6; + 42
|
|
CUST_ATTR(critical,r_rssiCritical,nullptr);
|
|
});
|
|
|
|
PACK(struct RFAlarmData {
|
|
int8_t warning;
|
|
int8_t critical;
|
|
});
|
|
|
|
typedef int16_t ls_telemetry_value_t;
|
|
|
|
#if !defined(COLORLCD)
|
|
PACK(struct FrSkyBarData {
|
|
source_t source CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
ls_telemetry_value_t barMin; // minimum for bar display
|
|
ls_telemetry_value_t barMax; // ditto for max display (would usually = ratio)
|
|
});
|
|
|
|
// This is used to be able to use
|
|
// custom read/write functions in
|
|
// an array made of typdef'ed literal types
|
|
// (YAML generator)
|
|
#if defined(YAML_GENERATOR)
|
|
PACK(struct LineDataSource {
|
|
source_t val CUST(r_mixSrcRaw,w_mixSrcRaw);
|
|
});
|
|
PACK(struct FrSkyLineData {
|
|
LineDataSource sources[NUM_LINE_ITEMS];
|
|
});
|
|
#else
|
|
// This here is the real structure used at run-time
|
|
PACK(struct FrSkyLineData {
|
|
source_t sources[NUM_LINE_ITEMS];
|
|
});
|
|
#endif
|
|
|
|
#if defined(PCBTARANIS)
|
|
PACK(struct TelemetryScriptData {
|
|
char file[LEN_SCRIPT_FILENAME];
|
|
int16_t inputs[MAX_TELEM_SCRIPT_INPUTS];
|
|
});
|
|
#endif
|
|
|
|
#if defined(YAML_GENERATOR)
|
|
union TelemetryScreenData_u {
|
|
FrSkyBarData bars[4];
|
|
FrSkyLineData lines[4];
|
|
#if defined(PCBTARANIS)
|
|
TelemetryScriptData script;
|
|
#endif
|
|
};
|
|
PACK(struct TelemetryScreenData {
|
|
CUST_ATTR(type,r_tele_screen_type,w_tele_screen_type);
|
|
TelemetryScreenData_u u FUNC(select_tele_screen_data);
|
|
});
|
|
#else
|
|
union TelemetryScreenData {
|
|
FrSkyBarData bars[4];
|
|
FrSkyLineData lines[4];
|
|
#if defined(PCBTARANIS)
|
|
TelemetryScriptData script;
|
|
#endif
|
|
} FUNC(select_tele_screen_data);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
PACK(struct VarioData {
|
|
uint8_t source:7 CUST(r_tele_sensor,w_tele_sensor); // telemetry sensor idx + 1
|
|
uint8_t centerSilent:1;
|
|
int8_t centerMax;
|
|
int8_t centerMin;
|
|
int8_t min;
|
|
int8_t max;
|
|
});
|
|
|
|
/*
|
|
* Telemetry Sensor structure
|
|
*/
|
|
|
|
#define TELEMETRY_ENDPOINT_NONE 0xFF
|
|
#define TELEMETRY_ENDPOINT_SPORT 0x07
|
|
|
|
PACK(struct TelemetrySensor {
|
|
union {
|
|
uint16_t id; // data identifier, for FrSky we can reuse existing ones.
|
|
// Source unit is derived from type.
|
|
NOBACKUP(uint16_t persistentValue);
|
|
} NAME(id1) FUNC(select_id1);
|
|
union {
|
|
NOBACKUP(PACK(struct {
|
|
uint8_t physID:5;
|
|
uint8_t rxIndex:3; // 1 bit for module index, 2 bits for receiver index
|
|
}) frskyInstance);
|
|
uint8_t instance;
|
|
NOBACKUP(uint8_t formula ENUM(TelemetrySensorFormula));
|
|
} NAME(id2) FUNC(select_id2);
|
|
NOBACKUP(char label[TELEM_LABEL_LEN]); // user defined label
|
|
uint8_t subId;
|
|
uint8_t type:1 ENUM(TelemetrySensorType); // 0=custom / 1=calculated
|
|
// user can choose what unit to display each value in
|
|
uint8_t spare1:1 SKIP;
|
|
uint8_t unit:6;
|
|
uint8_t prec:2;
|
|
uint8_t autoOffset:1;
|
|
uint8_t filter:1;
|
|
uint8_t logs:1;
|
|
uint8_t persistent:1;
|
|
uint8_t onlyPositive:1;
|
|
uint8_t spare2:1 SKIP;
|
|
union {
|
|
NOBACKUP(PACK(struct {
|
|
uint16_t ratio;
|
|
int16_t offset;
|
|
}) custom);
|
|
NOBACKUP(PACK(struct {
|
|
uint8_t source;
|
|
uint8_t index;
|
|
uint16_t spare SKIP;
|
|
}) cell);
|
|
NOBACKUP(PACK(struct {
|
|
int8_t sources[4];
|
|
}) calc);
|
|
NOBACKUP(PACK(struct {
|
|
uint8_t source;
|
|
uint8_t spare[3] SKIP;
|
|
}) consumption);
|
|
NOBACKUP(PACK(struct {
|
|
uint8_t gps;
|
|
uint8_t alt;
|
|
uint16_t spare SKIP;
|
|
}) dist);
|
|
uint32_t param;
|
|
} NAME(cfg) FUNC(select_sensor_cfg);
|
|
NOBACKUP(
|
|
void init(const char *label, uint8_t unit=UNIT_RAW, uint8_t prec=0);
|
|
void init(uint16_t id);
|
|
bool isAvailable() const;
|
|
int32_t getValue(int32_t value, uint8_t unit, uint8_t prec) const;
|
|
bool isConfigurable() const;
|
|
bool isPrecConfigurable() const;
|
|
int32_t getPrecMultiplier() const;
|
|
int32_t getPrecDivisor() const;
|
|
bool isSameInstance(TelemetryProtocol protocol, uint8_t instance);
|
|
);
|
|
});
|
|
|
|
/*
|
|
* Trainer module structure
|
|
*/
|
|
|
|
PACK(struct TrainerModuleData {
|
|
uint8_t mode CUST(r_trainerMode,w_trainerMode);
|
|
uint8_t channelsStart;
|
|
int8_t channelsCount; // 0=8 channels
|
|
int8_t frameLength;
|
|
int8_t delay:6;
|
|
uint8_t pulsePol:1;
|
|
uint8_t spare2:1 SKIP;
|
|
});
|
|
|
|
/*
|
|
* Module structure
|
|
*/
|
|
|
|
PACK(struct PpmModule {
|
|
int8_t delay:6;
|
|
uint8_t pulsePol:1;
|
|
uint8_t outputType:1; // false = open drain, true = push pull
|
|
int8_t frameLength;
|
|
});
|
|
|
|
PACK(struct ModuleData {
|
|
uint8_t type ENUM(ModuleType);
|
|
CUST_ATTR(subType,r_modSubtype,w_modSubtype);
|
|
uint8_t channelsStart;
|
|
int8_t channelsCount CUST(r_channelsCount,w_channelsCount); // 0=8 channels
|
|
uint8_t failsafeMode:4 ENUM(FailsafeModes); // only 3 bits used
|
|
uint8_t subType:4 SKIP;
|
|
|
|
union {
|
|
uint8_t raw[PXX2_MAX_RECEIVERS_PER_MODULE * PXX2_LEN_RX_NAME + 1];
|
|
NOBACKUP(PpmModule ppm);
|
|
NOBACKUP(struct {
|
|
uint8_t rfProtocol SKIP;
|
|
uint8_t disableTelemetry:1;
|
|
uint8_t disableMapping:1;
|
|
uint8_t autoBindMode:1;
|
|
uint8_t lowPowerMode:1;
|
|
uint8_t receiverTelemetryOff:1;
|
|
uint8_t receiverHigherChannels:1;
|
|
uint8_t spare:2 SKIP;
|
|
int8_t optionValue;
|
|
} multi);
|
|
NOBACKUP(struct {
|
|
uint8_t power:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
|
|
uint8_t spare1:2 SKIP;
|
|
uint8_t receiverTelemetryOff:1; // false = receiver telem enabled
|
|
uint8_t receiverHigherChannels:1; // false = pwm out 1-8, true 9-16
|
|
int8_t antennaMode:2;
|
|
uint8_t spare2 SKIP;
|
|
} pxx);
|
|
NOBACKUP(struct {
|
|
uint8_t spare1:6 SKIP;
|
|
uint8_t noninverted:1;
|
|
uint8_t spare2:1 SKIP;
|
|
int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)
|
|
} sbus);
|
|
NOBACKUP(struct {
|
|
uint8_t receivers:7; // 4 bits spare
|
|
uint8_t racingMode:1;
|
|
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME];
|
|
} pxx2);
|
|
NOBACKUP(struct {
|
|
uint8_t rx_id[4];
|
|
uint8_t mode:3;
|
|
uint8_t rfPower:1;
|
|
uint8_t reserved:4;
|
|
uint8_t rx_freq[2];
|
|
|
|
void setDefault() {
|
|
rx_id[0] = rx_id[1] = rx_id[2] = rx_id[3] = 0;
|
|
mode = 3;
|
|
rfPower = 0;
|
|
rx_freq[0] = 50;
|
|
rx_freq[1] = 0;
|
|
}
|
|
} flysky);
|
|
NOBACKUP(struct {
|
|
uint8_t emi:2;
|
|
uint8_t telemetry:1;
|
|
uint8_t phyMode:3;
|
|
uint8_t reserved:2;
|
|
uint8_t rfPower;
|
|
} afhds3);
|
|
NOBACKUP(struct {
|
|
uint8_t raw12bits:1;
|
|
uint8_t telemetryBaudrate:3;
|
|
uint8_t spare1:4 SKIP;
|
|
} ghost);
|
|
NOBACKUP(struct {
|
|
uint8_t telemetryBaudrate:3;
|
|
} crsf);
|
|
NOBACKUP(struct {
|
|
uint8_t flags;
|
|
} dsmp);
|
|
} NAME(mod) FUNC(select_mod_type);
|
|
|
|
NOBACKUP(inline uint8_t getChannelsCount() const
|
|
{
|
|
return channelsCount + 8;
|
|
})
|
|
});
|
|
|
|
/*
|
|
* Model structure
|
|
*/
|
|
|
|
#if LEN_BITMAP_NAME > 0
|
|
#define MODEL_HEADER_BITMAP_FIELD NOBACKUP(char bitmap[LEN_BITMAP_NAME]);
|
|
#else
|
|
#define MODEL_HEADER_BITMAP_FIELD
|
|
#endif
|
|
|
|
|
|
PACK(struct ModelHeader {
|
|
char name[LEN_MODEL_NAME]; // must be first for eeLoadModelName
|
|
uint8_t modelId[NUM_MODULES];
|
|
MODEL_HEADER_BITMAP_FIELD
|
|
#if defined(STORAGE_MODELSLIST)
|
|
char labels[LABELS_LENGTH];
|
|
#endif
|
|
});
|
|
|
|
// 2 bits per switch, max 32 switches
|
|
static_assert(sizeof(swconfig_t) >= (MAX_SWITCHES * 2 + 7) / 8,
|
|
"MAX_SWITCHES must fit swconfig_t");
|
|
|
|
static_assert(sizeof(swarnstate_t) >= (MAX_SWITCHES * 2 + 7) / 8,
|
|
"MAX_SWITCHES must fit swarnstate_t");
|
|
|
|
// pot config: 4 bits per pot
|
|
static_assert(sizeof(potconfig_t) * 8 >= ((MAX_POTS - 1) / 4) + 1,
|
|
"MAX_POTS must fit potconfig_t");
|
|
|
|
// pot warning enabled: 1 bit per pot
|
|
static_assert(sizeof(potwarnen_t) * 8 >= MAX_POTS,
|
|
"MAX_POTS must fit potwarnen_t");
|
|
|
|
#if defined(COLORLCD) && defined(BACKUP)
|
|
#define CUSTOM_SCREENS_DATA
|
|
#elif defined(COLORLCD)
|
|
#include "gui/colorlcd/layout.h"
|
|
#include "gui/colorlcd/topbar.h"
|
|
#define LAYOUT_ID_LEN 12
|
|
PACK(struct CustomScreenData {
|
|
char LayoutId[LAYOUT_ID_LEN];
|
|
LayoutPersistentData layoutData;
|
|
});
|
|
#define CUSTOM_SCREENS_DATA \
|
|
NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]); \
|
|
NOBACKUP(TopBarPersistentData topbarData); \
|
|
NOBACKUP(uint8_t view);
|
|
#else
|
|
#define CUSTOM_SCREENS_DATA \
|
|
uint8_t screensType SKIP; /* 2bits per screen (None/Gauges/Numbers/Script) */ \
|
|
TelemetryScreenData screens[MAX_TELEMETRY_SCREENS]; \
|
|
uint8_t view;
|
|
#endif
|
|
|
|
#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E)
|
|
// telemetry sensor idx + 1
|
|
#define TOPBAR_DATA \
|
|
NOBACKUP(uint8_t voltsSource CUST(r_tele_sensor,w_tele_sensor)); \
|
|
NOBACKUP(uint8_t altitudeSource CUST(r_tele_sensor,w_tele_sensor));
|
|
#else
|
|
#define TOPBAR_DATA
|
|
#endif
|
|
|
|
#if defined(PCBHORUS) || defined(PCBTARANIS) || defined(PCBNV14)
|
|
#define SCRIPT_DATA \
|
|
NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]);
|
|
#else
|
|
#define SCRIPT_DATA
|
|
#endif
|
|
|
|
#if defined(FUNCTION_SWITCHES)
|
|
#define FUNCTION_SWITCHS_FIELDS \
|
|
uint16_t functionSwitchConfig; \
|
|
uint16_t functionSwitchGroup; \
|
|
uint16_t functionSwitchStartConfig; \
|
|
uint8_t functionSwitchLogicalState; \
|
|
char switchNames[NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME];
|
|
#else
|
|
#define FUNCTION_SWITCHS_FIELDS
|
|
#endif
|
|
|
|
PACK(struct PartialModel {
|
|
ModelHeader header;
|
|
TimerData timers[MAX_TIMERS];
|
|
});
|
|
|
|
/*
|
|
* USB Joystick channel structure
|
|
*/
|
|
|
|
PACK(struct USBJoystickChData {
|
|
uint8_t mode:3 ENUM(USBJoystickCh);
|
|
uint8_t inversion:1;
|
|
uint8_t param:4;
|
|
uint8_t btn_num:5;
|
|
uint8_t switch_npos:3;
|
|
|
|
#if defined(USBJ_EX)
|
|
NOBACKUP(
|
|
uint8_t btnCount() {
|
|
// Use one less joystick button for 2POS and 3POS switches for Companion mode
|
|
if ((param == USBJOYS_BTN_MODE_COMPANION) && (switch_npos > 0) && (switch_npos < 3))
|
|
return switch_npos;
|
|
return switch_npos + 1;
|
|
}
|
|
uint8_t lastBtnNumNoCLip() {
|
|
uint8_t last = btn_num + switch_npos;
|
|
// Use one less joystick button for 2POS and 3POS switches for Companion mode
|
|
if ((param == USBJOYS_BTN_MODE_COMPANION) && (switch_npos > 0) && (switch_npos < 3)) last -= 1;
|
|
return last;
|
|
}
|
|
uint8_t lastBtnNum() {
|
|
uint8_t last = lastBtnNumNoCLip();
|
|
if (last >= USBJ_BUTTON_SIZE) {
|
|
last = USBJ_BUTTON_SIZE - 1;
|
|
}
|
|
return last;
|
|
}
|
|
);
|
|
#endif
|
|
});
|
|
|
|
PACK(struct ModelData {
|
|
CUST_ATTR(semver,nullptr,w_semver);
|
|
ModelHeader header;
|
|
TimerData timers[MAX_TIMERS];
|
|
uint8_t telemetryProtocol:3;
|
|
uint8_t thrTrim:1; // Enable Throttle Trim
|
|
uint8_t noGlobalFunctions:1;
|
|
uint8_t displayTrims:2;
|
|
uint8_t ignoreSensorIds:1;
|
|
int8_t trimInc:3; // Trim Increments
|
|
uint8_t disableThrottleWarning:1;
|
|
uint8_t displayChecklist:1;
|
|
uint8_t extendedLimits:1;
|
|
uint8_t extendedTrims:1;
|
|
uint8_t throttleReversed:1;
|
|
uint8_t enableCustomThrottleWarning:1;
|
|
uint8_t disableTelemetryWarning:1;
|
|
uint8_t showInstanceIds:1;
|
|
uint8_t spare3:5 SKIP;
|
|
int8_t customThrottleWarningPosition;
|
|
BeepANACenter beepANACenter;
|
|
MixData mixData[MAX_MIXERS] NO_IDX;
|
|
LimitData limitData[MAX_OUTPUT_CHANNELS];
|
|
ExpoData expoData[MAX_EXPOS] NO_IDX;
|
|
|
|
CurveHeader curves[MAX_CURVES];
|
|
int8_t points[MAX_CURVE_POINTS];
|
|
|
|
LogicalSwitchData logicalSw[MAX_LOGICAL_SWITCHES];
|
|
CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS] FUNC(cfn_is_active);
|
|
SwashRingData swashR FUNC(swash_is_active);
|
|
FlightModeData flightModeData[MAX_FLIGHT_MODES] FUNC(fmd_is_active);
|
|
|
|
NOBACKUP(uint8_t thrTraceSrc CUST(r_thrSrc,w_thrSrc));
|
|
CUST_ATTR(switchWarningState, r_swtchWarn, w_swtchWarn);
|
|
NOBACKUP(swarnstate_t switchWarningState SKIP);
|
|
|
|
GVarData gvars[MAX_GVARS];
|
|
|
|
NOBACKUP(VarioData varioData);
|
|
NOBACKUP(uint8_t rssiSource CUST(r_tele_sensor,w_tele_sensor));
|
|
|
|
TOPBAR_DATA
|
|
|
|
#if defined(YAML_GENERATOR)
|
|
RssiAlarmData rssiAlarms;
|
|
#endif
|
|
NOBACKUP(RFAlarmData rfAlarms);
|
|
|
|
uint8_t thrTrimSw:3;
|
|
uint8_t potsWarnMode:2 ENUM(PotsWarnMode);
|
|
NOBACKUP(uint8_t jitterFilter:2 ENUM(ModelOverridableEnable));
|
|
uint8_t spare1:1 SKIP;
|
|
|
|
ModuleData moduleData[NUM_MODULES];
|
|
int16_t failsafeChannels[MAX_OUTPUT_CHANNELS];
|
|
TrainerModuleData trainerData;
|
|
|
|
SCRIPT_DATA
|
|
|
|
NOBACKUP(char inputNames[MAX_INPUTS][LEN_INPUT_NAME]);
|
|
NOBACKUP(potwarnen_t potsWarnEnabled);
|
|
NOBACKUP(int8_t potsWarnPosition[MAX_POTS]);
|
|
|
|
NOBACKUP(TelemetrySensor telemetrySensors[MAX_TELEMETRY_SENSORS];)
|
|
|
|
TARANIS_PCBX9E_FIELD(uint8_t toplcdTimer)
|
|
|
|
CUSTOM_SCREENS_DATA
|
|
|
|
char modelRegistrationID[PXX2_LEN_REGISTRATION_ID];
|
|
|
|
FUNCTION_SWITCHS_FIELDS
|
|
|
|
uint8_t getThrottleStickTrimSource() const
|
|
{
|
|
// Makes Throttle the default (=0)
|
|
auto thr = inputMappingGetThrottle();
|
|
if (thrTrimSw == 0) {
|
|
return MIXSRC_FIRST_TRIM + thr;
|
|
} else if (thrTrimSw == thr) {
|
|
return MIXSRC_FIRST_TRIM;
|
|
} else {
|
|
return MIXSRC_FIRST_TRIM + thrTrimSw;
|
|
}
|
|
}
|
|
|
|
void setThrottleStickTrimSource(int16_t src)
|
|
{
|
|
auto thr = inputMappingGetThrottle();
|
|
if (src == MIXSRC_FIRST_TRIM + thr) {
|
|
thrTrimSw = 0;
|
|
} else if (src == MIXSRC_FIRST_TRIM) {
|
|
thrTrimSw = thr;
|
|
} else {
|
|
thrTrimSw = src - MIXSRC_FIRST_TRIM;
|
|
}
|
|
}
|
|
|
|
uint8_t usbJoystickExtMode:1;
|
|
uint8_t usbJoystickIfMode:3 ENUM(USBJoystickIfMode);
|
|
uint8_t usbJoystickCircularCut:4;
|
|
USBJoystickChData usbJoystickCh[USBJ_MAX_JOYSTICK_CHANNELS];
|
|
|
|
// Radio level tabs control (model settings)
|
|
#if defined(COLORLCD)
|
|
uint8_t radioThemesDisabled:2 ENUM(ModelOverridableEnable);
|
|
#endif
|
|
uint8_t radioGFDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t radioTrainerDisabled:2 ENUM(ModelOverridableEnable);
|
|
// Model level tabs control (model setting)
|
|
uint8_t modelHeliDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelFMDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelCurvesDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelGVDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelLSDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelSFDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelCustomScriptsDisabled:2 ENUM(ModelOverridableEnable);
|
|
uint8_t modelTelemetryDisabled:2 ENUM(ModelOverridableEnable);
|
|
});
|
|
|
|
/*
|
|
* Radio structure
|
|
*/
|
|
|
|
#if XPOTS_MULTIPOS_COUNT > 0
|
|
PACK(struct StepsCalibData {
|
|
uint8_t count;
|
|
uint8_t steps[XPOTS_MULTIPOS_COUNT-1];
|
|
});
|
|
#endif
|
|
|
|
PACK(struct CalibData {
|
|
CUST_IDX(calib, r_calib, w_calib);
|
|
int16_t mid;
|
|
int16_t spanNeg;
|
|
int16_t spanPos;
|
|
});
|
|
|
|
PACK(struct TrainerMix {
|
|
uint8_t srcChn:6; // 0-7 = ch1-8
|
|
uint8_t mode:2 ENUM(TrainerMultiplex); // off,add-mode,subst-mode
|
|
int8_t studWeight;
|
|
});
|
|
|
|
PACK(struct TrainerData {
|
|
int16_t calib[4];
|
|
NOBACKUP(TrainerMix mix[4]);
|
|
});
|
|
|
|
#if defined(COLORLCD)
|
|
#define SPLASH_MODE uint8_t splashSpares:3 SKIP
|
|
#else
|
|
#define SPLASH_MODE int8_t splashMode:3
|
|
#endif
|
|
|
|
#if defined(COLORLCD)
|
|
#define EXTRA_GENERAL_FIELDS \
|
|
NOBACKUP(char currModelFilename[LEN_MODEL_FILENAME+1]); \
|
|
NOBACKUP(uint8_t modelQuickSelect:1); \
|
|
NOBACKUP(uint8_t blOffBright:7); \
|
|
NOBACKUP(char bluetoothName[LEN_BLUETOOTH_NAME]);
|
|
#else
|
|
#if defined(STORAGE_BLUETOOTH)
|
|
#define BLUETOOTH_FIELDS \
|
|
uint8_t spare6 SKIP; \
|
|
char bluetoothName[LEN_BLUETOOTH_NAME];
|
|
#else
|
|
#define BLUETOOTH_FIELDS
|
|
#endif
|
|
#define EXTRA_GENERAL_FIELDS \
|
|
uint8_t backlightColor; \
|
|
BLUETOOTH_FIELDS
|
|
#endif
|
|
|
|
#if defined(COLORLCD) && !defined(BACKUP)
|
|
#include "theme.h"
|
|
#define THEME_NAME_LEN 8
|
|
#define THEME_DATA \
|
|
NOBACKUP(char themeName[THEME_NAME_LEN]); \
|
|
NOBACKUP(OpenTxTheme::PersistentData themeData);
|
|
#else
|
|
#define THEME_DATA
|
|
#endif
|
|
|
|
#if defined(BUZZER)
|
|
#define BUZZER_FIELD int8_t buzzerMode:2 // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware)
|
|
#else
|
|
#define BUZZER_FIELD int8_t spare2:2 SKIP
|
|
#endif
|
|
|
|
PACK(struct RadioData {
|
|
|
|
// Real attributes
|
|
NOBACKUP(uint8_t manuallyEdited:1);
|
|
NOBACKUP(int8_t spare0:7 SKIP);
|
|
CUST_ATTR(semver,nullptr,w_semver);
|
|
CUST_ATTR(board,nullptr,w_board);
|
|
CalibData calib[MAX_CALIB_ANALOG_INPUTS] NO_IDX;
|
|
NOBACKUP(uint16_t chkSum SKIP);
|
|
N_HORUS_FIELD(int8_t currModel);
|
|
N_HORUS_FIELD(uint8_t contrast);
|
|
NOBACKUP(uint8_t vBatWarn);
|
|
NOBACKUP(int8_t txVoltageCalibration);
|
|
uint8_t backlightMode:3 ENUM(BacklightMode);
|
|
int8_t antennaMode:2 ENUM(AntennaModes);
|
|
uint8_t disableRtcWarning:1;
|
|
uint8_t keysBacklight:1;
|
|
uint8_t spare1:1 SKIP;
|
|
uint8_t internalModule ENUM(ModuleType);
|
|
NOBACKUP(TrainerData trainer);
|
|
NOBACKUP(uint8_t view); // index of view in main screen
|
|
NOBACKUP(BUZZER_FIELD); /* 2bits */
|
|
NOBACKUP(uint8_t fai:1);
|
|
NOBACKUP(int8_t beepMode:2 ENUM(BeeperMode) CUST(r_beeperMode,w_beeperMode));
|
|
NOBACKUP(uint8_t alarmsFlash:1);
|
|
NOBACKUP(uint8_t disableMemoryWarning:1);
|
|
NOBACKUP(uint8_t disableAlarmWarning:1);
|
|
uint8_t stickMode:2;
|
|
int8_t timezone:5;
|
|
uint8_t adjustRTC:1;
|
|
NOBACKUP(uint8_t inactivityTimer);
|
|
CUST_ATTR(telemetryBaudrate, r_telemetryBaudrate, nullptr);
|
|
uint8_t internalModuleBaudrate:3;
|
|
SPLASH_MODE; /* 3bits */
|
|
int8_t hapticMode:2 CUST(r_beeperMode,w_beeperMode);
|
|
int8_t switchesDelay;
|
|
NOBACKUP(uint8_t lightAutoOff);
|
|
NOBACKUP(uint8_t templateSetup); // RETA order for receiver channels
|
|
NOBACKUP(int8_t PPM_Multiplier);
|
|
NOBACKUP(int8_t hapticLength CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t beepLength:3 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t hapticStrength:3 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(uint8_t gpsFormat:1);
|
|
NOBACKUP(uint8_t unexpectedShutdown:1 SKIP);
|
|
NOBACKUP(uint8_t speakerPitch CUST(r_spPitch,w_spPitch));
|
|
NOBACKUP(int8_t speakerVolume CUST(r_vol,w_vol));
|
|
NOBACKUP(int8_t vBatMin CUST(r_vbat_min,w_vbat_min));
|
|
NOBACKUP(int8_t vBatMax CUST(r_vbat_max,w_vbat_max));
|
|
|
|
NOBACKUP(uint8_t backlightBright);
|
|
NOBACKUP(uint32_t globalTimer);
|
|
NOBACKUP(uint8_t bluetoothBaudrate:4);
|
|
NOBACKUP(uint8_t bluetoothMode:4 ENUM(BluetoothModes));
|
|
|
|
NOBACKUP(uint8_t countryCode:2);
|
|
NOBACKUP(int8_t pwrOnSpeed:3);
|
|
NOBACKUP(int8_t pwrOffSpeed:3);
|
|
|
|
CUST_ATTR(jitterFilter, r_jitterFilter, nullptr);
|
|
NOBACKUP(uint8_t noJitterFilter:1); /* 0 - Jitter filter active */
|
|
NOBACKUP(uint8_t imperial:1);
|
|
NOBACKUP(uint8_t disableRssiPoweroffAlarm:1);
|
|
NOBACKUP(uint8_t USBMode:2);
|
|
NOBACKUP(uint8_t jackMode:2);
|
|
NOBACKUP(uint8_t sportUpdatePower:1 SKIP);
|
|
|
|
NOBACKUP(char ttsLanguage[2]);
|
|
NOBACKUP(int8_t beepVolume:4 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t wavVolume:4 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t varioVolume:4 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t backgroundVolume:4 CUST(r_5pos,w_5pos));
|
|
NOBACKUP(int8_t varioPitch CUST(r_vPitch,w_vPitch));
|
|
NOBACKUP(int8_t varioRange CUST(r_vPitch,w_vPitch));
|
|
NOBACKUP(int8_t varioRepeat);
|
|
CustomFunctionData customFn[MAX_SPECIAL_FUNCTIONS] FUNC(cfn_is_active);
|
|
|
|
CUST_ATTR(auxSerialMode, r_serialMode, nullptr);
|
|
CUST_ATTR(aux2SerialMode, r_serialMode, nullptr);
|
|
NOBACKUP(uint32_t serialPort ARRAY(SERIAL_CONF_BITS_PER_PORT,struct_serialConfig,nullptr));
|
|
|
|
CUST_ARRAY(sticksConfig, struct_stickConfig, MAX_STICKS, stick_name_valid);
|
|
CUST_ARRAY(slidersConfig, struct_sliderConfig, MAX_POTS, nullptr);
|
|
potconfig_t potsConfig ARRAY(4,struct_potConfig,nullptr);
|
|
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr);
|
|
|
|
EXTRA_GENERAL_FIELDS
|
|
|
|
THEME_DATA
|
|
|
|
char ownerRegistrationID[PXX2_LEN_REGISTRATION_ID];
|
|
|
|
CUST_ATTR(rotEncDirection, r_rotEncDirection, nullptr);
|
|
NOBACKUP(uint8_t rotEncMode:2);
|
|
|
|
NOBACKUP(int8_t uartSampleMode:2); // See UartSampleModes
|
|
|
|
#if defined(STICK_DEAD_ZONE)
|
|
NOBACKUP(uint8_t stickDeadZone:3);
|
|
#else
|
|
NOBACKUP(uint8_t stickDeadZoneSpare:3 SKIP);
|
|
#endif
|
|
NOBACKUP(uint8_t spare4:1 SKIP);
|
|
|
|
#if defined(IMU)
|
|
NOBACKUP(int8_t imuMax);
|
|
NOBACKUP(int8_t imuOffset);
|
|
#endif
|
|
|
|
#if defined(COLORLCD)
|
|
NOBACKUP(char selectedTheme[SELECTED_THEME_NAME_LEN]);
|
|
#endif
|
|
|
|
// Radio level tabs control (global settings)
|
|
#if defined(COLORLCD)
|
|
uint8_t radioThemesDisabled:1;
|
|
#endif
|
|
uint8_t radioGFDisabled:1;
|
|
uint8_t radioTrainerDisabled:1;
|
|
// Model level tabs control (global setting)
|
|
uint8_t modelHeliDisabled:1;
|
|
uint8_t modelFMDisabled:1;
|
|
uint8_t modelCurvesDisabled:1;
|
|
uint8_t modelGVDisabled:1;
|
|
uint8_t modelLSDisabled:1;
|
|
uint8_t modelSFDisabled:1;
|
|
uint8_t modelCustomScriptsDisabled:1;
|
|
uint8_t modelTelemetryDisabled:1;
|
|
});
|
|
|
|
#undef SWITCHES_WARNING_DATA
|
|
#undef MODEL_GVARS_DATA
|
|
#undef TELEMETRY_DATA
|
|
#undef SCRIPTS_DATA
|
|
#undef CUSTOM_SCREENS_DATA
|
|
#undef SPLASH_MODE
|
|
#undef EXTRA_GENERAL_FIELDS
|
|
#undef THEME_DATA
|
|
#undef NOBACKUP
|