From 3588c8d963507bede911ba6d52cd29d19461b0ae Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Sat, 6 Nov 2021 13:02:40 +0100 Subject: [PATCH] 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);