From 670e101fa574b12efc55ad6e97fee290e8e86aee Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 29 May 2019 16:04:09 +0200 Subject: [PATCH] Bsongis/menus refactoring (#6463) Menus refactoring --- radio/src/gui/128x64/gui.h | 52 +-- radio/src/gui/128x64/lcd.cpp | 18 - radio/src/gui/128x64/menus.h | 33 +- radio/src/gui/128x64/model_flightmodes.cpp | 2 +- radio/src/gui/128x64/model_inputs_mixes.cpp | 2 +- .../src/gui/128x64/model_logical_switches.cpp | 2 +- radio/src/gui/128x64/model_outputs.cpp | 2 +- radio/src/gui/128x64/model_select.cpp | 2 +- radio/src/gui/128x64/model_setup.cpp | 334 ++------------ radio/src/gui/128x64/radio_calibration.cpp | 2 +- radio/src/gui/128x64/radio_version.cpp | 2 +- radio/src/gui/128x64/view_statistics.cpp | 6 +- radio/src/gui/212x64/gui.h | 57 +-- radio/src/gui/212x64/menus.h | 23 +- radio/src/gui/212x64/model_select.cpp | 4 +- radio/src/gui/212x64/model_setup.cpp | 426 +++++++++++++----- radio/src/gui/212x64/radio_calibration.cpp | 3 +- radio/src/gui/212x64/view_statistics.cpp | 6 +- radio/src/gui/CMakeLists.txt | 8 - radio/src/gui/common/stdlcd/CMakeLists.txt | 27 +- .../gui/{128x64 => common/stdlcd}/menus.cpp | 25 +- radio/src/gui/common/stdlcd/menus.h | 51 +++ .../stdlcd}/model_module_options.cpp | 0 .../stdlcd/model_notes.cpp} | 46 -- .../stdlcd}/model_receiver_options.cpp | 2 +- .../gui/common/stdlcd/model_setup_pxx1.cpp | 47 ++ .../gui/common/stdlcd/model_setup_pxx2.cpp | 263 +++++++++++ radio/src/gui/common/stdlcd/widgets.cpp | 18 + radio/src/gui/gui_common.cpp | 2 +- radio/src/gui/navigation/navigation_x9d.cpp | 14 +- radio/src/keys.h | 4 - radio/src/opentx_types.h | 7 +- radio/src/pulses/pulses.h | 16 - radio/src/targets/common/arm/CMakeLists.txt | 4 + radio/src/targets/horus/CMakeLists.txt | 10 +- radio/src/translations/untranslated.h | 15 + 36 files changed, 848 insertions(+), 687 deletions(-) rename radio/src/gui/{128x64 => common/stdlcd}/menus.cpp (80%) create mode 100644 radio/src/gui/common/stdlcd/menus.h rename radio/src/gui/{128x64 => common/stdlcd}/model_module_options.cpp (100%) rename radio/src/gui/{212x64/menus.cpp => common/stdlcd/model_notes.cpp} (51%) rename radio/src/gui/{128x64 => common/stdlcd}/model_receiver_options.cpp (99%) create mode 100644 radio/src/gui/common/stdlcd/model_setup_pxx1.cpp create mode 100644 radio/src/gui/common/stdlcd/model_setup_pxx2.cpp diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index b453ba607b..c7cb83289e 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -71,7 +71,7 @@ extern int8_t s_editMode; // global editmode #define INCDEC_REP10 0x40 #define NO_DBLKEYS 0x80 -#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL +#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = nullptr #define INCDEC_SET_FLAG(f) incdecFlag = (f) #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) @@ -152,59 +152,39 @@ void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, u void check_submenu_simple(event_t event, uint8_t maxrow); void title(const char * s); -#define TITLE(str) title(str) #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__ -#if defined(NAVIGATION_X7) #define MENU_CHECK(tab, menu, lines_count) \ - check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count) -#else -#define MENU_CHECK(tab, menu, lines_count) \ - check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-1) -#endif + check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE) -#define MENU(title, tab, menu, lines_count, ...) \ +#define MENU(name, tab, menu, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ MENU_CHECK(tab, menu, lines_count); \ - TITLE(title) + title(name) -#if defined(NAVIGATION_X7) -#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \ - check_simple(event, menu, tab, DIM(tab), lines_count); #define SUBMENU_NOTITLE(lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); -#define SUBMENU(title, lines_count, ...) \ - MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \ - TITLE(title) -#define SIMPLE_SUBMENU_NOTITLE(lines_count) \ - check_submenu_simple(event, lines_count); -#else + check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE); + #define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \ - check_simple(event, menu, tab, DIM(tab), (lines_count)-1); -#define SUBMENU_NOTITLE(lines_count, ...) \ - MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); - -#define SUBMENU(title, lines_count, ...) \ - MENU_TAB(__VA_ARGS__); \ - check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \ - TITLE(title) + check_simple(event, menu, tab, DIM(tab), (lines_count)-HEADER_LINE); #define SIMPLE_SUBMENU_NOTITLE(lines_count) \ - check_submenu_simple(event, (lines_count)-1); + check_submenu_simple(event, (lines_count)-HEADER_LINE); -#endif +#define SUBMENU(name, lines_count, ...) \ + MENU_TAB(__VA_ARGS__); \ + check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-HEADER_LINE); \ + title(name) -#define SIMPLE_MENU(title, tab, menu, lines_count) \ +#define SIMPLE_MENU(name, tab, menu, lines_count) \ SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \ - TITLE(title) + title(name) -#define SIMPLE_SUBMENU(title, lines_count) \ +#define SIMPLE_SUBMENU(name, lines_count) \ SIMPLE_SUBMENU_NOTITLE(lines_count); \ - TITLE(title) + title(name) typedef int choice_t; diff --git a/radio/src/gui/128x64/lcd.cpp b/radio/src/gui/128x64/lcd.cpp index 4b94b72ffd..88303595f5 100644 --- a/radio/src/gui/128x64/lcd.cpp +++ b/radio/src/gui/128x64/lcd.cpp @@ -576,24 +576,6 @@ void lcdDrawVerticalLine(coord_t x, scoord_t y, scoord_t h, uint8_t pat, LcdFlag } } -void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags) -{ - if (isModulePXX2(moduleIdx)) { - if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') - lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags); - else - lcdDrawText(x, y, "---", flags); - } -#if defined(HARDWARE_INTERNAL_MODULE) - else if (moduleIdx == INTERNAL_MODULE) { - lcdDrawText(x, y, "Internal", flags); - } -#endif - else { - lcdDrawText(x, y, "External", flags); - } -} - void lcdDrawSolidVerticalLine(coord_t x, scoord_t y, scoord_t h, LcdFlags att) { lcdDrawVerticalLine(x, y, h, SOLID, att); diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index d56867b0cc..39fdf6acda 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -22,42 +22,16 @@ #define _MENUS_H_ #include "keys.h" +#include "common/stdlcd/menus.h" #if defined(PCBTARANIS) -typedef int8_t horzpos_t; #define NAVIGATION_LINE_BY_LINE 0x40 #define IS_LINE_SELECTED(sub, k) ((sub)==(k) && menuHorizontalPosition < 0) #else -typedef uint8_t horzpos_t; #define NAVIGATION_LINE_BY_LINE 0 #define IS_LINE_SELECTED(sub, k) (false) #endif -#if defined(SDCARD) -typedef uint16_t vertpos_t; -#else -typedef uint8_t vertpos_t; -#endif - -typedef void (*MenuHandlerFunc)(event_t event); - -extern tmr10ms_t menuEntryTime; - -extern vertpos_t menuVerticalPosition; -extern horzpos_t menuHorizontalPosition; -extern vertpos_t menuVerticalOffset; -extern uint8_t menuCalibrationState; - -extern MenuHandlerFunc menuHandlers[5]; -extern uint8_t menuVerticalPositions[4]; -extern uint8_t menuLevel; -extern uint8_t menuEvent; - -void chainMenu(MenuHandlerFunc newMenu); -void pushMenu(MenuHandlerFunc newMenu); -void popMenu(); -void abortPopMenu(); - inline bool isRadioMenuDisplayed() { return menuVerticalPositions[0] == 1; @@ -68,11 +42,6 @@ inline bool isModelMenuDisplayed() return menuVerticalPositions[0] == 0; } -inline MenuHandlerFunc lastPopMenu() -{ - return menuHandlers[menuLevel+1]; -} - void onMainViewMenu(const char * result); void menuFirstCalib(event_t event); void menuMainView(event_t event); diff --git a/radio/src/gui/128x64/model_flightmodes.cpp b/radio/src/gui/128x64/model_flightmodes.cpp index ecfe6725ce..c803d9dfcf 100644 --- a/radio/src/gui/128x64/model_flightmodes.cpp +++ b/radio/src/gui/128x64/model_flightmodes.cpp @@ -75,7 +75,7 @@ void menuModelFlightModeOne(event_t event) check(event, 0, NULL, 0, (s_currIdx == 0) ? mstate_tab_fm1 : mstate_tab_others, DIM(mstate_tab_others)-1, ITEM_MODEL_FLIGHT_MODE_MAX - HEADER_LINE - (s_currIdx==0 ? (ITEM_MODEL_FLIGHT_MODE_FADE_IN-ITEM_MODEL_FLIGHT_MODE_SWITCH-1) : 0)); - TITLE(STR_MENUFLIGHTMODE); + title(STR_MENUFLIGHTMODE); #define PHASE_ONE_FIRST_LINE (1+1*FH) #else diff --git a/radio/src/gui/128x64/model_inputs_mixes.cpp b/radio/src/gui/128x64/model_inputs_mixes.cpp index f43c56cc3e..83b2b12e43 100644 --- a/radio/src/gui/128x64/model_inputs_mixes.cpp +++ b/radio/src/gui/128x64/model_inputs_mixes.cpp @@ -378,7 +378,7 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) void menuModelMixOne(event_t event) { - TITLE(STR_MIXER); + title(STR_MIXER); MixData * md2 = mixAddress(s_currIdx) ; putsChn(lcdLastRightPos+1*FW, 0, md2->destCh+1,0); diff --git a/radio/src/gui/128x64/model_logical_switches.cpp b/radio/src/gui/128x64/model_logical_switches.cpp index 5242cd07d7..5bc3227f0e 100644 --- a/radio/src/gui/128x64/model_logical_switches.cpp +++ b/radio/src/gui/128x64/model_logical_switches.cpp @@ -54,7 +54,7 @@ void putsEdgeDelayParam(coord_t x, coord_t y, LogicalSwitchData *cs, uint8_t lat void menuModelLogicalSwitchOne(event_t event) { - TITLE(STR_MENULOGICALSWITCH); + title(STR_MENULOGICALSWITCH); LogicalSwitchData * cs = lswAddress(s_currIdx); diff --git a/radio/src/gui/128x64/model_outputs.cpp b/radio/src/gui/128x64/model_outputs.cpp index d82036a4b4..a069e2362f 100644 --- a/radio/src/gui/128x64/model_outputs.cpp +++ b/radio/src/gui/128x64/model_outputs.cpp @@ -98,7 +98,7 @@ enum MenuModelOutputsOneItems { void menuModelLimitsOne(event_t event) { - TITLE(STR_MENULIMITS); + title(STR_MENULIMITS); LimitData * ld = limitAddress(s_currIdx); putsChn(11*FW, 0, s_currIdx+1, 0); diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp index 8d16b6b73d..a53a2756dc 100644 --- a/radio/src/gui/128x64/model_select.cpp +++ b/radio/src/gui/128x64/model_select.cpp @@ -278,7 +278,7 @@ void menuModelSelect(event_t event) drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0); #endif - TITLE(STR_MENUMODELSEL); + title(STR_MENUMODELSEL); for (uint8_t i=0; i 5 ? TITLE_ROW : HIDDEN_ROW) #endif -#define INTERNAL_MODULE_TYPE_ROWS ((isModuleXJT(INTERNAL_MODULE) || isModulePXX2(INTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols #define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) -#define EXTERNAL_MODULE_BIND_ROWS() ((isModuleXJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW + +#if defined(INTERNAL_MODULE_PXX1) +#define INTERNAL_MODULE_TYPE_ROWS ((isModuleXJT(INTERNAL_MODULE) || isModulePXX2(INTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols +#else +#define INTERNAL_MODULE_TYPE_ROWS (0) // Module type + RF protocols +#endif + +#define EXTERNAL_MODULE_BIND_ROWS ((isModuleXJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW #if defined(PCBSKY9X) && defined(REVX) - #define OUTPUT_TYPE_ROWS() (isModulePPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW) , + #define OUTPUT_TYPE_ROW (isModulePPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW), #elif defined(PCBSKY9X) - #define OUTPUT_TYPE_ROWS() + #define OUTPUT_TYPE_ROW #endif #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) #define EXTERNAL_MODULE_TYPE_ROWS (isModulePXX(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 -#define POT_WARN_ITEMS() ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) +#define POT_WARN_ROWS ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) #define TIMER_ROWS 2, 0, 0, 0, 0 #if defined(PCBSKY9X) @@ -230,277 +241,6 @@ enum MenuModelSetupItems { #define TRAINER_ROWS #endif -#if defined(PXX2) -bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); -} - -void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx) -{ - memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); - g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx); - storageDirty(EE_MODEL); -} - -void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { - removePXX2Receiver(moduleIdx, receiverIdx); - } -} - -void onPXX2R9MBindModeMenu(const char * result) -{ - if (result == STR_8CH_WITH_TELEMETRY) { - reusableBuffer.moduleSetup.bindInformation.lbtMode = 0; - } - else if (result == STR_16CH_WITH_TELEMETRY) { - reusableBuffer.moduleSetup.bindInformation.lbtMode = 1; - } - else if (result == STR_16CH_WITHOUT_TELEMETRY) { - reusableBuffer.moduleSetup.bindInformation.lbtMode = 2; - } - else if (result == STR_FLEX_868) { - reusableBuffer.moduleSetup.bindInformation.flexMode = 0; - } - else if (result == STR_FLEX_915) { - reusableBuffer.moduleSetup.bindInformation.flexMode = 1; - } - else { - // the user pressed [Exit] - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - return; - } - -#if defined(SIMU) - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[reusableBuffer.moduleSetup.bindInformation.selectedReceiverIndex], PXX2_LEN_RX_NAME); - storageDirty(EE_MODEL); - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - reusableBuffer.moduleSetup.bindInformation.step = BIND_OK; - POPUP_INFORMATION(STR_BIND_OK); -#else - reusableBuffer.moduleSetup.bindInformation.step = BIND_START; -#endif -} - -void onPXX2BindMenu(const char * result) -{ - if (result != STR_EXIT) { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - reusableBuffer.moduleSetup.bindInformation.selectedReceiverIndex = (result - reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[0]) / sizeof(reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[0]); - if (isModuleR9M2(moduleIdx) && reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant == PXX2_VARIANT_EU) { - reusableBuffer.moduleSetup.bindInformation.step = BIND_RX_NAME_SELECTED; - POPUP_MENU_ADD_ITEM(STR_8CH_WITH_TELEMETRY); - POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); - POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); - POPUP_MENU_START(onPXX2R9MBindModeMenu); - } - else if (isModuleR9M2(moduleIdx) && reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant == PXX2_VARIANT_FLEX) { - reusableBuffer.moduleSetup.bindInformation.step = BIND_RX_NAME_SELECTED; - POPUP_MENU_ADD_ITEM(STR_FLEX_868); - POPUP_MENU_ADD_ITEM(STR_FLEX_915); - POPUP_MENU_START(onPXX2R9MBindModeMenu); - } - else { -#if defined(SIMU) - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], result, PXX2_LEN_RX_NAME); - storageDirty(EE_MODEL); - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - reusableBuffer.moduleSetup.bindInformation.step = BIND_OK; - POPUP_INFORMATION(STR_BIND_OK); -#else - reusableBuffer.moduleSetup.bindInformation.step = BIND_START; -#endif - } - } - else { - // the user pressed [Exit] - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - } -} - -void onResetReceiverConfirm(const char * result) -{ - if (result == STR_OK) { - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - moduleState[moduleIdx].mode = MODULE_MODE_RESET; - removePXX2Receiver(moduleIdx, receiverIdx); - } -} - -void onPXX2ReceiverMenu(const char * result) -{ - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); - - if (result == STR_OPTIONS) { - memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); - reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx; - g_moduleIdx = moduleIdx; - pushMenu(menuModelReceiverOptions); - } - else if (result == STR_BIND) { - memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation)); - reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx; - if (isModuleR9M2(moduleIdx)) { -#if defined(SIMU) - reusableBuffer.moduleSetup.pxx2.moduleInformation.information.modelID = 1; - reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant = 2; -#else - moduleState[moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); -#endif - } - else { - moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); - } - s_editMode = 1; - } - else if (result == STR_SHARE) { - reusableBuffer.moduleSetup.pxx2.shareReceiverIndex = receiverIdx; - moduleState[moduleIdx].mode = MODULE_MODE_SHARE; - s_editMode = 1; - } - else if (result == STR_DELETE || result == STR_RESET) { - memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); - reusableBuffer.moduleSetup.pxx2.resetReceiverIndex = receiverIdx; - reusableBuffer.moduleSetup.pxx2.resetReceiverFlags = (result == STR_RESET ? 0xFF : 0x01); - POPUP_CONFIRMATION(result == STR_RESET ? STR_RECEIVER_RESET : STR_RECEIVER_DELETE, onResetReceiverConfirm); - } - else { - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - } -} -#endif - -void onBindMenu(const char * result) -{ - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - - if (result == STR_BINDING_1_8_TELEM_ON) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; - } - else if (result == STR_BINDING_1_8_TELEM_OFF) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; - } - else if (result == STR_BINDING_9_16_TELEM_ON) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; - } - else if (result == STR_BINDING_9_16_TELEM_OFF) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; - } - else { - return; - } - - moduleState[moduleIdx].mode = MODULE_MODE_BIND; -} - -enum PopupRegisterItems { - ITEM_REGISTER_PASSWORD, - ITEM_REGISTER_MODULE_INDEX, - ITEM_REGISTER_RECEIVER_NAME, - ITEM_REGISTER_BUTTONS -}; - -void runPopupRegister(event_t event) -{ - uint8_t backupVerticalPosition = menuVerticalPosition; - uint8_t backupHorizontalPosition = menuHorizontalPosition; - uint8_t backupVerticalOffset = menuVerticalOffset; - int8_t backupEditMode = s_editMode; - - menuVerticalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition; - menuHorizontalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition; - s_editMode = reusableBuffer.moduleSetup.pxx2.registerPopupEditMode; - - switch (event) { - case EVT_KEY_BREAK(KEY_ENTER): - if (menuVerticalPosition != ITEM_REGISTER_BUTTONS) { - break; - } - else if (reusableBuffer.moduleSetup.pxx2.registerStep >= REGISTER_RX_NAME_RECEIVED && menuHorizontalPosition == 0) { - // [Enter] pressed - reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; - backupEditMode = EDIT_MODIFY_FIELD; // so that the [Register] button blinks and the REGISTER process can continue - } - // no break - - case EVT_KEY_LONG(KEY_EXIT): - s_editMode = 0; - // no break; - - case EVT_KEY_BREAK(KEY_EXIT): - if (s_editMode <= 0) { - warningText = nullptr; - } - break; - } - - if (warningText) { - const uint8_t dialogRows[] = { 0, 0, uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? READONLY_ROW : 0), uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? 0 : 1)}; - check(event, 0, nullptr, 0, dialogRows, 3, 4 - HEADER_LINE); // TODO add a comment for 3 - HEADER_LINE once understood - - drawMessageBox(warningText); - - // registration password - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4, STR_REG_ID); - editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4, g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID, event, menuVerticalPosition == ITEM_REGISTER_PASSWORD); - - // loop index (will be removed in future) - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + FH, "UID"); - lcdDrawNumber(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + FH, reusableBuffer.moduleSetup.pxx2.registerLoopIndex, menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX ? (s_editMode ? INVERS + BLINK : INVERS) : 0); - if (menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX && s_editMode) { - CHECK_INCDEC_MODELVAR_ZERO(event, reusableBuffer.moduleSetup.pxx2.registerLoopIndex, 2); - } - - // RX name - if (reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED) { - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, STR_WAITING); - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS ? INVERS : 0); - } - else { - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, STR_RX_NAME); - editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + 2 * FH, reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME, event, menuVerticalPosition == ITEM_REGISTER_RECEIVER_NAME); - lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_ENTER, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 0 ? INVERS : 0); - lcdDrawText(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 1 ? INVERS : 0); - } - - reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition = menuVerticalPosition; - reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition = menuHorizontalPosition; - reusableBuffer.moduleSetup.pxx2.registerPopupEditMode = s_editMode; - } - - menuVerticalPosition = backupVerticalPosition; - menuHorizontalPosition = backupHorizontalPosition; - menuVerticalOffset = backupVerticalOffset; - s_editMode = backupEditMode; -} - -void startRegisterDialog(uint8_t module) -{ - memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); - reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition = ITEM_REGISTER_BUTTONS; - moduleState[module].mode = MODULE_MODE_REGISTER; - s_editMode = 0; - killAllEvents(); - POPUP_INPUT("", runPopupRegister); -} - #if defined(BLUETOOTH) void onBluetoothConnectMenu(const char * result) { @@ -516,20 +256,26 @@ void onBluetoothConnectMenu(const char * result) } #endif +#include "common/stdlcd/model_setup_pxx1.cpp" + +#if defined(PXX2) +#include "common/stdlcd/model_setup_pxx2.cpp" +#endif + #if defined(HARDWARE_INTERNAL_MODULE) #define INTERNAL_MODULE_ROWS \ LABEL(InternalModule), \ INTERNAL_MODULE_TYPE_ROWS, \ INTERNAL_MODULE_CHANNELS_ROWS, \ IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1)), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* RxNum */ \ ANTENNA_ROW \ - IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), \ - IF_PXX2_MODULE(INTERNAL_MODULE, 0), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), \ - IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), + IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* Failsafe */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), /* Range check and Register buttons */ \ + IF_PXX2_MODULE(INTERNAL_MODULE, 0), /* Module options */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 1 */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 2 */ \ + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */ #else #define INTERNAL_MODULE_ROWS #endif @@ -565,7 +311,7 @@ void menuModelSetup(event_t event) 0, // Checklist 0, // Throttle warning SW_WARN_ROWS, // Switch warning - POT_WARN_ITEMS(), // Pot warning + POT_WARN_ROWS, // Pot warning NUM_STICKS + NUM_POTS + NUM_SLIDERS - 1, // Center beeps 0, // Global functions @@ -579,7 +325,7 @@ void menuModelSetup(event_t event) MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, - IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS()), // line reused for PPM: PPM settings + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), // line reused for PPM: PPM settings IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW), MULTIMODULE_MODULE_ROWS @@ -600,8 +346,8 @@ void menuModelSetup(event_t event) MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, - EXTERNAL_MODULE_BIND_ROWS(), - OUTPUT_TYPE_ROWS() + EXTERNAL_MODULE_BIND_ROWS, + OUTPUT_TYPE_ROW EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, @@ -612,6 +358,11 @@ void menuModelSetup(event_t event) #endif MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, HEADER_LINE + ITEM_MODEL_SETUP_LINES_COUNT); + title(STR_MENUSETUP); + + if (event == EVT_ENTRY) { + reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + } #if (defined(DSM2) || defined(PXX)) if (menuEvent) { @@ -622,12 +373,6 @@ void menuModelSetup(event_t event) } #endif - TITLE(STR_MENUSETUP); - - if (event == EVT_ENTRY) { - reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; - } - uint8_t sub = menuVerticalPosition - HEADER_LINE; for (uint8_t i=0; i= reusableBuffer.hardwareAndSettings.updateTime) { // menuVerticalOffset = 0; diff --git a/radio/src/gui/128x64/view_statistics.cpp b/radio/src/gui/128x64/view_statistics.cpp index 04cd7b2a6d..17363de69c 100644 --- a/radio/src/gui/128x64/view_statistics.cpp +++ b/radio/src/gui/128x64/view_statistics.cpp @@ -27,7 +27,7 @@ void menuStatisticsView(event_t event) { - TITLE(STR_MENUSTAT); + title(STR_MENUSTAT); switch (event) { case EVT_KEY_FIRST(KEY_UP): @@ -116,7 +116,7 @@ void menuStatisticsView(event_t event) void menuStatisticsDebug(event_t event) { - TITLE(STR_MENUDEBUG); + title(STR_MENUDEBUG); switch (event) { case EVT_KEY_LONG(KEY_ENTER): @@ -242,7 +242,7 @@ void menuStatisticsDebug(event_t event) #if defined(STM32) void menuStatisticsDebug2(event_t event) { - TITLE(STR_MENUDEBUG); + title(STR_MENUDEBUG); switch (event) { case EVT_KEY_FIRST(KEY_ENTER): diff --git a/radio/src/gui/212x64/gui.h b/radio/src/gui/212x64/gui.h index af294a58e4..2d131eff0c 100644 --- a/radio/src/gui/212x64/gui.h +++ b/radio/src/gui/212x64/gui.h @@ -91,7 +91,7 @@ extern int8_t s_editMode; // global editmode #define INCDEC_REP10 0x40 #define NO_DBLKEYS 0x80 -#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL +#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = nullptr #define INCDEC_SET_FLAG(f) incdecFlag = (f) #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) @@ -136,7 +136,7 @@ extern const CheckIncDecStops &stopsSwitch; #define CATEGORY_END(val) \ (val), (val+1) -int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100); +int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=nullptr, const CheckIncDecStops &stops=stops100); #define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL) #define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL) #define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL) @@ -169,49 +169,49 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla #define CURSOR_ON_LINE() (menuHorizontalPosition<0) #define CHECK_FLAG_NO_SCREEN_INDEX 1 -void check(const char * title, event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags=0); -void check_simple(const char *title, event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t maxrow); -void check_submenu_simple(const char * title, event_t event, uint8_t maxrow); +void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags=0); +void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t maxrow); +void check_submenu_simple(event_t event, uint8_t maxrow); void title(const char * s); -#define TITLE(str) title(str) #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__ -#define MENU_CHECK(title, tab, menu, lines_count) \ - check(title, event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count) +#define MENU_CHECK(tab, menu, lines_count) \ + check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count) -#define MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count) \ - check(title, event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count, flags) +#define MENU_CHECK_FLAGS(tab, menu, flags, lines_count) \ + check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count, flags) -#define MENU(title, tab, menu, lines_count, ...) \ +#define MENU(name, tab, menu, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - MENU_CHECK(title, tab, menu, lines_count) + MENU_CHECK(tab, menu, lines_count); \ + title(name) -#define MENU_FLAGS(title, tab, menu, flags, lines_count, ...) \ +#define MENU_FLAGS(name, tab, menu, flags, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count) + MENU_CHECK_FLAGS(tab, menu, flags, lines_count); \ + title(name) -#define SIMPLE_MENU_FLAGS(title, tab, menu, flags, lines_count, ...) \ - check(title, event, menu, tab, DIM(tab), NULL, 0, lines_count, flags) +#define SIMPLE_MENU(name, tab, menu, lines_count) \ + check_simple(event, menu, tab, DIM(tab), lines_count); \ + title(name) -#define SIMPLE_MENU(title, tab, menu, lines_count) \ - check_simple(title, event, menu, tab, DIM(tab), lines_count) - -#define SUBMENU_NOTITLE(lines_count, ...) { \ +#define SUBMENU_NOTITLE(lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - check(NULL, event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \ - } + check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); -#define SUBMENU(title, lines_count, ...) \ +#define SUBMENU(name, lines_count, ...) \ MENU_TAB(__VA_ARGS__); \ - check(title, event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count) + check(event, 0, nullptr, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \ + title(name) #define SIMPLE_SUBMENU_NOTITLE(lines_count) \ - check_submenu_simple(NULL, event, lines_count); + check_submenu_simple(event, lines_count) -#define SIMPLE_SUBMENU(title, lines_count) \ - check_submenu_simple(title, event, lines_count) +#define SIMPLE_SUBMENU(name, lines_count) \ + SIMPLE_SUBMENU_NOTITLE(lines_count); \ + title(name) typedef int choice_t; @@ -233,7 +233,8 @@ swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t e #define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v) #endif -void drawPower(coord_t x, coord_t y, int8_t dBm, LcdFlags att); +void drawPower(coord_t x, coord_t y, int8_t dBm, LcdFlags att = 0); +void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags=0); void gvarWeightItem(coord_t x, coord_t y, MixData * md, LcdFlags attr, event_t event); diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index 4f83c59e5d..38a993b278 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -22,26 +22,7 @@ #define _MENUS_H_ #include "keys.h" - -typedef int8_t horzpos_t; -typedef uint16_t vertpos_t; - -typedef void (*MenuHandlerFunc)(event_t event); - -extern tmr10ms_t menuEntryTime; -extern vertpos_t menuVerticalPosition; -extern horzpos_t menuHorizontalPosition; -extern vertpos_t menuVerticalOffset; -extern uint8_t menuCalibrationState; - -extern MenuHandlerFunc menuHandlers[5]; -extern uint8_t menuVerticalPositions[4]; -extern uint8_t menuLevel; -extern uint8_t menuEvent; - -void chainMenu(MenuHandlerFunc newMenu); -void pushMenu(MenuHandlerFunc newMenu); -void popMenu(); +#include "common/stdlcd/menus.h" inline bool isRadioMenuDisplayed() { @@ -54,7 +35,6 @@ inline bool isModelMenuDisplayed() } void onMainViewMenu(const char * result); - void menuFirstCalib(event_t event); void menuMainViewChannelsMonitor(event_t event); void menuChannelsView(event_t event); @@ -66,6 +46,7 @@ void menuStatisticsView(event_t event); void menuStatisticsDebug(event_t event); void menuStatisticsDebug2(event_t event); void menuAboutView(event_t event); + #if defined(DEBUG_TRACE_BUFFER) void menuTraceBuffer(event_t event); #endif diff --git a/radio/src/gui/212x64/model_select.cpp b/radio/src/gui/212x64/model_select.cpp index 758abc31b5..f9d76db6dc 100644 --- a/radio/src/gui/212x64/model_select.cpp +++ b/radio/src/gui/212x64/model_select.cpp @@ -83,7 +83,7 @@ void menuModelSelect(event_t event) int8_t oldSub = menuVerticalPosition; - check_submenu_simple(NULL, _event_, MAX_MODELS); + check_submenu_simple(_event_, MAX_MODELS); if (s_editMode > 0) s_editMode = 0; @@ -236,7 +236,7 @@ void menuModelSelect(event_t event) drawScreenIndex(MENU_MODEL_SELECT, DIM(menuTabModel), 0); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); - TITLE(STR_MENUMODELSEL); + title(STR_MENUMODELSEL); for (uint8_t i=0; i= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) - -void onBindMenu(const char * result) -{ - uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); - - if (result == STR_BINDING_1_8_TELEM_ON) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; - } - else if (result == STR_BINDING_1_8_TELEM_OFF) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; - } - else if (result == STR_BINDING_9_16_TELEM_ON) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; - } - else if (result == STR_BINDING_9_16_TELEM_OFF) { - g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; - g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; - } - else { - return; - } - - moduleState[moduleIdx].mode = MODULE_MODE_BIND; -} - void copySelection(char * dst, const char * src, uint8_t size) { if (memcmp(src, "---", 3) == 0) @@ -231,14 +218,15 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) } } -#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) -#if defined(INTERNAL_MODULE_PPM) - #define INTERNAL_MODULE_MODE_ROWS (isModuleXJT(INTERNAL_MODULE) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols -#else - #define INTERNAL_MODULE_MODE_ROWS 0 // (OFF / RF protocols) -#endif +#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) +#if defined(INTERNAL_MODULE_PXX1) +#define INTERNAL_MODULE_TYPE_ROWS ((isModuleXJT(INTERNAL_MODULE) || isModulePXX2(INTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols +#else +#define INTERNAL_MODULE_TYPE_ROWS (0) // Module type + RF protocols +#endif + #define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) #if defined(BLUETOOTH) && defined(USEHORUSBT) @@ -262,15 +250,31 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) #define TIMERS_ROWS TIMER_ROWS(0), TIMER_ROWS(1), TIMER_ROWS(2) #endif #if defined(PCBX9E) - #define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW), uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW) - #define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0), uint8_t(g_model.potsWarnMode ? TITLE_ROW : HIDDEN_ROW) + #define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW), uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW) + #define POT_WARN_ROWS uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0), uint8_t(g_model.potsWarnMode ? TITLE_ROW : HIDDEN_ROW) #define TOPLCD_ROWS 0, #else - #define SW_WARN_ITEMS() uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount()) - #define POT_WARN_ITEMS() uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0) + #define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsCount()) + #define POT_WARN_ROWS uint8_t(g_model.potsWarnMode ? NAVIGATION_LINE_BY_LINE|(NUM_POTS+NUM_SLIDERS) : 0) #define TOPLCD_ROWS #endif +#define IF_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? (uint8_t)(xxx) : HIDDEN_ROW) +#define IF_NOT_PXX2_MODULE(module, xxx) (isModulePXX2(module) ? HIDDEN_ROW : (uint8_t)(xxx)) +#define IF_ACCESS_MODULE_RF(module, xxx) (isModuleRFAccess(module) ? (uint8_t)(xxx) : HIDDEN_ROW) +#define IF_NOT_ACCESS_MODULE_RF(module, xxx) (isModuleRFAccess(module) ? HIDDEN_ROW : (uint8_t)(xxx)) + +#if defined(PXX2) +#define REGISTRATION_ID_ROWS uint8_t((isDefaultModelRegistrationID() || (warningText && popupFunc == runPopupRegister)) ? HIDDEN_ROW : READONLY_ROW), +#else +#define REGISTRATION_ID_ROWS +#endif + +#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) +#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1 : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1)) + +#include "common/stdlcd/model_setup_pxx1.cpp" +#include "common/stdlcd/model_setup_pxx2.cpp" void menuModelSetup(event_t event) { @@ -278,26 +282,75 @@ void menuModelSetup(event_t event) bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0); int8_t old_editMode = s_editMode; - MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, - LABEL(Throttle), 0, 0, 0, - LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_SLIDERS-1), 0, - LABEL(InternalModule), - INTERNAL_MODULE_MODE_ROWS, - INTERNAL_MODULE_CHANNELS_ROWS, - IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1), - IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), - LABEL(ExternalModule), - EXTERNAL_MODULE_MODE_ROWS, - MULTIMODULE_STATUS_ROWS - EXTERNAL_MODULE_CHANNELS_ROWS, - ((isModuleXJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, - FAILSAFE_ROWS(EXTERNAL_MODULE), - EXTERNAL_MODULE_OPTION_ROW, - MULTIMODULE_MODULE_ROWS - EXTERNAL_MODULE_POWER_ROW, - LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS}); - MENU_CHECK(STR_MENUSETUP, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_SETUP_MAX); + MENU_TAB({ + HEADER_LINE_COLUMNS + + 0, // Model name + 0, // Model image + + TIMERS_ROWS, + + TOPLCD_ROWS + + 0, // Extended limits + 1, // Extended trims + 0, // Show trims + 0, // Trims step + + LABEL(Throttle), + 0, // Thrxottle reverse + 0, // Throttle trace source + 0, // Throttle trim + + LABEL(PreflightCheck), + 0, // Checklist + 0, // Throttle warning + SW_WARN_ROWS, // Switch warning + POT_WARN_ROWS, // Pot warning + + NAVIGATION_LINE_BY_LINE | (NUM_STICKS+NUM_POTS+NUM_SLIDERS-1), // Center beeps + + 0, // Global functions + + REGISTRATION_ID_ROWS + + LABEL(InternalModule), + INTERNAL_MODULE_TYPE_ROWS, + INTERNAL_MODULE_CHANNELS_ROWS, + IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1)), + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // RxNum + IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), // Failsafe + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(INTERNAL_MODULE, 0), // Module options + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 1 + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 2 + IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3 + + LABEL(ExternalModule), + EXTERNAL_MODULE_MODE_ROWS, + MULTIMODULE_STATUS_ROWS + EXTERNAL_MODULE_CHANNELS_ROWS, + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, ((isModuleXJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW), + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum + IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW), + MULTIMODULE_MODULE_ROWS + EXTERNAL_MODULE_POWER_ROW, + FAILSAFE_ROWS(EXTERNAL_MODULE), + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3 + + LABEL(Trainer), + 0, + TRAINER_LINE1_ROWS, + TRAINER_LINE2_ROWS + }); + + MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_LINES_COUNT); + title(STR_MENUSETUP); if (event == EVT_ENTRY) { reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; @@ -665,48 +718,57 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, TR_INTERNALRF); break; -#if defined(INTERNAL_MODULE_PPM) - case ITEM_MODEL_SETUP_INTERNAL_MODULE_MODE: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE: + { lcdDrawTextAlignedLeft(y, STR_MODE); +#if defined(INTERNAL_MODULE_PXX1) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(INTERNAL_MODULE)) - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); - if (attr && s_editMode>0) { - switch (menuHorizontalPosition) { - case 0: - g_model.moduleData[INTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_XJT_PXX1, EE_MODEL, isModuleAvailable); - if (checkIncDec_Ret) { - g_model.moduleData[INTERNAL_MODULE].rfProtocol = 0; - g_model.moduleData[INTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE);; - } - break; - case 1: - g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, MODULE_SUBTYPE_PXX1_ACCST_D16, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); - if (checkIncDec_Ret) { - g_model.moduleData[INTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); - } + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); + else if (isModuleXJT2(INTERNAL_MODULE)) + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_ISRM_PXX2_RF_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); + if (attr) { + if (menuHorizontalPosition == 0) { + uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); + if (checkIncDec_Ret) { + // TODO this code should be common, in module.h (X10_new_UI branch) + memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); + g_model.moduleData[INTERNAL_MODULE].type = moduleType; + g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); } } - break; -#else - case ITEM_MODEL_SETUP_INTERNAL_MODULE_MODE: - lcdDrawTextAlignedLeft(y, STR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[0].rfProtocol, attr); - if (attr) { - g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, -1, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); - - if (checkIncDec_Ret) { - g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_XJT_PXX1; - g_model.moduleData[INTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); - if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == MODULE_SUBTYPE_PXX1_OFF) - g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_NONE; + else if (isModuleXJT(INTERNAL_MODULE)) { + g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, 0, MODULE_SUBTYPE_PXX1_LAST, EE_MODEL, isRfProtocolAvailable); + if (checkIncDec_Ret) { + g_model.moduleData[0].type = MODULE_TYPE_XJT_PXX1; + g_model.moduleData[0].channelsStart = 0; + g_model.moduleData[0].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); + } + } + else if (isModulePXX2(INTERNAL_MODULE)) { + g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_ISRM_PXX2_LAST, EE_MODEL, isRfProtocolAvailable); + } + } +#else + uint8_t index = 0; + if (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_ISRM_PXX2) { + index = 1 + g_model.moduleData[INTERNAL_MODULE].subType; + } + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_ISRM_PXX2_RF_PROTOCOLS, index, attr); + if (attr) { + index = checkIncDec(event, index, 0, 3, EE_MODEL); + if (checkIncDec_Ret) { + memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); + if (index > 0) { + g_model.moduleData[INTERNAL_MODULE].type = MODULE_TYPE_ISRM_PXX2; + g_model.moduleData[INTERNAL_MODULE].subType = index - 1; + g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); + } } } - break; #endif + break; + } case ITEM_MODEL_SETUP_TRAINER_MODE: lcdDrawTextAlignedLeft(y, STR_MODE); @@ -726,7 +788,7 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, TR_EXTERNALRF); break; - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_MODE: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE: lcdDrawTextAlignedLeft(y, STR_MODE); lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(EXTERNAL_MODULE)) @@ -829,9 +891,9 @@ void menuModelSetup(event_t event) } break; - case ITEM_MODEL_SETUP_TRAINER_LABEL: - lcdDrawTextAlignedLeft(y, STR_TRAINER); - break; + case ITEM_MODEL_SETUP_TRAINER_LABEL: + lcdDrawTextAlignedLeft(y, STR_TRAINER); + break; #if defined(BLUETOOTH) && defined(USEHORUSBT) case ITEM_MODEL_SETUP_TRAINER_LINE1: @@ -956,8 +1018,8 @@ void menuModelSetup(event_t event) } break; - case ITEM_MODEL_SETUP_INTERNAL_MODULE_BIND: - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_BIND: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; @@ -1003,7 +1065,7 @@ void menuModelSetup(event_t event) else { horzpos_t l_posHorz = menuHorizontalPosition; coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; - if (isModuleXJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol == MODULE_SUBTYPE_PXX1_ACCST_D8) { + if (isModuleXJT(moduleIdx) && IS_D8_RX(MODULE_SUBTYPE_PXX1_ACCST_D8)) { xOffsetBind = 0; lcdDrawTextAlignedLeft(y, STR_RECEIVER); if (attr) l_posHorz += 1; @@ -1011,7 +1073,7 @@ void menuModelSetup(event_t event) else { lcdDrawTextAlignedLeft(y, STR_RECEIVER_NUM); } - if (isModulePXX(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx)) { + if (isModulePXX2(moduleIdx) || isModulePXX(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx)) { if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2); if (attr && l_posHorz==0) { @@ -1219,6 +1281,7 @@ void menuModelSetup(event_t event) else g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event); break; + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: { lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); @@ -1227,15 +1290,158 @@ void menuModelSetup(event_t event) lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS: { - lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC); + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS: + { + lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC); char statusText[64]; multiSyncStatus.getRefreshString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } #endif + +#if defined(PXX2) + case ITEM_MODEL_SETUP_REGISTRATION_ID: + lcdDrawTextAlignedLeft(y, STR_REG_ID); + if (isDefaultModelRegistrationID()) + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_PXX2_DEFAULT); + else + lcdDrawSizedText(MODEL_SETUP_2ND_COLUMN, y, g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID, ZCHAR); + break; + + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_RECEIVER_NUM); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], attr | LEADING0 | LEFT, 2); + if (attr) { + CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], MAX_RX_NUM(moduleIdx)); + if (checkIncDec_Ret) { + modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx]; + } + } + } + break; + + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + lcdDrawTextAlignedLeft(y, STR_MODULE); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, BUTTON(TR_REGISTER), (menuHorizontalPosition == 0 ? attr : 0)); + lcdDrawText(lcdLastRightPos + 3, y, STR_MODULE_RANGE, (menuHorizontalPosition == 1 ? attr : 0)); + if (attr) { + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && s_editMode > 0) { + if (menuHorizontalPosition == 0 && event == EVT_KEY_BREAK(KEY_ENTER)) { + startRegisterDialog(moduleIdx); + } + else if (menuHorizontalPosition == 1) { + moduleState[moduleIdx].mode = MODULE_MODE_RANGECHECK; + } + } + if (s_editMode == 0 && !warningText) { + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + } + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { + // REGISTER finished + s_editMode = 0; + } + } + } + break; + + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_OPTIONS: + lcdDrawText(INDENT_WIDTH, y, STR_OPTIONS); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); + if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { + g_moduleIdx = CURRENT_MODULE_EDITED(k); + pushMenu(menuModelModuleOptions); + } + break; + + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3: + { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); + ModuleInformation & moduleInformation = reusableBuffer.moduleSetup.pxx2.moduleInformation; + + drawStringWithIndex(INDENT_WIDTH, y, STR_RECEIVER, receiverIdx + 1); + + if (!(g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx))) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, attr); + if (attr && s_editMode > 0) { + s_editMode = 0; + killEvents(event); + g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx); + memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); + storageDirty(EE_MODEL); + } + else { + break; + } + } + + drawReceiverName(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, receiverIdx, attr); + + if (s_editMode && isModuleR9M2(moduleIdx) && moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && moduleInformation.information.modelID) { + moduleInformation.information.modelID = 0; + moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); + } + + if (attr && (moduleState[moduleIdx].mode == 0 || s_editMode == 0)) { + if (moduleState[moduleIdx].mode) { + moduleState[moduleIdx].mode = 0; + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + killEvents(event); // we stopped BIND / SHARE, we don't want to re-open the menu + event = 0; + CLEAR_POPUP(); + } + s_editMode = 0; + } + + if (moduleState[moduleIdx].mode == MODULE_MODE_BIND) { + if (reusableBuffer.moduleSetup.bindInformation.step == BIND_INIT) { + if (reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount > 0) { + popupMenuItemsCount = min(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); + for (uint8_t i = 0; i < popupMenuItemsCount; i++) { + popupMenuItems[i] = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[i]; + } + popupMenuTitle = STR_PXX2_SELECT_RX; + CLEAR_POPUP(); + POPUP_MENU_START(onPXX2BindMenu); + } + else { + POPUP_WAIT(STR_WAITING_FOR_RX); + } + } + } + + if (attr && EVT_KEY_MASK(event) == KEY_ENTER) { + killEvents(event); + if (!isSimu() && isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { + onPXX2ReceiverMenu(STR_BIND); + } + else { + POPUP_MENU_ADD_ITEM(STR_BIND); + POPUP_MENU_ADD_ITEM(STR_OPTIONS); + POPUP_MENU_ADD_ITEM(STR_SHARE); + POPUP_MENU_ADD_ITEM(STR_DELETE); + POPUP_MENU_ADD_ITEM(STR_RESET); + } + POPUP_MENU_START(onPXX2ReceiverMenu); + } + } + break; +#endif + } } @@ -1248,12 +1454,12 @@ void menuModelSetup(event_t event) if (old_editMode > 0 && s_editMode == 0) { switch(menuVerticalPosition) { - case ITEM_MODEL_SETUP_INTERNAL_MODULE_BIND: + case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, INTERNAL_MODULE); break; - case ITEM_MODEL_SETUP_EXTERNAL_MODULE_BIND: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND: if (menuHorizontalPosition == 0) checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE); break; diff --git a/radio/src/gui/212x64/radio_calibration.cpp b/radio/src/gui/212x64/radio_calibration.cpp index bf76cbb359..d12bfbf120 100644 --- a/radio/src/gui/212x64/radio_calibration.cpp +++ b/radio/src/gui/212x64/radio_calibration.cpp @@ -195,7 +195,8 @@ void menuCommonCalib(event_t event) void menuRadioCalibration(event_t event) { - check_submenu_simple(STR_MENUCALIBRATION, event, 0); + check_submenu_simple(event, 0); + title(STR_MENUCALIBRATION); menuCommonCalib(READ_ONLY() ? 0 : event); if (menuEvent) { menuCalibrationState = CALIB_START; diff --git a/radio/src/gui/212x64/view_statistics.cpp b/radio/src/gui/212x64/view_statistics.cpp index 191a4a95bf..aa7aeee4f7 100644 --- a/radio/src/gui/212x64/view_statistics.cpp +++ b/radio/src/gui/212x64/view_statistics.cpp @@ -27,7 +27,7 @@ void menuStatisticsView(event_t event) { - TITLE(STR_MENUSTAT); + title(STR_MENUSTAT); switch(event) { @@ -105,7 +105,7 @@ void menuStatisticsView(event_t event) void menuStatisticsDebug(event_t event) { - TITLE(STR_MENUDEBUG); + title(STR_MENUDEBUG); #if defined(WATCHDOG_TEST) if (warningResult) { @@ -200,7 +200,7 @@ void menuStatisticsDebug(event_t event) void menuStatisticsDebug2(event_t event) { - TITLE(STR_MENUDEBUG); + title(STR_MENUDEBUG); switch(event) { diff --git a/radio/src/gui/CMakeLists.txt b/radio/src/gui/CMakeLists.txt index 31ba4430bf..5c13c957c3 100644 --- a/radio/src/gui/CMakeLists.txt +++ b/radio/src/gui/CMakeLists.txt @@ -5,7 +5,6 @@ set(GUI_SRC fonts.cpp popups.cpp widgets.cpp - menus.cpp menu_model.cpp model_select.cpp model_setup.cpp @@ -31,13 +30,6 @@ set(SRC gui/navigation/common.cpp ) -if (PXX2) - set(GUI_SRC - ${GUI_SRC} - model_module_options.cpp - model_receiver_options.cpp - ) -endif() string(TOUPPER ${NAVIGATION_TYPE} NAVIGATION_TYPE) add_definitions(-DNAVIGATION_${NAVIGATION_TYPE}) diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index fbda7a3c50..8ae7e5d56b 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -1,29 +1,24 @@ +add_definitions(-DGRAPHICS) + set(GUI_SRC ${GUI_SRC} + ../common/stdlcd/menus.cpp ../common/stdlcd/widgets.cpp ../common/stdlcd/popups.cpp + ../common/stdlcd/model_inputs.cpp + ../common/stdlcd/model_mixes.cpp + ../common/stdlcd/view_text.cpp + ../common/stdlcd/model_module_options.cpp + ../common/stdlcd/model_receiver_options.cpp + ../common/stdlcd/model_notes.cpp + ../common/stdlcd/model_curves.cpp + model_curve_edit.cpp ) if(HELI) set(GUI_SRC ${GUI_SRC} ../common/stdlcd/model_heli.cpp) endif() -add_definitions(-DGRAPHICS) -set(GUI_SRC - ${GUI_SRC} - ../common/stdlcd/model_inputs.cpp - ../common/stdlcd/model_mixes.cpp - ../common/stdlcd/view_text.cpp -) -set(CURVE_EDIT_SRC ) - - -set(GUI_SRC - ${GUI_SRC} - ../common/stdlcd/model_curves.cpp - model_curve_edit.cpp - ) - if(SDCARD) set(GUI_SRC ${GUI_SRC} diff --git a/radio/src/gui/128x64/menus.cpp b/radio/src/gui/common/stdlcd/menus.cpp similarity index 80% rename from radio/src/gui/128x64/menus.cpp rename to radio/src/gui/common/stdlcd/menus.cpp index e094484607..b3e2b6f59d 100644 --- a/radio/src/gui/128x64/menus.cpp +++ b/radio/src/gui/common/stdlcd/menus.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -27,9 +27,10 @@ uint8_t menuLevel = 0; void popMenu() { - assert(menuLevel>0); - menuLevel = menuLevel-1; + assert(menuLevel > 0); + menuLevel = menuLevel - 1; menuEvent = EVT_ENTRY_UP; + // TODO ? AUDIO_KEY_PRESS(); TRACE("popMenu(%d)", menuLevel); } @@ -44,6 +45,7 @@ void chainMenu(MenuHandlerFunc newMenu) { menuHandlers[menuLevel] = newMenu; menuEvent = EVT_ENTRY; + // TODO ? AUDIO_KEY_PRESS(); TRACE("chainMenu(%d, %p)", menuLevel, newMenu); } @@ -67,21 +69,6 @@ void pushMenu(MenuHandlerFunc newMenu) menuHandlers[menuLevel] = newMenu; menuEvent = EVT_ENTRY; + // ? AUDIO_KEY_PRESS(); TRACE("pushMenu(%d, %p)", menuLevel, newMenu); } - -void menuModelNotes(event_t event) -{ - if (event == EVT_ENTRY) { - strcpy(s_text_file, MODELS_PATH "/"); - char *buf = strcat_modelname(&s_text_file[sizeof(MODELS_PATH)], g_eeGeneral.currModel); - strcpy(buf, TEXT_EXT); - } - - menuTextView(event); -} - -void pushModelNotes() -{ - pushMenu(menuModelNotes); -} diff --git a/radio/src/gui/common/stdlcd/menus.h b/radio/src/gui/common/stdlcd/menus.h new file mode 100644 index 0000000000..77745e3495 --- /dev/null +++ b/radio/src/gui/common/stdlcd/menus.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _COMMON_MENUS_H_ +#define _COMMON_MENUS_H_ + +#include "opentx_types.h" + +typedef int8_t horzpos_t; +typedef uint16_t vertpos_t; + +typedef void (* MenuHandlerFunc)(event_t event); + +extern tmr10ms_t menuEntryTime; +extern vertpos_t menuVerticalPosition; +extern horzpos_t menuHorizontalPosition; +extern vertpos_t menuVerticalOffset; +extern uint8_t menuCalibrationState; +extern MenuHandlerFunc menuHandlers[5]; +extern uint8_t menuVerticalPositions[4]; +extern uint8_t menuLevel; +extern uint8_t menuEvent; + +void chainMenu(MenuHandlerFunc newMenu); +void pushMenu(MenuHandlerFunc newMenu); +void popMenu(); +void abortPopMenu(); + +inline MenuHandlerFunc lastPopMenu() +{ + return menuHandlers[menuLevel + 1]; +} + +#endif // _COMMON_MENUS_H_ diff --git a/radio/src/gui/128x64/model_module_options.cpp b/radio/src/gui/common/stdlcd/model_module_options.cpp similarity index 100% rename from radio/src/gui/128x64/model_module_options.cpp rename to radio/src/gui/common/stdlcd/model_module_options.cpp diff --git a/radio/src/gui/212x64/menus.cpp b/radio/src/gui/common/stdlcd/model_notes.cpp similarity index 51% rename from radio/src/gui/212x64/menus.cpp rename to radio/src/gui/common/stdlcd/model_notes.cpp index 574585e2a9..00de5a5d10 100644 --- a/radio/src/gui/212x64/menus.cpp +++ b/radio/src/gui/common/stdlcd/model_notes.cpp @@ -20,52 +20,6 @@ #include "opentx.h" -MenuHandlerFunc menuHandlers[5]; -uint8_t menuEvent = 0; -uint8_t menuVerticalPositions[4]; -uint8_t menuLevel = 0; - -void popMenu() -{ - assert(menuLevel>0); - menuLevel = menuLevel-1; - menuEvent = EVT_ENTRY_UP; - AUDIO_KEY_PRESS(); - TRACE("popMenu(%d)", menuLevel); -} - -void chainMenu(MenuHandlerFunc newMenu) -{ - menuHandlers[menuLevel] = newMenu; - menuEvent = EVT_ENTRY; - AUDIO_KEY_PRESS(); - TRACE("chainMenu(%d, %p)", menuLevel, newMenu); -} - -void pushMenu(MenuHandlerFunc newMenu) -{ - killEvents(KEY_ENTER); - - if (menuLevel == 0) { - if (newMenu == menuRadioSetup) - menuVerticalPositions[0] = 1; - if (newMenu == menuModelSelect) - menuVerticalPositions[0] = 0; - } - else { - menuVerticalPositions[menuLevel] = menuVerticalPosition; - } - - menuLevel++; - - assert(menuLevel < DIM(menuHandlers)); - - menuHandlers[menuLevel] = newMenu; - menuEvent = EVT_ENTRY; - AUDIO_KEY_PRESS(); - TRACE("pushMenu(%d, %p)", menuLevel, newMenu); -} - void menuModelNotes(event_t event) { if (event == EVT_ENTRY) { diff --git a/radio/src/gui/128x64/model_receiver_options.cpp b/radio/src/gui/common/stdlcd/model_receiver_options.cpp similarity index 99% rename from radio/src/gui/128x64/model_receiver_options.cpp rename to radio/src/gui/common/stdlcd/model_receiver_options.cpp index 9d6061d669..87c596be06 100644 --- a/radio/src/gui/128x64/model_receiver_options.cpp +++ b/radio/src/gui/common/stdlcd/model_receiver_options.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" #define RECEIVER_OPTIONS_2ND_COLUMN 80 diff --git a/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp new file mode 100644 index 0000000000..79231c5f99 --- /dev/null +++ b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +void onBindMenu(const char * result) +{ + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + + if (result == STR_BINDING_1_8_TELEM_ON) { + g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; + g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; + } + else if (result == STR_BINDING_1_8_TELEM_OFF) { + g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; + g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false; + } + else if (result == STR_BINDING_9_16_TELEM_ON) { + g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false; + g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; + } + else if (result == STR_BINDING_9_16_TELEM_OFF) { + g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true; + g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true; + } + else { + return; + } + + moduleState[moduleIdx].mode = MODULE_MODE_BIND; +} \ No newline at end of file diff --git a/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp b/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp new file mode 100644 index 0000000000..36f82ba6a9 --- /dev/null +++ b/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx) +{ + return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); +} + +void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx) +{ + memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); + g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx); + storageDirty(EE_MODEL); +} + +void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx) +{ + if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { + removePXX2Receiver(moduleIdx, receiverIdx); + } +} + +void onPXX2R9MBindModeMenu(const char * result) +{ + if (result == STR_8CH_WITH_TELEMETRY) { + reusableBuffer.moduleSetup.bindInformation.lbtMode = 0; + } + else if (result == STR_16CH_WITH_TELEMETRY) { + reusableBuffer.moduleSetup.bindInformation.lbtMode = 1; + } + else if (result == STR_16CH_WITHOUT_TELEMETRY) { + reusableBuffer.moduleSetup.bindInformation.lbtMode = 2; + } + else if (result == STR_FLEX_868) { + reusableBuffer.moduleSetup.bindInformation.flexMode = 0; + } + else if (result == STR_FLEX_915) { + reusableBuffer.moduleSetup.bindInformation.flexMode = 1; + } + else { + // the user pressed [Exit] + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + return; + } + +#if defined(SIMU) + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[reusableBuffer.moduleSetup.bindInformation.selectedReceiverIndex], PXX2_LEN_RX_NAME); + storageDirty(EE_MODEL); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + reusableBuffer.moduleSetup.bindInformation.step = BIND_OK; + POPUP_INFORMATION(STR_BIND_OK); +#else + reusableBuffer.moduleSetup.bindInformation.step = BIND_START; +#endif +} + +void onPXX2BindMenu(const char * result) +{ + if (result != STR_EXIT) { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + reusableBuffer.moduleSetup.bindInformation.selectedReceiverIndex = (result - reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[0]) / sizeof(reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[0]); + if (isModuleR9M2(moduleIdx) && reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant == PXX2_VARIANT_EU) { + reusableBuffer.moduleSetup.bindInformation.step = BIND_RX_NAME_SELECTED; + POPUP_MENU_ADD_ITEM(STR_8CH_WITH_TELEMETRY); + POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); + POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); + POPUP_MENU_START(onPXX2R9MBindModeMenu); + } + else if (isModuleR9M2(moduleIdx) && reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant == PXX2_VARIANT_FLEX) { + reusableBuffer.moduleSetup.bindInformation.step = BIND_RX_NAME_SELECTED; + POPUP_MENU_ADD_ITEM(STR_FLEX_868); + POPUP_MENU_ADD_ITEM(STR_FLEX_915); + POPUP_MENU_START(onPXX2R9MBindModeMenu); + } + else { +#if defined(SIMU) + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], result, PXX2_LEN_RX_NAME); + storageDirty(EE_MODEL); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + reusableBuffer.moduleSetup.bindInformation.step = BIND_OK; + POPUP_INFORMATION(STR_BIND_OK); +#else + reusableBuffer.moduleSetup.bindInformation.step = BIND_START; +#endif + } + } + else { + // the user pressed [Exit] + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + } +} + +void onResetReceiverConfirm(const char * result) +{ + if (result == STR_OK) { + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + moduleState[moduleIdx].mode = MODULE_MODE_RESET; + removePXX2Receiver(moduleIdx, receiverIdx); + } +} + +void onPXX2ReceiverMenu(const char * result) +{ + uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); + uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); + + if (result == STR_OPTIONS) { + memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); + reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx; + g_moduleIdx = moduleIdx; + pushMenu(menuModelReceiverOptions); + } + else if (result == STR_BIND) { + memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation)); + reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx; + if (isModuleR9M2(moduleIdx)) { +#if defined(SIMU) + reusableBuffer.moduleSetup.pxx2.moduleInformation.information.modelID = 1; + reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant = 2; +#else + moduleState[moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); +#endif + } + else { + moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); + } + s_editMode = 1; + } + else if (result == STR_SHARE) { + reusableBuffer.moduleSetup.pxx2.shareReceiverIndex = receiverIdx; + moduleState[moduleIdx].mode = MODULE_MODE_SHARE; + s_editMode = 1; + } + else if (result == STR_DELETE || result == STR_RESET) { + memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); + reusableBuffer.moduleSetup.pxx2.resetReceiverIndex = receiverIdx; + reusableBuffer.moduleSetup.pxx2.resetReceiverFlags = (result == STR_RESET ? 0xFF : 0x01); + POPUP_CONFIRMATION(result == STR_RESET ? STR_RECEIVER_RESET : STR_RECEIVER_DELETE, onResetReceiverConfirm); + } + else { + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + } +} + +enum PopupRegisterItems { + ITEM_REGISTER_PASSWORD, + ITEM_REGISTER_MODULE_INDEX, + ITEM_REGISTER_RECEIVER_NAME, + ITEM_REGISTER_BUTTONS +}; + +void runPopupRegister(event_t event) +{ + uint8_t backupVerticalPosition = menuVerticalPosition; + uint8_t backupHorizontalPosition = menuHorizontalPosition; + uint8_t backupVerticalOffset = menuVerticalOffset; + int8_t backupEditMode = s_editMode; + + menuVerticalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition; + menuHorizontalPosition = reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition; + s_editMode = reusableBuffer.moduleSetup.pxx2.registerPopupEditMode; + + switch (event) { + case EVT_KEY_BREAK(KEY_ENTER): + if (menuVerticalPosition != ITEM_REGISTER_BUTTONS) { + break; + } + else if (reusableBuffer.moduleSetup.pxx2.registerStep >= REGISTER_RX_NAME_RECEIVED && menuHorizontalPosition == 0) { + // [Enter] pressed + reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; + backupEditMode = EDIT_MODIFY_FIELD; // so that the [Register] button blinks and the REGISTER process can continue + } + // no break + + case EVT_KEY_LONG(KEY_EXIT): + s_editMode = 0; + // no break; + + case EVT_KEY_BREAK(KEY_EXIT): + if (s_editMode <= 0) { + warningText = nullptr; + } + break; + } + + if (warningText) { + const uint8_t dialogRows[] = { 0, 0, uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? READONLY_ROW : 0), uint8_t(reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED ? 0 : 1)}; + check(event, 0, nullptr, 0, dialogRows, 3, 4 - HEADER_LINE); // TODO add a comment for 3 - HEADER_LINE once understood + + drawMessageBox(warningText); + + // registration password + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4, STR_REG_ID); + editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4, g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID, event, menuVerticalPosition == ITEM_REGISTER_PASSWORD); + + // loop index (will be removed in future) + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + FH, "UID"); + lcdDrawNumber(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + FH, reusableBuffer.moduleSetup.pxx2.registerLoopIndex, menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX ? (s_editMode ? INVERS + BLINK : INVERS) : 0); + if (menuVerticalPosition == ITEM_REGISTER_MODULE_INDEX && s_editMode) { + CHECK_INCDEC_MODELVAR_ZERO(event, reusableBuffer.moduleSetup.pxx2.registerLoopIndex, 2); + } + + // RX name + if (reusableBuffer.moduleSetup.pxx2.registerStep < REGISTER_RX_NAME_RECEIVED) { + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, STR_WAITING); + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS ? INVERS : 0); + } + else { + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 4 + 2 * FH, STR_RX_NAME); + editName(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 4 + 2 * FH, reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME, event, menuVerticalPosition == ITEM_REGISTER_RECEIVER_NAME); + lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y - 2 + 3 * FH, TR_ENTER, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 0 ? INVERS : 0); + lcdDrawText(WARNING_LINE_X + 8*FW, WARNING_LINE_Y - 2 + 3 * FH, TR_EXIT, menuVerticalPosition == ITEM_REGISTER_BUTTONS && menuHorizontalPosition == 1 ? INVERS : 0); + } + + reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition = menuVerticalPosition; + reusableBuffer.moduleSetup.pxx2.registerPopupHorizontalPosition = menuHorizontalPosition; + reusableBuffer.moduleSetup.pxx2.registerPopupEditMode = s_editMode; + } + + menuVerticalPosition = backupVerticalPosition; + menuHorizontalPosition = backupHorizontalPosition; + menuVerticalOffset = backupVerticalOffset; + s_editMode = backupEditMode; +} + +void startRegisterDialog(uint8_t module) +{ + memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); + reusableBuffer.moduleSetup.pxx2.registerPopupVerticalPosition = ITEM_REGISTER_BUTTONS; + moduleState[module].mode = MODULE_MODE_REGISTER; + s_editMode = 0; + killAllEvents(); + POPUP_INPUT("", runPopupRegister); +} diff --git a/radio/src/gui/common/stdlcd/widgets.cpp b/radio/src/gui/common/stdlcd/widgets.cpp index 1aa2109053..c05fa5114e 100644 --- a/radio/src/gui/common/stdlcd/widgets.cpp +++ b/radio/src/gui/common/stdlcd/widgets.cpp @@ -215,3 +215,21 @@ void drawPower(coord_t x, coord_t y, int8_t dBm, LcdFlags att) } } } + +void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags) +{ + if (isModulePXX2(moduleIdx)) { + if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') + lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags); + else + lcdDrawText(x, y, "---", flags); + } +#if defined(HARDWARE_INTERNAL_MODULE) + else if (moduleIdx == INTERNAL_MODULE) { + lcdDrawText(x, y, "Internal", flags); + } +#endif + else { + lcdDrawText(x, y, "External", flags); + } +} diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 16d104bb61..6e9185a702 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -655,7 +655,7 @@ bool isExternalModuleAvailable(int moduleType) return false; #endif -#if !defined(EXTERNAL_MODULE_PPM) +#if !defined(PPM) if (moduleType == MODULE_TYPE_PPM) return false; #endif diff --git a/radio/src/gui/navigation/navigation_x9d.cpp b/radio/src/gui/navigation/navigation_x9d.cpp index 1cfb7d438e..b6d171afd9 100644 --- a/radio/src/gui/navigation/navigation_x9d.cpp +++ b/radio/src/gui/navigation/navigation_x9d.cpp @@ -336,7 +336,7 @@ void onLongMenuPress(const char * result) tmr10ms_t menuEntryTime; -void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t rowcount, uint8_t flags) +void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const uint8_t *horTab, uint8_t horTabMax, vertpos_t rowcount, uint8_t flags) { vertpos_t l_posVert = menuVerticalPosition; horzpos_t l_posHorz = menuHorizontalPosition; @@ -577,23 +577,19 @@ void check(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc drawVerticalScrollbar(scrollbar_X, MENU_HEADER_HEIGHT, LCD_H-MENU_HEADER_HEIGHT, menuVerticalOffset, linesCount, NUM_BODY_LINES); } - if (name) { - title(name); - } - menuVerticalPosition = l_posVert; menuHorizontalPosition = l_posHorz; } -void check_simple(const char * name, event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t rowcount) +void check_simple(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, vertpos_t rowcount) { - check(name, event, curr, menuTab, menuTabSize, 0, 0, rowcount); + check(event, curr, menuTab, menuTabSize, 0, 0, rowcount); } -void check_submenu_simple(const char * name, event_t event, uint8_t rowcount) +void check_submenu_simple(event_t event, uint8_t rowcount) { - check_simple(name, event, 0, 0, 0, rowcount); + check_simple(event, 0, nullptr, 0, rowcount); } void repeatLastCursorMove(event_t event) diff --git a/radio/src/keys.h b/radio/src/keys.h index 90bf813091..e60e9dfe6e 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -56,7 +56,6 @@ #define IS_KEY_BREAK(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_BREAK) #if defined(PCBXLITE) - typedef uint16_t event_t; #define EVT_ROTARY_BREAK EVT_KEY_BREAK(KEY_ENTER) #define EVT_ROTARY_LONG EVT_KEY_LONG(KEY_ENTER) #define EVT_ROTARY_LEFT 0xDF00 @@ -64,7 +63,6 @@ #define IS_NEXT_EVENT(event) (event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)) #define IS_PREVIOUS_EVENT(event) (event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)) #elif (defined(PCBHORUS) || defined(PCBTARANIS)) && defined(ROTARY_ENCODER_NAVIGATION) - typedef uint16_t event_t; #define EVT_ROTARY_BREAK EVT_KEY_BREAK(KEY_ENTER) #define EVT_ROTARY_LONG EVT_KEY_LONG(KEY_ENTER) #define EVT_ROTARY_LEFT 0xDF00 @@ -72,7 +70,6 @@ #define IS_NEXT_EVENT(event) (event==EVT_ROTARY_RIGHT) #define IS_PREVIOUS_EVENT(event) (event==EVT_ROTARY_LEFT) #elif defined(ROTARY_ENCODER_NAVIGATION) - typedef uint8_t event_t; #define EVT_ROTARY_BREAK 0xcf #define EVT_ROTARY_LONG 0xce #define EVT_ROTARY_LEFT 0xdf @@ -80,7 +77,6 @@ #define IS_NEXT_EVENT(event) (event==EVT_ROTARY_RIGHT || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)) #define IS_PREVIOUS_EVENT(event) (event==EVT_ROTARY_LEFT || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)) #else - typedef uint8_t event_t; #define IS_NEXT_EVENT(event) (event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)) #define IS_PREVIOUS_EVENT(event) (event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)) #endif diff --git a/radio/src/opentx_types.h b/radio/src/opentx_types.h index a1fe876d36..8d6f86977d 100644 --- a/radio/src/opentx_types.h +++ b/radio/src/opentx_types.h @@ -18,8 +18,8 @@ * GNU General Public License for more details. */ -#ifndef _OTXTYPES_H_ -#define _OTXTYPES_H_ +#ifndef _OPENTX_TYPES_H_ +#define _OPENTX_TYPES_H_ #include @@ -30,5 +30,6 @@ typedef uint32_t mixsrc_t; typedef int32_t swsrc_t; typedef int16_t safetych_t; typedef uint32_t bitfield_channels_t; +typedef uint16_t event_t; -#endif // _OTXTYPES_H_ +#endif // _OPENTX_TYPES_H_ diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index c1246e2d48..95f29544ef 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -370,17 +370,6 @@ inline void SEND_FAILSAFE_1S() // for channels not set previously to HOLD or NOPULSE void setCustomFailsafe(uint8_t moduleIndex); -#define LEN_R9M_REGION "\006" -#define TR_R9M_REGION "FCC\0 ""EU\0 ""868MHz""915MHz" -#define LEN_R9M_LITE_FCC_POWER_VALUES "\010" -#define LEN_R9M_LITE_LBT_POWER_VALUES "\015" -#define TR_R9M_LITE_FCC_POWER_VALUES "(100 mW)" -#define TR_R9M_LITE_LBT_POWER_VALUES "25 mW 8ch\0 ""25 mW 16ch\0 ""100mW no tele" - -enum R9MLiteFCCPowerValues { - R9M_LITE_FCC_POWER_100 = 0, - R9M_LITE_FCC_POWER_MAX = R9M_LITE_FCC_POWER_100 -}; enum R9MLiteLBTPowerValues { R9M_LITE_LBT_POWER_25 = 0, @@ -389,11 +378,6 @@ enum R9MLiteLBTPowerValues { R9M_LITE_LBT_POWER_MAX = R9M_LITE_LBT_POWER_100 }; -#define LEN_R9M_FCC_POWER_VALUES "\006" -#define LEN_R9M_LBT_POWER_VALUES "\013" -#define TR_R9M_FCC_POWER_VALUES "10 mW\0" "100 mW" "500 mW" "1 W\0" -#define TR_R9M_LBT_POWER_VALUES "25 mW 8ch\0 ""25 mW 16ch\0" "200 mW 16ch" "500 mW 16ch" - enum R9MFCCPowerValues { R9M_FCC_POWER_10 = 0, R9M_FCC_POWER_100, diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index f47dc8df1f..b3756b7d69 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -95,6 +95,10 @@ endif() # Protocols supported +if(PPM) + add_definitions(-DPPM) +endif() + if(DSM2) add_definitions(-DDSM2) endif() diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 6975aa4859..d59086cc99 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -102,6 +102,7 @@ set(GUI_SRC topbar.cpp layout.cpp widget.cpp + menus.cpp ${THEMES_SRC} ${LAYOUTS_SRC} ${WIDGETS_SRC} @@ -117,15 +118,6 @@ if(INTERNAL_GPS) message("Horus: Internal GPS enabled") endif() -if(PXX2) - set(GUI_SRC - ${GUI_SRC} - radio_tools.cpp - radio_power_meter.cpp - radio_spectrum_analyser.cpp - ) -endif() - set(AUX_SERIAL_DRIVER ../common/arm/stm32/serial2_driver.cpp) set(GVAR_SCREEN model_gvars.cpp) diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index 8a4a57fd8b..681333243a 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -108,6 +108,21 @@ #define LEN_R9M_PXX2_RF_PROTOCOLS "\006" #define TR_R9M_PXX2_RF_PROTOCOLS "ACCESS""FCC\0 ""EU\0 ""Flex" +#define LEN_R9M_REGION "\006" +#define TR_R9M_REGION "FCC\0 ""EU\0 ""868MHz""915MHz" + +#define LEN_R9M_LITE_FCC_POWER_VALUES "\010" +#define TR_R9M_LITE_FCC_POWER_VALUES "(100 mW)" + +#define LEN_R9M_LITE_LBT_POWER_VALUES "\015" +#define TR_R9M_LITE_LBT_POWER_VALUES "25 mW 8ch\0 ""25 mW 16ch\0 ""100mW no tele" + +#define LEN_R9M_FCC_POWER_VALUES "\006" +#define TR_R9M_FCC_POWER_VALUES "10 mW\0" "100 mW" "500 mW" "1 W\0" + +#define LEN_R9M_LBT_POWER_VALUES "\013" +#define TR_R9M_LBT_POWER_VALUES "25 mW 8ch\0 ""25 mW 16ch\0" "200 mW 16ch" "500 mW 16ch" + #define LEN_DSM_PROTOCOLS "\004" #define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX"