Merge pull request #1040 from EdgeTX/sw-warnings

This commit is contained in:
Raphael Coeffic
2021-12-17 13:05:13 +01:00
committed by GitHub
49 changed files with 400 additions and 488 deletions
+10 -10
View File
@@ -116,20 +116,20 @@ static inline void check_struct()
CHKSIZE(TrainerData, 16);
#if defined(PCBXLITES)
CHKSIZE(RadioData, 862);
CHKSIZE(ModelData, 6158);
#elif defined(PCBXLITE)
CHKSIZE(RadioData, 860);
CHKSIZE(ModelData, 6158);
CHKSIZE(ModelData, 6159);
#elif defined(PCBXLITE)
CHKSIZE(RadioData, 858);
CHKSIZE(ModelData, 6159);
#elif defined(PCBX7)
CHKSIZE(RadioData, 866);
CHKSIZE(ModelData, 6158);
CHKSIZE(RadioData, 864);
CHKSIZE(ModelData, 6159);
#elif defined(PCBX9E)
CHKSIZE(RadioData, 962);
CHKSIZE(ModelData, 6615);
CHKSIZE(RadioData, 954);
CHKSIZE(ModelData, 6611);
#elif defined(PCBX9D) || defined(PCBX9DP)
CHKSIZE(RadioData, 900);
CHKSIZE(ModelData, 6605);
CHKSIZE(RadioData, 896);
CHKSIZE(ModelData, 6603);
#elif defined(PCBHORUS)
#if defined(PCBX10)
CHKSIZE(RadioData, 921);
+4 -20
View File
@@ -571,27 +571,12 @@ typedef uint32_t swarnstate_t;
#elif defined(PCBX9E)
typedef uint64_t swconfig_t;
typedef uint64_t swarnstate_t;
typedef uint32_t swarnenable_t;
#elif defined(PCBX9D) || defined(PCBX9DP)
typedef uint32_t swconfig_t;
typedef uint32_t swarnstate_t;
typedef uint16_t swarnenable_t; // TODO remove it in 2.4
#elif defined(PCBTARANIS)
#else
typedef uint16_t swconfig_t;
typedef uint16_t swarnstate_t;
typedef uint8_t swarnenable_t; // TODO remove it in 2.4
#else
typedef uint8_t swarnstate_t;
typedef uint8_t swarnenable_t;
#endif
#if defined(COLORLCD)
#define SWITCHES_WARNING_DATA \
NOBACKUP(swarnstate_t switchWarningState CUST(r_swtchWarn,w_swtchWarn));
#else
#define SWITCHES_WARNING_DATA \
swarnstate_t switchWarningState CUST(r_swtchWarn,w_swtchWarn); \
swarnenable_t switchWarningEnable; // TODO remove it in 2.4
typedef uint32_t swarnstate_t;
#endif
#if defined(COLORLCD) && defined(BACKUP)
@@ -664,8 +649,8 @@ PACK(struct ModelData {
FlightModeData flightModeData[MAX_FLIGHT_MODES] FUNC(fmd_is_active);
NOBACKUP(uint8_t thrTraceSrc CUST(r_thrSrc,w_thrSrc));
SWITCHES_WARNING_DATA
CUST_ATTR(switchWarningState, r_swtchWarn, w_swtchWarn);
NOBACKUP(swarnstate_t switchWarningState SKIP);
GVarData gvars[MAX_GVARS];
@@ -807,7 +792,6 @@ PACK(struct TrainerData {
uint8_t slidersConfig:4 ARRAY(1,struct_sliderConfig,nullptr); \
uint8_t potsConfig ARRAY(2,struct_potConfig,nullptr); /* two bits per pot */\
uint8_t backlightColor; \
swarnstate_t switchUnlockStates; \
CUST_ARRAY(sticksConfig, struct_sticksConfig, stick_name_valid); \
swconfig_t switchConfig ARRAY(2,struct_switchConfig,nullptr); \
char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME] SKIP; \
+29 -68
View File
@@ -657,7 +657,6 @@ void menuModelSetup(event_t event)
g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLE_WARNING, attr, event);
break;
#if defined(PCBTARANIS)
case ITEM_MODEL_SETUP_SWITCHES_WARNING2:
if (i==0) {
if (CURSOR_MOVED_LEFT(event))
@@ -666,10 +665,8 @@ void menuModelSetup(event_t event)
menuVerticalOffset++;
}
break;
#endif
case ITEM_MODEL_SETUP_SWITCHES_WARNING1:
#if defined(PCBTARANIS)
{
#define FIRSTSW_STR STR_VSRCRAW+(MIXSRC_FIRST_SWITCH-MIXSRC_Rud+1)*length
uint8_t switchWarningsCount = getSwitchWarningsCount();
@@ -705,10 +702,18 @@ void menuModelSetup(event_t event)
break;
case EVT_KEY_LONG(KEY_ENTER):
if (menuHorizontalPosition < 0 || menuHorizontalPosition >= switchWarningsCount) {
if (menuHorizontalPosition < 0 ||
menuHorizontalPosition >= switchWarningsCount) {
START_NO_HIGHLIGHT();
getMovedSwitch();
g_model.switchWarningState = switches_states;
// Mask switches enabled for warnings
swarnstate_t sw_mask = 0;
for(uint8_t i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i))
if (g_model.switchWarningState & (0x07 << (3 * i)))
sw_mask |= (0x07 << (3 * i));
}
g_model.switchWarningState = switches_states & sw_mask;
AUDIO_WARNING1();
storageDirty(EE_MODEL);
}
@@ -722,80 +727,37 @@ void menuModelSetup(event_t event)
for (int i = 0; i < NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
div_t qr = div(current, MAX_SWITCH_PER_LINE);
if (!READ_ONLY() && event==EVT_KEY_BREAK(KEY_ENTER) && attr && l_posHorz == current && old_posHorz >= 0) {
g_model.switchWarningEnable ^= (1 << i);
if (!READ_ONLY() && event == EVT_KEY_BREAK(KEY_ENTER) && attr &&
l_posHorz == current && old_posHorz >= 0) {
uint8_t curr_state = (states & 0x07);
// remove old setting
g_model.switchWarningState &= ~(0x07 << (3 * i));
// add the new one (if switch UP and 2POS, jump directly to DOWN)
curr_state += (curr_state != 1 || IS_CONFIG_3POS(i) ? 1 : 2);
g_model.switchWarningState |= (curr_state & 0x03) << (3 * i);
storageDirty(EE_MODEL);
#if defined(PCBXLITE)
s_editMode = 0;
#endif
}
uint8_t swactive = !(g_model.switchWarningEnable & (1<<i));
c = (STR_CHAR_UP "-" STR_CHAR_DOWN)[states & 0x03];
// lcdDrawChar(MODEL_SETUP_2ND_COLUMN+qr.rem*(2*FW+1), y+FH*qr.quot, 'A'+i, attr && (menuHorizontalPosition==current) ? INVERS : 0);
lcdDrawSizedText(MODEL_SETUP_2ND_COLUMN + qr.rem*((2*FW)+1), y+FH*qr.quot, FIRSTSW_STR+(i*length)+3, 1, attr && (menuHorizontalPosition==current) ? INVERS : 0);
if (swactive) lcdDrawChar(lcdNextPos, y+FH*qr.quot, c);
c = (" " STR_CHAR_UP "-" STR_CHAR_DOWN)[states & 0x03];
lcdDrawSizedText(
MODEL_SETUP_2ND_COLUMN + qr.rem * ((2 * FW) + 1),
y + FH * qr.quot, FIRSTSW_STR + (i * length) + 3, 1,
attr && (menuHorizontalPosition == current) ? INVERS : 0);
lcdDrawChar(lcdNextPos, y + FH * qr.quot, c);
++current;
}
states >>= 2;
states >>= 3;
}
if (attr && ((menuHorizontalPosition < 0) || menuHorizontalPosition >= switchWarningsCount)) {
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), 1+FH*((current+4)/5));
if (attr && ((menuHorizontalPosition < 0) ||
menuHorizontalPosition >= switchWarningsCount)) {
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN - 1, y - 1,
8 * (2 * FW + 1), 1 + FH * ((current + 4) / 5));
}
#else // PCBTARANIS
{
lcdDrawTextAlignedLeft(y, STR_SWITCHWARNING);
swarnstate_t states = g_model.switchWarningState;
char c;
if (attr) {
s_editMode = 0;
if (!READ_ONLY()) {
switch (event) {
case EVT_KEY_BREAK(KEY_ENTER):
if (menuHorizontalPosition < NUM_SWITCHES-1) {
g_model.switchWarningEnable ^= (1 << menuHorizontalPosition);
storageDirty(EE_MODEL);
}
break;
case EVT_KEY_LONG(KEY_ENTER):
if (menuHorizontalPosition == NUM_SWITCHES-1) {
START_NO_HIGHLIGHT();
getMovedSwitch();
g_model.switchWarningState = switches_states;
AUDIO_WARNING1();
storageDirty(EE_MODEL);
}
killEvents(event);
break;
}
}
}
for (uint8_t i = 0; i < NUM_SWITCHES-1/*not on TRN switch*/; i++) {
uint8_t swactive = !(g_model.switchWarningEnable & (1u << i));
uint8_t swattr = 0;
if (IS_3POS(i)) {
c = '0' + (states & 0x03);
states >>= 2u;
}
else {
if ((states & 0x01) && swactive)
swattr = INVERS;
c = *(STR_VSWITCHES - 2 + 9 + (3*(i+1)));
states >>= 1u;
}
if (attr && (menuHorizontalPosition == i)) {
swattr = BLINK | INVERS;
}
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+i*FW, y, swactive ? c : '-', swattr);
lcdDrawText(MODEL_SETUP_2ND_COLUMN+(NUM_SWITCHES*FW), y, "<]", (menuHorizontalPosition == NUM_SWITCHES-1 && !NO_HIGHLIGHT()) ? attr : 0);
}
#endif
break;
}
#if defined(PCBTARANIS)
case ITEM_MODEL_SETUP_POTS_WARNING:
lcdDrawTextAlignedLeft(y, STR_POTWARNING);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, "\004""OFF\0""Man\0""Auto", g_model.potsWarnMode, (menuHorizontalPosition == 0) ? attr : 0);
@@ -842,7 +804,6 @@ void menuModelSetup(event_t event)
}
}
break;
#endif
case ITEM_MODEL_SETUP_BEEP_CENTER:
lcdDrawTextAlignedLeft(y, STR_BEEPCTR);
-10
View File
@@ -33,16 +33,6 @@ void drawSplash()
{
lcdClear();
lcdDraw1bitBitmap(0, 0, splash_lbm, 0, 0);
#if MENUS_LOCK == 1
if (readonly == false) {
lcdDrawFilledRect((LCD_W - (sizeof(TR_UNLOCKED) - 1) * FW) / 2 - 9, 50,
(sizeof(TR_UNLOCKED) - 1) * FW + 16, 11, SOLID,
ERASE | ROUND);
lcdDrawText((LCD_W - (sizeof(TR_UNLOCKED) - 1) * FW) / 2, 53, STR_UNLOCKED);
}
#endif
lcdRefresh();
}
#endif
+1 -2
View File
@@ -461,7 +461,6 @@ void menuMainView(event_t event)
POPUP_MENU_START(onMainViewMenu);
break;
#if MENUS_LOCK != 2 /*no menus*/
#if defined(EVT_KEY_LAST_MENU)
case EVT_KEY_LAST_MENU:
pushMenu(lastPopMenu());
@@ -478,7 +477,7 @@ void menuMainView(event_t event)
pushMenu(menuTabGeneral[0]);
killEvents(event);
break;
#endif
#if defined(HARDWARE_NO_TRIMS)
case EVT_KEY_FIRST(KEY_ENTER):
if (!trimSelection.preEnterValid) {
+23 -8
View File
@@ -679,7 +679,14 @@ void menuModelSetup(event_t event)
if (menuHorizontalPosition < 0) {
START_NO_HIGHLIGHT();
getMovedSwitch();
g_model.switchWarningState = switches_states;
// Mask switches enabled for warnings
swarnstate_t sw_mask = 0;
for(uint8_t i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i))
if (g_model.switchWarningState & (0x07 << (3 * i)))
sw_mask |= (0x07 << (3 * i));
}
g_model.switchWarningState = switches_states & sw_mask;
AUDIO_WARNING1();
storageDirty(EE_MODEL);
}
@@ -695,17 +702,25 @@ void menuModelSetup(event_t event)
for (int i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
div_t qr = div(current, 8);
if (!READ_ONLY() && event==EVT_KEY_BREAK(KEY_ENTER) && line && l_posHorz==current) {
g_model.switchWarningEnable ^= (1 << i);
if (!READ_ONLY() && event == EVT_KEY_BREAK(KEY_ENTER) && line &&
l_posHorz == current) {
uint8_t curr_state = (states & 0x07);
// remove old setting
g_model.switchWarningState &= ~(0x07 << (3 * i));
// add the new one (if switch UP and 2POS, jump directly to DOWN)
curr_state += (curr_state != 1 || IS_CONFIG_3POS(i) ? 1 : 2);
g_model.switchWarningState |= (curr_state & 0x03) << (3 * i);
storageDirty(EE_MODEL);
}
uint8_t swactive = !(g_model.switchWarningEnable & (1<<i));
c = (STR_CHAR_UP "-" STR_CHAR_DOWN)[states & 0x03];
lcdDrawChar(MODEL_SETUP_2ND_COLUMN+qr.rem*(2*FW+1), y+FH*qr.quot, 'A'+i, line && (menuHorizontalPosition==current) ? INVERS : 0);
if (swactive) lcdDrawChar(lcdNextPos, y+FH*qr.quot, c);
c = (" " STR_CHAR_UP "-" STR_CHAR_DOWN)[states & 0x03];
lcdDrawChar(
MODEL_SETUP_2ND_COLUMN + qr.rem * (2 * FW + 1),
y + FH * qr.quot, 'A' + i,
line && (menuHorizontalPosition == current) ? INVERS : 0);
lcdDrawChar(lcdNextPos, y + FH * qr.quot, c);
++current;
}
states >>= 2;
states >>= 3;
}
if (attr && menuHorizontalPosition < 0) {
#if defined(PCBX9E)
-10
View File
@@ -37,16 +37,6 @@ void drawSplash()
{
lcdClear();
lcdDrawRleBitmap(0, 0, splash_lbm);
#if MENUS_LOCK == 1
if (readonly == false) {
lcdDrawFilledRect((LCD_W - (sizeof(TR_UNLOCKED) - 1) * FW) / 2 - 9, 50,
(sizeof(TR_UNLOCKED) - 1) * FW + 16, 11, SOLID,
ERASE | ROUND);
lcdDrawText((LCD_W - (sizeof(TR_UNLOCKED) - 1) * FW) / 2, 53, STR_UNLOCKED);
}
#endif
lcdRefresh();
}
#endif
-2
View File
@@ -449,7 +449,6 @@ void menuMainView(event_t event)
POPUP_MENU_START(onMainViewMenu);
break;
#if MENUS_LOCK != 2/*no menus*/
case EVT_KEY_BREAK(KEY_MENU):
pushMenu(menuModelSelect);
break;
@@ -458,7 +457,6 @@ void menuMainView(event_t event)
pushMenu(menuTabGeneral[0]);
killEvents(event);
break;
#endif
case EVT_KEY_BREAK(KEY_PAGE):
storageDirty(EE_MODEL);
+17 -38
View File
@@ -20,37 +20,11 @@
*/
#include "switch_warn_dialog.h"
#include "switches.h"
bool SwitchWarnDialog::warningInactive()
{
GET_ADC_IF_MIXER_NOT_RUNNING();
getMovedSwitch();
bool warn = false;
for (int i = 0; i < NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
unsigned int state = ((states >> (3 * i)) & 0x07);
if (state && state - 1 != ((switches_states >> (i * 2)) & 0x03)) {
warn = true;
}
}
}
if (g_model.potsWarnMode) {
evalFlightModeMixes(e_perout_mode_normal, 0);
bad_pots = 0;
for (int i = 0; i < NUM_POTS + NUM_SLIDERS; i++) {
if (!IS_POT_SLIDER_AVAILABLE(POT1 + i)) {
continue;
}
if ( (g_model.potsWarnEnabled & (1 << i)) && (abs(g_model.potsWarnPosition[i] - GET_LOWRES_POT_POSITION(i)) > 1)) {
warn = true;
bad_pots |= (1 << i);
}
}
}
if (!warn)
if (!isSwitchWarningRequired(bad_pots))
return true;
if (last_bad_switches != switches_states || last_bad_pots != bad_pots) {
@@ -74,19 +48,24 @@ void SwitchWarnDialog::paint(BitmapBuffer * dc)
FullScreenDialog::paint(dc);
coord_t x = ALERT_MESSAGE_LEFT;
coord_t y = ALERT_MESSAGE_TOP; // ALERT_FRAME_TOP + ALERT_FRAME_PADDING + ALERT_TITLE_LINE_HEIGHT * 3;
coord_t y = ALERT_MESSAGE_TOP;
swarnstate_t states = g_model.switchWarningState;
for (int i = 0; i < NUM_SWITCHES; ++i) {
if (SWITCH_WARNING_ALLOWED(i)) {
unsigned int state = ((g_model.switchWarningState >> (3 * i)) & 0x07);
if (state && state - 1 != ((switches_states >> (i * 2)) & 0x03)) {
if (y < LCD_H) {
x = drawSwitch(dc, x, y, SWSRC_FIRST_SWITCH + i * 3 + state - 1, COLOR_THEME_PRIMARY1 | FONT(BOLD));
x += 5;
}
else {
dc->drawText(x, y, "...", COLOR_THEME_PRIMARY1 | FONT(BOLD));
break;
swarnstate_t mask = ((swarnstate_t)0x07 << (i*3));
if (states & mask) {
if ((switches_states & mask) != (states & mask)) {
swarnstate_t state = (states >> (i*3)) & 0x07;
if (x < LCD_W) {
x = drawSwitch(dc, x, y, SWSRC_FIRST_SWITCH + i * 3 + state - 1,
COLOR_THEME_PRIMARY1 | FONT(BOLD));
x += 5;
}
else {
dc->drawText(x, y, "...", COLOR_THEME_PRIMARY1 | FONT(BOLD));
break;
}
}
}
}
+2 -4
View File
@@ -33,7 +33,6 @@ class SwitchWarnDialog: public FullScreenDialog {
FullScreenDialog(WARNING_TYPE_ALERT, STR_SWITCHWARN)
{
last_bad_switches = 0xff;
states = g_model.switchWarningState;
bad_pots = 0;
last_bad_pots = 0xff;
setCloseCondition(std::bind(&SwitchWarnDialog::warningInactive, this));
@@ -50,9 +49,8 @@ class SwitchWarnDialog: public FullScreenDialog {
protected:
swarnstate_t last_bad_switches;
swarnstate_t states;
uint8_t bad_pots;
uint8_t last_bad_pots;
uint8_t bad_pots;
uint8_t last_bad_pots;
bool warningInactive();
};
+1 -24
View File
@@ -579,20 +579,6 @@ void resetBacklightTimeout()
lightOffCounter = ((uint16_t)g_eeGeneral.lightAutoOff*250) << 1;
}
#if MENUS_LOCK == 1
bool readonly = true;
bool readonlyUnlocked()
{
if (readonly) {
POPUP_WARNING(STR_MODS_FORBIDDEN);
return false;
}
else {
return true;
}
}
#endif
#if defined(SPLASH)
void doSplash()
{
@@ -1750,9 +1736,7 @@ void opentxInit()
#elif defined(GUI)
// TODO add a function for this (duplicated)
menuHandlers[0] = menuMainView;
#if MENUS_LOCK != 2/*no menus*/
menuHandlers[1] = menuModelSelect;
#endif
menuHandlers[1] = menuModelSelect;
#endif
#if defined(EEPROM)
@@ -1857,13 +1841,6 @@ void opentxInit()
aux2SerialInit(g_eeGeneral.aux2SerialMode, modelTelemetryProtocol());
#endif
#if MENUS_LOCK == 1
getMovedSwitch();
if (TRIMS_PRESSED() && g_eeGeneral.switchUnlockStates==switches_states) {
readonly = false;
}
#endif
currentSpeakerVolume = requiredSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF;
currentBacklightBright = requiredBacklightBright = g_eeGeneral.backlightBright;
#if !defined(SOFTWARE_VOLUME)
+3 -9
View File
@@ -621,15 +621,9 @@ void flightReset(uint8_t check=true);
void doSplash();
#endif
#if MENUS_LOCK == 1
extern bool readonly;
extern bool readonlyUnlocked();
#define READ_ONLY() readonly
#define READ_ONLY_UNLOCKED() readonlyUnlocked()
#else
#define READ_ONLY() false
#define READ_ONLY_UNLOCKED() true
#endif
// disabled function (not used anywhere)
#define READ_ONLY() false
#define READ_ONLY_UNLOCKED() true
void checkLowEEPROM();
void checkThrottleStick();
@@ -525,6 +525,7 @@ bool swash_is_active(void* user, uint8_t* data, uint32_t bitoffs)
#define r_swtchWarn nullptr
#if defined(COLORLCD)
bool w_swtchWarn(const YamlNode* node, uint32_t val, yaml_writer_func wf, void* opaque)
{
for (int i = 0; i < STORAGE_NUM_SWITCHES; i++) {
@@ -538,7 +539,7 @@ bool w_swtchWarn(const YamlNode* node, uint32_t val, yaml_writer_func wf, void*
// state == 1 -> UP
// state == 2 -> MIDDLE
// state == 3 -> DOWN
char swtchWarn[2] = {(char)('A' + i), 0};
char swtchWarn[2] = {getRawSwitchFromIdx(i), 0};
switch (state) {
case 0:
@@ -568,6 +569,58 @@ bool w_swtchWarn(const YamlNode* node, uint32_t val, yaml_writer_func wf, void*
return true;
}
#else
bool w_swtchWarn(void* user, uint8_t* data, uint32_t bitoffs,
yaml_writer_func wf, void* opaque)
{
data += (bitoffs >> 3UL);
// switchWarningState
swarnstate_t states = *(swarnstate_t*)data;
data += sizeof(swarnstate_t);
// switchWarningEnable
swarnenable_t enables = *(swarnenable_t*)data;
for (int i = 0; i < STORAGE_NUM_SWITCHES; i++) {
// decode check state
// -> 2 bits per switch + enable
swarnenable_t en = (enables >> i) & 0x01;
if (en) continue;
// state == 0 -> no check
// state == 1 -> UP
// state == 2 -> MIDDLE
// state == 3 -> DOWN
char swtchWarn[2] = {(char)('A' + i), 0};
uint8_t state = (states >> (2 * i)) & 0x03;
switch (state) {
case 0:
swtchWarn[1] = 'u';
break;
case 1:
swtchWarn[1] = '-';
break;
case 2:
swtchWarn[1] = 'd';
break;
default:
// this should never happen
swtchWarn[1] = 'x';
break;
}
if (swtchWarn[1] != 0) {
if (!wf(opaque, swtchWarn, 2)) {
return false;
}
}
}
return true;
}
#endif
extern const struct YamlIdStr enum_BeeperMode[];
@@ -818,8 +818,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -818,8 +818,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -818,8 +818,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -818,8 +818,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -818,8 +818,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -831,8 +831,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 32, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 16 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 48 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -870,8 +870,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 64, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 32 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 96 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -803,8 +803,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -813,8 +813,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -810,8 +810,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -814,8 +814,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState", NULL, w_swtchWarn ),
YAML_PADDING( 24 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -828,89 +828,94 @@ static bool swash_is_active(void* user, uint8_t* data, uint32_t bitoffs)
return yaml_conv_220::swash_is_active(user, data, bitoffs);
}
static uint32_t r_swtchWarn(const YamlNode* node, const char* val, uint8_t val_len)
static void r_swtchWarn(void* user, uint8_t* data, uint32_t bitoffs,
const char* val, uint8_t val_len)
{
// Read from string like 'AdBuC-':
//
// -> reads:
// - Switch A: must be DOWN
// - Switch B: must be UP
// - Switch C: must be MIDDLE
//
// -> switches not in the list shall not be checked
//
swarnstate_t swtchWarn = 0;
while(val_len--) {
data += (bitoffs >> 3UL);
swarnstate_t& swtchWarn = *(swarnstate_t*)data;
signed swtch = *(val++) - 'A';
if (swtch >= NUM_SWITCHES)
break;
// Read from string like 'AdBuC-':
//
// -> reads:
// - Switch A: must be DOWN
// - Switch B: must be UP
// - Switch C: must be MIDDLE
//
// -> switches not in the list shall not be checked
//
swtchWarn = 0;
while (val_len--) {
signed swtch = getRawSwitchIdx(*(val++));
if (swtch < 0) break;
unsigned state = 0;
switch (*(val++)) {
case 'u':
state = 1;
break;
case '-':
state = 2;
break;
case 'd':
state = 3;
break;
default:
// no check
break;
}
// 3 bits per switch
swtchWarn |= (state << (3*swtch));
unsigned state = 0;
switch (*(val++)) {
case 'u':
state = 1;
break;
case '-':
state = 2;
break;
case 'd':
state = 3;
break;
default:
// no check
break;
}
return swtchWarn;
// 3 bits per switch
swtchWarn |= (state << (3 * swtch));
}
}
static bool w_swtchWarn(const YamlNode* node, uint32_t val, yaml_writer_func wf, void* opaque)
static bool w_swtchWarn(void* user, uint8_t* data, uint32_t bitoffs,
yaml_writer_func wf, void* opaque)
{
for (int i = 0; i < NUM_SWITCHES; i++) {
if (SWITCH_EXISTS(i)) {
data += (bitoffs >> 3UL);
swarnstate_t states = *(swarnstate_t*)data;
// decode check state
// -> 3 bits per switch
auto state = (val >> (3*i)) & 0x07;
for (int i = 0; i < NUM_SWITCHES; i++) {
// TODO: SWITCH_EXISTS() uses the g_eeGeneral stucture, which might not be
// avail
if (SWITCH_EXISTS(i)) {
// decode check state
// -> 3 bits per switch
auto state = (states >> (3 * i)) & 0x07;
// state == 0 -> no check
// state == 1 -> UP
// state == 2 -> MIDDLE
// state == 3 -> DOWN
char swtchWarn[2] = {(char)('A' + i), 0};
// state == 0 -> no check
// state == 1 -> UP
// state == 2 -> MIDDLE
// state == 3 -> DOWN
char swtchWarn[2] = {getRawSwitchFromIdx(i), 0};
switch (state) {
case 0:
break;
case 1:
swtchWarn[1] = 'u';
break;
case 2:
swtchWarn[1] = '-';
break;
case 3:
swtchWarn[1] = 'd';
break;
default:
// this should never happen
swtchWarn[1] = 'x';
break;
}
switch (state) {
case 0:
break;
case 1:
swtchWarn[1] = 'u';
break;
case 2:
swtchWarn[1] = '-';
break;
case 3:
swtchWarn[1] = 'd';
break;
default:
// this should never happen
swtchWarn[1] = 'x';
break;
}
if (swtchWarn[1] != 0) {
if (!wf(opaque, swtchWarn, 2)) {
return false;
}
}
if (swtchWarn[1] != 0) {
if (!wf(opaque, swtchWarn, 2)) {
return false;
}
}
}
}
return true;
return true;
}
extern const struct YamlIdStr enum_BeeperMode[];
@@ -850,7 +850,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 32, r_swtchWarn, w_swtchWarn ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -403,7 +403,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 192 ),
@@ -818,8 +817,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -403,7 +403,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 192 ),
@@ -818,8 +817,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -403,7 +403,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 192 ),
@@ -818,8 +817,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -403,7 +403,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 192 ),
@@ -818,8 +817,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -869,7 +869,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 32, r_swtchWarn, w_swtchWarn ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -867,7 +867,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 352, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 32, r_swtchWarn, w_swtchWarn ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -403,7 +403,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 192 ),
@@ -818,8 +817,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -410,7 +410,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 32 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 16, struct_switchConfig, nullptr),
YAML_PADDING( 216 ),
@@ -831,8 +830,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 32, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 16 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -449,7 +449,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 64 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 32, struct_switchConfig, nullptr),
YAML_PADDING( 432 ),
@@ -870,8 +869,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 320, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 64, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 32 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 64 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -390,7 +390,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 120 ),
@@ -803,8 +802,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -398,7 +398,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 168 ),
@@ -813,8 +812,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -395,7 +395,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 144 ),
@@ -810,8 +809,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
@@ -397,7 +397,6 @@ static const struct YamlNode struct_RadioData[] = {
YAML_ARRAY("slidersConfig", 1, 4, struct_sliderConfig, nullptr),
YAML_ARRAY("potsConfig", 2, 4, struct_potConfig, nullptr),
YAML_UNSIGNED( "backlightColor", 8 ),
YAML_UNSIGNED( "switchUnlockStates", 16 ),
YAML_ARRAY("sticksConfig", 0, 4, struct_sticksConfig, stick_name_valid),
YAML_ARRAY("switchConfig", 2, 8, struct_switchConfig, nullptr),
YAML_PADDING( 144 ),
@@ -814,8 +813,8 @@ static const struct YamlNode struct_ModelData[] = {
YAML_STRUCT("swashR", 64, struct_SwashRingData, swash_is_active),
YAML_ARRAY("flightModeData", 288, 9, struct_FlightModeData, fmd_is_active),
YAML_UNSIGNED_CUST( "thrTraceSrc", 8, r_thrSrc, w_thrSrc ),
YAML_UNSIGNED_CUST( "switchWarningState", 16, r_swtchWarn, w_swtchWarn ),
YAML_UNSIGNED( "switchWarningEnable", 8 ),
YAML_CUSTOM("switchWarningState",r_swtchWarn,w_swtchWarn),
YAML_PADDING( 32 ),
YAML_ARRAY("gvars", 56, 9, struct_GVarData, NULL),
YAML_STRUCT("varioData", 40, struct_VarioData, NULL),
YAML_UNSIGNED_CUST( "rssiSource", 8, r_tele_sensor, w_tele_sensor ),
+40 -14
View File
@@ -421,6 +421,45 @@ char *getFlightModeString(char *dest, int8_t idx)
// }
#if !defined(PCBSKY9X)
int getRawSwitchIdx(char sw)
{
if (sw < 'A' || sw > 'Z')
return -1;
#if defined(PCBX7) && !defined(RADIO_TX12)
if (sw >= 'H')
return sw - 'H' + 5;
#if defined(RADIO_T12)
else if (sw == 'G')
#else
else if (sw == 'F')
#endif
return 4;
else
return sw - 'A';
#else
return sw - 'A';
#endif
}
char getRawSwitchFromIdx(int idx)
{
#if defined(PCBX7) && !defined(RADIO_TX12)
if (idx >= 5)
return 'H' + idx - 5;
else if (idx == 4)
#if defined(RADIO_T12)
return 'G';
#else
return 'F';
#endif
else
return 'A' + idx;
#else
return 'A' + idx;
#endif
}
char *getSwitchName(char *dest, swsrc_t idx)
{
div_t swinfo = switchInfo(idx);
@@ -429,20 +468,7 @@ char *getSwitchName(char *dest, swsrc_t idx)
strAppend(dest, g_eeGeneral.switchNames[swinfo.quot], LEN_SWITCH_NAME);
} else {
*dest++ = 'S';
#if defined(PCBX7) && !defined(RADIO_TX12)
if (swinfo.quot >= 5)
*dest++ = 'H' + swinfo.quot - 5;
else if (swinfo.quot == 4)
#if defined(RADIO_T12)
*dest++ = 'G';
#else
*dest++ = 'F';
#endif
else
*dest++ = 'A' + swinfo.quot;
#else
*dest++ = 'A' + swinfo.quot;
#endif
*dest++ = getRawSwitchFromIdx(swinfo.quot);
}
return dest;
}
+2
View File
@@ -74,6 +74,8 @@ char *getGVarString(int idx);
char *getSwitchPositionName(char *dest, swsrc_t idx);
char *getSwitchName(char *dest, swsrc_t idx);
char *getSourceString(char *dest, mixsrc_t idx);
int getRawSwitchIdx(char sw);
char getRawSwitchFromIdx(int sw);
#endif
char *getFlightModeString(char *dest, int8_t idx);
+59 -131
View File
@@ -525,16 +525,16 @@ swsrc_t getMovedSwitch()
static tmr10ms_t s_move_last_time = 0;
swsrc_t result = 0;
#if defined(PCBFRSKY) || defined(PCBNV14)
// Switches
for (int i = 0; i < NUM_SWITCHES; i++) {
if (SWITCH_EXISTS(i)) {
swarnstate_t mask = ((swarnstate_t) 0x03 << (i * 2));
uint8_t prev = (switches_states & mask) >> (i * 2);
uint8_t next = (1024 + getValue(MIXSRC_SA + i)) / 1024;
swarnstate_t mask = ((swarnstate_t) 0x07 << (i * 3));
uint8_t prev = (switches_states & mask) >> (i * 3);
uint8_t next = (1024 + getValue(MIXSRC_SA + i)) / 1024 + 1;
if (prev != next) {
switches_states = (switches_states & (~mask)) | ((swarnstate_t) next << (i * 2));
result = 1 + (3 * i) + next;
switches_states =
(switches_states & (~mask)) | ((swarnstate_t)(next) << (i * 3));
result = (3 * i) + next;
}
}
}
@@ -551,26 +551,6 @@ swsrc_t getMovedSwitch()
}
}
}
#else
// return delivers 1 to 3 for ID1 to ID3
// 4..8 for all other switches if changed to true
// -4..-8 for all other switches if changed to false
// 9 for Trainer switch if changed to true; Change to false is ignored
swarnstate_t mask = 0x80;
for (uint8_t i=NUM_SWITCHES_POSITIONS; i>1; i--) {
bool prev;
prev = (switches_states & mask);
// don't use getSwitch here to always get the proper value, even getSwitch manipulates
bool next = switchState(i-1);
if (prev != next) {
if (((i<NUM_SWITCHES_POSITIONS) && (i>3)) || next==true)
result = next ? i : -i;
if (i<=3 && result==0) result = 1;
switches_states ^= mask;
}
mask >>= 1;
}
#endif
if ((tmr10ms_t)(get_tmr10ms() - s_move_last_time) > 10)
result = 0;
@@ -579,10 +559,49 @@ swsrc_t getMovedSwitch()
return result;
}
bool isSwitchWarningRequired(uint8_t &bad_pots)
{
swarnstate_t states = g_model.switchWarningState;
GET_ADC_IF_MIXER_NOT_RUNNING();
getMovedSwitch();
bool warn = false;
for (int i = 0; i < NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
swarnstate_t mask = ((swarnstate_t)0x07 << (i * 3));
if ((states & mask) && !((states & mask) == (switches_states & mask))) {
warn = true;
}
}
}
if (g_model.potsWarnMode) {
evalFlightModeMixes(e_perout_mode_normal, 0);
bad_pots = 0;
for (int i = 0; i < NUM_POTS + NUM_SLIDERS; i++) {
if (!IS_POT_SLIDER_AVAILABLE(POT1 + i)) {
continue;
}
if (!(g_model.potsWarnEnabled & (1 << i)) &&
(abs(g_model.potsWarnPosition[i] - GET_LOWRES_POT_POSITION(i)) > 1)) {
warn = true;
bad_pots |= (1 << i);
}
}
}
return warn;
}
#if defined(COLORLCD)
#include "switch_warn_dialog.h"
void checkSwitches()
{
uint8_t bad_pots = 0;
if (!isSwitchWarningRequired(bad_pots))
return;
auto dialog = new SwitchWarnDialog();
dialog->runForever();
}
@@ -591,112 +610,21 @@ void checkSwitches()
{
swarnstate_t last_bad_switches = 0xff;
swarnstate_t states = g_model.switchWarningState;
#if defined(PCBFRSKY) || defined(PCBFLYSKY)
uint8_t bad_pots = 0, last_bad_pots = 0xff;
#endif
#if defined(PWR_BUTTON_PRESS)
bool refresh = false;
#endif
while (true) {
#if defined(PCBFRSKY)
#define GETADC_COUNT 1
#endif
#ifdef GETADC_COUNT
for (uint8_t i=0; i<GETADC_COUNT; i++) {
GET_ADC_IF_MIXER_NOT_RUNNING();
}
#undef GETADC_COUNT
#endif
getMovedSwitch();
bool warn = false;
#if defined(COLORLCD)
for (int i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i)) {
unsigned int state = ((states >> (3*i)) & 0x07);
if (state && state-1 != ((switches_states >> (i*2)) & 0x03)) {
warn = true;
}
}
}
if (g_model.potsWarnMode) {
evalFlightModeMixes(e_perout_mode_normal, 0);
bad_pots = 0;
for (int i=0; i<NUM_POTS+NUM_SLIDERS; i++) {
if (!IS_POT_SLIDER_AVAILABLE(POT1+i)) {
continue;
}
if (!(g_model.potsWarnEnabled & (1 << i)) && (abs(g_model.potsWarnPosition[i] - GET_LOWRES_POT_POSITION(i)) > 1)) {
warn = true;
bad_pots |= (1<<i);
}
}
}
#elif defined(PCBTARANIS)
for (int i=0; i<NUM_SWITCHES; i++) {
if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) {
swarnstate_t mask = ((swarnstate_t)0x03 << (i*2));
if (!((states & mask) == (switches_states & mask))) {
warn = true;
}
}
}
if (g_model.potsWarnMode) {
evalFlightModeMixes(e_perout_mode_normal, 0);
bad_pots = 0;
for (int i=0; i<NUM_POTS+NUM_SLIDERS; i++) {
if (!IS_POT_SLIDER_AVAILABLE(POT1+i)) {
continue;
}
if (!(g_model.potsWarnEnabled & (1 << i)) && (abs(g_model.potsWarnPosition[i] - GET_LOWRES_POT_POSITION(i)) > 1)) {
warn = true;
bad_pots |= (1<<i);
}
}
}
#else
for (int i=0; i<NUM_SWITCHES-1; i++) {
if (!(g_model.switchWarningEnable & (1<<i))) {
if (i == 0) {
if ((states & 0x03) != (switches_states & 0x03)) {
warn = true;
}
}
else if ((states & (1<<(i+1))) != (switches_states & (1<<(i+1)))) {
warn = true;
}
}
}
#endif
if (!warn) {
if (!isSwitchWarningRequired(bad_pots))
break;
}
LED_ERROR_BEGIN();
resetBacklightTimeout();
// first - display warning
#if defined(PCBSKY9X)
if (last_bad_switches != switches_states) {
RAISE_ALERT(STR_SWITCHWARN, NULL, STR_PRESS_ANY_KEY_TO_SKIP, last_bad_switches == 0xff ? AU_SWITCH_ALERT : AU_NONE);
uint8_t x = 2;
for (uint8_t i=0; i<NUM_SWITCHES-1; i++) {
uint8_t attr;
if (i == 0)
attr = ((states & 0x03) != (switches_states & 0x03)) ? INVERS : 0;
else
attr = (states & (1 << (i+1))) == (switches_states & (1 << (i+1))) ? 0 : INVERS;
if (!(g_model.switchWarningEnable & (1<<i)))
drawSwitch(x, 5*FH, (i>0?(i+3):(states&0x3)+1), attr);
x += 3*FW+FW/2;
}
#else
if (last_bad_switches != switches_states || last_bad_pots != bad_pots) {
drawAlertBox(STR_SWITCHWARN, nullptr, STR_PRESS_ANY_KEY_TO_SKIP);
if (last_bad_switches == 0xff || last_bad_pots == 0xff) {
@@ -704,20 +632,21 @@ void checkSwitches()
}
int x = SWITCH_WARNING_LIST_X;
int y = SWITCH_WARNING_LIST_Y;
#if defined(COLORLCD)
lcdNextPos = SWITCH_WARNING_LIST_X;
#endif
int numWarnings = 0;
for (int i=0; i<NUM_SWITCHES; ++i) {
if (SWITCH_WARNING_ALLOWED(i) && !(g_model.switchWarningEnable & (1<<i))) {
swarnstate_t mask = ((swarnstate_t)0x03 << (i*2));
LcdFlags attr = ((states & mask) == (switches_states & mask)) ? 0 : INVERS;
if (attr) {
if (++numWarnings < 6) {
char c = (STR_CHAR_UP "-" STR_CHAR_DOWN)[(states & mask) >> (i*2)];
drawSource(x, y, MIXSRC_FIRST_SWITCH+i, attr);
lcdDrawChar(lcdNextPos, y, c, attr);
x = lcdNextPos + 3;
if (SWITCH_WARNING_ALLOWED(i)) {
swarnstate_t mask = ((swarnstate_t)0x07 << (i*3));
if (states & mask) {
LcdFlags attr =
((states & mask) == (switches_states & mask)) ? 0 : INVERS;
if (attr) {
if (++numWarnings < 6) {
char c = (" " STR_CHAR_UP
"-" STR_CHAR_DOWN)[(states & mask) >> (i * 3)];
drawSource(x, y, MIXSRC_FIRST_SWITCH + i, attr);
lcdDrawChar(lcdNextPos, y, c, attr);
x = lcdNextPos + 3;
}
}
}
}
@@ -748,7 +677,6 @@ void checkSwitches()
}
last_bad_pots = bad_pots;
#endif
lcdRefresh();
lcdSetContrast();
+2
View File
@@ -38,3 +38,5 @@ typedef int16_t delayval_t;
uint8_t lswFamily(uint8_t func);
int16_t lswTimerValue(delayval_t val);
bool isSwitchWarningRequired(uint8_t &bad_pots);
+29
View File
@@ -73,6 +73,18 @@ TEST(Conversions, ConversionX9DPFrom23)
EXPECT_STRNEQ("Tes", g_eeGeneral.switchNames[0]); // ZSTREQ
EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(0));
swarnstate_t state =
(0x01) | // SA up
(0x03 << (3 * 1)) | // SB down
(0x02 << (3 * 2)) | // SC middle
(0x01 << (3 * 3)) | // SD up
(0x02 << (3 * 4)) | // SE middle
(0x03 << (3 * 5)) | // SF down
(0x02 << (3 * 6)); // SG middle
// check only the "allowed switches"
EXPECT_EQ(state, g_model.switchWarningState & 0xFFFFF);
EXPECT_STRNEQ("Test", g_model.header.name); // ZSTREQ
EXPECT_EQ(TMRMODE_ON, g_model.timers[0].mode); // new!
EXPECT_EQ(SWSRC_SA0, g_model.timers[0].swtch); // new!
@@ -240,6 +252,17 @@ TEST(Conversions, ConversionX7From23)
EXPECT_STRNEQ("Tes", g_eeGeneral.switchNames[0]);
EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(0));
swarnstate_t state =
(0x02) | // SA middle
(0x01 << (3 * 1)) | // SB up
(0x03 << (3 * 2)) | // SC down
(0x03 << (3 * 4)); // SF down
swarnstate_t sw_mask = (1 << (STORAGE_NUM_SWITCHES * 3)) - 1;
// check only the "allowed switches"
EXPECT_EQ(state & sw_mask, g_model.switchWarningState & 0x7FFF);
EXPECT_STRNEQ("Test", g_model.header.name);
EXPECT_EQ(MODULE_TYPE_R9M_PXX1, g_model.moduleData[EXTERNAL_MODULE].type);
EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, g_model.moduleData[EXTERNAL_MODULE].subType);
@@ -469,6 +492,12 @@ TEST(Conversions, ConversionTX16SFrom25)
writeModelYaml(modelname2);
loadModel(modelname2);
constexpr swarnstate_t swWarnState =
(0x01) |// SA up
(0x02 << (3 * 2)) | // SB middle
(0x03 << (3 * 5)); // SF down
EXPECT_EQ(swWarnState, g_model.switchWarningState);
EXPECT_EQ(MIXSRC_FIRST_LOGICAL_SWITCH + 4, g_model.mixData[4].srcRaw);
EXPECT_EQ(MIXSRC_SC, g_model.mixData[5].srcRaw);
EXPECT_EQ(MIXSRC_SB, g_model.mixData[6].srcRaw);
Binary file not shown.
Binary file not shown.
Binary file not shown.
-5
View File
@@ -925,11 +925,6 @@ const char * const STR_LSW_DESCRIPTIONS[] = TR_LSW_DESCRIPTIONS;
const char * const STR_GVAR_HEADERS[] = TR_GVAR_HEADERS;
#endif
#if MENUS_LOCK == 1
const char STR_UNLOCKED[] = TR_UNLOCKED;
const char STR_MODS_FORBIDDEN[] = TR_MODS_FORBIDDEN;
#endif
#if defined(BLUETOOTH)
const char STR_BLUETOOTH[] = TR_BLUETOOTH;
const char STR_BLUETOOTH_DISC[] = TR_BLUETOOTH_DISC;
-5
View File
@@ -1088,11 +1088,6 @@ extern const char STR_RTC_CHECK[];
extern const char STR_SPORT_UPDATE_POWER_MODE[];
extern const char STR_SPORT_UPDATE_POWER_MODES[];
#if MENUS_LOCK == 1
extern const char STR_UNLOCKED[];
extern const char STR_MODS_FORBIDDEN[];
#endif
extern const char STR_MODULE_RANGE[];
extern const char STR_RECEIVER_OPTIONS[];