diff --git a/radio/src/gui/480x272/CMakeLists.txt b/radio/src/gui/480x272/CMakeLists.txt index 1a722278f..227bba2c7 100644 --- a/radio/src/gui/480x272/CMakeLists.txt +++ b/radio/src/gui/480x272/CMakeLists.txt @@ -8,6 +8,8 @@ set(GUI_SRC menu_model.cpp model_select.cpp model_setup.cpp + model_module_options.cpp +# model_receiver_options.cpp model_failsafe.cpp model_logical_switches.cpp model_special_functions.cpp diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index 8ba739d7e..b57f727a5 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -179,6 +179,7 @@ bool menuModelCustomScripts(event_t event); bool menuModelTelemetryFrsky(event_t event); bool menuModelSensor(event_t event); bool menuModelExpoOne(event_t event); +bool menuModelModuleOptions(event_t event); extern const MenuHandlerFunc menuTabModel[MENU_MODEL_PAGES_COUNT]; diff --git a/radio/src/gui/480x272/model_module_options.cpp b/radio/src/gui/480x272/model_module_options.cpp new file mode 100644 index 000000000..686b154b0 --- /dev/null +++ b/radio/src/gui/480x272/model_module_options.cpp @@ -0,0 +1,210 @@ +/* + * 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 +#include + +#define RECEIVER_OPTIONS_2ND_COLUMN 200 + +extern uint8_t g_moduleIdx; + +enum { + MODULE_SETTINGS_OK = 0, + MODULE_SETTINGS_DIRTY = 1, + MODULE_SETTINGS_REBIND = 2, + MODULE_SETTINGS_WRITING = 4, +}; + +void onTxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_WRITING; + moduleState[g_moduleIdx].writeModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + else { + popMenu(); + } +} + +bool isTelemetryAvailable() +{ + return reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant != PXX2_VARIANT_EU || + reusableBuffer.hardwareAndSettings.moduleSettings.txPower <= 14; +} + +enum { + ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, + ITEM_MODULE_SETTINGS_POWER, + ITEM_MODULE_SETTINGS_TELEMETRY, + ITEM_MODULE_SETTINGS_COUNT +}; + +#define IF_MODULE_OPTIONS(option, count) uint8_t(isPXX2ModuleOptionAvailable(modelId, option) ? count : HIDDEN_ROW) + +bool isPowerAvailable(int value) +{ + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; + uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + + if (modelId == PXX2_MODULE_R9M_LITE) { + if (variant == PXX2_VARIANT_EU) + return (value == 14 /* 25 mW with telemetry */ || + value == 20 /* 100 mW without telemetry */); + else + return value == 20; /* 100 mW */ + } + else if (modelId == PXX2_MODULE_R9M || modelId == PXX2_MODULE_R9M_LITE_PRO) { + if (variant == PXX2_VARIANT_EU) + return (value == 14 /* 25 mW */ || + value == 23 /* 200 mW */ || + value == 27 /* 500 mW */); + else + return (value == 10 /* 10 mW */ || + value == 20 /* 100 mW */ || + value == 27 /* 500 mW */ || + value == 30 /* 1000 mW */); + } + else { + return (value <= 20); /* 100 mW max for XJTs */ + } +} + +bool menuModelModuleOptions(event_t event) +{ + if (event == EVT_ENTRY) { + memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; +#endif + } + + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.modelID; + // uint8_t variant = reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information.variant; + uint8_t optionsAvailable = getPXX2ModuleOptions(modelId) & ((1 << MODULE_OPTION_EXTERNAL_ANTENNA) | (1 << MODULE_OPTION_POWER)); + + SUBMENU(STR_MODULE_OPTIONS, ICON_MODEL_SETUP, ITEM_MODULE_SETTINGS_COUNT, { + !optionsAvailable ? (uint8_t)0 : IF_MODULE_OPTIONS(MODULE_OPTION_EXTERNAL_ANTENNA, 0), + IF_MODULE_OPTIONS(MODULE_OPTION_POWER, 0), + IF_MODULE_OPTIONS(MODULE_OPTION_POWER, isTelemetryAvailable() ? HIDDEN_ROW : READONLY_ROW) + }); + + lcdDrawText(50, 3 + FH, getPXX2ModuleName(modelId), MENU_TITLE_COLOR); + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_HARDWARE_INFO && moduleState[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + if (!modelId) + moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[g_moduleIdx], PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); + else + moduleState[g_moduleIdx].readModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + + if (menuEvent) { + killEvents(KEY_EXIT); + moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION(STR_UPDATE_TX_OPTIONS, onTxOptionsUpdateConfirm); + } + else { + return false; + } + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_OK; + moduleState[g_moduleIdx].writeModuleSettings(&reusableBuffer.hardwareAndSettings.moduleSettings); + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty == MODULE_SETTINGS_WRITING && reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + return false; + } + + if (modelId != 0 && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + menuVerticalPosition = 0; + while (menuVerticalPosition < ITEM_MODULE_SETTINGS_COUNT && mstate_tab[menuVerticalPosition] == HIDDEN_ROW) { + ++menuVerticalPosition; + } + } + + int8_t sub = menuVerticalPosition; + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + if (optionsAvailable) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXT_ANTENNA); + reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY; + } + break; + + case ITEM_MODULE_SETTINGS_POWER: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWER); + lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, attr); + lcdDrawText(lcdNextPos, y, "dBm("); + drawPower(lcdNextPos, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower); + lcdDrawText(lcdNextPos, y, ")"); + if (attr) { + bool previousTelemetry = isTelemetryAvailable(); + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, 0, 30, 0, &isPowerAvailable); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = MODULE_SETTINGS_DIRTY; + if (previousTelemetry != isTelemetryAvailable()) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty |= MODULE_SETTINGS_REBIND; + } + } + if (s_editMode == 0 && (reusableBuffer.hardwareAndSettings.moduleSettings.dirty & MODULE_SETTINGS_REBIND)) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty &= ~MODULE_SETTINGS_REBIND; + POPUP_WARNING(STR_REBIND); + } + } + break; + + case ITEM_MODULE_SETTINGS_TELEMETRY: + // only displayed in EU mode when TX power > 25mW + lcdDrawText(RECEIVER_OPTIONS_2ND_COLUMN, y, "Telem OFF", attr | SMLSIZE); + break; + } + } + } + else { + lcdDrawCenteredText(LCD_H/2, STR_NO_TX_OPTIONS); + s_editMode = 0; + } + } + else { + lcdDrawCenteredText(LCD_H/2, STR_WAITING_FOR_TX); + s_editMode = 0; + } + + return true; +} diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 607593efe..23788b0c0 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -84,18 +84,25 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL, ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE, - ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER, #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_NOT_ACCESS_BIND, - ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE, + 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, #if defined(BLUETOOTH) @@ -1301,12 +1308,12 @@ bool menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_OPTIONS: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_OPTIONS: lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_OPTIONS); drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_SET, attr); if (event == EVT_KEY_BREAK(KEY_ENTER) && attr) { g_moduleIdx = CURRENT_MODULE_EDITED(k); - memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); - // TODO pushMenu(menuModelModuleOptions); + pushMenu(menuModelModuleOptions); } break; diff --git a/radio/src/gui/480x272/model_telemetry_sensor.cpp b/radio/src/gui/480x272/model_telemetry_sensor.cpp index 1926e1af5..176d0d550 100644 --- a/radio/src/gui/480x272/model_telemetry_sensor.cpp +++ b/radio/src/gui/480x272/model_telemetry_sensor.cpp @@ -59,7 +59,7 @@ bool menuModelSensor(event_t event) SUBMENU("SENSOR", ICON_MODEL_TELEMETRY, SENSOR_FIELD_MAX, { 0, 0, sensor->type == TELEM_TYPE_CALCULATED ? (uint8_t)0 : (uint8_t)1, SENSOR_UNIT_ROWS, SENSOR_PREC_ROWS, SENSOR_PARAM1_ROWS, SENSOR_PARAM2_ROWS, SENSOR_PARAM3_ROWS, SENSOR_PARAM4_ROWS, SENSOR_AUTOOFFSET_ROWS, SENSOR_ONLYPOS_ROWS, SENSOR_FILTER_ROWS, SENSOR_PERSISTENT_ROWS, 0 }); lcdDrawNumber(lcdNextPos, 3, s_currIdx+1, MENU_TITLE_COLOR|LEFT); - drawSensorCustomValue(50, 3+FH, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), MENU_TITLE_COLOR|LEFT); + drawSensorCustomValue(50, 3 + FH, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), MENU_TITLE_COLOR|LEFT); for (uint8_t i=0; i