From 3588c8d963507bede911ba6d52cd29d19461b0ae Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 6 Nov 2021 13:02:40 +0100 Subject: [PATCH 01/12] Cleanup first a bit --- radio/src/gui/colorlcd/CMakeLists.txt | 4 + radio/src/gui/colorlcd/access_settings.cpp | 305 +++++++++++++++++++++ radio/src/gui/colorlcd/access_settings.h | 85 ++++++ radio/src/gui/colorlcd/model_setup.cpp | 284 +------------------ radio/src/opentx.h | 28 +- radio/src/pulses/pulses.cpp | 44 ++- radio/src/pulses/pulses.h | 116 +------- radio/src/pulses/pxx2.cpp | 15 + radio/src/pulses/pxx2.h | 103 +++++++ radio/src/telemetry/frsky_pxx2.cpp | 15 +- 10 files changed, 574 insertions(+), 425 deletions(-) create mode 100644 radio/src/gui/colorlcd/access_settings.cpp create mode 100644 radio/src/gui/colorlcd/access_settings.h diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index af4c5cb7f..b1cd3261f 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -98,6 +98,10 @@ if(PXX2 OR MULTIMODULE) add_gui_src(radio_spectrum_analyser.cpp) endif() +if(PXX2) + add_gui_src(access_settings.cpp) +endif() + if(MULTIMODULE) add_gui_src(multi_rfprotos.cpp) endif() diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp new file mode 100644 index 000000000..9dddab5c2 --- /dev/null +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * 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" +#include "access_settings.h" + +#include + +#define SET_DIRTY() storageDirty(EE_MODEL) + +BindRxChoiceMenu::BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, + uint8_t receiverIdx) : + Menu(parent), moduleIdx(moduleIdx), receiverIdx(receiverIdx) +{ + const auto& bindInfo = getPXX2BindInformationBuffer(); + auto receiversCount = min(bindInfo.candidateReceiversCount, + PXX2_MAX_RECEIVERS_PER_MODULE); + + for (uint8_t i = 0; i < receiversCount; i++) { + const char* receiverName = bindInfo.candidateReceiversNames[i]; + addLine(receiverName, [=]() { + auto& bindInfo = getPXX2BindInformationBuffer(); + auto& modInfo = getPXX2ModuleSetupBuffer().moduleInformation; + bindInfo.selectedReceiverIndex = i; + if (isModuleR9MAccess(moduleIdx) && + modInfo.information.variant == PXX2_VARIANT_EU) { + bindInfo.step = BIND_RX_NAME_SELECTED; + // POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); + // POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); + // POPUP_MENU_START(onPXX2R9MBindModeMenu); + } else if (isModuleR9MAccess(moduleIdx) && + modInfo.information.variant == PXX2_VARIANT_FLEX) { + bindInfo.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) + memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], + receiverName, PXX2_LEN_RX_NAME); + storageDirty(EE_MODEL); + bindInfo.step = BIND_OK; + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + new MessageDialog(parent, STR_BIND, STR_BIND_OK); +#else + bindInfo.step = BIND_START; + new BindWaitDialog(parent, moduleIdx, receiverIdx); +#endif + } + }); + } + + setCancelHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); +} + +BindWaitDialog::BindWaitDialog(Window* parent, uint8_t moduleIdx, + uint8_t receiverIdx) : + Dialog(parent, STR_BIND, {50, 73, LCD_W - 100, LCD_H - 146}), + moduleIdx(moduleIdx), + receiverIdx(receiverIdx) +{ + new StaticText(&content->form, {0, height() / 2, width(), PAGE_LINE_HEIGHT}, + STR_WAITING_FOR_RX, 0, CENTERED | COLOR_THEME_PRIMARY1); +} + +void BindWaitDialog::checkEvents() +{ + auto& bindInfo = getPXX2BindInformationBuffer(); + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + deleteLater(); + if (bindInfo.step == BIND_OK) { + new MessageDialog(parent, STR_BIND, STR_BIND_OK); + } else { + // TODO: display error??? + } + return; + } + + if (bindInfo.step == BIND_INIT && bindInfo.candidateReceiversCount > 0) { + new BindRxChoiceMenu(parent, moduleIdx, receiverIdx); + deleteLater(); + return; + } + + Dialog::checkEvents(); +} + +#if defined(HARDWARE_KEYS) +void BindWaitDialog::onEvent(event_t event) +{ + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), + event); + + if (event == EVT_KEY_BREAK(KEY_EXIT)) { + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + deleteLater(); + } +} +#endif + +ReceiverButton::ReceiverButton(FormGroup* parent, rect_t rect, + uint8_t moduleIdx, uint8_t receiverIdx) : + TextButton(parent, rect, STR_BIND, + std::bind(&ReceiverButton::pressBind, this)), + moduleIdx(moduleIdx), + receiverIdx(receiverIdx) +{ +} + +uint8_t ReceiverButton::pressBind() +{ + if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] == '\0') { + startBind(); + } else { + auto menu = new Menu(parent); + menu->addLine(STR_BIND, [=]() { + startBind(); + return 0; + }); + menu->addLine(STR_OPTIONS, [=]() { + auto hwSettings = getPXX2HardwareAndSettingsBuffer(); + memclear(&hwSettings, sizeof(hwSettings)); + hwSettings.receiverSettings.receiverId = receiverIdx; + // pushMenu(menuModelReceiverOptions); + return 0; + }); + menu->addLine(STR_SHARE, [=]() { + auto& modSetup = getPXX2ModuleSetupBuffer(); + modSetup.shareReceiverIndex = receiverIdx; + moduleState[moduleIdx].mode = MODULE_MODE_SHARE; + return 0; + }); + menu->addLine(STR_DELETE, [=]() { + auto& modSetup = getPXX2ModuleSetupBuffer(); + memclear(&modSetup, sizeof(modSetup)); + modSetup.resetReceiverIndex = receiverIdx; + modSetup.resetReceiverFlags = 0x01; + new ConfirmDialog(parent, STR_RECEIVER, STR_RECEIVER_DELETE, [=]() { + moduleState[moduleIdx].mode = MODULE_MODE_RESET; + removePXX2Receiver(moduleIdx, receiverIdx); + }); + return 0; + }); + menu->addLine(STR_RESET, [=]() { + auto& modSetup = getPXX2ModuleSetupBuffer(); + memclear(&modSetup, sizeof(modSetup)); + modSetup.resetReceiverIndex = receiverIdx; + modSetup.resetReceiverFlags = 0xFF; + new ConfirmDialog(parent, STR_RECEIVER, STR_RECEIVER_DELETE, [=]() { + moduleState[moduleIdx].mode = MODULE_MODE_RESET; + removePXX2Receiver(moduleIdx, receiverIdx); + }); + return 0; + }); + menu->setCloseHandler( + [=]() { removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); }); + } + return 0; +} + +void ReceiverButton::startBind() +{ + auto& bindInfo = getPXX2BindInformationBuffer(); + auto& modSetup = getPXX2ModuleSetupBuffer(); + + memclear(&bindInfo, sizeof(bindInfo)); + bindInfo.rxUid = receiverIdx; + + if (isModuleR9MAccess(moduleIdx)) { + bindInfo.step = BIND_MODULE_TX_INFORMATION_REQUEST; +#if defined(SIMU) + modSetup.moduleInformation.information.modelID = 1; + modSetup.moduleInformation.information.variant = 2; +#else + moduleState[moduleIdx].readModuleInformation( + &modSetup.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); +#endif + } else { + moduleState[moduleIdx].startBind(&bindInfo); + } + + new BindWaitDialog(parent, moduleIdx, receiverIdx); +} + +void ReceiverButton::checkEvents() +{ + if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') { + char receiverName[PXX2_LEN_RX_NAME + 1]; + memset(receiverName, 0, sizeof(receiverName)); + strncpy(receiverName, + g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], + effectiveLen( + g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], + PXX2_LEN_RX_NAME)); + setText(receiverName); + } else { + setText(STR_BIND); + } + + TextButton::checkEvents(); +} + +RegisterDialog::RegisterDialog(Window* parent, uint8_t moduleIdx) : + Dialog(parent, STR_REGISTER, {50, 73, LCD_W - 100, 0}), moduleIdx(moduleIdx) +{ + FormGroup* form = &content->form; + FormGridLayout grid(content->form.width()); + grid.setLabelWidth(150); + grid.spacer(PAGE_PADDING); + + // Register ID + new StaticText(form, grid.getLabelSlot(), STR_REG_ID, 0, + COLOR_THEME_PRIMARY1); + auto edit = + new ModelTextEdit(form, grid.getFieldSlot(), g_model.modelRegistrationID, + sizeof(g_model.modelRegistrationID)); + grid.nextLine(); + + // UID + new StaticText(form, grid.getLabelSlot(), "UID", 0, COLOR_THEME_PRIMARY1); + uid = new NumberEdit( + form, grid.getFieldSlot(), 0, 2, + GET_SET_DEFAULT(getPXX2ModuleSetupBuffer().registerLoopIndex)); + grid.nextLine(); + + // RX name + new StaticText(form, grid.getLabelSlot(), STR_RX_NAME, 0, + COLOR_THEME_PRIMARY1); + waiting = new StaticText(form, grid.getFieldSlot(), STR_WAITING, 0, + COLOR_THEME_PRIMARY1); + grid.nextLine(); + grid.spacer(6); + + // Buttons + exitButton = + new TextButton(form, grid.getLabelSlot(), "EXIT", [=]() -> int8_t { + this->deleteLater(); + return 0; + }); + exitButton->setFocus(SET_FOCUS_DEFAULT); + grid.nextLine(); + grid.spacer(PAGE_PADDING); + + FormField::link(exitButton, edit); + form->setHeight(grid.getWindowHeight()); + content->adjustHeight(); + + start(); + + setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); +} + +void RegisterDialog::start() +{ + auto& pxx2Setup = getPXX2ModuleSetupBuffer(); + memclear(&pxx2Setup, sizeof(pxx2Setup)); + moduleState[moduleIdx].mode = MODULE_MODE_REGISTER; +} + +void RegisterDialog::checkEvents() +{ + if (!rxName && reusableBuffer.moduleSetup.pxx2.registerStep >= + REGISTER_RX_NAME_RECEIVED) { + rect_t rect = waiting->getRect(); + waiting->deleteLater(); + + rxName = new ModelTextEdit(&content->form, rect, + reusableBuffer.moduleSetup.pxx2.registerRxName, + PXX2_LEN_RX_NAME); + rect = exitButton->getRect(); + auto okButton = new TextButton(&content->form, rect, "OK", [=]() -> int8_t { + reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; + return 0; + }); + exitButton->setLeft(left() + rect.w + 10); + FormField::link(uid, rxName); + FormField::link(rxName, okButton); + FormField::link(okButton, exitButton); + okButton->setFocus(SET_FOCUS_DEFAULT); + } else if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_OK) { + deleteLater(); + POPUP_INFORMATION(STR_REG_OK); + } + + Dialog::checkEvents(); +} diff --git a/radio/src/gui/colorlcd/access_settings.h b/radio/src/gui/colorlcd/access_settings.h new file mode 100644 index 000000000..2a6422ed3 --- /dev/null +++ b/radio/src/gui/colorlcd/access_settings.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * 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. + */ + +#pragma once + +#include "menu.h" +#include "static.h" +#include "button.h" +#include "dialog.h" +#include "textedit.h" +#include "numberedit.h" + +class BindRxChoiceMenu : public Menu +{ + public: + BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, uint8_t receiverIdx); + + protected: + uint8_t moduleIdx; + uint8_t receiverIdx; +}; + +class BindWaitDialog : public Dialog +{ + public: + BindWaitDialog(Window* parent, uint8_t moduleIdx, uint8_t receiverIdx); + + void checkEvents() override; +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif + + protected: + uint8_t moduleIdx; + uint8_t receiverIdx; +}; + +class ReceiverButton : public TextButton +{ + public: + ReceiverButton(FormGroup* parent, rect_t rect, uint8_t moduleIdx, + uint8_t receiverIdx); + + uint8_t pressBind(); + void startBind(); + void checkEvents() override; + + protected: + uint8_t moduleIdx; + uint8_t receiverIdx; +}; + +class RegisterDialog : public Dialog +{ + public: + RegisterDialog(Window* parent, uint8_t moduleIdx); + + void start(); + void checkEvents() override; + + protected: + uint8_t moduleIdx; + NumberEdit* uid; + StaticText* waiting; + TextEdit* rxName = nullptr; + TextButton* exitButton; +}; diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index a4d7605a8..e227f416f 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -29,6 +29,8 @@ #include "storage/modelslist.h" #include "algorithm" +#include "access_settings.h" + #define SET_DIRTY() storageDirty(EE_MODEL) std::string switchWarninglabel(swsrc_t index) @@ -162,172 +164,6 @@ class FailSafePage : public Page { uint8_t moduleIdx; }; -class RegisterDialog: public Dialog { - public: - RegisterDialog(Window * parent, uint8_t moduleIdx): - Dialog(parent, STR_REGISTER, {50, 73, LCD_W - 100, 0}), - moduleIdx(moduleIdx) - { - FormGroup * form = &content->form; - FormGridLayout grid(content->form.width()); - grid.setLabelWidth(150); - grid.spacer(PAGE_PADDING); - - // Register ID - new StaticText(form, grid.getLabelSlot(), STR_REG_ID, 0, COLOR_THEME_PRIMARY1); - auto edit = new ModelTextEdit(form, grid.getFieldSlot(), g_model.modelRegistrationID, sizeof(g_model.modelRegistrationID)); - grid.nextLine(); - - // UID - new StaticText(form, grid.getLabelSlot(), "UID", 0, COLOR_THEME_PRIMARY1); - uid = new NumberEdit(form, grid.getFieldSlot(), 0, 2, GET_SET_DEFAULT(reusableBuffer.moduleSetup.pxx2.registerLoopIndex)); - grid.nextLine(); - - // RX name - new StaticText(form, grid.getLabelSlot(), STR_RX_NAME, 0, COLOR_THEME_PRIMARY1); - waiting = new StaticText(form, grid.getFieldSlot(), STR_WAITING, 0, COLOR_THEME_PRIMARY1); - grid.nextLine(); - grid.spacer(6); - - // Buttons - exitButton = new TextButton(form, grid.getLabelSlot(), "EXIT", - [=]() -> int8_t { - this->deleteLater(); - return 0; - }); - exitButton->setFocus(SET_FOCUS_DEFAULT); - grid.nextLine(); - grid.spacer(PAGE_PADDING); - - FormField::link(exitButton, edit); - form->setHeight(grid.getWindowHeight()); - content->adjustHeight(); - - start(); - - setCloseHandler([=]() { - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - }); - } - - void start() - { - memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); - moduleState[moduleIdx].mode = MODULE_MODE_REGISTER; - } - - void checkEvents() override - { - if (!rxName && reusableBuffer.moduleSetup.pxx2.registerStep >= REGISTER_RX_NAME_RECEIVED) { - rect_t rect = waiting->getRect(); - waiting->deleteLater(); - - rxName = new ModelTextEdit(&content->form, rect, reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME); - rect = exitButton->getRect(); - auto okButton = new TextButton(&content->form, rect, "OK", - [=]() -> int8_t { - reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; - return 0; - }); - exitButton->setLeft(left() + rect.w + 10); - FormField::link(uid, rxName); - FormField::link(rxName, okButton); - FormField::link(okButton, exitButton); - okButton->setFocus(SET_FOCUS_DEFAULT); - } - else if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_OK) { - deleteLater(); - POPUP_INFORMATION(STR_REG_OK); - } - - Dialog::checkEvents(); - } - - protected: - uint8_t moduleIdx; - NumberEdit * uid; - StaticText * waiting; - TextEdit * rxName = nullptr; - TextButton * exitButton; -}; - -class BindWaitDialog: public Dialog { - public: - BindWaitDialog(Window * parent, uint8_t moduleIdx, uint8_t receiverIdx): - Dialog(parent, STR_BIND, {50, 73, LCD_W - 100, LCD_H - 146}), - moduleIdx(moduleIdx), - receiverIdx(receiverIdx) - { - new StaticText(&content->form, {0, height() / 2, width(), PAGE_LINE_HEIGHT}, STR_WAITING_FOR_RX, 0, CENTERED | COLOR_THEME_PRIMARY1); - } - - void checkEvents() override; - -#if defined(HARDWARE_KEYS) - void onEvent(event_t event) override - { - TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event); - - if (event == EVT_KEY_BREAK(KEY_EXIT)) { - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - deleteLater(); - } - } -#endif - - protected: - uint8_t moduleIdx; - uint8_t receiverIdx; -}; - -class BindRxChoiceMenu: public Menu { - public: - BindRxChoiceMenu(Window * parent, uint8_t moduleIdx, uint8_t receiverIdx): - Menu(parent), - moduleIdx(moduleIdx), - receiverIdx(receiverIdx) - { - auto receiversCount = min(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); - for (uint8_t i = 0; i < receiversCount; i++) { - const char * receiverName = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[i]; - addLine(receiverName, [=]() { - reusableBuffer.moduleSetup.bindInformation.selectedReceiverIndex = i; - if (isModuleR9MAccess(moduleIdx) && reusableBuffer.moduleSetup.pxx2.moduleInformation.information.variant == PXX2_VARIANT_EU) { - reusableBuffer.moduleSetup.bindInformation.step = BIND_RX_NAME_SELECTED; -// POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); -// POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); -// POPUP_MENU_START(onPXX2R9MBindModeMenu); - } - else if (isModuleR9MAccess(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) - memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], receiverName, PXX2_LEN_RX_NAME); - storageDirty(EE_MODEL); - reusableBuffer.moduleSetup.bindInformation.step = BIND_OK; - new MessageDialog(parent, STR_BIND, STR_BIND_OK); -#else - reusableBuffer.moduleSetup.bindInformation.step = BIND_START; - new BindWaitDialog(parent, moduleIdx, receiverIdx); -#endif - } - }); - } - - setCancelHandler([=]() { - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - }); - } - - protected: - uint8_t moduleIdx; - uint8_t receiverIdx; -}; - class BindChoiceMenu : public Menu { protected: @@ -400,122 +236,6 @@ class BindChoiceMenu : public Menu } }; -void BindWaitDialog::checkEvents() -{ - if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - deleteLater(); - if (reusableBuffer.moduleSetup.bindInformation.step == BIND_OK) - POPUP_INFORMATION(STR_BIND_OK); - return; - } - - if (reusableBuffer.moduleSetup.bindInformation.step == BIND_INIT && reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount > 0) { - deleteLater(); - new BindRxChoiceMenu(this, moduleIdx, receiverIdx); - return; - } - - Dialog::checkEvents(); -} - -class ReceiverButton: public TextButton -{ - public: - ReceiverButton(FormGroup * parent, rect_t rect, uint8_t moduleIdx, uint8_t receiverIdx): - TextButton(parent, rect, STR_BIND, [=]() { - if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] == '\0') { - startBind(); - } - else { - auto menu = new Menu(parent); - menu->addLine(STR_BIND, [=]() { - startBind(); - return 0; - }); - menu->addLine(STR_OPTIONS, [=]() { - memclear(&reusableBuffer.hardwareAndSettings, sizeof(reusableBuffer.hardwareAndSettings)); - reusableBuffer.hardwareAndSettings.receiverSettings.receiverId = receiverIdx; - // pushMenu(menuModelReceiverOptions); - return 0; - }); - menu->addLine(STR_SHARE, [=]() { - reusableBuffer.moduleSetup.pxx2.shareReceiverIndex = receiverIdx; - moduleState[moduleIdx].mode = MODULE_MODE_SHARE; - return 0; - }); - menu->addLine(STR_DELETE, [=]() { - memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); - reusableBuffer.moduleSetup.pxx2.resetReceiverIndex = receiverIdx; - reusableBuffer.moduleSetup.pxx2.resetReceiverFlags = 0x01; - new ConfirmDialog(parent, STR_RECEIVER, STR_RECEIVER_DELETE, [=]() { - moduleState[moduleIdx].mode = MODULE_MODE_RESET; - removePXX2Receiver(moduleIdx, receiverIdx); - }); - return 0; - }); - menu->addLine(STR_RESET, [=]() { - memclear(&reusableBuffer.moduleSetup.pxx2, sizeof(reusableBuffer.moduleSetup.pxx2)); - reusableBuffer.moduleSetup.pxx2.resetReceiverIndex = receiverIdx; - reusableBuffer.moduleSetup.pxx2.resetReceiverFlags = 0xFF; - new ConfirmDialog(parent, STR_RECEIVER, STR_RECEIVER_DELETE, [=]() { - moduleState[moduleIdx].mode = MODULE_MODE_RESET; - removePXX2Receiver(moduleIdx, receiverIdx); - }); - return 0; - }); - menu->setCloseHandler([=]() { - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - }); - } - return 0; - }), - moduleIdx(moduleIdx), - receiverIdx(receiverIdx) - { - } - - void startBind() - { - memclear(&reusableBuffer.moduleSetup.bindInformation, sizeof(BindInformation)); - reusableBuffer.moduleSetup.bindInformation.rxUid = receiverIdx; - if (isModuleR9MAccess(moduleIdx)) { - reusableBuffer.moduleSetup.bindInformation.step = BIND_MODULE_TX_INFORMATION_REQUEST; -#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); - } - - new BindWaitDialog(parent, moduleIdx, receiverIdx); - } - - void checkEvents() override - { - if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') { - char receiverName[PXX2_LEN_RX_NAME + 1]; - memset(receiverName, 0, sizeof(receiverName)); - strncpy(receiverName, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], - effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME)); - setText(receiverName); - } - else { - setText(STR_BIND); - } - - TextButton::checkEvents(); - } - - protected: - uint8_t moduleIdx; - uint8_t receiverIdx; -}; - class TrChoice : public Choice { public: diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 58d8219a6..5edf7714e 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1036,24 +1036,7 @@ union ReusableBuffer uint8_t previousType; uint8_t newType; BindInformation bindInformation; - struct { - union { - uint8_t registerStep; - uint8_t resetStep; - }; - uint8_t registerPopupVerticalPosition; - uint8_t registerPopupHorizontalPosition; - int8_t registerPopupEditMode; - char registerRxName[PXX2_LEN_RX_NAME]; - uint8_t registerLoopIndex; // will be removed later - union { - uint8_t shareReceiverIndex; - uint8_t resetReceiverIndex; - }; - uint8_t resetReceiverFlags; - ModuleInformation moduleInformation; - ModuleSettings moduleSettings; - } pxx2; + PXX2ModuleSetup pxx2; #if defined(BLUETOOTH) struct { char devices[MAX_BLUETOOTH_DISTANT_ADDR][LEN_BLUETOOTH_ADDR+1]; @@ -1096,13 +1079,8 @@ union ReusableBuffer } version; #endif - struct { - ModuleInformation modules[NUM_MODULES]; - uint32_t updateTime; - ModuleSettings moduleSettings; - ReceiverSettings receiverSettings; // when dealing with receiver settings, we also need module settings - char msg[64]; - } hardwareAndSettings; // moduleOptions, receiverOptions, radioVersion + // moduleOptions, receiverOptions, radioVersion + PXX2HardwareAndSettings hardwareAndSettings; struct { ModuleInformation modules[NUM_MODULES]; diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index f8a6124b0..83bea0623 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -33,8 +33,9 @@ InternalModulePulsesData intmodulePulsesData __DMA; ExternalModulePulsesData extmodulePulsesData __DMA; TrainerPulsesData trainerPulsesData __DMA; -//use only for PXX -void ModuleState::startBind(BindInformation * destination, ModuleCallback bindCallback) +// use only for PXX +void ModuleState::startBind(BindInformation* destination, + ModuleCallback bindCallback) { bindInformation = destination; callback = bindCallback; @@ -46,6 +47,45 @@ void ModuleState::startBind(BindInformation * destination, ModuleCallback bindCa #endif } +void ModuleState::readModuleInformation(ModuleInformation* destination, + int8_t first, int8_t last) +{ + moduleInformation = destination; + moduleInformation->current = first; + moduleInformation->maximum = last; + mode = MODULE_MODE_GET_HARDWARE_INFO; +} + +void ModuleState::readModuleSettings(ModuleSettings* destination) +{ + moduleSettings = destination; + moduleSettings->state = PXX2_SETTINGS_READ; + mode = MODULE_MODE_MODULE_SETTINGS; +} + +void ModuleState::writeModuleSettings(ModuleSettings* source) +{ + moduleSettings = source; + moduleSettings->state = PXX2_SETTINGS_WRITE; + moduleSettings->timeout = 0; + mode = MODULE_MODE_MODULE_SETTINGS; +} + +void ModuleState::readReceiverSettings(ReceiverSettings* destination) +{ + receiverSettings = destination; + receiverSettings->state = PXX2_SETTINGS_READ; + mode = MODULE_MODE_RECEIVER_SETTINGS; +} + +void ModuleState::writeReceiverSettings(ReceiverSettings* source) +{ + receiverSettings = source; + receiverSettings->state = PXX2_SETTINGS_WRITE; + receiverSettings->timeout = 0; + mode = MODULE_MODE_RECEIVER_SETTINGS; +} + void getModuleStatusString(uint8_t moduleIdx, char * statusText) { *statusText = 0; diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 7b46b946d..e23a41c87 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -67,77 +67,6 @@ extern uint8_t s_pulses_paused; -PACK(struct PXX2Version { - uint8_t major; - uint8_t revision:4; - uint8_t minor:4; -}); - -PACK(struct PXX2HardwareInformation { - uint8_t modelID; - PXX2Version hwVersion; - PXX2Version swVersion; - uint8_t variant; - uint32_t capabilities; // variable length - uint8_t capabilityNotSupported; -}); - -PACK(struct ModuleInformation { - int8_t current; - int8_t maximum; - uint8_t timeout; - PXX2HardwareInformation information; - struct { - PXX2HardwareInformation information; - tmr10ms_t timestamp; - } receivers[PXX2_MAX_RECEIVERS_PER_MODULE]; -}); - -class ModuleSettings { - public: - uint8_t state; // 0x00 = READ 0x40 = WRITE - tmr10ms_t timeout; - uint8_t externalAntenna; - int8_t txPower; - uint8_t dirty; -}; - -class ReceiverSettings { - public: - uint8_t state; // 0x00 = READ 0x40 = WRITE - tmr10ms_t timeout; - uint8_t receiverId; - uint8_t dirty; - uint8_t telemetryDisabled; - uint8_t telemetry25mw; - uint8_t pwmRate; - uint8_t fport; - uint8_t enablePwmCh5Ch6; - uint8_t fport2; - uint8_t outputsCount; - uint8_t outputsMapping[24]; -}; - -class BindInformation { - public: - int8_t step; - uint32_t timeout; - char candidateReceiversNames[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME + 1]; - uint8_t candidateReceiversCount; - uint8_t selectedReceiverIndex; - uint8_t rxUid; - uint8_t lbtMode; - uint8_t flexMode; - PXX2HardwareInformation receiverInformation; -}; - -class OtaUpdateInformation: public BindInformation { - public: - char filename[FF_MAX_LFN + 1]; - uint32_t address; - uint32_t module; -}; - typedef void (* ModuleCallback)(); PACK(struct ModuleState { @@ -146,6 +75,8 @@ PACK(struct ModuleState { uint8_t paused:1; uint8_t spare:7; uint16_t counter; + + // PXX specific items union { ModuleInformation * moduleInformation; @@ -157,44 +88,11 @@ PACK(struct ModuleState { ModuleCallback callback; void startBind(BindInformation * destination, ModuleCallback bindCallback = nullptr); - - void readModuleInformation(ModuleInformation * destination, int8_t first, int8_t last) - { - moduleInformation = destination; - moduleInformation->current = first; - moduleInformation->maximum = last; - mode = MODULE_MODE_GET_HARDWARE_INFO; - } - - void readModuleSettings(ModuleSettings * destination) - { - moduleSettings = destination; - moduleSettings->state = PXX2_SETTINGS_READ; - mode = MODULE_MODE_MODULE_SETTINGS; - } - - void writeModuleSettings(ModuleSettings * source) - { - moduleSettings = source; - moduleSettings->state = PXX2_SETTINGS_WRITE; - moduleSettings->timeout = 0; - mode = MODULE_MODE_MODULE_SETTINGS; - } - - void readReceiverSettings(ReceiverSettings * destination) - { - receiverSettings = destination; - receiverSettings->state = PXX2_SETTINGS_READ; - mode = MODULE_MODE_RECEIVER_SETTINGS; - } - - void writeReceiverSettings(ReceiverSettings * source) - { - receiverSettings = source; - receiverSettings->state = PXX2_SETTINGS_WRITE; - receiverSettings->timeout = 0; - mode = MODULE_MODE_RECEIVER_SETTINGS; - } + void readModuleInformation(ModuleInformation * destination, int8_t first, int8_t last); + void readModuleSettings(ModuleSettings * destination); + void writeModuleSettings(ModuleSettings * source); + void readReceiverSettings(ReceiverSettings * destination); + void writeReceiverSettings(ReceiverSettings * source); }); extern ModuleState moduleState[NUM_MODULES]; diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 926e36ab6..ffdfade86 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -25,6 +25,21 @@ #include "io/frsky_firmware_update.h" #include "libopenui/src/libopenui_file.h" +PXX2ModuleSetup& getPXX2ModuleSetupBuffer() +{ + return reusableBuffer.moduleSetup.pxx2; +} + +BindInformation& getPXX2BindInformationBuffer() +{ + return reusableBuffer.moduleSetup.bindInformation; +} + +PXX2HardwareAndSettings& getPXX2HardwareAndSettingsBuffer() +{ + return reusableBuffer.hardwareAndSettings; +} + uint8_t Pxx2Pulses::addFlag0(uint8_t module) { uint8_t flag0 = g_model.header.modelId[module] & 0x3F; diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 8b91b27c5..5c1305631 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -316,6 +316,109 @@ enum PXX2ReceiverStatus { PXX2_SETTINGS_OK }; +PACK(struct PXX2Version { + uint8_t major; + uint8_t revision:4; + uint8_t minor:4; +}); + +PACK(struct PXX2HardwareInformation { + uint8_t modelID; + PXX2Version hwVersion; + PXX2Version swVersion; + uint8_t variant; + uint32_t capabilities; // variable length + uint8_t capabilityNotSupported; +}); + +PACK(struct ModuleInformation { + int8_t current; + int8_t maximum; + uint8_t timeout; + PXX2HardwareInformation information; + struct { + PXX2HardwareInformation information; + tmr10ms_t timestamp; + } receivers[PXX2_MAX_RECEIVERS_PER_MODULE]; +}); + +class ModuleSettings { + public: + uint8_t state; // 0x00 = READ 0x40 = WRITE + tmr10ms_t timeout; + uint8_t externalAntenna; + int8_t txPower; + uint8_t dirty; +}; + +struct PXX2ModuleSetup { + union { + uint8_t registerStep; + uint8_t resetStep; + }; + uint8_t registerPopupVerticalPosition; + uint8_t registerPopupHorizontalPosition; + int8_t registerPopupEditMode; + char registerRxName[PXX2_LEN_RX_NAME]; + uint8_t registerLoopIndex; // will be removed later + union { + uint8_t shareReceiverIndex; + uint8_t resetReceiverIndex; + }; + uint8_t resetReceiverFlags; + ModuleInformation moduleInformation; + ModuleSettings moduleSettings; +}; + +class ReceiverSettings { + public: + uint8_t state; // 0x00 = READ 0x40 = WRITE + tmr10ms_t timeout; + uint8_t receiverId; + uint8_t dirty; + uint8_t telemetryDisabled; + uint8_t telemetry25mw; + uint8_t pwmRate; + uint8_t fport; + uint8_t enablePwmCh5Ch6; + uint8_t fport2; + uint8_t outputsCount; + uint8_t outputsMapping[24]; +}; + +class BindInformation { + public: + int8_t step; + uint32_t timeout; + char candidateReceiversNames[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME + 1]; + uint8_t candidateReceiversCount; + uint8_t selectedReceiverIndex; + uint8_t rxUid; + uint8_t lbtMode; + uint8_t flexMode; + PXX2HardwareInformation receiverInformation; +}; + +class OtaUpdateInformation: public BindInformation { + public: + char filename[FF_MAX_LFN + 1]; + uint32_t address; + uint32_t module; +}; + +struct PXX2HardwareAndSettings { + ModuleInformation modules[NUM_MODULES]; + uint32_t updateTime; + ModuleSettings moduleSettings; + ReceiverSettings receiverSettings; // when dealing with receiver settings, we + // also need module settings + char msg[64]; +}; + +PXX2ModuleSetup& getPXX2ModuleSetupBuffer(); +BindInformation& getPXX2BindInformationBuffer(); +PXX2HardwareAndSettings& getPXX2HardwareAndSettingsBuffer(); + extern ModuleFifo intmoduleFifo; extern ModuleFifo extmoduleFifo; diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index db071a4c7..e9338302e 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -117,13 +117,14 @@ void processRegisterFrame(uint8_t module, const uint8_t * frame) return; } + PXX2ModuleSetup& mod = reusableBuffer.moduleSetup.pxx2; switch(frame[3]) { case 0x00: - if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_INIT) { + if (mod.registerStep == REGISTER_INIT) { // RX_NAME follows, we store it for the next step - str2zchar(reusableBuffer.moduleSetup.pxx2.registerRxName, (const char *)&frame[4], PXX2_LEN_RX_NAME); - reusableBuffer.moduleSetup.pxx2.registerLoopIndex = frame[12]; - reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_RECEIVED; + str2zchar(mod.registerRxName, (const char *)&frame[4], PXX2_LEN_RX_NAME); + mod.registerLoopIndex = frame[12]; + mod.registerStep = REGISTER_RX_NAME_RECEIVED; #if defined(COLORLCD) pushEvent(EVT_REFRESH); #endif @@ -131,11 +132,11 @@ void processRegisterFrame(uint8_t module, const uint8_t * frame) break; case 0x01: - if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_RX_NAME_SELECTED) { + if (mod.registerStep == REGISTER_RX_NAME_SELECTED) { // RX_NAME + PASSWORD follow, we check they are good - if (memcmp(&frame[4], reusableBuffer.moduleSetup.pxx2.registerRxName, PXX2_LEN_RX_NAME) == 0 && + if (memcmp(&frame[4], mod.registerRxName, PXX2_LEN_RX_NAME) == 0 && memcmp(&frame[12], g_model.modelRegistrationID, PXX2_LEN_REGISTRATION_ID) == 0) { - reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_OK; + mod.registerStep = REGISTER_OK; moduleState[module].mode = MODULE_MODE_NORMAL; #if !defined(COLORLCD) POPUP_INFORMATION(STR_REG_OK); From eb9425678ff99d8a5e1a2b2705094544a15efd87 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 6 Nov 2021 15:57:21 +0100 Subject: [PATCH 02/12] Fixed registering/binding --- radio/src/gui/colorlcd/access_settings.cpp | 26 ++++++++++++++++------ radio/src/gui/colorlcd/access_settings.h | 3 +++ radio/src/opentx.h | 1 - radio/src/strhelpers.h | 1 + radio/src/telemetry/frsky_pxx2.cpp | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index 9dddab5c2..aa544ec46 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -88,7 +88,7 @@ void BindWaitDialog::checkEvents() removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); deleteLater(); if (bindInfo.step == BIND_OK) { - new MessageDialog(parent, STR_BIND, STR_BIND_OK); + POPUP_INFORMATION(STR_REG_OK); } else { // TODO: display error??? } @@ -278,17 +278,17 @@ void RegisterDialog::start() void RegisterDialog::checkEvents() { - if (!rxName && reusableBuffer.moduleSetup.pxx2.registerStep >= - REGISTER_RX_NAME_RECEIVED) { + auto& modSetup = getPXX2ModuleSetupBuffer(); + if (!rxName && modSetup.registerStep >= REGISTER_RX_NAME_RECEIVED) { rect_t rect = waiting->getRect(); waiting->deleteLater(); - rxName = new ModelTextEdit(&content->form, rect, - reusableBuffer.moduleSetup.pxx2.registerRxName, + rxName = new ModelTextEdit(&content->form, rect, modSetup.registerRxName, PXX2_LEN_RX_NAME); rect = exitButton->getRect(); auto okButton = new TextButton(&content->form, rect, "OK", [=]() -> int8_t { - reusableBuffer.moduleSetup.pxx2.registerStep = REGISTER_RX_NAME_SELECTED; + auto& modSetup = getPXX2ModuleSetupBuffer(); + modSetup.registerStep = REGISTER_RX_NAME_SELECTED; return 0; }); exitButton->setLeft(left() + rect.w + 10); @@ -296,10 +296,22 @@ void RegisterDialog::checkEvents() FormField::link(rxName, okButton); FormField::link(okButton, exitButton); okButton->setFocus(SET_FOCUS_DEFAULT); - } else if (reusableBuffer.moduleSetup.pxx2.registerStep == REGISTER_OK) { + } else if (modSetup.registerStep == REGISTER_OK) { deleteLater(); POPUP_INFORMATION(STR_REG_OK); } Dialog::checkEvents(); } + +#if defined(HARDWARE_KEYS) +void RegisterDialog::onEvent(event_t event) +{ + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), + event); + + if (event == EVT_KEY_BREAK(KEY_EXIT)) { + deleteLater(); + } +} +#endif diff --git a/radio/src/gui/colorlcd/access_settings.h b/radio/src/gui/colorlcd/access_settings.h index 2a6422ed3..a685a31fb 100644 --- a/radio/src/gui/colorlcd/access_settings.h +++ b/radio/src/gui/colorlcd/access_settings.h @@ -75,6 +75,9 @@ class RegisterDialog : public Dialog void start(); void checkEvents() override; +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif protected: uint8_t moduleIdx; diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 5edf7714e..a428da306 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1163,7 +1163,6 @@ extern ReusableBuffer reusableBuffer; uint8_t zlen(const char *str, uint8_t size); bool zexist(const char *str, uint8_t size); -unsigned int effectiveLen(const char * str, unsigned int size); char * strcat_zchar(char *dest, const char *name, uint8_t size, const char spaceSym = 0, const char *defaultName=nullptr, uint8_t defaultNameSize=0, uint8_t defaultIdx=0); #define strcatFlightmodeName(dest, idx) strcat_zchar(dest, g_model.flightModeData[idx].name, LEN_FLIGHT_MODE_NAME, 0, STR_FM, PSIZE(TR_FM), idx+1) #if defined(EEPROM) diff --git a/radio/src/strhelpers.h b/radio/src/strhelpers.h index ede5a31ee..f8d863fc9 100644 --- a/radio/src/strhelpers.h +++ b/radio/src/strhelpers.h @@ -51,6 +51,7 @@ int8_t char2zchar(char c); void str2zchar(char *dest, const char *src, int size); int zchar2str(char *dest, const char *src, int size); int strnlen(const char *src, int max_size); +unsigned int effectiveLen(const char * str, unsigned int size); char *strAppend(char *dest, const char *source, int len = 0); char *strAppendUnsigned(char *dest, uint32_t value, uint8_t digits = 0, diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index e9338302e..53e00fabb 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -122,7 +122,7 @@ void processRegisterFrame(uint8_t module, const uint8_t * frame) case 0x00: if (mod.registerStep == REGISTER_INIT) { // RX_NAME follows, we store it for the next step - str2zchar(mod.registerRxName, (const char *)&frame[4], PXX2_LEN_RX_NAME); + memcpy(mod.registerRxName, (const char *)&frame[4], PXX2_LEN_RX_NAME); mod.registerLoopIndex = frame[12]; mod.registerStep = REGISTER_RX_NAME_RECEIVED; #if defined(COLORLCD) From 5fbd4d3b1fbb39687a7a82b4c784e25d8b605392 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 6 Nov 2021 17:52:09 +0100 Subject: [PATCH 03/12] Fixed targets without PXX2 support --- radio/src/gui/colorlcd/model_setup.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index e227f416f..477cefe6d 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -29,7 +29,9 @@ #include "storage/modelslist.h" #include "algorithm" +#if defined(PXX2) #include "access_settings.h" +#endif #define SET_DIRTY() storageDirty(EE_MODEL) @@ -1181,6 +1183,7 @@ class ModuleWindow : public FormGroup { grid.nextLine(); } +#if defined(PXX2) // Register and Range buttons if (isModuleRFAccess(moduleIdx)) { new StaticText(this, grid.getLabelSlot(true), STR_MODULE, 0, COLOR_THEME_PRIMARY1); @@ -1204,6 +1207,7 @@ class ModuleWindow : public FormGroup { grid.nextLine(); } +#endif // R9M Power if (isModuleR9M_FCC(moduleIdx)) { @@ -1218,7 +1222,7 @@ class ModuleWindow : public FormGroup { GET_DEFAULT(min(g_model.moduleData[moduleIdx].pxx.power, R9M_LBT_POWER_MAX)), SET_DEFAULT(g_model.moduleData[moduleIdx].pxx.power)); } - +#if defined(PXX2) // Receivers if (isModuleRFAccess(moduleIdx)) { for (uint8_t receiverIdx = 0; receiverIdx < PXX2_MAX_RECEIVERS_PER_MODULE; receiverIdx++) { @@ -1229,7 +1233,7 @@ class ModuleWindow : public FormGroup { grid.nextLine(); } } - +#endif // SBUS refresh rate if (isModuleSBUS(moduleIdx)) { new StaticText(this, grid.getLabelSlot(true), STR_REFRESHRATE, 0, COLOR_THEME_PRIMARY1); From 33e5aac846be55685c7b83aabe86881a0ba0807d Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 7 Nov 2021 11:28:45 +0100 Subject: [PATCH 04/12] Module and receiver options --- radio/src/gui/colorlcd/access_settings.cpp | 546 +++++++++++++++++- radio/src/gui/colorlcd/access_settings.h | 66 +++ radio/src/gui/colorlcd/channel_bar.h | 35 +- radio/src/gui/colorlcd/model_setup.cpp | 14 +- .../common/stdlcd/model_module_options.cpp | 25 +- radio/src/pulses/pxx2.cpp | 29 + radio/src/pulses/pxx2.h | 2 + 7 files changed, 679 insertions(+), 38 deletions(-) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index aa544ec46..d6c87acc1 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -21,6 +21,7 @@ #include "opentx.h" #include "access_settings.h" +#include "channel_bar.h" #include @@ -43,12 +44,14 @@ BindRxChoiceMenu::BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, if (isModuleR9MAccess(moduleIdx) && modInfo.information.variant == PXX2_VARIANT_EU) { bindInfo.step = BIND_RX_NAME_SELECTED; + // TODO: // POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); // POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); // POPUP_MENU_START(onPXX2R9MBindModeMenu); } else if (isModuleR9MAccess(moduleIdx) && modInfo.information.variant == PXX2_VARIANT_FLEX) { bindInfo.step = BIND_RX_NAME_SELECTED; + // TODO: // POPUP_MENU_ADD_ITEM(STR_FLEX_868); // POPUP_MENU_ADD_ITEM(STR_FLEX_915); // POPUP_MENU_START(onPXX2R9MBindModeMenu); @@ -137,10 +140,8 @@ uint8_t ReceiverButton::pressBind() return 0; }); menu->addLine(STR_OPTIONS, [=]() { - auto hwSettings = getPXX2HardwareAndSettingsBuffer(); - memclear(&hwSettings, sizeof(hwSettings)); - hwSettings.receiverSettings.receiverId = receiverIdx; // pushMenu(menuModelReceiverOptions); + new RxOptions(this, moduleIdx, receiverIdx); return 0; }); menu->addLine(STR_SHARE, [=]() { @@ -245,7 +246,7 @@ RegisterDialog::RegisterDialog(Window* parent, uint8_t moduleIdx) : // RX name new StaticText(form, grid.getLabelSlot(), STR_RX_NAME, 0, COLOR_THEME_PRIMARY1); - waiting = new StaticText(form, grid.getFieldSlot(), STR_WAITING, 0, + waiting = new StaticText(form, grid.getFieldSlot(), STR_WAITING_FOR_RX, 0, COLOR_THEME_PRIMARY1); grid.nextLine(); grid.spacer(6); @@ -315,3 +316,540 @@ void RegisterDialog::onEvent(event_t event) } } #endif + +ModuleOptions::ModuleOptions(Window* parent, uint8_t moduleIdx): + Dialog(parent, STR_MODULE_OPTIONS, {50, 73, LCD_W - 100, LCD_H - 146}), + moduleIdx(moduleIdx) +{ + setCloseWhenClickOutside(true); + auto form = &content->form; + new StaticText(form, {0, height() / 2, width(), PAGE_LINE_HEIGHT}, + STR_WAITING_FOR_MODULE, CENTERED | VCENTERED | COLOR_THEME_PRIMARY1); + +#if defined(SIMU) + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + memclear(&hwSettings, sizeof(hwSettings)); + hwSettings.moduleSettings.state = PXX2_SETTINGS_OK; + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + state = MO_ReadModuleSettings; +#endif + setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); + setFocus(); +} + +void ModuleOptions::checkEvents() +{ + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + switch (state) { + case MO_Init: + // kickstart fetching HW settings + memclear(&hwSettings, sizeof(hwSettings)); + moduleState[moduleIdx].readModuleInformation( + &hwSettings.modules[moduleIdx], PXX2_HW_INFO_TX_ID, + PXX2_HW_INFO_TX_ID); + state = MO_ReadModuleInfo; + break; + case MO_ReadModuleInfo: + // times out after a while (see pxx2.cpp) + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { + moduleState[moduleIdx].readModuleSettings(&hwSettings.moduleSettings); + state = MO_ReadModuleSettings; + } + break; + case MO_ReadModuleSettings: + // this one does NOT timeout (see pxx2.cpp) + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && + hwSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + state = MO_DisplaySettings; + update(); + } + break; + case MO_WriteSettings: + // TODO: ask for confirmation ??? + moduleState[moduleIdx].writeModuleSettings(&hwSettings.moduleSettings); + state = MO_WritingSettings; + break; + + case MO_WritingSettings: +#if defined(SIMU) + statusText.clear(); + deleteLater(); +#else + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && + hwSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + statusText.clear(); + deleteLater(); + } +#endif + break; + + default: // MO_DisplaySettings + break; + } + + Dialog::checkEvents(); +} + +#if defined(HARDWARE_KEYS) +void ModuleOptions::onEvent(event_t event) +{ + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), + event); + + if (event == EVT_KEY_BREAK(KEY_EXIT)) { + deleteLater(); + } +} +#endif + +uint8_t ModuleOptions::getModuleSettingsState() +{ + const auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.moduleSettings.state; +} + +void ModuleOptions::update() +{ + auto form = &content->form; + form->clear(); + + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + uint8_t modelId = hwSettings.modules[moduleIdx].information.modelID; + +#if defined(SIMU) + if (modelId == 0) { + modelId = PXX2_MODULE_R9M_LITE_PRO; + hwSettings.modules[moduleIdx].information.modelID = modelId; + hwSettings.modules[moduleIdx].information.variant = PXX2_VARIANT_FCC; + } +#endif + + uint8_t optionsAvailable = + getPXX2ModuleOptions(modelId) & + ((1 << MODULE_OPTION_EXTERNAL_ANTENNA) | (1 << MODULE_OPTION_POWER)); + + FormGridLayout grid(content->form.width(), 10); + grid.setLabelWidth(width() / 3); + + new StaticText(form, grid.getLabelSlot(), STR_MODULE); + new StaticText(form, grid.getFieldSlot(), getPXX2ModuleName(modelId)); + grid.nextLine(); + + if (!optionsAvailable) { + // no options available + new StaticText(form, grid.getCenteredSlot(), STR_NO_TX_OPTIONS, 0, CENTERED); + } else { + // some options available + if (optionsAvailable & (1 << MODULE_OPTION_EXTERNAL_ANTENNA)) { + new StaticText(form, grid.getLabelSlot(), STR_EXT_ANTENNA, 0, + COLOR_THEME_PRIMARY1); + new CheckBox(form, grid.getFieldSlot(), + []() { + const auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.moduleSettings.externalAntenna; + }, + [&](uint8_t val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.moduleSettings.externalAntenna = val; + }); + grid.nextLine(); + } + + if (optionsAvailable & (1 << MODULE_OPTION_POWER)) { + + // TODO: use isTelemetryAvailable() to check if rebind is necessary + new StaticText(form, grid.getLabelSlot(), STR_POWER, 0, + COLOR_THEME_PRIMARY1); + auto txPower = new Choice( + form, grid.getFieldSlot(), 0, 30, + []() { + const auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.moduleSettings.txPower; + }, + [&](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.moduleSettings.txPower = val; + //state = MO_WriteSettings; + }); + + txPower->setTextHandler([](int val) { + switch (val) { + case 10: + return std::string("10 mW"); + case 14: + return std::string("25 mW"); + case 20: + return std::string("100 mW"); + case 23: + return std::string("200 mW"); + case 27: + return std::string("500 mW"); + case 30: + return std::string("1000 mW"); + default: + return std::string("---"); + } + }); + + txPower->setAvailableHandler([=](int val) { + const auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return isPXX2PowerAvailable(hwSettings.modules[moduleIdx].information, val); + }); + grid.nextLine(); + } + } + + new DynamicText(form, grid.getFieldSlot(), [=]() { return statusText; }); + grid.setLabelWidth(15); + grid.setMarginRight(15); + grid.nextLine(); + + auto exitButton = + new TextButton(form, grid.getFieldSlot(2, 0), STR_EXIT, [=]() -> int8_t { + this->deleteLater(); + return 0; + }); + + new TextButton(form, grid.getFieldSlot(2, 1), STR_OK, [=]() -> int8_t { + this->writeSettings(); + return 0; + }); + + exitButton->setFocus(SET_FOCUS_DEFAULT); + grid.nextLine(); + grid.spacer(PAGE_PADDING); + + form->setInnerHeight(grid.getWindowHeight()); + form->setHeight(form->getInnerHeight()); + + content->adjustHeight(); + content->setWindowCentered(); +} + +void ModuleOptions::writeSettings() +{ + if (state == MO_DisplaySettings) { + statusText = STR_WRITING; + state = MO_WriteSettings; + } +} + +RxOptions::RxOptions(Window* parent, uint8_t moduleIdx, uint8_t rxIdx): + Dialog(parent, STR_RECEIVER_OPTIONS, {50, 73, LCD_W - 100, LCD_H - 146}), + moduleIdx(moduleIdx), + receiverIdx(rxIdx) +{ + setCloseWhenClickOutside(true); + auto form = &content->form; + new StaticText( + form, + {0, static_cast(form->height() / 2 - PAGE_LINE_HEIGHT), + form->width(), PAGE_LINE_HEIGHT}, + STR_WAITING_FOR_RX, 0, CENTERED | VCENTERED | COLOR_THEME_PRIMARY1); + +#if defined(SIMU) + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + memclear(&hwSettings, sizeof(hwSettings)); + hwSettings.moduleSettings.state = PXX2_SETTINGS_OK; + hwSettings.receiverSettings.state = PXX2_SETTINGS_OK; + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + state = RO_ReadReceiverSettings; + auto& rxInfo = hwSettings.modules[moduleIdx].receivers[receiverIdx].information; + rxInfo.capabilities = 0xFFFFFFFF; + hwSettings.receiverSettings.outputsCount = 6; + for (int i=0; i<6; i++) { + hwSettings.receiverSettings.outputsMapping[i] = i; + } +#endif + setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); + setFocus(); +} + +void RxOptions::checkEvents() +{ + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + auto& module = hwSettings.modules[moduleIdx]; + auto& receiver = module.receivers[receiverIdx]; + + switch (state) { + case RO_Init: + // kickstart fetching RX settings + memclear(&hwSettings, sizeof(hwSettings)); + //hwSettings.receiverSettings.receiverId = receiverIdx; + moduleState[moduleIdx].readModuleInformation( + &hwSettings.modules[moduleIdx], receiverIdx, receiverIdx); + state = RO_ReadModuleInfo; + break; + case RO_ReadModuleInfo: + // times out after a while (see pxx2.cpp) + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { + // uint8_t rxModelId = receiver.information.modelID; + uint8_t rxVariant = receiver.information.variant; + if (isModuleR9MAccess(moduleIdx) && rxVariant == PXX2_VARIANT_EU && + !hwSettings.moduleSettings.txPower) { + moduleState[moduleIdx].readModuleSettings(&hwSettings.moduleSettings); + state = RO_ReadModuleSettings; + } else { + moduleState[moduleIdx].readReceiverSettings(&hwSettings.receiverSettings); + state = RO_ReadReceiverSettings; + } + } + break; + case RO_ReadModuleSettings: + // this one does NOT timeout (see pxx2.cpp) + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && + hwSettings.moduleSettings.state == PXX2_SETTINGS_OK) { + moduleState[moduleIdx].readReceiverSettings(&hwSettings.receiverSettings); + state = RO_ReadReceiverSettings; + } + break; + case RO_ReadReceiverSettings: + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && + hwSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + state = RO_DisplaySettings; + update(); + } + break; + case RO_WriteSettings: + // TODO: ask for confirmation ??? + moduleState[moduleIdx].writeReceiverSettings(&hwSettings.receiverSettings); + state = RO_WritingSettings; + break; + + case RO_WritingSettings: +#if defined(SIMU) + statusText.clear(); + deleteLater(); +#else + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && + hwSettings.receiverSettings.state == PXX2_SETTINGS_OK) { + statusText.clear(); + deleteLater(); + } +#endif + break; + + default: // RO_DisplaySettings + break; + } + + Dialog::checkEvents(); +} + +#if defined(HARDWARE_KEYS) +void RxOptions::onEvent(event_t event) +{ + TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), + event); + + if (event == EVT_KEY_BREAK(KEY_EXIT)) { + deleteLater(); + } +} +#endif + +#define CH_ENABLE_SPORT 4 +#define CH_ENABLE_SBUS 5 + +static uint8_t getShiftedChannel(int8_t moduleIdx, int ch) +{ + return g_model.moduleData[moduleIdx].channelsStart + ch; +} + +static std::string getChannelText(int8_t moduleIdx, uint8_t pin, int val) +{ + uint8_t ch = getShiftedChannel(moduleIdx, val); + uint8_t channelsMax = sentModuleChannels(moduleIdx) - 1; + if (val <= channelsMax) { + return std::string("CH") + std::to_string(ch + 1); + } else if (pin == CH_ENABLE_SPORT) { + return std::string("S.PORT"); + } else if (pin == CH_ENABLE_SBUS) { + return std::string("SBUS"); + } + return std::string(); +} + +void RxOptions::update() +{ + auto form = &content->form; + form->clear(); + + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + auto& rxInfo = hwSettings.modules[moduleIdx].receivers[receiverIdx].information; + // uint8_t receiverModelId = rxInfo.modelID; + uint8_t receiverVariant = rxInfo.variant; + uint8_t capabilities = rxInfo.capabilities; + + FormGridLayout grid(content->form.width(), 10); + grid.setLabelWidth(width() / 3); + + new StaticText(form, grid.getLabelSlot(), STR_RECEIVER); + new StaticText(form, grid.getFieldSlot(), + g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx]); + grid.nextLine(); + + // PWM rate + new StaticText(form, grid.getLabelSlot(), + isModuleR9MAccess(moduleIdx) ? "6.67ms PWM" : "7ms PWM"); + new CheckBox( + form, grid.getFieldSlot(), + []() { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.receiverSettings.pwmRate; + }, + [](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.receiverSettings.pwmRate = val; + }); + grid.nextLine(); + + // telemetry disabled + new StaticText(form, grid.getLabelSlot(), STR_TELEMETRY_DISABLED); + auto tele25mw = new CheckBox( + form, grid.getFieldSlot(), + []() { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.receiverSettings.telemetryDisabled; + }, + [](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.receiverSettings.telemetryDisabled = val; + }); + + if (isModuleR9MAccess(moduleIdx) && receiverVariant == PXX2_VARIANT_EU && + hwSettings.moduleSettings.txPower > 14 /*25mW*/) { + // read only field in this case + tele25mw->disable(); + } + grid.nextLine(); + + if (capabilities & (1 << RECEIVER_CAPABILITY_TELEMETRY_25MW)) { + // telemetry 25 mW + new StaticText(form, grid.getLabelSlot(), "25mw Tele"); + new CheckBox( + form, grid.getFieldSlot(), + []() { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.receiverSettings.telemetry25mw; + }, + [](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.receiverSettings.telemetry25mw = val; + }); + grid.nextLine(); + } + + if (capabilities & + ((1 << RECEIVER_CAPABILITY_FPORT) | (1 << RECEIVER_CAPABILITY_FPORT2))) { + + // SPORT modes + new StaticText(form, grid.getLabelSlot(), STR_PROTOCOL); + auto sportModes = new Choice( + form, grid.getFieldSlot(2, 0), STR_SPORT_MODES, 0, 2, + []() { + const auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + const auto& rxSettings = hwSettings.receiverSettings; + return rxSettings.fport | (rxSettings.fport2 << 1); + }, + [](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + auto& rxSettings = hwSettings.receiverSettings; + rxSettings.fport = val & 0x01; + rxSettings.fport2 = (val & 0x02) >> 1; + }); + + sportModes->setAvailableHandler([=](int val) { + switch (val) { + case 1: // FPORT + return (bool)(capabilities & (1 << RECEIVER_CAPABILITY_FPORT)); + case 2: // FPORT2 + return (bool)(capabilities & (1 << RECEIVER_CAPABILITY_FPORT2)); + } + return true; + }); + grid.nextLine(); + } + + auto outputsCount = min(16, hwSettings.receiverSettings.outputsCount); + for (uint8_t i = 0; i < outputsCount; i++) { + std::string i_str = std::to_string(i+1); + new StaticText(form, grid.getLabelSlot(), std::string(STR_PIN) + i_str); + + uint8_t channelsMax = sentModuleChannels(moduleIdx) - 1; + uint8_t selectionMax = channelsMax; + if (capabilities & (1 << RECEIVER_CAPABILITY_ENABLE_PWM_CH5_CH6) + && (CH_ENABLE_SPORT == i || CH_ENABLE_SBUS == i)) { + selectionMax++; + } + + uint8_t mapping = hwSettings.receiverSettings.outputsMapping[i]; + uint8_t channel = getShiftedChannel(moduleIdx, mapping); + + auto r = grid.getFieldSlot(2, 1); + if (r.h > BAR_HEIGHT) { + r.y += (r.h - BAR_HEIGHT)/2; + r.h = BAR_HEIGHT; + } + auto chBar = new OutputChannelBar(form, r, channel); + + auto chDn = new Choice( + form, grid.getFieldSlot(2, 0), 0, selectionMax, + [=]() { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + return hwSettings.receiverSettings.outputsMapping[i]; + }, + [=](int val) { + auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); + hwSettings.receiverSettings.outputsMapping[i] = val; + if (val <= channelsMax) { + chBar->setChannel(getShiftedChannel(moduleIdx, val)); + chBar->setEnabled(true); + } else { + chBar->setEnabled(false); + } + }); + chDn->setTextHandler( + [=](int val) { return getChannelText(moduleIdx, i, val); }); + + grid.nextLine(); + } + + new DynamicText(form, grid.getFieldSlot(), [=]() { return statusText; }); + grid.setLabelWidth(15); + grid.setMarginRight(15); + grid.nextLine(); + + auto exitButton = + new TextButton(form, grid.getFieldSlot(2, 0), STR_EXIT, [=]() -> int8_t { + this->deleteLater(); + return 0; + }); + + new TextButton(form, grid.getFieldSlot(2, 1), STR_OK, [=]() -> int8_t { + this->writeSettings(); + return 0; + }); + + exitButton->setFocus(SET_FOCUS_DEFAULT); + grid.nextLine(); + grid.spacer(PAGE_PADDING); + + form->setInnerHeight(grid.getWindowHeight()); + if (form->getInnerHeight() < LCD_H - 2*POPUP_HEADER_HEIGHT) { + form->setHeight(form->getInnerHeight()); + } else { + form->setHeight(LCD_H - 2*POPUP_HEADER_HEIGHT); + } + + content->adjustHeight(); + content->setWindowCentered(); +} + +void RxOptions::writeSettings() +{ + if (state == RO_DisplaySettings) { + statusText = STR_WRITING; + state = RO_WriteSettings; + } +} diff --git a/radio/src/gui/colorlcd/access_settings.h b/radio/src/gui/colorlcd/access_settings.h index a685a31fb..945fa03af 100644 --- a/radio/src/gui/colorlcd/access_settings.h +++ b/radio/src/gui/colorlcd/access_settings.h @@ -86,3 +86,69 @@ class RegisterDialog : public Dialog TextEdit* rxName = nullptr; TextButton* exitButton; }; + +class ModuleOptions : public Dialog +{ + public: + ModuleOptions(Window* parent, uint8_t moduleIdx); + + void checkEvents() override; +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif + + protected: + + enum { + MO_Init=0, + MO_ReadModuleInfo, + MO_ReadModuleSettings, + MO_DisplaySettings, + MO_WriteSettings, + MO_WritingSettings, + }; + + uint8_t moduleIdx; + uint8_t state = MO_Init; + + std::string statusText; + + uint8_t getModuleSettingsState(); + + void update(); + void writeSettings(); +}; + +class RxOptions : public Dialog +{ + public: + RxOptions(Window* parent, uint8_t moduleIdx, uint8_t rxIdx); + + void checkEvents() override; +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override; +#endif + + protected: + + enum { + RO_Init=0, + RO_ReadModuleInfo, + RO_ReadModuleSettings, + RO_ReadReceiverSettings, + RO_DisplaySettings, + RO_WriteSettings, + RO_WritingSettings, + }; + + uint8_t moduleIdx; + uint8_t receiverIdx; + uint8_t state = RO_Init; + + std::string statusText; + + uint8_t getRxSettingsState(); + + void update(); + void writeSettings(); +}; diff --git a/radio/src/gui/colorlcd/channel_bar.h b/radio/src/gui/colorlcd/channel_bar.h index 6d8644ab9..84bf3a354 100644 --- a/radio/src/gui/colorlcd/channel_bar.h +++ b/radio/src/gui/colorlcd/channel_bar.h @@ -36,15 +36,26 @@ constexpr coord_t LEG_COLORBOX = 15; class ChannelBar : public Window { - public: - ChannelBar(Window * parent, const rect_t & rect, uint8_t channel): - Window(parent, rect), - channel(channel) - { - } - - protected: - uint8_t channel = 0; + public: + ChannelBar(Window* parent, const rect_t& rect, uint8_t channel) : + Window(parent, rect), channel(channel) + { + } + + void setChannel(uint8_t ch) + { + channel = ch; + invalidate(); + } + + void setEnabled(bool en) + { + enabled = en; + } + + protected: + uint8_t channel = 0; + bool enabled = true; }; class MixerChannelBar : public ChannelBar @@ -54,6 +65,8 @@ class MixerChannelBar : public ChannelBar void paint(BitmapBuffer * dc) override { + if (!enabled) return; + int chanVal = calcRESXto100(ex_chans[channel]); const int displayVal = chanVal; @@ -112,6 +125,8 @@ class OutputChannelBar : public ChannelBar void paint(BitmapBuffer * dc) override { + if (!enabled) return; + int chanVal = calcRESXto100(channelOutputs[channel]); int displayVal = chanVal; @@ -238,6 +253,8 @@ class ComboChannelBar : public ChannelBar void paint(BitmapBuffer * dc) override { + if (!enabled) return; + char chanString[] = "CH32 "; int usValue = PPM_CH_CENTER(channel) + channelOutputs[channel] / 2; diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index 477cefe6d..284d39424 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -639,7 +639,9 @@ class ModuleWindow : public FormGroup { update(); rfChoice->setFocus(SET_FOCUS_DEFAULT); }); - } else if (isModulePXX2(moduleIdx)) { + } +#if defined(PXX2) + else if (isModulePXX2(moduleIdx)) { rfChoice = new Choice(this, grid.getFieldSlot(2, 1), STR_ISRM_RF_PROTOCOLS, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_LR12, @@ -651,6 +653,7 @@ class ModuleWindow : public FormGroup { rfChoice->setFocus(SET_FOCUS_DEFAULT); }); } +#endif #if defined(AFHDS2) || defined(AFHDS3) else if (isModuleFlySky(moduleIdx)) { rfChoice = @@ -1206,6 +1209,15 @@ class ModuleWindow : public FormGroup { }); grid.nextLine(); + + new StaticText(this, grid.getLabelSlot(true), TR_OPTIONS, 0, + COLOR_THEME_PRIMARY1); + auto options = new TextButton(this, grid.getFieldSlot(2, 0), TR_SET); + options->setPressHandler([=]() { + new ModuleOptions(this, moduleIdx); + return 0; + }); + grid.nextLine(); } #endif diff --git a/radio/src/gui/common/stdlcd/model_module_options.cpp b/radio/src/gui/common/stdlcd/model_module_options.cpp index 3af79e172..6274cae3f 100644 --- a/radio/src/gui/common/stdlcd/model_module_options.cpp +++ b/radio/src/gui/common/stdlcd/model_module_options.cpp @@ -61,30 +61,7 @@ enum { 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 */ - } + return isPXX2PowerAvailable(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].information, value); } void menuModelModuleOptions(event_t event) diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index ffdfade86..fa02b77e7 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -25,6 +25,35 @@ #include "io/frsky_firmware_update.h" #include "libopenui/src/libopenui_file.h" +bool isPXX2PowerAvailable(const PXX2HardwareInformation& info, int value) +{ + uint8_t modelId = info.modelID; + uint8_t variant = info.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 { + // other modules do not have the power option + return false; + } +} + PXX2ModuleSetup& getPXX2ModuleSetupBuffer() { return reusableBuffer.moduleSetup.pxx2; diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 5c1305631..f3c6db6b5 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -331,6 +331,8 @@ PACK(struct PXX2HardwareInformation { uint8_t capabilityNotSupported; }); +bool isPXX2PowerAvailable(const PXX2HardwareInformation& info, int value); + PACK(struct ModuleInformation { int8_t current; int8_t maximum; From b7ddca5fdbfb00bab895b7d44f80ed94840a02bb Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 7 Nov 2021 20:17:43 +0100 Subject: [PATCH 05/12] Exclude PXX2 module and receiver option UI files when PXX2 not enabled --- radio/src/gui/common/stdlcd/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index a453932f9..bdc984a41 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -9,8 +9,6 @@ set(GUI_SRC ../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 ../common/stdlcd/radio_hardware.cpp @@ -55,3 +53,11 @@ if(PXX2 OR MULTIMODULE) ../common/stdlcd/radio_spectrum_analyser.cpp ) endif() + +if(PXX2) + set(GUI_SRC + ${GUI_SRC} + ../common/stdlcd/model_module_options.cpp + ../common/stdlcd/model_receiver_options.cpp + ) +endif() From ce97a9fc773d4e77a1934d96a9345f031a330af5 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sun, 7 Nov 2021 20:37:59 +0100 Subject: [PATCH 06/12] FIx "cannot bind packed field" (GGC-ARM) --- radio/src/gui/colorlcd/access_settings.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index d6c87acc1..e3d5c35b9 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -569,7 +569,7 @@ void RxOptions::checkEvents() { auto& hwSettings = getPXX2HardwareAndSettingsBuffer(); auto& module = hwSettings.modules[moduleIdx]; - auto& receiver = module.receivers[receiverIdx]; + auto& rxInfo = module.receivers[receiverIdx].information; switch (state) { case RO_Init: @@ -583,8 +583,8 @@ void RxOptions::checkEvents() case RO_ReadModuleInfo: // times out after a while (see pxx2.cpp) if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { - // uint8_t rxModelId = receiver.information.modelID; - uint8_t rxVariant = receiver.information.variant; + // uint8_t rxModelId = rxInfo.modelID; + uint8_t rxVariant = rxInfo.variant; if (isModuleR9MAccess(moduleIdx) && rxVariant == PXX2_VARIANT_EU && !hwSettings.moduleSettings.txPower) { moduleState[moduleIdx].readModuleSettings(&hwSettings.moduleSettings); From 17bbb8b7998a2c60b8f9f478596a588802ad1ef9 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 8 Nov 2021 10:27:09 +0100 Subject: [PATCH 07/12] Fixed R9M ACCESS binding --- radio/src/gui/colorlcd/access_settings.cpp | 120 ++++++++++++++++----- radio/src/pulses/pxx2.cpp | 10 +- 2 files changed, 98 insertions(+), 32 deletions(-) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index e3d5c35b9..7cc720705 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -27,6 +27,41 @@ #define SET_DIRTY() storageDirty(EE_MODEL) +static void startBindWaitDialog(Window* parent, uint8_t moduleIdx, + uint8_t receiverIdx) +{ + auto& bindInfo = getPXX2BindInformationBuffer(); +#if defined(SIMU) + const char* receiverName = + bindInfo.candidateReceiversNames[bindInfo.selectedReceiverIndex]; + memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], + receiverName, PXX2_LEN_RX_NAME); + storageDirty(EE_MODEL); + bindInfo.step = BIND_OK; + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + new MessageDialog(parent, STR_BIND, STR_BIND_OK); +#else + bindInfo.step = BIND_START; + new BindWaitDialog(parent, moduleIdx, receiverIdx); +#endif +} + +static void startFlexBindWaitDialog(Window* parent, uint8_t moduleIdx, + uint8_t receiverIdx, uint8_t flex) +{ + auto& bindInfo = getPXX2BindInformationBuffer(); + bindInfo.flexMode = flex; + startBindWaitDialog(parent, moduleIdx, receiverIdx); +} + +static void startLBTBindWaitDialog(Window* parent, uint8_t moduleIdx, + uint8_t receiverIdx, uint8_t lbt) +{ + auto& bindInfo = getPXX2BindInformationBuffer(); + bindInfo.lbtMode = lbt; + startBindWaitDialog(parent, moduleIdx, receiverIdx); +} + BindRxChoiceMenu::BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, uint8_t receiverIdx) : Menu(parent), moduleIdx(moduleIdx), receiverIdx(receiverIdx) @@ -43,31 +78,30 @@ BindRxChoiceMenu::BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, bindInfo.selectedReceiverIndex = i; if (isModuleR9MAccess(moduleIdx) && modInfo.information.variant == PXX2_VARIANT_EU) { - bindInfo.step = BIND_RX_NAME_SELECTED; - // TODO: - // POPUP_MENU_ADD_ITEM(STR_16CH_WITH_TELEMETRY); - // POPUP_MENU_ADD_ITEM(STR_16CH_WITHOUT_TELEMETRY); - // POPUP_MENU_START(onPXX2R9MBindModeMenu); + + auto& modSetup = getPXX2ModuleSetupBuffer(); + if (modSetup.moduleSettings.txPower <= 14) { + // with telemetry + startLBTBindWaitDialog(parent, moduleIdx, receiverIdx, 1); + } else { + // without telemetry + startLBTBindWaitDialog(parent, moduleIdx, receiverIdx, 2); + } + return; } else if (isModuleR9MAccess(moduleIdx) && modInfo.information.variant == PXX2_VARIANT_FLEX) { bindInfo.step = BIND_RX_NAME_SELECTED; - // TODO: - // POPUP_MENU_ADD_ITEM(STR_FLEX_868); - // POPUP_MENU_ADD_ITEM(STR_FLEX_915); - // POPUP_MENU_START(onPXX2R9MBindModeMenu); - } else { -#if defined(SIMU) - memcpy(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], - receiverName, PXX2_LEN_RX_NAME); - storageDirty(EE_MODEL); - bindInfo.step = BIND_OK; - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; - new MessageDialog(parent, STR_BIND, STR_BIND_OK); -#else - bindInfo.step = BIND_START; - new BindWaitDialog(parent, moduleIdx, receiverIdx); -#endif + auto flexMenu = new Menu(parent); + flexMenu->addLine(STR_FLEX_868, [=]() { + startFlexBindWaitDialog(parent, moduleIdx, receiverIdx, 0); + }); + flexMenu->addLine(STR_FLEX_915, [=]() { + startFlexBindWaitDialog(parent, moduleIdx, receiverIdx, 1); + }); + return; } + + startBindWaitDialog(parent, moduleIdx, receiverIdx); }); } @@ -82,18 +116,49 @@ BindWaitDialog::BindWaitDialog(Window* parent, uint8_t moduleIdx, { new StaticText(&content->form, {0, height() / 2, width(), PAGE_LINE_HEIGHT}, STR_WAITING_FOR_RX, 0, CENTERED | COLOR_THEME_PRIMARY1); + + setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); } void BindWaitDialog::checkEvents() { auto& bindInfo = getPXX2BindInformationBuffer(); + if (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL) { - removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); - deleteLater(); - if (bindInfo.step == BIND_OK) { - POPUP_INFORMATION(STR_REG_OK); - } else { - // TODO: display error??? + + // returned to normal after bind + if (bindInfo.step > BIND_INIT) { + removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); + deleteLater(); + if (bindInfo.step == BIND_OK) { + POPUP_INFORMATION(STR_REG_OK); + } + return; + } + + // pre-bind phase: fetching info for R9M + auto& modSetup = getPXX2ModuleSetupBuffer(); + switch(bindInfo.step) { + case BIND_MODULE_TX_INFORMATION_REQUEST: + if (modSetup.moduleInformation.information.variant == PXX2_VARIANT_EU) { + // In EU mode we will need the power of the module to know if telemetry + // can be proposed + bindInfo.step = BIND_MODULE_TX_SETTINGS_REQUEST; +#if defined(SIMU) + modSetup.moduleSettings.txPower = 14; +#else + moduleState[moduleIdx].readModuleSettings(&modSetup.moduleSettings); +#endif + } else { + bindInfo.step = 0; + moduleState[moduleIdx].startBind(&bindInfo); + } + break; + case BIND_MODULE_TX_SETTINGS_REQUEST: + // We just receive the module settings (for TX power) + bindInfo.step = 0; + moduleState[moduleIdx].startBind(&bindInfo); + break; } return; } @@ -114,7 +179,6 @@ void BindWaitDialog::onEvent(event_t event) event); if (event == EVT_KEY_BREAK(KEY_EXIT)) { - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; deleteLater(); } } diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index fa02b77e7..cf495617e 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -462,12 +462,14 @@ bool Pxx2Pulses::setupFrame(uint8_t module) setupRegisterFrame(module); break; case MODULE_MODE_BIND: - if (g_model.moduleData[module].type == MODULE_TYPE_ISRM_PXX2 && g_model.moduleData[module].subType != MODULE_SUBTYPE_ISRM_PXX2_ACCESS) + if ((g_model.moduleData[module].type == MODULE_TYPE_ISRM_PXX2 && + g_model.moduleData[module].subType != + MODULE_SUBTYPE_ISRM_PXX2_ACCESS) || + (g_model.moduleData[module].type == MODULE_TYPE_XJT_LITE_PXX2)) { setupAccstBindFrame(module); - else if (g_model.moduleData[module].type == MODULE_TYPE_XJT_LITE_PXX2) - setupAccstBindFrame(module); - else + } else { setupAccessBindFrame(module); + } break; case MODULE_MODE_RESET: setupResetFrame(module); From 26756a6a0b3a49637be33019717e6e648cd91015 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Tue, 9 Nov 2021 11:02:50 +0100 Subject: [PATCH 08/12] Fix binding being canceled on BindWaitDialog being closed --- radio/src/gui/colorlcd/access_settings.cpp | 21 +++++++++++++++++++++ radio/src/gui/colorlcd/access_settings.h | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index 7cc720705..3c4d46981 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -108,6 +108,21 @@ BindRxChoiceMenu::BindRxChoiceMenu(Window* parent, uint8_t moduleIdx, setCancelHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; }); } +#if defined(HARDWARE_TOUCH) +bool BindRxChoiceMenu::onTouchEnd(coord_t x, coord_t y) +{ + // Note: onCancel() is not called when the menu is discarded + // by clicking outside the menu window and the onCancel + // handler is not accessible from here + if (!Window::onTouchEnd(x, y)) { + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + onKeyPress(); + deleteLater(); + } + return true; +} +#endif + BindWaitDialog::BindWaitDialog(Window* parent, uint8_t moduleIdx, uint8_t receiverIdx) : Dialog(parent, STR_BIND, {50, 73, LCD_W - 100, LCD_H - 146}), @@ -164,7 +179,12 @@ void BindWaitDialog::checkEvents() } if (bindInfo.step == BIND_INIT && bindInfo.candidateReceiversCount > 0) { + + // create RX choice dialog... new BindRxChoiceMenu(parent, moduleIdx, receiverIdx); + + // ... prevent module mode being reset to NORMAL before exiting + setCloseHandler(nullptr); deleteLater(); return; } @@ -249,6 +269,7 @@ void ReceiverButton::startBind() memclear(&bindInfo, sizeof(bindInfo)); bindInfo.rxUid = receiverIdx; + bindInfo.step = BIND_INIT; if (isModuleR9MAccess(moduleIdx)) { bindInfo.step = BIND_MODULE_TX_INFORMATION_REQUEST; diff --git a/radio/src/gui/colorlcd/access_settings.h b/radio/src/gui/colorlcd/access_settings.h index 945fa03af..68d74e8c7 100644 --- a/radio/src/gui/colorlcd/access_settings.h +++ b/radio/src/gui/colorlcd/access_settings.h @@ -36,6 +36,10 @@ class BindRxChoiceMenu : public Menu protected: uint8_t moduleIdx; uint8_t receiverIdx; + +#if defined(HARDWARE_TOUCH) + bool onTouchEnd(coord_t x, coord_t y) override; +#endif }; class BindWaitDialog : public Dialog From f6789866c223132b13864c9619ea2e96c5bb4f49 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Wed, 10 Nov 2021 08:22:54 +0100 Subject: [PATCH 09/12] Properly set the receiver id before fetching settings --- radio/src/gui/colorlcd/access_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/colorlcd/access_settings.cpp b/radio/src/gui/colorlcd/access_settings.cpp index 3c4d46981..25b969a5e 100644 --- a/radio/src/gui/colorlcd/access_settings.cpp +++ b/radio/src/gui/colorlcd/access_settings.cpp @@ -660,7 +660,7 @@ void RxOptions::checkEvents() case RO_Init: // kickstart fetching RX settings memclear(&hwSettings, sizeof(hwSettings)); - //hwSettings.receiverSettings.receiverId = receiverIdx; + hwSettings.receiverSettings.receiverId = receiverIdx; moduleState[moduleIdx].readModuleInformation( &hwSettings.modules[moduleIdx], receiverIdx, receiverIdx); state = RO_ReadModuleInfo; From 668174dd53ea91c223f27508ffabd25e503b7186 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Wed, 10 Nov 2021 09:02:24 +0100 Subject: [PATCH 10/12] Use RSSI dialog for ACCESS as well --- radio/src/gui/colorlcd/model_setup.cpp | 42 ++++++++++++-------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index 284d39424..68aa82f01 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -514,8 +514,6 @@ class TrainerModuleWindow : public FormGroup #endif }; - - class ModuleWindow : public FormGroup { public: ModuleWindow(FormWindow * parent, const rect_t &rect, uint8_t moduleIdx) : @@ -1124,18 +1122,7 @@ class ModuleWindow : public FormGroup { resetPulsesAFHDS2(); } #endif - auto rssiDialog = new DynamicMessageDialog( - this, "Range Test", - [=]() { - char buf[16]; - sprintf(buf, "%d db", (int)TELEMETRY_RSSI()); - return std::string(buf); - }, - "RSSI:", 50, - COLOR_THEME_SECONDARY1 | CENTERED | FONT(BOLD) | FONT(XL)); - rssiDialog->setCloseHandler([this]() { - rangeButton->check(false); - moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + startRSSIDialog([]() { #if defined(AFHDS2) if (isModuleFlySky(moduleIdx)) { resetPulsesAFHDS2(); @@ -1204,20 +1191,12 @@ class ModuleWindow : public FormGroup { } else { moduleState[moduleIdx].mode = MODULE_MODE_RANGECHECK; + startRSSIDialog(); return 1; } }); grid.nextLine(); - - new StaticText(this, grid.getLabelSlot(true), TR_OPTIONS, 0, - COLOR_THEME_PRIMARY1); - auto options = new TextButton(this, grid.getFieldSlot(2, 0), TR_SET); - options->setPressHandler([=]() { - new ModuleOptions(this, moduleIdx); - return 0; - }); - grid.nextLine(); } #endif @@ -1268,6 +1247,23 @@ class ModuleWindow : public FormGroup { par->adjustInnerHeight(); } + void startRSSIDialog(std::function closeHandler = nullptr) + { + auto rssiDialog = new DynamicMessageDialog( + parent, "Range Test", + [=]() { + return std::to_string((int)TELEMETRY_RSSI()) + std::string(" db"); + }, + "RSSI:", 50, + COLOR_THEME_SECONDARY1 | CENTERED | FONT(BOLD) | FONT(XL)); + + rssiDialog->setCloseHandler([this, closeHandler]() { + rangeButton->check(false); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + if (closeHandler) closeHandler(); + }); + } + void checkEvents() override { if (isModuleFailsafeAvailable(moduleIdx) != hasFailsafe From 5142d9f4fcaf5af24f8d1f79e410734ed45528e7 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Wed, 10 Nov 2021 09:41:40 +0100 Subject: [PATCH 11/12] Fixed NV14 target --- radio/src/gui/colorlcd/model_setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index 68aa82f01..02b045e91 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -1122,7 +1122,7 @@ class ModuleWindow : public FormGroup { resetPulsesAFHDS2(); } #endif - startRSSIDialog([]() { + startRSSIDialog([=]() { #if defined(AFHDS2) if (isModuleFlySky(moduleIdx)) { resetPulsesAFHDS2(); From 78442c1cecd5126b66db7ddee35cd754c6af1528 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Thu, 11 Nov 2021 08:13:53 +0100 Subject: [PATCH 12/12] Re-added inadvertently removed module options --- radio/src/gui/colorlcd/model_setup.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index 02b045e91..2be662f4f 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -1197,6 +1197,15 @@ class ModuleWindow : public FormGroup { }); grid.nextLine(); + + new StaticText(this, grid.getLabelSlot(true), TR_OPTIONS, 0, + COLOR_THEME_PRIMARY1); + auto options = new TextButton(this, grid.getFieldSlot(2, 0), TR_SET); + options->setPressHandler([=]() { + new ModuleOptions(this, moduleIdx); + return 0; + }); + grid.nextLine(); } #endif