From 4248b1fce946e78eb0bcc3b7982180cfe2950485 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 27 Mar 2019 08:56:06 +0100 Subject: [PATCH] Model Setup file splitted --- radio/src/gui/128x64/menus.h | 3 + radio/src/gui/128x64/model_failsafe.cpp | 138 +++++++ radio/src/gui/128x64/model_module_options.cpp | 121 ++++++ .../src/gui/128x64/model_receiver_options.cpp | 156 ++++++++ radio/src/gui/128x64/model_setup.cpp | 347 ------------------ radio/src/gui/212x64/menus.h | 2 + radio/src/gui/CMakeLists.txt | 3 + 7 files changed, 423 insertions(+), 347 deletions(-) create mode 100644 radio/src/gui/128x64/model_failsafe.cpp create mode 100644 radio/src/gui/128x64/model_module_options.cpp create mode 100644 radio/src/gui/128x64/model_receiver_options.cpp diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index 0f7c64342..26e9af134 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -135,6 +135,9 @@ enum MenuModelIndexes { void menuModelSelect(event_t event); void menuModelSetup(event_t event); +void menuModelFailsafe(event_t event); +void menuModelModuleOptions(event_t event); +void menuModelReceiverOptions(event_t event); void menuModelHeli(event_t event); void menuModelFlightModesAll(event_t event); void menuModelExpoOne(event_t event); diff --git a/radio/src/gui/128x64/model_failsafe.cpp b/radio/src/gui/128x64/model_failsafe.cpp new file mode 100644 index 000000000..905b293f7 --- /dev/null +++ b/radio/src/gui/128x64/model_failsafe.cpp @@ -0,0 +1,138 @@ +/* + * 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 + +extern uint8_t g_moduleIdx; + +void menuModelFailsafe(event_t event) +{ + const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + uint8_t wbar = LCD_W - FW * 4 - FWNUM * 4; +#if defined(PPM_UNIT_PERCENT_PREC1) + wbar -= 6; +#endif + + if (event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + event = 0; + + if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { + if (s_editMode > 0) { + g_model.failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; + s_editMode = 0; + } + else { + int16_t & failsafe = g_model.failsafeChannels[menuVerticalPosition]; + if (failsafe < FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_HOLD; + else if (failsafe == FAILSAFE_CHANNEL_HOLD) + failsafe = FAILSAFE_CHANNEL_NOPULSE; + else + failsafe = 0; + } + } + else { + // "Outputs => Failsafe" menu item + setCustomFailsafe(g_moduleIdx); + } + + storageDirty(EE_MODEL); + AUDIO_WARNING1(); + SEND_FAILSAFE_NOW(g_moduleIdx); + } + + SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1); + + lcdDrawTextAlignedCenter(0, FAILSAFESET); + lcdInvertLine(0); + + const coord_t x = 1; + coord_t y = FH + 1; + uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); + uint8_t ch = (menuVerticalPosition >= 8 ? 8 : 0) + line; + + // Channels + for (; line < 8; line++) { + const int32_t channelValue = channelOutputs[ch+channelStart]; + int32_t failsafeValue = g_model.failsafeChannels[ch]; + + // Channel + putsChn(x+1, y, ch+1, SMLSIZE); + + // Value + LcdFlags flags = TINSIZE; + if (menuVerticalPosition == ch) { + flags |= INVERS; + if (s_editMode > 0) { + if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + s_editMode = 0; + } + else { + flags |= BLINK; + CHECK_INCDEC_MODELVAR(event, g_model.failsafeChannels[ch], -lim, +lim); + } + } + } + + uint8_t xValue = x+LCD_W-4-wbar; + if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { + lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); + failsafeValue = 0; + } + else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); + failsafeValue = 0; + } + else { +#if defined(PPM_UNIT_US) + lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); +#elif defined(PPM_UNIT_PERCENT_PREC1) + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); +#else + lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); +#endif + } + + // Gauge +#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines + lcdDrawRect(x+LCD_W-3-wbar, y, wbar+1, 6); +#endif + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2); + const uint8_t lenFailsafe = limit(1, (abs(failsafeValue) * wbar/2 + lim/2) / lim, wbar/2); + const coord_t xChannel = (channelValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenChannel; + const coord_t xFailsafe = (failsafeValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenFailsafe; + lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); + lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); + lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); + lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); + + y += FH - 1; + + if (++ch >= sentModuleChannels(g_moduleIdx)) + break; + } + + if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { + // Outputs => Failsafe + lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); + } +} diff --git a/radio/src/gui/128x64/model_module_options.cpp b/radio/src/gui/128x64/model_module_options.cpp new file mode 100644 index 000000000..302e77d75 --- /dev/null +++ b/radio/src/gui/128x64/model_module_options.cpp @@ -0,0 +1,121 @@ +/* + * 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 + +#define RECEIVER_OPTIONS_2ND_COLUMN 80 + +extern uint8_t g_moduleIdx; + +void onTxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = 2; + reusableBuffer.hardwareAndSettings.moduleSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; + } + else { + popMenu(); + } +} + +enum MenuModelModuleOptionsItems { + ITEM_MODULE_SETTINGS_RF_PROTOCOL, + ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, + ITEM_MODULE_SETTINGS_POWER, + ITEM_MODULE_SETTINGS_COUNT +}; + +void menuModelModuleOptions(event_t event) +{ + SIMPLE_SUBMENU_NOTITLE(ITEM_MODULE_SETTINGS_COUNT); + + if (menuEvent) { + moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION("Update TX options?", onTxOptionsUpdateConfirm); + } + else { + return; + } + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + } + + int8_t sub = menuVerticalPosition; + + lcdDrawTextAlignedLeft(0, "Module options"); + lcdInvertLine(0); + + if (event == EVT_ENTRY) { +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; +#else + moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; +#endif + } + + if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_MODULE_SETTINGS_RF_PROTOCOL: + lcdDrawText(0, y, "RF Protocol"); + lcdDrawTextAtIndex(RECEIVER_OPTIONS_2ND_COLUMN, y, STR_XJT_PROTOCOLS, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol + 1, attr); + if (attr) { + reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, 0, nullptr); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + } + break; + + case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: + reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, "Ext. antenna", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + break; + + case ITEM_MODULE_SETTINGS_POWER: + lcdDrawText(0, y, "Power"); + lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, attr); + lcdDrawText(lcdNextPos, y, "dBm"); + if (attr) { + reusableBuffer.hardwareAndSettings.moduleSettings.txPower = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, -127, 127); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; + } + } + break; + } + } + } + else { + lcdDrawText(4 * FW, 4 * FH, "Waiting for TX..."); + } +} diff --git a/radio/src/gui/128x64/model_receiver_options.cpp b/radio/src/gui/128x64/model_receiver_options.cpp new file mode 100644 index 000000000..59dcbe47a --- /dev/null +++ b/radio/src/gui/128x64/model_receiver_options.cpp @@ -0,0 +1,156 @@ +/* + * 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 + +#define RECEIVER_OPTIONS_2ND_COLUMN 80 + +extern uint8_t g_moduleIdx; +extern void drawReceiverName(uint8_t x, uint8_t y, uint8_t receiverSlot); + +void onRxOptionsUpdateConfirm(const char * result) +{ + if (result == STR_OK) { + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 2; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + else { + popMenu(); + } +} + +enum { + ITEM_RECEIVER_TELEMETRY, + ITEM_RECEIVER_PWM_RATE, + ITEM_RECEIVER_PINMAP_FIRST +}; + +void menuModelReceiverOptions(event_t event) +{ + const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; + uint8_t wbar = LCD_W / 2 - 20; + auto outputsCount = min(16, reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount); + + SIMPLE_SUBMENU_NOTITLE(ITEM_RECEIVER_PINMAP_FIRST + outputsCount); + + if (event == EVT_ENTRY) { +#if defined(SIMU) + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_OK; + reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount = 8; +#else + // no need to initialize reusableBuffer.hardwareAndSettings.receiverSettings.state to PXX2_HARDWARE_INFO + moduleSettings[g_moduleIdx].mode = MODULE_MODE_GET_HARDWARE_INFO; +#endif + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_HARDWARE_INFO && moduleSettings[g_moduleIdx].mode == MODULE_MODE_NORMAL) { + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_READ; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + + if (menuEvent) { + moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + abortPopMenu(); + POPUP_CONFIRMATION("Update RX options?", onRxOptionsUpdateConfirm); + } + else { + return; + } + } + + if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { + killEvents(event); + reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 0; + reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; + moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; + } + + if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + popMenu(); + return; + } + + int8_t sub = menuVerticalPosition; + + lcdDrawTextAlignedLeft(0, STR_RECEIVER_OPTIONS); + drawReceiverName(FW * 13, 0, reusableBuffer.hardwareAndSettings.receiverSettings.receiverId); + lcdInvertLine(0); + + if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); + + switch (i) { + case ITEM_RECEIVER_TELEMETRY: + reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled, RECEIVER_OPTIONS_2ND_COLUMN, y, "Telem. disabled", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + break; + + case ITEM_RECEIVER_PWM_RATE: + reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate, RECEIVER_OPTIONS_2ND_COLUMN, y, "9ms PWM", attr, event); + if (attr && checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + break; + + default: + // Pin + { + uint8_t pin = i - ITEM_RECEIVER_PINMAP_FIRST; + uint8_t channel = reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin]; + int32_t channelValue = channelOutputs[channel]; + lcdDrawText(0, y, "Pin"); + lcdDrawNumber(lcdLastRightPos + 1, y, pin + 1); + putsChn(7 * FW, y, channel + 1, attr); + + // Channel + if (attr) { + channel = checkIncDec(event, channel, 0, sentModuleChannels(g_moduleIdx) - 1); + if (checkIncDec_Ret) { + reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin] = channel; + reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; + } + } + + // Bargraph +#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines + lcdDrawRect(LCD_W - 3 - wbar, y + 1, wbar + 1, 4); +#endif + const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar / 2 + lim / 2) / lim, wbar / 2); + const coord_t xChannel = (channelValue > 0) ? LCD_W - 3 - wbar / 2 : LCD_W - 2 - wbar / 2 - lenChannel; + lcdDrawHorizontalLine(xChannel, y + 2, lenChannel, SOLID, 0); + lcdDrawHorizontalLine(xChannel, y + 3, lenChannel, SOLID, 0); + break; + } + } + } + } + else { + lcdDrawText(4 * FW, 4 * FH, "Waiting for RX..."); + } +} diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 14b8bc4ca..e26dd2cc9 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -38,10 +38,6 @@ void drawReceiverName(uint8_t x, uint8_t y, uint8_t receiverSlot) lcdDrawText(x, y, "---"); } -void menuModelFailsafe(event_t event); -void menuModelModuleOptions(event_t event); -void menuModelReceiverOptions(event_t event); - #if defined(PCBTARANIS) uint8_t getSwitchWarningsCount() { @@ -1822,346 +1818,3 @@ void menuModelSetup(event_t event) } } } - -void menuModelFailsafe(event_t event) -{ - const uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; - const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; - uint8_t wbar = LCD_W - FW * 4 - FWNUM * 4; -#if defined(PPM_UNIT_PERCENT_PREC1) - wbar -= 6; -#endif - - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - event = 0; - - if (menuVerticalPosition < sentModuleChannels(g_moduleIdx)) { - if (s_editMode > 0) { - g_model.failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; - s_editMode = 0; - } - else { - int16_t & failsafe = g_model.failsafeChannels[menuVerticalPosition]; - if (failsafe < FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_HOLD; - else if (failsafe == FAILSAFE_CHANNEL_HOLD) - failsafe = FAILSAFE_CHANNEL_NOPULSE; - else - failsafe = 0; - } - } - else { - // "Outputs => Failsafe" menu item - setCustomFailsafe(g_moduleIdx); - } - - storageDirty(EE_MODEL); - AUDIO_WARNING1(); - SEND_FAILSAFE_NOW(g_moduleIdx); - } - - SIMPLE_SUBMENU_NOTITLE(sentModuleChannels(g_moduleIdx) + 1); - - lcdDrawTextAlignedCenter(0, FAILSAFESET); - lcdInvertLine(0); - - const coord_t x = 1; - coord_t y = FH + 1; - uint8_t line = (menuVerticalPosition >= sentModuleChannels(g_moduleIdx) ? 2 : 0); - uint8_t ch = (menuVerticalPosition >= 8 ? 8 : 0) + line; - - // Channels - for (; line < 8; line++) { - const int32_t channelValue = channelOutputs[ch+channelStart]; - int32_t failsafeValue = g_model.failsafeChannels[ch]; - - // Channel - putsChn(x+1, y, ch+1, SMLSIZE); - - // Value - LcdFlags flags = TINSIZE; - if (menuVerticalPosition == ch) { - flags |= INVERS; - if (s_editMode > 0) { - if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - s_editMode = 0; - } - else { - flags |= BLINK; - CHECK_INCDEC_MODELVAR(event, g_model.failsafeChannels[ch], -lim, +lim); - } - } - } - - uint8_t xValue = x+LCD_W-4-wbar; - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - lcdDrawText(xValue, y, STR_HOLD, RIGHT|flags); - failsafeValue = 0; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { - lcdDrawText(xValue, y, STR_NONE, RIGHT|flags); - failsafeValue = 0; - } - else { -#if defined(PPM_UNIT_US) - lcdDrawNumber(xValue, y, PPM_CH_CENTER(ch)+failsafeValue/2, RIGHT|flags); -#elif defined(PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue), RIGHT|PREC1|flags); -#else - lcdDrawNumber(xValue, y, calcRESXto1000(failsafeValue)/10, RIGHT|flags); -#endif - } - - // Gauge -#if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines - lcdDrawRect(x+LCD_W-3-wbar, y, wbar+1, 6); -#endif - const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar/2 + lim/2) / lim, wbar/2); - const uint8_t lenFailsafe = limit(1, (abs(failsafeValue) * wbar/2 + lim/2) / lim, wbar/2); - const coord_t xChannel = (channelValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenChannel; - const coord_t xFailsafe = (failsafeValue>0) ? x+LCD_W-3-wbar/2 : x+LCD_W-2-wbar/2-lenFailsafe; - lcdDrawHorizontalLine(xChannel, y+1, lenChannel, DOTTED, 0); - lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0); - lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe); - lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe); - - y += FH - 1; - - if (++ch >= sentModuleChannels(g_moduleIdx)) - break; - } - - if (menuVerticalPosition >= sentModuleChannels(g_moduleIdx)) { - // Outputs => Failsafe - lcdDrawText(CENTER_OFS, LCD_H - (FH + 1), STR_OUTPUTS2FAILSAFE, INVERS); - } -} - -#define RECEIVER_OPTIONS_2ND_COLUMN 80 - -void onTxOptionsUpdateConfirm(const char * result) -{ - if (result == STR_OK) { - reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_WRITE; - reusableBuffer.hardwareAndSettings.moduleSettings.dirty = 2; - reusableBuffer.hardwareAndSettings.moduleSettings.timeout = 0; - moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; - } - else { - popMenu(); - } -} - -enum MenuModelModuleOptionsItems { - ITEM_MODULE_SETTINGS_RF_PROTOCOL, - ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA, - ITEM_MODULE_SETTINGS_POWER, - ITEM_MODULE_SETTINGS_COUNT -}; - -void menuModelModuleOptions(event_t event) -{ - SIMPLE_SUBMENU_NOTITLE(ITEM_MODULE_SETTINGS_COUNT); - - if (menuEvent) { - moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; - if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty) { - abortPopMenu(); - POPUP_CONFIRMATION("Update TX options?", onTxOptionsUpdateConfirm); - } - else { - return; - } - } - - if (reusableBuffer.hardwareAndSettings.moduleSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { - popMenu(); - } - - int8_t sub = menuVerticalPosition; - - lcdDrawTextAlignedLeft(0, "Module options"); - lcdInvertLine(0); - - if (event == EVT_ENTRY) { -#if defined(SIMU) - reusableBuffer.hardwareAndSettings.moduleSettings.state = PXX2_SETTINGS_OK; -#else - moduleSettings[g_moduleIdx].mode = MODULE_MODE_MODULE_SETTINGS; -#endif - } - - if (reusableBuffer.hardwareAndSettings.moduleSettings.state == PXX2_SETTINGS_OK) { - for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); - - switch (i) { - case ITEM_MODULE_SETTINGS_RF_PROTOCOL: - lcdDrawText(0, y, "RF Protocol"); - lcdDrawTextAtIndex(RECEIVER_OPTIONS_2ND_COLUMN, y, STR_XJT_PROTOCOLS, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol + 1, attr); - if (attr) { - reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, 0, nullptr); - if (checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; - } - } - break; - - case ITEM_MODULE_SETTINGS_EXTERNAL_ANTENNA: - reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna = editCheckBox(reusableBuffer.hardwareAndSettings.moduleSettings.externalAntenna, RECEIVER_OPTIONS_2ND_COLUMN, y, "Ext. antenna", attr, event); - if (attr && checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; - } - break; - - case ITEM_MODULE_SETTINGS_POWER: - lcdDrawText(0, y, "Power"); - lcdDrawNumber(RECEIVER_OPTIONS_2ND_COLUMN, y, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, attr); - lcdDrawText(lcdNextPos, y, "dBm"); - if (attr) { - reusableBuffer.hardwareAndSettings.moduleSettings.txPower = checkIncDec(event, reusableBuffer.hardwareAndSettings.moduleSettings.txPower, -127, 127); - if (checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.moduleSettings.dirty = true; - } - } - break; - } - } - } - else { - lcdDrawText(4 * FW, 4 * FH, "Waiting for TX..."); - } -} - -void onRxOptionsUpdateConfirm(const char * result) -{ - if (result == STR_OK) { - reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; - reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 2; - reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; - moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; - } - else { - popMenu(); - } -} - -enum { - ITEM_RECEIVER_TELEMETRY, - ITEM_RECEIVER_PWM_RATE, - ITEM_RECEIVER_PINMAP_FIRST -}; - -void menuModelReceiverOptions(event_t event) -{ - const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2; - uint8_t wbar = LCD_W / 2 - 20; - auto outputsCount = min(16, reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount); - - SIMPLE_SUBMENU_NOTITLE(ITEM_RECEIVER_PINMAP_FIRST + outputsCount); - - if (event == EVT_ENTRY) { -#if defined(SIMU) - reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_OK; - reusableBuffer.hardwareAndSettings.receiverSettings.outputsCount = 8; -#else - // no need to initialize reusableBuffer.hardwareAndSettings.receiverSettings.state to PXX2_HARDWARE_INFO - moduleSettings[g_moduleIdx].mode = MODULE_MODE_GET_HARDWARE_INFO; -#endif - } - - if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_HARDWARE_INFO && moduleSettings[g_moduleIdx].mode == MODULE_MODE_NORMAL) { - reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_READ; - moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; - } - - if (menuEvent) { - moduleSettings[g_moduleIdx].mode = MODULE_MODE_NORMAL; - if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { - abortPopMenu(); - POPUP_CONFIRMATION("Update RX options?", onRxOptionsUpdateConfirm); - } - else { - return; - } - } - - if (event == EVT_KEY_LONG(KEY_ENTER) && reusableBuffer.hardwareAndSettings.receiverSettings.dirty) { - killEvents(event); - reusableBuffer.hardwareAndSettings.receiverSettings.state = PXX2_SETTINGS_WRITE; - reusableBuffer.hardwareAndSettings.receiverSettings.dirty = 0; - reusableBuffer.hardwareAndSettings.receiverSettings.timeout = 0; - moduleSettings[g_moduleIdx].mode = MODULE_MODE_RECEIVER_SETTINGS; - } - - if (reusableBuffer.hardwareAndSettings.receiverSettings.dirty == 2 && reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { - popMenu(); - return; - } - - int8_t sub = menuVerticalPosition; - - lcdDrawTextAlignedLeft(0, STR_RECEIVER_OPTIONS); - drawReceiverName(FW * 13, 0, reusableBuffer.hardwareAndSettings.receiverSettings.receiverId); - lcdInvertLine(0); - - if (reusableBuffer.hardwareAndSettings.receiverSettings.state == PXX2_SETTINGS_OK) { - for (uint8_t k=0; k0 ? BLINK|INVERS : INVERS) : 0); - - switch (i) { - case ITEM_RECEIVER_TELEMETRY: - reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.telemetryDisabled, RECEIVER_OPTIONS_2ND_COLUMN, y, "Telem. disabled", attr, event); - if (attr && checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; - } - break; - - case ITEM_RECEIVER_PWM_RATE: - reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.pwmRate, RECEIVER_OPTIONS_2ND_COLUMN, y, "9ms PWM", attr, event); - if (attr && checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; - } - break; - - default: - // Pin - { - uint8_t pin = i - ITEM_RECEIVER_PINMAP_FIRST; - uint8_t channel = reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin]; - int32_t channelValue = channelOutputs[channel]; - lcdDrawText(0, y, "Pin"); - lcdDrawNumber(lcdLastRightPos + 1, y, pin + 1); - putsChn(7 * FW, y, channel + 1, attr); - - // Channel - if (attr) { - channel = checkIncDec(event, channel, 0, sentModuleChannels(g_moduleIdx) - 1); - if (checkIncDec_Ret) { - reusableBuffer.hardwareAndSettings.receiverSettings.outputsMapping[pin] = channel; - reusableBuffer.hardwareAndSettings.receiverSettings.dirty = true; - } - } - - // Bargraph - #if !defined(PCBX7) // X7 LCD doesn't like too many horizontal lines - lcdDrawRect(LCD_W - 3 - wbar, y + 1, wbar + 1, 4); - #endif - const uint8_t lenChannel = limit(1, (abs(channelValue) * wbar / 2 + lim / 2) / lim, wbar / 2); - const coord_t xChannel = (channelValue > 0) ? LCD_W - 3 - wbar / 2 : LCD_W - 2 - wbar / 2 - lenChannel; - lcdDrawHorizontalLine(xChannel, y + 2, lenChannel, SOLID, 0); - lcdDrawHorizontalLine(xChannel, y + 3, lenChannel, SOLID, 0); - break; - } - } - } - } - else { - lcdDrawText(4 * FW, 4 * FH, "Waiting for RX..."); - } -} diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index f8ed87b9c..c2338d94f 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -119,6 +119,8 @@ enum MenuModelIndexes { void menuModelSelect(event_t event); void menuModelSetup(event_t event); void menuModelFailsafe(event_t event); +void menuModelModuleOptions(event_t event); +void menuModelReceiverOptions(event_t event); void menuModelHeli(event_t event); void menuModelFlightModesAll(event_t event); void menuModelExpoOne(event_t event); diff --git a/radio/src/gui/CMakeLists.txt b/radio/src/gui/CMakeLists.txt index 6ec951c20..0dd24c589 100644 --- a/radio/src/gui/CMakeLists.txt +++ b/radio/src/gui/CMakeLists.txt @@ -9,6 +9,9 @@ set(GUI_SRC menu_model.cpp model_select.cpp model_setup.cpp + model_failsafe.cpp + model_module_options.cpp + model_receiver_options.cpp model_logical_switches.cpp model_special_functions.cpp model_telemetry.cpp