diff --git a/radio/src/Makefile b/radio/src/Makefile index 4fc1c398e..6c67d8ab0 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -366,7 +366,7 @@ M2561_VARIANT = +16384 EEPROM_VARIANT = 0 ifeq ($(PCB), TARANIS) - GUIMODELSRC = gui/menu_model.cpp gui/menu_model_select.cpp gui/menu_model_setup.cpp gui/menu_model_inputs_mixes.cpp gui/menu_model_limits.cpp gui/Taranis/menu_model_logical_switches.cpp gui/menu_model_custom_functions.cpp gui/menu_model_telemetry.cpp + GUIMODELSRC = gui/menu_model.cpp gui/menu_model_select.cpp gui/Taranis/menu_model_setup.cpp gui/menu_model_inputs_mixes.cpp gui/Taranis/menu_model_limits.cpp gui/Taranis/menu_model_logical_switches.cpp gui/menu_model_custom_functions.cpp gui/menu_model_telemetry.cpp else GUIMODELSRC = gui/menu_model.cpp gui/menu_model_select.cpp gui/menu_model_setup.cpp gui/menu_model_inputs_mixes.cpp gui/menu_model_limits.cpp gui/menu_model_logical_switches.cpp gui/menu_model_custom_functions.cpp gui/menu_model_telemetry.cpp endif @@ -1054,7 +1054,11 @@ endif ifeq ($(FLIGHT_MODES), YES) CPPDEFS += -DFLIGHT_MODES - GUIMODELSRC += gui/menu_model_flightmodes.cpp + ifeq ($(PCB), TARANIS) + GUIMODELSRC += gui/Taranis/menu_model_flightmodes.cpp + else + GUIMODELSRC += gui/menu_model_flightmodes.cpp + endif endif ifeq ($(CURVES), YES) diff --git a/radio/src/gui/Taranis/menu_model_flightmodes.cpp b/radio/src/gui/Taranis/menu_model_flightmodes.cpp new file mode 100755 index 000000000..dc6d140eb --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_flightmodes.cpp @@ -0,0 +1,154 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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. + * + */ + +#include "../opentx.h" + +void displayFlightModes(coord_t x, coord_t y, FlightModesType value) +{ + lcd_puts(x, y, STR_FP); + x = lcdNextPos + 1; + for (uint8_t p=0; p 0) { posHorz += 1; } + + if (sub=0) { + displayColumnHeader(STR_PHASES_HEADERS, posHorz); + } + + for (uint8_t i=0; i0) ? BLINK|INVERS : INVERS) : 0); + uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; + switch (j) { + case ITEM_FLIGHT_MODES_NAME: + editName(4*FW-1, y, p->name, sizeof(p->name), event, attr); + break; + + case ITEM_FLIGHT_MODES_SWITCH: + putsSwitches((5+LEN_FLIGHT_MODE_NAME)*FW+FW/2, y, p->swtch, attr); + if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); + break; + + case ITEM_FLIGHT_MODES_TRIM_RUD: + case ITEM_FLIGHT_MODES_TRIM_ELE: + case ITEM_FLIGHT_MODES_TRIM_THR: + case ITEM_FLIGHT_MODES_TRIM_AIL: + { + uint8_t t = j-ITEM_FLIGHT_MODES_TRIM_RUD; + putsTrimMode((4+LEN_FLIGHT_MODE_NAME)*FW+j*(5*FW/2), y, k, t, attr); + if (active) { + trim_t & v = p->trim[t]; + v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable); + } + break; + } + + case ITEM_FLIGHT_MODES_FADE_IN: + lcd_outdezAtt(32*FW-2, y, (10/DELAY_STEP)*p->fadeIn, attr|PREC1); + if (active) p->fadeIn = checkIncDec(event, p->fadeIn, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); + break; + + case ITEM_FLIGHT_MODES_FADE_OUT: + lcd_outdezAtt(35*FW, y, (10/DELAY_STEP)*p->fadeOut, attr|PREC1); + if (active) p->fadeOut = checkIncDec(event, p->fadeOut, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); + break; + + } + } + } +} diff --git a/radio/src/gui/Taranis/menu_model_limits.cpp b/radio/src/gui/Taranis/menu_model_limits.cpp new file mode 100755 index 000000000..410118aaa --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_limits.cpp @@ -0,0 +1,281 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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. + * + */ + +#include "../opentx.h" + +bool isThrottleOutput(uint8_t ch) +{ + for (uint8_t i=0; idestCh==ch && mix->srcRaw==MIXSRC_Thr) + return true; + } + return false; +} + +enum LimitsItems { + ITEM_LIMITS_CH_NAME, + ITEM_LIMITS_OFFSET, + ITEM_LIMITS_MIN, + ITEM_LIMITS_MAX, + ITEM_LIMITS_DIRECTION, +#if defined(CURVES) + ITEM_LIMITS_CURVE, +#endif +#if defined(PPM_CENTER_ADJUSTABLE) + ITEM_LIMITS_PPM_CENTER, +#endif +#if defined(PPM_LIMITS_SYMETRICAL) + ITEM_LIMITS_SYMETRICAL, +#endif + ITEM_LIMITS_COUNT, + ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1 +}; + + #define LIMITS_NAME_POS 4*FW + #define LIMITS_OFFSET_POS 14*FW+4 + #define LIMITS_MIN_POS 20*FW-3 + #if defined(PPM_CENTER_ADJUSTABLE) + #define LIMITS_DIRECTION_POS 20*FW-3 + #define LIMITS_MAX_POS 24*FW+2 + #define LIMITS_REVERT_POS 25*FW-1 + #define LIMITS_CURVE_POS 27*FW-1 + #define LIMITS_PPM_CENTER_POS 34*FW + #else + #define LIMITS_DIRECTION_POS 21*FW + #define LIMITS_MAX_POS 26*FW + #define LIMITS_REVERT_POS 27*FW + #define LIMITS_CURVE_POS 32*FW-3 + #endif + + #define LIMITS_MIN_MAX_OFFSET 1000 + #define CONVERT_US_MIN_MAX(x) (((x)*1280)/250) + #define MIN_MAX_ATTR attr|PREC1 + +#if defined(PPM_UNIT_US) + #define SET_MIN_MAX(x, val) x = ((val)*250)/128 + #define MIN_MAX_DISPLAY(x) CONVERT_US_MIN_MAX(x) +#else + #define MIN_MAX_DISPLAY(x) (x) + #define SET_MIN_MAX(x, val) x = (val) +#endif + +void onLimitsMenu(const char *result) +{ + uint8_t ch = m_posVert - 1; + + if (result == STR_RESET) { + LimitData *ld = limitAddress(ch); + ld->min = 0; + ld->max = 0; + ld->offset = 0; + ld->ppmCenter = 0; + ld->revert = false; + ld->curve = 0; + } + else if (result == STR_COPY_STICKS_TO_OFS) { + copySticksToOffset(ch); + } + else if (result == STR_COPY_TRIMS_TO_OFS) { + copyTrimsToOffset(ch); + } +} + +void menuModelLimits(uint8_t event) +{ + uint8_t sub = m_posVert - 1; + + if (sub < NUM_CHNOUT) { +#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US) + lcd_outdezAtt(13*FW, 0, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, 0); + lcd_puts(13*FW, 0, STR_US); +#else + lcd_outdezAtt(13*FW, 0, calcRESXto1000(channelOutputs[sub]), PREC1); +#endif + } + + MENU(STR_MENULIMITS, menuTabModel, e_Limits, 1+NUM_CHNOUT+1, {0, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, NAVIGATION_LINE_BY_LINE|ITEM_LIMITS_MAXROW, 0}); + + if (sub=0) { + displayColumnHeader(STR_LIMITS_HEADERS, m_posHorz); + } + + if (s_warning_result) { + s_warning_result = 0; + LimitData *ld = limitAddress(sub); + ld->revert = !ld->revert; + eeDirty(EE_MODEL); + } + + for (uint8_t i=0; irevert) ? -LIMIT_OFS(ld) : LIMIT_OFS(ld); + char swVal = '-'; // '-', '<', '>' + if ((channelOutputs[k] - v) > 50) swVal = (ld->revert ? 127 : 126); // Switch to raw inputs? - remove trim! + if ((channelOutputs[k] - v) < -50) swVal = (ld->revert ? 126 : 127); + lcd_putc(LIMITS_DIRECTION_POS, y, swVal); + + int limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 1000); + + putsChn(0, y, k+1, (sub==k && m_posHorz < 0) ? INVERS : 0); + if (sub==k && m_posHorz < 0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { + killEvents(event); + MENU_ADD_ITEM(STR_RESET); + MENU_ADD_ITEM(STR_COPY_TRIMS_TO_OFS); + MENU_ADD_ITEM(STR_COPY_STICKS_TO_OFS); + menuHandler = onLimitsMenu; + } + + for (uint8_t j=0; j0) ? BLINK|INVERS : INVERS) : 0); + uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; + if (active) STICK_SCROLL_DISABLE(); + switch(j) + { + case ITEM_LIMITS_CH_NAME: + editName(LIMITS_NAME_POS, y, ld->name, sizeof(ld->name), event, attr); + break; + + case ITEM_LIMITS_OFFSET: + if (GV_IS_GV_VALUE(ld->offset, -1000, 1000) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { + ld->offset = GVAR_MENU_ITEM(LIMITS_OFFSET_POS, y, ld->offset, -1000, 1000, attr|PREC1, 0, event); + break; + } + +#if defined(PPM_UNIT_US) + lcd_outdezAtt(LIMITS_OFFSET_POS, y, ((int32_t)ld->offset*128) / 25, attr|PREC1); +#else + lcd_outdezAtt(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1); +#endif + if (active) { + ld->offset = checkIncDec(event, ld->offset, -1000, 1000, EE_MODEL, NULL, stops1000); + } + else if (attr && event==EVT_KEY_LONG(KEY_MENU)) { + copySticksToOffset(k); + s_editMode = 0; + } + break; + + case ITEM_LIMITS_MIN: + if (GV_IS_GV_VALUE(ld->min, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { + ld->min = GVAR_MENU_ITEM(LIMITS_MIN_POS, y, ld->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); + break; + } + lcd_outdezAtt(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); + if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL, NULL, stops1000); + break; + + case ITEM_LIMITS_MAX: + if (GV_IS_GV_VALUE(ld->max, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { + ld->max = GVAR_MENU_ITEM(LIMITS_MAX_POS, y, ld->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); + break; + } + lcd_outdezAtt(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); + if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL, NULL, stops1000); + break; + + case ITEM_LIMITS_DIRECTION: + { + uint8_t revert = ld->revert; +#if defined(PPM_CENTER_ADJUSTABLE) + lcd_putcAtt(LIMITS_REVERT_POS, y, revert ? 127 : 126, attr); +#else + lcd_putsiAtt(LIMITS_REVERT_POS, y, STR_MMMINV, revert, attr); +#endif + if (active) { + uint8_t revert_new = checkIncDecModel(event, revert, 0, 1); + if (checkIncDec_Ret && isThrottleOutput(k)) { + POPUP_CONFIRMATION(STR_INVERT_THR); + } + else { + ld->revert = revert_new; + } + } + break; + } + +#if defined(CURVES) + case ITEM_LIMITS_CURVE: + putsCurve(LIMITS_CURVE_POS, y, ld->curve, attr); + if (attr && event==EVT_KEY_LONG(KEY_ENTER) && ld->curve>0) { + s_curveChan = (ld->curve<0 ? -ld->curve-1 : ld->curve-1); + pushMenu(menuModelCurveOne); + } + if (active) { + CHECK_INCDEC_MODELVAR(event, ld->curve, -MAX_CURVES, +MAX_CURVES); + } + break; +#endif + +#if defined(PPM_CENTER_ADJUSTABLE) + case ITEM_LIMITS_PPM_CENTER: + lcd_outdezAtt(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, attr); + if (active) { + CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX); + } + break; +#endif + +#if defined(PPM_LIMITS_SYMETRICAL) + case ITEM_LIMITS_SYMETRICAL: + lcd_putcAtt(LCD_W-FW-MENUS_SCROLLBAR_WIDTH, y, ld->symetrical ? '=' : '\306', attr); + if (active) { + CHECK_INCDEC_MODELVAR_ZERO(event, ld->symetrical, 1); + } + break; +#endif + } + } + } +} diff --git a/radio/src/gui/Taranis/menu_model_setup.cpp b/radio/src/gui/Taranis/menu_model_setup.cpp new file mode 100644 index 000000000..4ebbecf97 --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_setup.cpp @@ -0,0 +1,773 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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. + * + */ + +#include "../opentx.h" + +uint8_t g_moduleIdx; +void menuModelFailsafe(uint8_t event); + +enum menuModelSetupItems { + ITEM_MODEL_NAME, + ITEM_MODEL_BITMAP, + ITEM_MODEL_TIMER1, + ITEM_MODEL_TIMER1_NAME, + CASE_PERSISTENT_TIMERS(ITEM_MODEL_TIMER1_PERSISTENT) + ITEM_MODEL_TIMER1_MINUTE_BEEP, + ITEM_MODEL_TIMER1_COUNTDOWN_BEEP, + ITEM_MODEL_TIMER2, + ITEM_MODEL_TIMER2_NAME, + CASE_PERSISTENT_TIMERS(ITEM_MODEL_TIMER2_PERSISTENT) + ITEM_MODEL_TIMER2_MINUTE_BEEP, + ITEM_MODEL_TIMER2_COUNTDOWN_BEEP, + ITEM_MODEL_TIMER3, + ITEM_MODEL_TIMER3_NAME, + ITEM_MODEL_TIMER3_PERSISTENT, + ITEM_MODEL_TIMER3_MINUTE_BEEP, + ITEM_MODEL_TIMER3_COUNTDOWN_BEEP, + ITEM_MODEL_EXTENDED_LIMITS, + ITEM_MODEL_EXTENDED_TRIMS, + ITEM_MODEL_DISPLAY_TRIMS, + ITEM_MODEL_TRIM_INC, + ITEM_MODEL_THROTTLE_LABEL, + ITEM_MODEL_THROTTLE_REVERSED, + ITEM_MODEL_THROTTLE_TRACE, + ITEM_MODEL_THROTTLE_TRIM, + ITEM_MODEL_PREFLIGHT_LABEL, + ITEM_MODEL_CHECKLIST_DISPLAY, + ITEM_MODEL_THROTTLE_WARNING, + ITEM_MODEL_SWITCHES_WARNING, + ITEM_MODEL_SWITCHES_WARNING2, + ITEM_MODEL_POT_WARNING, + ITEM_MODEL_BEEP_CENTER, + ITEM_MODEL_USE_GLOBAL_FUNCTIONS, + ITEM_MODEL_INTERNAL_MODULE_LABEL, + ITEM_MODEL_INTERNAL_MODULE_MODE, + ITEM_MODEL_INTERNAL_MODULE_CHANNELS, + ITEM_MODEL_INTERNAL_MODULE_BIND, + ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_EXTERNAL_MODULE_LABEL, + ITEM_MODEL_EXTERNAL_MODULE_MODE, + ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, + ITEM_MODEL_EXTERNAL_MODULE_BIND, + ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, + ITEM_MODEL_TRAINER_LABEL, + ITEM_MODEL_TRAINER_MODE, + ITEM_MODEL_TRAINER_CHANNELS, + ITEM_MODEL_TRAINER_SETTINGS, + ITEM_MODEL_SETUP_MAX +}; + +#define FIELD_PROTOCOL_MAX 1 + +#define MODEL_SETUP_2ND_COLUMN (LCD_W-17*FW-MENUS_SCROLLBAR_WIDTH) +#define MODEL_SETUP_BIND_OFS 3*FW-2 +#define MODEL_SETUP_RANGE_OFS 7*FW +#define MODEL_SETUP_SET_FAILSAFE_OFS 10*FW + +void copySelection(char *dst, const char *src, uint8_t size) +{ + if (memcmp(src, "---", 3) == 0) + memset(dst, 0, size); + else + memcpy(dst, src, size); +} + +void onModelSetupBitmapMenu(const char *result) +{ + if (result == STR_UPDATE_LIST) { + if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), NULL)) { + POPUP_WARNING(STR_NO_BITMAPS_ON_SD); + s_menu_flags = 0; + } + } + else { + // The user choosed a bmp file in the list + copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); + LOAD_MODEL_BITMAP(); + memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); + eeDirty(EE_MODEL); + } +} + +#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) + +void menuModelSetup(uint8_t event) +{ + horzpos_t l_posHorz = m_posHorz; + #define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? HIDDEN_ROW : (uint8_t)(x)) + #define IF_EXTERNAL_MODULE_ON(x) (g_model.externalModule == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x)) + #define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW) + #define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW) + #define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8) + #define INTERNAL_MODULE_CHANNELS_ROWS() IF_INTERNAL_MODULE_ON(1) + #define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1) + #define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1) + #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS() : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS() : TRAINER_CHANNELS_ROWS())) + #define FAILSAFE_ROWS(x) ((g_model.moduleData[x].rfProtocol==RF_PROTO_X16 || g_model.moduleData[x].rfProtocol==RF_PROTO_LR12) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW) + #define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX) + #define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0) + #define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 + bool CURSOR_ON_CELL = (m_posHorz >= 0); + MENU_TAB({ 0, 0, 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsAllowed()), ONE_2x2POS_DEFINED() ? TITLE_ROW : HIDDEN_ROW, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(InternalModule), 0, IF_INTERNAL_MODULE_ON(1), IF_INTERNAL_MODULE_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); + + MENU_CHECK(menuTabModel, e_ModelSetup, MODEL_SETUP_MAX_LINES); + +#if (defined(DSM2) || defined(PXX)) + if (menuEvent) { + moduleFlag[0] = 0; + moduleFlag[1] = 0; + } +#endif + + TITLE(STR_MENUSETUP); + + uint8_t sub = m_posVert - 1; + int8_t editMode = s_editMode; + + for (uint8_t i=0; i0) ? BLINK|INVERS : INVERS); + LcdFlags attr = (sub == k ? blink : 0); + + switch(k) { + case ITEM_MODEL_NAME: + editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_MODELNAME, g_model.header.name, sizeof(g_model.header.name), event, attr); + memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name)); + break; + + case ITEM_MODEL_BITMAP: + lcd_putsLeft(y, STR_BITMAP); + if (ZEXIST(g_model.header.bitmap)) + lcd_putsnAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.bitmap, sizeof(g_model.header.bitmap), attr); + else + lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); + if (attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) { + s_editMode = 0; + if (listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), g_model.header.bitmap, LIST_NONE_SD_FILE)) { + menuHandler = onModelSetupBitmapMenu; + } + else { + POPUP_WARNING(STR_NO_BITMAPS_ON_SD); + s_menu_flags = 0; + } + } + break; + + case ITEM_MODEL_TIMER1: + case ITEM_MODEL_TIMER2: + case ITEM_MODEL_TIMER3: + { + unsigned int timerIdx = (k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)); + TimerData * timer = &g_model.timers[timerIdx]; + putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); + putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); + putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); + if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); + if (attr && (editMode>0 || p1valdiff)) { + div_t qr = div(timer->start, 60); + switch (m_posHorz) { + case 0: + { + int8_t timerMode = timer->mode; + if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; + CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); + if (timerMode < 0) timerMode += TMRMODE_COUNT-1; + timer->mode = timerMode; +#if defined(AUTOSWITCH) + if (s_editMode>0) { + int8_t val = timer->mode - (TMRMODE_COUNT-1); + int8_t switchVal = checkIncDecMovedSwitch(val); + if (val != switchVal) { + timer->mode = switchVal + (TMRMODE_COUNT-1); + eeDirty(EE_MODEL); + } + } +#endif + break; + } + case 1: + CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59); + timer->start = qr.rem + qr.quot*60; + break; + case 2: + qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2; + timer->start -= qr.rem ; + if ((int16_t)timer->start < 0) timer->start=0; + break; + } + } + break; + } + + case ITEM_MODEL_TIMER1_NAME: + case ITEM_MODEL_TIMER2_NAME: + case ITEM_MODEL_TIMER3_NAME: + { + TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)]; + editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_TIMER_NAME, timer->name, sizeof(timer->name), event, attr); + break; + } + + case ITEM_MODEL_TIMER1_MINUTE_BEEP: + case ITEM_MODEL_TIMER2_MINUTE_BEEP: + case ITEM_MODEL_TIMER3_MINUTE_BEEP: + { + TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)]; + timer->minuteBeep = onoffMenuItem(timer->minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); + break; + } + + case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP: + case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP: + case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP: + { + TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)]; + timer->countdownBeep = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, STR_VBEEPCOUNTDOWN, timer->countdownBeep, 0, 2, attr, event); + break; + } + + case ITEM_MODEL_TIMER1_PERSISTENT: + case ITEM_MODEL_TIMER2_PERSISTENT: + case ITEM_MODEL_TIMER3_PERSISTENT: + { + TimerData * timer = &g_model.timers[k>=ITEM_MODEL_TIMER3 ? 2 : (k>=ITEM_MODEL_TIMER2 ? 1 : 0)]; + timer->persistent = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_PERSISTENT, STR_VPERSISTENT, timer->persistent, 0, 2, attr, event); + break; + } + + case ITEM_MODEL_EXTENDED_LIMITS: + ON_OFF_MENU_ITEM(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, STR_ELIMITS, attr, event); + break; + + case ITEM_MODEL_EXTENDED_TRIMS: + ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, m_posHorz<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0); + lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_RESET_BTN, m_posHorz>0 && !s_noHi ? attr : 0); + if (attr && m_posHorz>0) { + s_editMode = 0; + if (event==EVT_KEY_LONG(KEY_ENTER)) { + s_noHi = NO_HI_LEN; + for (uint8_t i=0; i MIXSRC_Thr) + idx += 1; + if (idx >= MIXSRC_FIRST_POT+NUM_POTS) + idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS; + putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr); + break; + } + + case ITEM_MODEL_THROTTLE_TRIM: + ON_OFF_MENU_ITEM(g_model.thrTrim, MODEL_SETUP_2ND_COLUMN, y, STR_TTRIM, attr, event); + break; + + case ITEM_MODEL_PREFLIGHT_LABEL: + lcd_putsLeft(y, STR_PREFLIGHT); + break; + + case ITEM_MODEL_CHECKLIST_DISPLAY: + ON_OFF_MENU_ITEM(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST, attr, event); + break; + + case ITEM_MODEL_THROTTLE_WARNING: + g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event); + break; + + // TODO something more generic + case ITEM_MODEL_SWITCHES_WARNING2: + if (i==0) s_pgOfs++; + break; + + case ITEM_MODEL_SWITCHES_WARNING: + // TODO something more generic + if (i==LCD_LINES-2) { + s_pgOfs++; + break; + } + { + lcd_putsLeft(y, STR_SWITCHWARNING); + swarnstate_t states = g_model.switchWarningState; + char c; + if (attr) { + s_editMode = 0; + if (!READ_ONLY()) { + switch (event) { + CASE_EVT_ROTARY_BREAK + case EVT_KEY_BREAK(KEY_ENTER): + break; + + case EVT_KEY_LONG(KEY_ENTER): + if (m_posHorz < 0) { + s_noHi = NO_HI_LEN; + getMovedSwitch(); + g_model.switchWarningState = switches_states; + AUDIO_WARNING1(); + eeDirty(EE_MODEL); + } + killEvents(event); + break; + } + } + } + + LcdFlags line = attr; + + for (int i=0, current=0; i>= 2; + } + if (attr && m_posHorz < 0) { + lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), ONE_2x2POS_DEFINED() ? 2*FH+1 : FH+1); + } + break; + } + + case ITEM_MODEL_POT_WARNING: + { + lcd_putsLeft(y, STR_POTWARNING); + uint8_t potMode = g_model.nPotsToWarn >> 6; + if (attr) { + if (m_posHorz) s_editMode = 0; + if (!READ_ONLY() && m_posHorz) { + switch (event) { + case EVT_KEY_LONG(KEY_ENTER): + killEvents(event); + if (potMode == 1) { + SAVE_POT_POSITION(m_posHorz-1); + AUDIO_WARNING1(); + eeDirty(EE_MODEL); + } + break; + case EVT_KEY_BREAK(KEY_ENTER): + g_model.nPotsToWarn ^= (1 << (m_posHorz-1)); + eeDirty(EE_MODEL); + break; + } + } + } + lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), potMode, (m_posHorz == 0) ? attr : 0); + if (potMode) { + coord_t x = MODEL_SETUP_2ND_COLUMN+5*FW; + for (int i=0; i POT3) { + x -= FW; + } +#endif + lcd_putsiAtt(x, y, STR_RETA123, i, ((m_posHorz==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + g_model.externalModule = checkIncDec(event, g_model.externalModule, MODULE_TYPE_NONE, MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable); + if (checkIncDec_Ret) { + g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; + g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; + if (g_model.externalModule == MODULE_TYPE_PPM) + g_model.moduleData[EXTERNAL_MODULE].channelsCount = 0; + else + g_model.moduleData[EXTERNAL_MODULE].channelsCount = MAX_EXTERNAL_MODULE_CHANNELS(); + } + break; + case 1: + if (IS_MODULE_DSM2(EXTERNAL_MODULE)) + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); + else + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST); + if (checkIncDec_Ret) { + g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; + g_model.moduleData[EXTERNAL_MODULE].channelsCount = MAX_EXTERNAL_MODULE_CHANNELS(); + } + } + } + break; + + case ITEM_MODEL_TRAINER_LABEL: + lcd_putsLeft(y, STR_TRAINER); + break; + + case ITEM_MODEL_INTERNAL_MODULE_CHANNELS: + case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS: + case ITEM_MODEL_TRAINER_CHANNELS: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + ModuleData & moduleData = g_model.moduleData[moduleIdx]; + lcd_putsLeft(y, STR_CHANNELRANGE); + if ((int8_t)PORT_CHANNELS_ROWS(moduleIdx) >= 0) { + lcd_putsAtt(MODEL_SETUP_2ND_COLUMN, y, STR_CH, m_posHorz==0 ? attr : 0); + lcd_outdezAtt(lcdLastPos, y, moduleData.channelsStart+1, LEFT | (m_posHorz==0 ? attr : 0)); + lcd_putc(lcdLastPos, y, '-'); + lcd_outdezAtt(lcdLastPos + FW+1, y, moduleData.channelsStart+NUM_CHANNELS(moduleIdx), LEFT | (m_posHorz==1 ? attr : 0)); + if (attr && (editMode>0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min(MAX_CHANNELS(moduleIdx), 32-8-moduleData.channelsStart)); + if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.externalModule == MODULE_TYPE_PPM) || (k == ITEM_MODEL_TRAINER_CHANNELS)) { + SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + } + break; + } + } + } + break; + } + + case ITEM_MODEL_INTERNAL_MODULE_BIND: + case ITEM_MODEL_EXTERNAL_MODULE_BIND: + case ITEM_MODEL_TRAINER_SETTINGS: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + ModuleData & moduleData = g_model.moduleData[moduleIdx]; + if (IS_MODULE_PPM(moduleIdx)) { + lcd_putsLeft(y, STR_PPMFRAME); + lcd_puts(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); + lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppmFrameLength*5 + 225, (m_posHorz<=0 ? attr : 0) | PREC1|LEFT); + lcd_putc(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); + lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (moduleData.ppmDelay*50)+300, (CURSOR_ON_LINE() || m_posHorz==1) ? attr : 0); + lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, moduleData.ppmPulsePol ? '+' : '-', (CURSOR_ON_LINE() || m_posHorz==2) ? attr : 0); + + if (attr && (editMode>0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + CHECK_INCDEC_MODELVAR(event, moduleData.ppmFrameLength, -20, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, moduleData.ppmDelay, -4, 10); + break; + case 2: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.ppmPulsePol, 1); + break; + } + } + } + else { + horzpos_t l_posHorz = m_posHorz; + coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; + if (IS_MODULE_XJT(moduleIdx) && IS_D8_RX(moduleIdx)) { + xOffsetBind = 0; + lcd_putsLeft(y, INDENT "Receiver"); + if (attr) l_posHorz += 1; + } + else { + lcd_putsLeft(y, STR_RXNUM); + } + if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx)) { + if (xOffsetBind) lcd_outdezNAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId, (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2); + if (attr && l_posHorz==0) { + if (editMode>0 || p1valdiff) { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId, IS_MODULE_DSM2(moduleIdx) ? 20 : 63); + if (checkIncDec_Ret) { + modelHeaders[g_eeGeneral.currModel].modelId = g_model.header.modelId; + } + } + if (editMode==0 && event==EVT_KEY_BREAK(KEY_ENTER)) { + checkModelIdUnique(g_eeGeneral.currModel); + } + } + lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, l_posHorz==1 ? attr : 0); + lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); + uint8_t newFlag = 0; + if (attr && l_posHorz>0 && s_editMode>0) { + if (l_posHorz == 1) + newFlag = MODULE_BIND; + else if (l_posHorz == 2) { + newFlag = MODULE_RANGECHECK; + } + } + moduleFlag[moduleIdx] = newFlag; + } + } + break; + } + + case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE: + case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + ModuleData & moduleData = g_model.moduleData[moduleIdx]; + lcd_putsLeft(y, TR_FAILSAFE); + if (IS_MODULE_XJT(moduleIdx)) { + lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, m_posHorz==0 ? attr : 0); + if (moduleData.failsafeMode == FAILSAFE_CUSTOM) lcd_putsAtt(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, m_posHorz==1 ? attr : 0); + if (attr) { + if (moduleData.failsafeMode != FAILSAFE_CUSTOM) + m_posHorz = 0; + if (m_posHorz==0) { + if (editMode>0 || p1valdiff) { + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.failsafeMode, FAILSAFE_LAST); + if (checkIncDec_Ret) SEND_FAILSAFE_NOW(moduleIdx); + } + } + else if (m_posHorz==1) { + s_editMode = 0; + if (moduleData.failsafeMode==FAILSAFE_CUSTOM && event==EVT_KEY_FIRST(KEY_ENTER)) { + g_moduleIdx = moduleIdx; + pushMenu(menuModelFailsafe); + } + } + else { + lcd_filled_rect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + } + } + } + break; + } + } + } + +#if defined(PXX) + if (IS_RANGECHECK_ENABLE()) { + displayPopup("RSSI: "); + lcd_outdezAtt(16+4*FW, 5*FH, TELEMETRY_RSSI(), BOLD); + } +#endif +} + +void menuModelFailsafe(uint8_t event) +{ + static bool longNames = false; + bool newLongNames = false; + uint8_t ch = 0; + + if (event == EVT_KEY_LONG(KEY_ENTER) && s_editMode) { + s_noHi = NO_HI_LEN; + g_model.moduleData[g_moduleIdx].failsafeChannels[m_posVert] = channelOutputs[m_posVert]; + eeDirty(EE_MODEL); + AUDIO_WARNING1(); + SEND_FAILSAFE_NOW(g_moduleIdx); + } + + SIMPLE_SUBMENU_NOTITLE(NUM_CHNOUT); + + SET_SCROLLBAR_X(0); + + #define COL_W (LCD_W/2) + const uint8_t SLIDER_W = 64; + // Column separator + lcd_vline(LCD_W/2, FH, LCD_H-FH); + + if (m_posVert >= 16) { + ch = 16; + } + + lcd_putsCenter(0*FH, FAILSAFESET); + lcd_invert_line(0); + + for (uint8_t col=0; col<2; col++) { + coord_t x = col*COL_W+1; + + // Channels + for (uint8_t line=0; line<8; line++) { + coord_t y = 9+line*7; + int32_t val; + uint8_t ofs = (col ? 0 : 1); + + if (ch < g_model.moduleData[g_moduleIdx].channelsStart || ch >= NUM_CHANNELS(g_moduleIdx) + g_model.moduleData[g_moduleIdx].channelsStart) + val = 0; + else if (s_editMode && m_posVert == ch) + val = channelOutputs[ch]; + else + val = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; + + // Channel name if present, number if not + uint8_t lenLabel = ZLEN(g_model.limitData[ch].name); + if (lenLabel > 4) { + newLongNames = longNames = true; + } + + if (lenLabel > 0) + lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE); + else + putsChn(x+1-ofs, y, ch+1, SMLSIZE); + + // Value + LcdFlags flags = TINSIZE; + if (m_posVert == ch && !s_noHi) { + flags |= INVERS; + if (s_editMode) + flags |= BLINK; + } +#if defined(PPM_UNIT_US) + uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W); + lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+val/2, flags); +#elif defined(PPM_UNIT_PERCENT_PREC1) + uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6); + lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val), PREC1|flags); +#else + uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W); + lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val)/10, flags); +#endif + + // Gauge + lcd_rect(x+COL_W-3-wbar-ofs, y, wbar+1, 6); + uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2; + uint8_t len = limit((uint8_t)1, uint8_t((abs(val) * wbar/2 + lim/2) / lim), uint8_t(wbar/2)); + coord_t x0 = (val>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-len; + lcd_hline(x0, y+1, len); + lcd_hline(x0, y+2, len); + lcd_hline(x0, y+3, len); + lcd_hline(x0, y+4, len); + + ch++; + } + } + + longNames = newLongNames; +} diff --git a/radio/src/gui/menu_model_flightmodes.cpp b/radio/src/gui/menu_model_flightmodes.cpp index 69d9e7b87..5c477b7a9 100755 --- a/radio/src/gui/menu_model_flightmodes.cpp +++ b/radio/src/gui/menu_model_flightmodes.cpp @@ -35,17 +35,7 @@ #include "../opentx.h" -#if defined(PCBTARANIS) -void displayFlightModes(coord_t x, coord_t y, FlightModesType value) -{ - lcd_puts(x, y, STR_FP); - x = lcdNextPos + 1; - for (uint8_t p=0; p 0) { posHorz += 1; } - - if (sub=0) { - displayColumnHeader(STR_PHASES_HEADERS, posHorz); - } - - for (uint8_t i=0; i0) ? BLINK|INVERS : INVERS) : 0); - uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; - switch (j) { - case ITEM_FLIGHT_MODES_NAME: - editName(4*FW-1, y, p->name, sizeof(p->name), event, attr); - break; - - case ITEM_FLIGHT_MODES_SWITCH: - putsSwitches((5+LEN_FLIGHT_MODE_NAME)*FW+FW/2, y, p->swtch, attr); - if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); - break; - - case ITEM_FLIGHT_MODES_TRIM_RUD: - case ITEM_FLIGHT_MODES_TRIM_ELE: - case ITEM_FLIGHT_MODES_TRIM_THR: - case ITEM_FLIGHT_MODES_TRIM_AIL: - { - uint8_t t = j-ITEM_FLIGHT_MODES_TRIM_RUD; - putsTrimMode((4+LEN_FLIGHT_MODE_NAME)*FW+j*(5*FW/2), y, k, t, attr); - if (active) { - trim_t & v = p->trim[t]; - v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable); - } - break; - } - - case ITEM_FLIGHT_MODES_FADE_IN: - lcd_outdezAtt(32*FW-2, y, (10/DELAY_STEP)*p->fadeIn, attr|PREC1); - if (active) p->fadeIn = checkIncDec(event, p->fadeIn, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); - break; - - case ITEM_FLIGHT_MODES_FADE_OUT: - lcd_outdezAtt(35*FW, y, (10/DELAY_STEP)*p->fadeOut, attr|PREC1); - if (active) p->fadeOut = checkIncDec(event, p->fadeOut, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); - break; - - } - } - } -} - -#else // PCBTARANIS enum menuModelPhaseItems { ITEM_MODEL_PHASE_NAME, @@ -407,5 +284,3 @@ void menuModelFlightModesAll(uint8_t event) lcd_status_line(); } } - -#endif // defined(PCBTARANIS) diff --git a/radio/src/gui/menu_model_limits.cpp b/radio/src/gui/menu_model_limits.cpp index f580dd643..5876bc98d 100755 --- a/radio/src/gui/menu_model_limits.cpp +++ b/radio/src/gui/menu_model_limits.cpp @@ -46,16 +46,10 @@ bool isThrottleOutput(uint8_t ch) } enum LimitsItems { -#if defined(PCBTARANIS) - ITEM_LIMITS_CH_NAME, -#endif ITEM_LIMITS_OFFSET, ITEM_LIMITS_MIN, ITEM_LIMITS_MAX, ITEM_LIMITS_DIRECTION, -#if defined(PCBTARANIS) && defined(CURVES) - ITEM_LIMITS_CURVE, -#endif #if defined(PPM_CENTER_ADJUSTABLE) ITEM_LIMITS_PPM_CENTER, #endif @@ -66,61 +60,37 @@ enum LimitsItems { ITEM_LIMITS_MAXROW = ITEM_LIMITS_COUNT-1 }; -#if defined(PCBTARANIS) - #define LIMITS_NAME_POS 4*FW - #define LIMITS_OFFSET_POS 14*FW+4 - #define LIMITS_MIN_POS 20*FW-3 +#if defined(PPM_UNIT_US) + #define LIMITS_MIN_POS 12*FW+1 +#else + #define LIMITS_MIN_POS 12*FW +#endif +#define LIMITS_OFFSET_POS 8*FW +#if defined(PPM_LIMITS_SYMETRICAL) #if defined(PPM_CENTER_ADJUSTABLE) - #define LIMITS_DIRECTION_POS 20*FW-3 - #define LIMITS_MAX_POS 24*FW+2 - #define LIMITS_REVERT_POS 25*FW-1 - #define LIMITS_CURVE_POS 27*FW-1 - #define LIMITS_PPM_CENTER_POS 34*FW + #define LIMITS_MAX_POS 15*FW + #define LIMITS_REVERT_POS 16*FW-3 + #define LIMITS_PPM_CENTER_POS 20*FW+1 #else - #define LIMITS_DIRECTION_POS 21*FW - #define LIMITS_MAX_POS 26*FW - #define LIMITS_REVERT_POS 27*FW - #define LIMITS_CURVE_POS 32*FW-3 + #define LIMITS_DIRECTION_POS 12*FW+4 + #define LIMITS_MAX_POS 16*FW+4 + #define LIMITS_REVERT_POS 17*FW #endif #else - #if defined(PPM_UNIT_US) - #define LIMITS_MIN_POS 12*FW+1 + #if defined(PPM_CENTER_ADJUSTABLE) + #define LIMITS_MAX_POS 16*FW + #define LIMITS_REVERT_POS 17*FW-2 + #define LIMITS_PPM_CENTER_POS 21*FW+2 #else - #define LIMITS_MIN_POS 12*FW - #endif - #define LIMITS_OFFSET_POS 8*FW - #if defined(PPM_LIMITS_SYMETRICAL) - #if defined(PPM_CENTER_ADJUSTABLE) - #define LIMITS_MAX_POS 15*FW - #define LIMITS_REVERT_POS 16*FW-3 - #define LIMITS_PPM_CENTER_POS 20*FW+1 - #else - #define LIMITS_DIRECTION_POS 12*FW+4 - #define LIMITS_MAX_POS 16*FW+4 - #define LIMITS_REVERT_POS 17*FW - #endif - #else - #if defined(PPM_CENTER_ADJUSTABLE) - #define LIMITS_MAX_POS 16*FW - #define LIMITS_REVERT_POS 17*FW-2 - #define LIMITS_PPM_CENTER_POS 21*FW+2 - #else - #define LIMITS_MAX_POS 17*FW - #define LIMITS_REVERT_POS 18*FW - #define LIMITS_DIRECTION_POS 12*FW+5 - #endif + #define LIMITS_MAX_POS 17*FW + #define LIMITS_REVERT_POS 18*FW + #define LIMITS_DIRECTION_POS 12*FW+5 #endif #endif -#if defined(PCBTARANIS) - #define LIMITS_MIN_MAX_OFFSET 1000 - #define CONVERT_US_MIN_MAX(x) (((x)*1280)/250) - #define MIN_MAX_ATTR attr|PREC1 -#else - #define LIMITS_MIN_MAX_OFFSET 100 - #define CONVERT_US_MIN_MAX(x) ((int16_t(x)*128)/25) - #define MIN_MAX_ATTR attr -#endif +#define LIMITS_MIN_MAX_OFFSET 100 +#define CONVERT_US_MIN_MAX(x) ((int16_t(x)*128)/25) +#define MIN_MAX_ATTR attr #if defined(PPM_UNIT_US) #define SET_MIN_MAX(x, val) x = ((val)*250)/128 @@ -132,29 +102,6 @@ enum LimitsItems { #define MIN_MAX_DISPLAY(x) ((int8_t)(x)) #endif -#if defined(PCBTARANIS) -void onLimitsMenu(const char *result) -{ - uint8_t ch = m_posVert - 1; - - if (result == STR_RESET) { - LimitData *ld = limitAddress(ch); - ld->min = 0; - ld->max = 0; - ld->offset = 0; - ld->ppmCenter = 0; - ld->revert = false; - ld->curve = 0; - } - else if (result == STR_COPY_STICKS_TO_OFS) { - copySticksToOffset(ch); - } - else if (result == STR_COPY_TRIMS_TO_OFS) { - copyTrimsToOffset(ch); - } -} -#endif - void menuModelLimits(uint8_t event) { uint8_t sub = m_posVert - 1; @@ -174,12 +121,6 @@ void menuModelLimits(uint8_t event) MENU(STR_MENULIMITS, menuTabModel, e_Limits, 1+NUM_CHNOUT+1, {0, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, ITEM_LIMITS_MAXROW, 0}); #endif -#if LCD_W >= 212 - if (sub=0) { - displayColumnHeader(STR_LIMITS_HEADERS, m_posHorz); - } -#endif - if (s_warning_result) { s_warning_result = 0; LimitData *ld = limitAddress(sub); @@ -208,35 +149,18 @@ void menuModelLimits(uint8_t event) LimitData *ld = limitAddress(k); -#if LCD_W >= 212 || !defined(PPM_CENTER_ADJUSTABLE) +#if !defined(PPM_CENTER_ADJUSTABLE) int16_t v = (ld->revert) ? -LIMIT_OFS(ld) : LIMIT_OFS(ld); char swVal = '-'; // '-', '<', '>' if ((channelOutputs[k] - v) > 50) swVal = (ld->revert ? 127 : 126); // Switch to raw inputs? - remove trim! if ((channelOutputs[k] - v) < -50) swVal = (ld->revert ? 126 : 127); -#if !defined(PCBTARANIS) putsChn(0, y, k+1, 0); -#endif lcd_putc(LIMITS_DIRECTION_POS, y, swVal); #endif -#if defined(PCBTARANIS) - int limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 1000); -#else int8_t limit = (g_model.extendedLimits ? LIMIT_EXT_MAX : 100); -#endif -#if defined(PCBTARANIS) - putsChn(0, y, k+1, (sub==k && m_posHorz < 0) ? INVERS : 0); - if (sub==k && m_posHorz < 0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { - killEvents(event); - MENU_ADD_ITEM(STR_RESET); - MENU_ADD_ITEM(STR_COPY_TRIMS_TO_OFS); - MENU_ADD_ITEM(STR_COPY_STICKS_TO_OFS); - menuHandler = onLimitsMenu; - } -#else putsChn(0, y, k+1, 0); -#endif for (uint8_t j=0; j0) ? BLINK|INVERS : INVERS) : 0); @@ -244,20 +168,7 @@ void menuModelLimits(uint8_t event) if (active) STICK_SCROLL_DISABLE(); switch(j) { -#if defined(PCBTARANIS) - case ITEM_LIMITS_CH_NAME: - editName(LIMITS_NAME_POS, y, ld->name, sizeof(ld->name), event, attr); - break; -#endif - case ITEM_LIMITS_OFFSET: -#if defined(PCBTARANIS) - if (GV_IS_GV_VALUE(ld->offset, -1000, 1000) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { - ld->offset = GVAR_MENU_ITEM(LIMITS_OFFSET_POS, y, ld->offset, -1000, 1000, attr|PREC1, 0, event); - break; - } -#endif - #if defined(PPM_UNIT_US) lcd_outdezAtt(LIMITS_OFFSET_POS, y, ((int32_t)ld->offset*128) / 25, attr|PREC1); #else @@ -277,12 +188,6 @@ void menuModelLimits(uint8_t event) break; case ITEM_LIMITS_MIN: -#if defined(PCBTARANIS) - if (GV_IS_GV_VALUE(ld->min, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { - ld->min = GVAR_MENU_ITEM(LIMITS_MIN_POS, y, ld->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); - break; - } -#endif lcd_outdezAtt(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); #if defined(CPUARM) if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL, NULL, stops1000); @@ -292,12 +197,6 @@ void menuModelLimits(uint8_t event) break; case ITEM_LIMITS_MAX: -#if defined(PCBTARANIS) - if (GV_IS_GV_VALUE(ld->max, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { - ld->max = GVAR_MENU_ITEM(LIMITS_MAX_POS, y, ld->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); - break; - } -#endif lcd_outdezAtt(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); #if defined(CPUARM) if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL, NULL, stops1000); @@ -326,19 +225,6 @@ void menuModelLimits(uint8_t event) break; } -#if defined(PCBTARANIS) && defined(CURVES) - case ITEM_LIMITS_CURVE: - putsCurve(LIMITS_CURVE_POS, y, ld->curve, attr); - if (attr && event==EVT_KEY_LONG(KEY_ENTER) && ld->curve>0) { - s_curveChan = (ld->curve<0 ? -ld->curve-1 : ld->curve-1); - pushMenu(menuModelCurveOne); - } - if (active) { - CHECK_INCDEC_MODELVAR(event, ld->curve, -MAX_CURVES, +MAX_CURVES); - } - break; -#endif - #if defined(PPM_CENTER_ADJUSTABLE) case ITEM_LIMITS_PPM_CENTER: lcd_outdezAtt(LIMITS_PPM_CENTER_POS, y, PPM_CENTER+ld->ppmCenter, attr); diff --git a/radio/src/gui/menu_model_setup.cpp b/radio/src/gui/menu_model_setup.cpp index ecaf29b0f..960a3b398 100755 --- a/radio/src/gui/menu_model_setup.cpp +++ b/radio/src/gui/menu_model_setup.cpp @@ -42,7 +42,6 @@ void menuModelFailsafe(uint8_t event); enum menuModelSetupItems { ITEM_MODEL_NAME, - CASE_PCBTARANIS(ITEM_MODEL_BITMAP) ITEM_MODEL_TIMER1, CASE_CPUARM(ITEM_MODEL_TIMER1_NAME) CASE_PERSISTENT_TIMERS(ITEM_MODEL_TIMER1_PERSISTENT) @@ -62,7 +61,6 @@ enum menuModelSetupItems { ITEM_MODEL_EXTENDED_TRIMS, CASE_CPUARM(ITEM_MODEL_DISPLAY_TRIMS) ITEM_MODEL_TRIM_INC, - CASE_PCBTARANIS(ITEM_MODEL_THROTTLE_LABEL) ITEM_MODEL_THROTTLE_REVERSED, ITEM_MODEL_THROTTLE_TRACE, ITEM_MODEL_THROTTLE_TRIM, @@ -70,26 +68,9 @@ enum menuModelSetupItems { CASE_CPUARM(ITEM_MODEL_CHECKLIST_DISPLAY) ITEM_MODEL_THROTTLE_WARNING, ITEM_MODEL_SWITCHES_WARNING, - CASE_PCBTARANIS(ITEM_MODEL_SWITCHES_WARNING2) - CASE_PCBTARANIS(ITEM_MODEL_POT_WARNING) ITEM_MODEL_BEEP_CENTER, CASE_CPUARM(ITEM_MODEL_USE_GLOBAL_FUNCTIONS) -#if defined(PCBTARANIS) - ITEM_MODEL_INTERNAL_MODULE_LABEL, - ITEM_MODEL_INTERNAL_MODULE_MODE, - ITEM_MODEL_INTERNAL_MODULE_CHANNELS, - ITEM_MODEL_INTERNAL_MODULE_BIND, - ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, - ITEM_MODEL_EXTERNAL_MODULE_LABEL, - ITEM_MODEL_EXTERNAL_MODULE_MODE, - ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, - ITEM_MODEL_EXTERNAL_MODULE_BIND, - ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, - ITEM_MODEL_TRAINER_LABEL, - ITEM_MODEL_TRAINER_MODE, - ITEM_MODEL_TRAINER_CHANNELS, - ITEM_MODEL_TRAINER_SETTINGS, -#elif defined(CPUARM) +#if defined(CPUARM) ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_MODE, ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, @@ -113,48 +94,12 @@ enum menuModelSetupItems { #define FIELD_PROTOCOL_MAX 1 #endif -#if LCD_W >= 212 - #define MODEL_SETUP_2ND_COLUMN (LCD_W-17*FW-MENUS_SCROLLBAR_WIDTH) - #define MODEL_SETUP_BIND_OFS 3*FW-2 - #define MODEL_SETUP_RANGE_OFS 7*FW - #define MODEL_SETUP_SET_FAILSAFE_OFS 10*FW -#else - #define MODEL_SETUP_2ND_COLUMN (LCD_W-11*FW-MENUS_SCROLLBAR_WIDTH) - #define MODEL_SETUP_BIND_OFS 2*FW+1 - #define MODEL_SETUP_RANGE_OFS 4*FW+3 - #define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2 -#endif +#define MODEL_SETUP_2ND_COLUMN (LCD_W-11*FW-MENUS_SCROLLBAR_WIDTH) +#define MODEL_SETUP_BIND_OFS 2*FW+1 +#define MODEL_SETUP_RANGE_OFS 4*FW+3 +#define MODEL_SETUP_SET_FAILSAFE_OFS 7*FW-2 -#if defined(PCBTARANIS) && defined(SDCARD) -void copySelection(char *dst, const char *src, uint8_t size) -{ - if (memcmp(src, "---", 3) == 0) - memset(dst, 0, size); - else - memcpy(dst, src, size); -} - -void onModelSetupBitmapMenu(const char *result) -{ - if (result == STR_UPDATE_LIST) { - if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), NULL)) { - POPUP_WARNING(STR_NO_BITMAPS_ON_SD); - s_menu_flags = 0; - } - } - else { - // The user choosed a bmp file in the list - copySelection(g_model.header.bitmap, result, sizeof(g_model.header.bitmap)); - LOAD_MODEL_BITMAP(); - memcpy(modelHeaders[g_eeGeneral.currModel].bitmap, g_model.header.bitmap, sizeof(g_model.header.bitmap)); - eeDirty(EE_MODEL); - } -} -#endif - -#if defined(PCBTARANIS) - #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)) -#elif defined(PCBSKY9X) && !defined(REVA) && !defined(REVX) +#if defined(PCBSKY9X) && !defined(REVA) && !defined(REVX) #define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE) #else #define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE) @@ -162,24 +107,7 @@ void onModelSetupBitmapMenu(const char *result) void menuModelSetup(uint8_t event) { -#if defined(PCBTARANIS) - horzpos_t l_posHorz = m_posHorz; - #define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? HIDDEN_ROW : (uint8_t)(x)) - #define IF_EXTERNAL_MODULE_ON(x) (g_model.externalModule == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x)) - #define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW) - #define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW) - #define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8) - #define INTERNAL_MODULE_CHANNELS_ROWS() IF_INTERNAL_MODULE_ON(1) - #define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1) - #define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1) - #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS() : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS() : TRAINER_CHANNELS_ROWS())) - #define FAILSAFE_ROWS(x) ((g_model.moduleData[x].rfProtocol==RF_PROTO_X16 || g_model.moduleData[x].rfProtocol==RF_PROTO_LR12) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW) - #define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX) - #define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0) - #define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 - bool CURSOR_ON_CELL = (m_posHorz >= 0); - MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsAllowed()), ONE_2x2POS_DEFINED() ? TITLE_ROW : HIDDEN_ROW, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(InternalModule), 0, IF_INTERNAL_MODULE_ON(1), IF_INTERNAL_MODULE_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); -#elif defined(CPUARM) +#if defined(CPUARM) #define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW) #define IF_EXTERNAL_MODULE_ON(x) (g_model.externalModule == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x)) #define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8) @@ -197,17 +125,17 @@ void menuModelSetup(uint8_t event) #define EXTRA_MODULE_ROWS #endif #define TRAINER_MODULE_ROWS - MENU_TAB({ 0, 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, 0, LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), EXTRA_MODULE_ROWS TRAINER_MODULE_ROWS }); + MENU_TAB({ 0, 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, 0, LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), EXTRA_MODULE_ROWS TRAINER_MODULE_ROWS }); #elif defined(CPUM64) #define CURSOR_ON_CELL (true) #define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX) uint8_t protocol = g_model.protocol; - MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 }); + MENU_TAB({ 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2 }); #else #define CURSOR_ON_CELL (true) #define MODEL_SETUP_MAX_LINES ((IS_PPM_PROTOCOL(protocol)||IS_DSM2_PROTOCOL(protocol)||IS_PXX_PROTOCOL(protocol)) ? 1+ITEM_MODEL_SETUP_MAX : ITEM_MODEL_SETUP_MAX) uint8_t protocol = g_model.protocol; - MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, NUM_SWITCHES, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, CASE_PCBSKY9X(1) CASE_PCBSKY9X(2) }); + MENU_TAB({ 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 2, CASE_PERSISTENT_TIMERS(0) 0, 0, 0, 1, 0, 0, 0, 0, 0, NUM_SWITCHES, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, FIELD_PROTOCOL_MAX, 2, CASE_PCBSKY9X(1) CASE_PCBSKY9X(2) }); #endif MENU_CHECK(menuTabModel, e_ModelSetup, MODEL_SETUP_MAX_LINES); @@ -226,8 +154,8 @@ void menuModelSetup(uint8_t event) uint8_t sub = m_posVert - 1; int8_t editMode = s_editMode; - for (uint8_t i=0; i0) ? BLINK|INVERS : INVERS); - uint8_t attr = (sub == k ? blink : 0); + LcdFlags blink = ((editMode>0) ? BLINK|INVERS : INVERS); + LcdFlags attr = (sub == k ? blink : 0); switch(k) { case ITEM_MODEL_NAME: @@ -247,26 +175,6 @@ void menuModelSetup(uint8_t event) #endif break; -#if defined(PCBTARANIS) && defined(SDCARD) - case ITEM_MODEL_BITMAP: - lcd_putsLeft(y, STR_BITMAP); - if (ZEXIST(g_model.header.bitmap)) - lcd_putsnAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.bitmap, sizeof(g_model.header.bitmap), attr); - else - lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); - if (attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) { - s_editMode = 0; - if (listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), g_model.header.bitmap, LIST_NONE_SD_FILE)) { - menuHandler = onModelSetupBitmapMenu; - } - else { - POPUP_WARNING(STR_NO_BITMAPS_ON_SD); - s_menu_flags = 0; - } - } - break; -#endif - #if defined(CPUARM) case ITEM_MODEL_TIMER1: case ITEM_MODEL_TIMER2: @@ -277,9 +185,6 @@ void menuModelSetup(uint8_t event) putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); -#if defined(PCBTARANIS) - if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); -#endif if (attr && (editMode>0 || p1valdiff)) { div_t qr = div(timer->start, 60); switch (m_posHorz) { @@ -439,12 +344,6 @@ void menuModelSetup(uint8_t event) g_model.trimInc = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_TRIMINC, STR_VTRIMINC, g_model.trimInc, -2, 2, attr, event); break; -#if defined(PCBTARANIS) - case ITEM_MODEL_THROTTLE_LABEL: - lcd_putsLeft(y, STR_THROTTLE_LABEL); - break; -#endif - case ITEM_MODEL_THROTTLE_REVERSED: ON_OFF_MENU_ITEM(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ; break; @@ -480,21 +379,7 @@ void menuModelSetup(uint8_t event) g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event); break; -#if defined(PCBTARANIS) - // TODO something more generic - case ITEM_MODEL_SWITCHES_WARNING2: - if (i==0) s_pgOfs++; - break; -#endif - case ITEM_MODEL_SWITCHES_WARNING: -#if defined(PCBTARANIS) - // TODO something more generic - if (i==LCD_LINES-2) { - s_pgOfs++; - break; - } -#endif { lcd_putsLeft(y, STR_SWITCHWARNING); swarnstate_t states = g_model.switchWarningState; @@ -508,7 +393,7 @@ void menuModelSetup(uint8_t event) #if defined(CPUM64) g_model.switchWarningEnable ^= (1 << m_posHorz); eeDirty(EE_MODEL); -#elif !defined(PCBTARANIS) +#else if (m_posHorz < NUM_SWITCHES-1) { g_model.switchWarningEnable ^= (1 << m_posHorz); eeDirty(EE_MODEL); @@ -522,14 +407,6 @@ void menuModelSetup(uint8_t event) g_model.switchWarningState = switches_states; AUDIO_WARNING1(); eeDirty(EE_MODEL); -#elif defined(PCBTARANIS) - if (m_posHorz < 0) { - s_noHi = NO_HI_LEN; - getMovedSwitch(); - g_model.switchWarningState = switches_states; - AUDIO_WARNING1(); - eeDirty(EE_MODEL); - } #else if (m_posHorz == NUM_SWITCHES-1) { s_noHi = NO_HI_LEN; @@ -547,26 +424,6 @@ void menuModelSetup(uint8_t event) LcdFlags line = attr; -#if defined(PCBTARANIS) - for (int i=0, current=0; i>= 2; - } - if (attr && m_posHorz < 0) { - lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), ONE_2x2POS_DEFINED() ? 2*FH+1 : FH+1); - } -#else for (uint8_t i=0; i> 6; - if (attr) { - if (m_posHorz) s_editMode = 0; - if (!READ_ONLY() && m_posHorz) { - switch (event) { - case EVT_KEY_LONG(KEY_ENTER): - killEvents(event); - if (potMode == 1) { - SAVE_POT_POSITION(m_posHorz-1); - AUDIO_WARNING1(); - eeDirty(EE_MODEL); - } - break; - case EVT_KEY_BREAK(KEY_ENTER): - g_model.nPotsToWarn ^= (1 << (m_posHorz-1)); - eeDirty(EE_MODEL); - break; - } - } - } - lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), potMode, attr & ((m_posHorz == 0) ? attr : !INVERS)); - if (potMode) { - coord_t x = MODEL_SETUP_2ND_COLUMN+5*FW; - for (uint8_t i=0; i POT3) { - x -= FW; - } -#endif lcd_putsiAtt(x, y, STR_RETA123, i, ((m_posHorz==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<(MAX_CHANNELS(moduleIdx), 32-8-moduleData.channelsStart)); - if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.externalModule == MODULE_TYPE_PPM) -#if defined(PCBTARANIS) - || (k == ITEM_MODEL_TRAINER_CHANNELS) -#endif - ) + if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.externalModule == MODULE_TYPE_PPM)) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + } break; } } @@ -791,16 +554,11 @@ void menuModelSetup(uint8_t event) } #endif -#if defined(PCBTARANIS) - case ITEM_MODEL_INTERNAL_MODULE_BIND: -#elif defined(PCBSKY9X) && !defined(REVX) +#if defined(PCBSKY9X) && !defined(REVX) case ITEM_MODEL_EXTRA_MODULE_BIND: #endif #if defined(CPUARM) case ITEM_MODEL_EXTERNAL_MODULE_BIND: -#if defined(PCBTARANIS) - case ITEM_MODEL_TRAINER_SETTINGS: -#endif { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; @@ -867,9 +625,6 @@ void menuModelSetup(uint8_t event) } #endif -#if defined(PCBTARANIS) - case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE: -#endif #if defined(CPUARM) case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE: { @@ -1058,29 +813,15 @@ void menuModelFailsafe(uint8_t event) SET_SCROLLBAR_X(0); -#if LCD_W >= 212 - #define COL_W (LCD_W/2) - const uint8_t SLIDER_W = 64; - // Column separator - lcd_vline(LCD_W/2, FH, LCD_H-FH); - - if (m_posVert >= 16) { - ch = 16; - } -#else #define COL_W (LCD_W) const uint8_t SLIDER_W = 90; ch = 8 * (m_posVert / 8); -#endif lcd_putsCenter(0*FH, FAILSAFESET); lcd_invert_line(0); -#if LCD_W >= 212 - for (uint8_t col=0; col<2; col++) -#else uint8_t col = 0; -#endif + { coord_t x = col*COL_W+1; @@ -1097,20 +838,7 @@ void menuModelFailsafe(uint8_t event) else val = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; -#if defined(PCBTARANIS) - // Channel name if present, number if not - uint8_t lenLabel = ZLEN(g_model.limitData[ch].name); - if (lenLabel > 4) { - newLongNames = longNames = true; - } - - if (lenLabel > 0) - lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE); - else - putsChn(x+1-ofs, y, ch+1, SMLSIZE); -#else putsChn(x+1-ofs, y, ch+1, SMLSIZE); -#endif // Value LcdFlags flags = TINSIZE; diff --git a/radio/src/lcd.h b/radio/src/lcd.h index b4913bc4a..7e7906846 100644 --- a/radio/src/lcd.h +++ b/radio/src/lcd.h @@ -332,4 +332,9 @@ char * strAppend(char * dest, const char * source); char * strAppendDate(char * str, bool time=false); char * strAppendFilename(char * dest, const char * filename, const int size); +#define NUM_BODY_LINES LCD_LINES-1 +#define HEIGHT_BODY_LINE FH +#define MENU_TITLE_HEIGHT FH +#define MENU_NAVIG_HEIGHT 0 + #endif