1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-21 15:25:12 +03:00

Bsongis/menus refactoring (#6463)

Menus refactoring
This commit is contained in:
Bertrand Songis 2019-05-29 16:04:09 +02:00 committed by GitHub
parent 1b71b7fcbc
commit 670e101fa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 848 additions and 687 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;

View file

@ -76,9 +76,11 @@ enum MenuModelSetupItems {
#endif
ITEM_MODEL_SETUP_BEEP_CENTER,
ITEM_MODEL_SETUP_USE_GLOBAL_FUNCTIONS,
#if defined(PXX2)
ITEM_MODEL_SETUP_REGISTRATION_ID,
#endif
#if defined(HARDWARE_INTERNAL_MODULE)
ITEM_MODEL_SETUP_INTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE,
@ -95,6 +97,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3,
#endif
ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE,
#if defined(MULTIMODULE)
@ -119,11 +122,13 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3,
#if defined(PCBSKY9X)
ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS,
ITEM_MODEL_SETUP_EXTRA_MODULE_BIND,
#endif
#if defined(PCBTARANIS)
ITEM_MODEL_SETUP_TRAINER_LABEL,
ITEM_MODEL_SETUP_TRAINER_MODE,
@ -174,21 +179,27 @@ enum MenuModelSetupItems {
#define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 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<NUM_BODY_LINES; ++i) {
@ -1012,7 +757,8 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, TR_INTERNALRF);
break;
case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE: {
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);

View file

@ -173,7 +173,7 @@ void menuCommonCalib(event_t event)
void menuRadioCalibration(event_t event)
{
check_submenu_simple(event, 0);
TITLE(STR_MENUCALIBRATION);
title(STR_MENUCALIBRATION);
menuCommonCalib(READ_ONLY() ? 0 : event);
if (menuEvent) {
menuCalibrationState = CALIB_START;

View file

@ -63,7 +63,7 @@ void menuRadioModulesVersion(event_t event)
return;
}
TITLE(STR_MENU_MODULES_RX_VERSION);
title(STR_MENU_MODULES_RX_VERSION);
if (event == EVT_ENTRY || get_tmr10ms() >= reusableBuffer.hardwareAndSettings.updateTime) {
// menuVerticalOffset = 0;

View file

@ -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):

View file

@ -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);

View file

@ -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

View file

@ -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<NUM_BODY_LINES; i++) {
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;

View file

@ -80,31 +80,47 @@ enum MenuModelSetupItems {
#endif
ITEM_MODEL_SETUP_BEEP_CENTER,
ITEM_MODEL_SETUP_USE_GLOBAL_FUNCTIONS,
#if defined(PXX2)
ITEM_MODEL_SETUP_REGISTRATION_ID,
#endif
ITEM_MODEL_SETUP_INTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_INTERNAL_MODULE_MODE,
ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE,
ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS,
ITEM_MODEL_SETUP_INTERNAL_MODULE_BIND,
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM,
ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_MODE,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE,
#if defined (MULTIMODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS,
#endif
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_BIND,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
#if defined(MULTIMODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND,
#endif
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_OPTIONS,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3,
ITEM_MODEL_SETUP_TRAINER_LABEL,
ITEM_MODEL_SETUP_TRAINER_MODE,
ITEM_MODEL_SETUP_TRAINER_LINE1,
ITEM_MODEL_SETUP_TRAINER_LINE2,
ITEM_MODEL_SETUP_SETUP_MAX
ITEM_MODEL_SETUP_LINES_COUNT
};
#define MODEL_SETUP_2ND_COLUMN (LCD_W-17*FW-MENUS_SCROLLBAR_WIDTH-1)
@ -113,35 +129,6 @@ enum MenuModelSetupItems {
#define MODEL_SETUP_RANGE_OFS 7*FW
#define MODEL_SETUP_SET_FAILSAFE_OFS 10*FW-2
#define CURRENT_MODULE_EDITED(k) (k >= 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<uint8_t>(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;

View file

@ -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;

View file

@ -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)
{

View file

@ -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})

View file

@ -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}

View file

@ -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);
}

View file

@ -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_

View file

@ -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) {

View file

@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include <opentx.h>
#include "opentx.h"
#define RECEIVER_OPTIONS_2ND_COLUMN 80

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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 <inttypes.h>
@ -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_

View file

@ -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,

View file

@ -95,6 +95,10 @@ endif()
# Protocols supported
if(PPM)
add_definitions(-DPPM)
endif()
if(DSM2)
add_definitions(-DDSM2)
endif()

View file

@ -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)

View file

@ -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"