diff --git a/radio/src/gui/colorlcd/CMakeLists.txt b/radio/src/gui/colorlcd/CMakeLists.txt index bc1d9a0af03..60398902e2f 100644 --- a/radio/src/gui/colorlcd/CMakeLists.txt +++ b/radio/src/gui/colorlcd/CMakeLists.txt @@ -149,6 +149,10 @@ if(MULTIMODULE) add_gui_src(mpm_settings.cpp) endif() +if(INTERNAL_MODULE_PXX1) + add_gui_src(pxx1_settings.cpp) +endif() + if(PXX2) add_gui_src(access_settings.cpp) endif() diff --git a/radio/src/gui/colorlcd/hw_intmodule.cpp b/radio/src/gui/colorlcd/hw_intmodule.cpp index 9e62d211702..ad66e647b0a 100644 --- a/radio/src/gui/colorlcd/hw_intmodule.cpp +++ b/radio/src/gui/colorlcd/hw_intmodule.cpp @@ -54,12 +54,44 @@ InternalModuleWindow::InternalModuleWindow(Window *parent) : internalModule->setAvailableHandler( [](int module) { return isInternalModuleSupported(module); }); -#if defined(CROSSFIRE) +#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) box = new FormGroup(box, rect_t{}); box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(8)); + ant_box = box->getLvObj(); + lv_obj_set_width(ant_box, LV_SIZE_CONTENT); + lv_obj_set_style_flex_cross_place(ant_box, LV_FLEX_ALIGN_CENTER, 0); + + new StaticText(box, rect_t{}, STR_ANTENNA, 0, COLOR_THEME_PRIMARY1); + new Choice( + box, rect_t{}, STR_ANTENNA_MODES, ANTENNA_MODE_INTERNAL, + ANTENNA_MODE_EXTERNAL, GET_DEFAULT(g_eeGeneral.antennaMode), + [](int antenna) { + if (!isExternalAntennaEnabled() && + (antenna == ANTENNA_MODE_EXTERNAL || + (antenna == ANTENNA_MODE_PER_MODEL && + g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode == + ANTENNA_MODE_EXTERNAL))) { + if (confirmationDialog(STR_ANTENNACONFIRM1, STR_ANTENNACONFIRM2)) { + g_eeGeneral.antennaMode = antenna; + SET_DIRTY(); + } + } else { + g_eeGeneral.antennaMode = antenna; + checkExternalAntenna(); + SET_DIRTY(); + } + }); + + updateAntennaLine(); +#endif + +#if defined(CROSSFIRE) + box = new FormGroup(box, rect_t{}); + box->setFlexLayout(LV_FLEX_FLOW_ROW); + br_box = box->getLvObj(); - lv_obj_set_width(br_box, LV_SIZE_CONTENT); + lv_obj_set_width(br_box, LV_SIZE_CONTENT); lv_obj_set_style_flex_cross_place(br_box, LV_FLEX_ALIGN_CENTER, 0); new StaticText(box, rect_t{}, STR_BAUDRATE, 0, COLOR_THEME_PRIMARY1); @@ -78,6 +110,7 @@ void InternalModuleWindow::setModuleType(int moduleType) } g_eeGeneral.internalModule = moduleType; updateBaudrateLine(); + updateAntennaLine(); SET_DIRTY(); } @@ -105,3 +138,14 @@ void InternalModuleWindow::updateBaudrateLine() } #endif } + +void InternalModuleWindow::updateAntennaLine() +{ +#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) + if (isInternalModuleAvailable(MODULE_TYPE_XJT_PXX1)) { + lv_obj_clear_flag(ant_box, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_add_flag(ant_box, LV_OBJ_FLAG_HIDDEN); + } +#endif +} diff --git a/radio/src/gui/colorlcd/hw_intmodule.h b/radio/src/gui/colorlcd/hw_intmodule.h index e55a65a3185..d94343429d6 100644 --- a/radio/src/gui/colorlcd/hw_intmodule.h +++ b/radio/src/gui/colorlcd/hw_intmodule.h @@ -31,6 +31,7 @@ class InternalModuleWindow : public FormGroup::Line protected: uint8_t lastModule = 0; lv_obj_t* br_box = nullptr; + lv_obj_t* ant_box = nullptr; #if defined(CROSSFIRE) static int getBaudrate(); @@ -39,4 +40,5 @@ class InternalModuleWindow : public FormGroup::Line void setModuleType(int moduleType); void updateBaudrateLine(); + void updateAntennaLine(); }; diff --git a/radio/src/gui/colorlcd/module_setup.cpp b/radio/src/gui/colorlcd/module_setup.cpp index 11d5480ea30..ce198327e71 100644 --- a/radio/src/gui/colorlcd/module_setup.cpp +++ b/radio/src/gui/colorlcd/module_setup.cpp @@ -33,6 +33,10 @@ #include "channel_range.h" #include "storage/modelslist.h" +#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) +#include "pxx1_settings.h" +#endif + #if defined(PXX2) #include "access_settings.h" #endif @@ -219,6 +223,12 @@ void ModuleWindow::updateModule() modOpts = new MultimoduleSettings(this, grid, moduleIdx); } #endif +#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) + else if (moduleIdx == INTERNAL_MODULE && isModuleXJT(moduleIdx) && + g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL) { + modOpts = new PXX1AntennaSettings(this, grid, moduleIdx); + } +#endif // Channel Range auto line = newLine(&grid); @@ -533,17 +543,6 @@ void ModuleWindow::startRSSIDialog(std::function closeHandler) }); } -// void ModuleWindow::checkEvents() -// { -// if (isModuleFailsafeAvailable(moduleIdx) != hasFailsafe && rfChoice && -// !rfChoice->isEditMode()) { -// hasFailsafe = isModuleFailsafeAvailable(moduleIdx); -// update(); -// } - -// FormGroup::checkEvents(); -// } - class ModuleSubTypeChoice: public Choice { uint8_t moduleIdx; diff --git a/radio/src/gui/colorlcd/pxx1_settings.cpp b/radio/src/gui/colorlcd/pxx1_settings.cpp new file mode 100644 index 00000000000..f69bb32d8d5 --- /dev/null +++ b/radio/src/gui/colorlcd/pxx1_settings.cpp @@ -0,0 +1,63 @@ +/* + * 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 "pxx1_settings.h" +#include "choice.h" + +#include "opentx.h" + +#define SET_DIRTY() storageDirty(EE_MODEL) + +PXX1AntennaSettings::PXX1AntennaSettings(Window* parent, + const FlexGridLayout& g, + uint8_t moduleIdx) : + FormGroup(parent, rect_t{}), md(&g_model.moduleData[moduleIdx]) +{ + FlexGridLayout grid(g); + setFlexLayout(); + + auto line = newLine(&grid); + new StaticText(line, rect_t{}, STR_ANTENNA, 0, COLOR_THEME_PRIMARY1); + + if (md->pxx.antennaMode == ANTENNA_MODE_PER_MODEL) { + md->pxx.antennaMode = ANTENNA_MODE_INTERNAL; + SET_DIRTY(); + } + + auto antennaChoice = new Choice( + line, rect_t{}, STR_ANTENNA_MODES, ANTENNA_MODE_INTERNAL, + ANTENNA_MODE_EXTERNAL, GET_DEFAULT(md->pxx.antennaMode), + [=](int32_t antenna) -> void { + if (!isExternalAntennaEnabled() && (antenna == ANTENNA_MODE_EXTERNAL)) { + if (confirmationDialog(STR_ANTENNACONFIRM1, STR_ANTENNACONFIRM2)) { + md->pxx.antennaMode = antenna; + SET_DIRTY(); + } + } else { + md->pxx.antennaMode = antenna; + SET_DIRTY(); + checkExternalAntenna(); + } + }); + + antennaChoice->setAvailableHandler( + [=](int8_t mode) { return mode != ANTENNA_MODE_PER_MODEL; }); +} diff --git a/radio/src/gui/colorlcd/pxx1_settings.h b/radio/src/gui/colorlcd/pxx1_settings.h new file mode 100644 index 00000000000..3709b5d51b8 --- /dev/null +++ b/radio/src/gui/colorlcd/pxx1_settings.h @@ -0,0 +1,37 @@ +/* + * 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 "form.h" +#include "module_setup.h" + +struct ModuleData; + +class PXX1AntennaSettings : public FormGroup, public ModuleOptions +{ + ModuleData* md; + + void update() override {} + +public: + PXX1AntennaSettings(Window* parent, const FlexGridLayout& g, uint8_t moduleIdx); +}; diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index c89e51db100..18de0210268 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -573,6 +573,104 @@ bool isSourceAvailableInResetSpecialFunction(int index) } } +#if defined(EXTERNAL_ANTENNA) && defined(INTERNAL_MODULE_PXX1) + +#if defined(COLORLCD) + +class AntennaSelectionMenu : public Menu +{ + bool& done; + +public: + AntennaSelectionMenu(bool& done) : Menu(MainWindow::instance()), done(done) { + setTitle(STR_ANTENNA); + addLine(STR_USE_INTERNAL_ANTENNA, + [] { globalData.externalAntennaEnabled = false; }); + addLine(STR_USE_EXTERNAL_ANTENNA, + [] { globalData.externalAntennaEnabled = true; }); + setCloseHandler([=]() { this->done = true; }); + setCloseWhenClickOutside(false); + } +protected: + void onCancel() override {} +}; + +static void runAntennaSelectionMenu() +{ + bool finished = false; + new AntennaSelectionMenu(finished); + + while (!finished) { + WDG_RESET(); + MainWindow::instance()->run(); + LvglWrapper::runNested(); + RTOS_WAIT_MS(20); + } +} +#else +void onAntennaSelection(const char* result) +{ + if (result == STR_USE_INTERNAL_ANTENNA) { + globalData.externalAntennaEnabled = false; + } else if (result == STR_USE_EXTERNAL_ANTENNA) { + globalData.externalAntennaEnabled = true; + } else { + checkExternalAntenna(); + } +} + +void onAntennaSwitchConfirm(const char * result) +{ + if (result == STR_OK) { + // Switch to external antenna confirmation + globalData.externalAntennaEnabled = true; + } +} +#endif + +void checkExternalAntenna() +{ + if (isModuleXJT(INTERNAL_MODULE)) { + if (g_eeGeneral.antennaMode == ANTENNA_MODE_EXTERNAL) { + // TRACE("checkExternalAntenna(): External"); + globalData.externalAntennaEnabled = true; + } else if (g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL && + g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode == + ANTENNA_MODE_EXTERNAL) { + // TRACE("checkExternalAntenna(): Per Model, External"); + if (!globalData.externalAntennaEnabled) { +#if defined(COLORLCD) + if (confirmationDialog(STR_ANTENNACONFIRM1, STR_ANTENNACONFIRM2)) { + globalData.externalAntennaEnabled = true; + } +#else + POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onAntennaSwitchConfirm); + SET_WARNING_INFO(STR_ANTENNACONFIRM2, sizeof(TR_ANTENNACONFIRM2), 0); +#endif + } + } else if (g_eeGeneral.antennaMode == ANTENNA_MODE_ASK || + (g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL && + g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode == + ANTENNA_MODE_ASK)) { + + // TRACE("checkExternalAntenna(): Ask"); + globalData.externalAntennaEnabled = false; + +#if defined(COLORLCD) + runAntennaSelectionMenu(); +#else + POPUP_MENU_ADD_ITEM(STR_USE_INTERNAL_ANTENNA); + POPUP_MENU_ADD_ITEM(STR_USE_EXTERNAL_ANTENNA); + POPUP_MENU_START(onAntennaSelection); +#endif + } else { + globalData.externalAntennaEnabled = false; + } + } else { + globalData.externalAntennaEnabled = false; + } +} +#endif #if defined(PXX2) bool isPxx2IsrmChannelsCountAllowed(int channels) diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 34e8ab563bd..cbf9ef23184 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -195,6 +195,12 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx) } } +#if defined(EXTERNAL_ANTENNA) && defined(INTERNAL_MODULE_PXX1) +void onAntennaSwitchConfirm(const char * result); +void checkExternalAntenna(); +void onAntennaSelection(const char* result); +#endif + #if defined(PXX2) inline bool isRacingModeAllowed() { diff --git a/radio/src/pulses/modules_constants.h b/radio/src/pulses/modules_constants.h index a5dd23e01bc..0e12712acc3 100644 --- a/radio/src/pulses/modules_constants.h +++ b/radio/src/pulses/modules_constants.h @@ -88,7 +88,7 @@ enum R9MLBTPowerValues { }; enum AntennaTypes { - XJT_INTERNAL_ANTENNA, + XJT_INTERNAL_ANTENNA = 0, XJT_EXTERNAL_ANTENNA }; diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 928fc359df3..624eba48ebd 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -106,64 +106,6 @@ void postRadioSettingsLoad() #endif } -#if defined(EXTERNAL_ANTENNA) && defined(INTERNAL_MODULE_PXX1) -void onAntennaSelection(const char * result) -{ - if (result == STR_USE_INTERNAL_ANTENNA) { - globalData.externalAntennaEnabled = false; - } - else if (result == STR_USE_EXTERNAL_ANTENNA) { - globalData.externalAntennaEnabled = true; - } - else { - checkExternalAntenna(); - } -} - -void onAntennaSwitchConfirm(const char * result) -{ - if (result == STR_OK) { - // Switch to external antenna confirmation - globalData.externalAntennaEnabled = true; - } -} - -void checkExternalAntenna() -{ - if (isModuleXJT(INTERNAL_MODULE)) { - if (g_eeGeneral.antennaMode == ANTENNA_MODE_EXTERNAL) { - globalData.externalAntennaEnabled = true; - } - else if (g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL && g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode == ANTENNA_MODE_EXTERNAL) { - if (!globalData.externalAntennaEnabled) { -#if defined(COLORLCD) -#warning "Antenna confirmation dialog needed" -#else - POPUP_CONFIRMATION(STR_ANTENNACONFIRM1, onAntennaSwitchConfirm); - SET_WARNING_INFO(STR_ANTENNACONFIRM2, sizeof(TR_ANTENNACONFIRM2), 0); -#endif - } - } - else if (g_eeGeneral.antennaMode == ANTENNA_MODE_ASK || (g_eeGeneral.antennaMode == ANTENNA_MODE_PER_MODEL && g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode == ANTENNA_MODE_ASK)) { - globalData.externalAntennaEnabled = false; -#if defined(COLORLCD) -#warning "Antenna confirmation dialog needed" -#else - POPUP_MENU_ADD_ITEM(STR_USE_INTERNAL_ANTENNA); - POPUP_MENU_ADD_ITEM(STR_USE_EXTERNAL_ANTENNA); - POPUP_MENU_START(onAntennaSelection); -#endif - } - else { - globalData.externalAntennaEnabled = false; - } - } - else { - globalData.externalAntennaEnabled = false; - } -} -#endif - void postModelLoad(bool alarms) { #if defined(PXX2) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 5046e747d0d..a279b256ff9 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -810,10 +810,10 @@ #define FLYSKY_HALL_TX_DMA_Stream_IRQHandler DMA1_Stream4_IRQHandler #endif -// Internal Module -#if !defined(RADIO_FAMILY_T16) - #define EXTERNAL_ANTENNA -#endif +// Internal PXX1 Module: +// -> let's assume all internal XJT modules used are either X10 or X12S type +#define EXTERNAL_ANTENNA + #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) #define INTMODULE_PWR_GPIO GPIOA #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PA.08