Files
edgetx-gx12/radio/src/datastructs_private.h
T
philmozandGitHub 5327c890f2 feat: Add options to disable radio and model menu tabs (#3484)
* Add options to disable radio and model menu tabs.
- Update radio and model data structs
- UI for color LCD radios
- Convert existing 'noGlobalFunctions' property.
- Language strings.

* Make 'theme' control specific to color LCD radios.

* Add B&W radio UI.

* Simplify code, reduce compiled code size.
Fix page count display on model select tab.
Fix GVARS for 212x64 radios.

* Collapse timer sections if timer is off.

* Remove 'Use global functions' checkbox from B&W model setup.

* Make preflight checks, throttle and view options sections expand & collapse (default collapsed).

* Fix build.

* Add view options to companion data classes, save and load values in YAML files.
Fix scrolling for radio setup view options.

* Add Companion UI for view option settings.

* Remove 'Mixes' from list of tabs that can be hidden.

* Updated Companion UI from elecpower.

* Use view options flags to enable/disable functionality:
- skip heli mixer logic if heli not enabled
- Remove heli, gvars and telemetry options from source selection if not enabled

* Remove 'flight mode', 'curve' and 'global variable' settings from input & mix editors if option disabled.

* Rename 'View Options' to 'Enabled Features'.
Put GVAR option under Flight Mode and indent text.
Make relationship between FM and GV more obvious.

* Remove global variable option dependency on flight modes.
Hide FM1-FM8 in global variables if flight modes hidden.

* Hide 'Custom Mixer Scripts' in source selection menu popup if disabled.

* Add translation strings for Hebrew language file.

* Fix typo. Add comment for double call to setCurrentTab.
2023-05-22 20:08:16 +10:00

1001 lines
27 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"
#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:14 CUST(in_read_weight,in_write_weight);
int32_t swtch:9 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:9 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);
int32_t spare:1 SKIP;
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:9 CUST(r_swtchSrc,w_swtchSrc); // TODO rename to xswtch
uint32_t andswtype:1 SKIP; // TODO rename to xswtchType (AND / OR)
uint32_t spare:2 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:9 CUST(r_swtchSrc,w_swtchSrc);
uint16_t func:7 ENUM(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[NUM_TRIMS];
NOBACKUP(char name[LEN_FLIGHT_MODE_NAME]);
int16_t swtch:9 ENUM(SwitchSources) CUST(r_swtchSrc,w_swtchSrc); // swtch of phase[0] is not used
int16_t spare:7 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;
} 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
});
#if defined(COLORLCD)
typedef uint32_t swconfig_t;
typedef uint32_t swarnstate_t;
#elif defined(PCBX9E)
typedef uint64_t swconfig_t;
typedef uint64_t swarnstate_t;
#elif defined(PCBX9D) || defined(PCBX9DP)
typedef uint32_t swconfig_t;
typedef uint32_t swarnstate_t;
#else
typedef uint16_t swconfig_t;
typedef uint32_t swarnstate_t;
#endif
#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) && NUM_FUNCTIONS_SWITCHES < 8
#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(uint16_t potsWarnEnabled);
NOBACKUP(int8_t potsWarnPosition[STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS]);
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
{
// The order here is TERA, so that 0 (default) means Throttle
switch (thrTrimSw) {
case 0:
return MIXSRC_TrimThr;
case 2:
return MIXSRC_TrimRud;
default:
return thrTrimSw + MIXSRC_FIRST_TRIM;
}
}
void setThrottleStickTrimSource(int16_t src)
{
// The order here is TERA, so that 0 (default) means Throttle
switch (src) {
case MIXSRC_TrimThr:
thrTrimSw = 0;
break;
case MIXSRC_TrimRud:
thrTrimSw = 2;
break;
default:
thrTrimSw = src - MIXSRC_FIRST_TRIM;
break;
}
}
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 \
CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \
uint16_t potsConfig ARRAY(2,struct_potConfig,nullptr); /* two bits per pot */ \
uint8_t slidersConfig ARRAY(1,struct_sliderConfig,nullptr); /* 1 bit per slider */ \
NOBACKUP(char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME] SKIP); \
NOBACKUP(char anaNames[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP); \
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 slidersConfig:4 ARRAY(1,struct_sliderConfig,nullptr); \
uint8_t spare5:4 SKIP; \
uint8_t potsConfig ARRAY(2,struct_potConfig,nullptr); /* two bits per pot */\
uint8_t backlightColor; \
CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \
char switchNames[STORAGE_NUM_SWITCHES - NUM_FUNCTIONS_SWITCHES][LEN_SWITCH_NAME] SKIP; \
char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME] SKIP; \
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[NUM_STICKS + STORAGE_NUM_POTS + STORAGE_NUM_SLIDERS + STORAGE_NUM_MOUSE_ANALOGS] 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;
NOBACKUP(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));
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