diff --git a/fw.json b/fw.json index 8fa8b3372..93509d005 100644 --- a/fw.json +++ b/fw.json @@ -7,9 +7,9 @@ ["X9D Plus 2019", "x9dp2019-"], ["T-Lite", "tlite-"], ["X-Lite", "xlite-"], - ["X-Lite", "xlites-"], + ["X-Lite S", "xlites-"], ["X9 Lite", "x9lite-"], - ["X9 Lite", "x9lites-"], + ["X9 Lite S", "x9lites-"], ["T16", "t16-"], ["T18", "t18-"], ["TX12", "tx12-"], diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 08f1072c1..9a5f4bd69 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -240,7 +240,10 @@ inline uint8_t MODULE_SUBTYPE_ROWS(int moduleIdx) } #define POT_WARN_ROWS ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) -#define TIMER_ROWS 1, 0, 1, 0, 0, 0 +#define TIMER_ROWS(x) \ + 1, 0, 1, 0, 0, \ + g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 \ + : (uint8_t)0 #if defined(PCBSKY9X) #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, @@ -411,9 +414,9 @@ void menuModelSetup(event_t event) MENU_TAB({ HEADER_LINE_COLUMNS 0, - TIMER_ROWS, - TIMER_ROWS, - TIMER_ROWS, + TIMER_ROWS(0), + TIMER_ROWS(1), + TIMER_ROWS(2), 0, // Extended limits 1, // Extended trims 0, // Show trims diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 86878a30b..5b187a545 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -275,8 +275,10 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) #define TRAINER_ROWS LABEL(Trainer), 0, TRAINER_CHANNELS_ROW, TRAINER_PPM_PARAMS_ROW #endif -#define TIMER_ROWS \ - 1 | NAVIGATION_LINE_BY_LINE, 0, 1 | NAVIGATION_LINE_BY_LINE, 0, 0, 0 +#define TIMER_ROWS(x) \ + 1 | NAVIGATION_LINE_BY_LINE, 0, 1 | NAVIGATION_LINE_BY_LINE, 0, 0, \ + g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 \ + : (uint8_t)0 inline uint8_t EXTERNAL_MODULE_TYPE_ROW() { @@ -287,11 +289,11 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW() } #if TIMERS == 1 - #define TIMERS_ROWS TIMER_ROWS +#define TIMERS_ROWS TIMER_ROWS(0) #elif TIMERS == 2 - #define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS +#define TIMERS_ROWS TIMER_ROWS(0), TIMER_ROWS(1) #elif TIMERS == 3 - #define TIMERS_ROWS TIMER_ROWS, TIMER_ROWS, TIMER_ROWS +#define TIMERS_ROWS TIMER_ROWS(0), TIMER_ROWS(1), TIMER_ROWS(2) #endif #if defined(PCBX9E) #define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > 8 ? TITLE_ROW : HIDDEN_ROW), uint8_t(getSwitchWarningsCount() > 16 ? TITLE_ROW : HIDDEN_ROW) diff --git a/radio/src/gui/colorlcd/message_dialog.cpp b/radio/src/gui/colorlcd/message_dialog.cpp index 8d5c4571f..067d69500 100644 --- a/radio/src/gui/colorlcd/message_dialog.cpp +++ b/radio/src/gui/colorlcd/message_dialog.cpp @@ -21,18 +21,23 @@ #include "static.h" MessageDialog::MessageDialog(Window* parent, const char* title, - const char* message, const char* info) : + const char* message, const char* info, + const int lineHeight, + const WindowFlags windowFlags, + const LcdFlags textFlags) : Dialog(parent, title, {50, 73, LCD_W - 100, LCD_H - 146}) { + setWindowFlags(windowFlags); + messageWidget = new StaticText( this, {0, coord_t(height() - PAGE_LINE_HEIGHT) / 2, width(), PAGE_LINE_HEIGHT}, message, 0, CENTERED); - infoWidget = new StaticText(this, - {0, 30 + coord_t(height() - PAGE_LINE_HEIGHT) / 2, - width(), PAGE_LINE_HEIGHT}, - info, 0, CENTERED); + infoWidget = new StaticText( + this, + {0, 30 + coord_t(height() - PAGE_LINE_HEIGHT) / 2, width(), lineHeight}, + info, 0, textFlags); setCloseWhenClickOutside(true); setFocus(); } diff --git a/radio/src/gui/colorlcd/message_dialog.h b/radio/src/gui/colorlcd/message_dialog.h index ed2fcf1d2..bf0d570ba 100644 --- a/radio/src/gui/colorlcd/message_dialog.h +++ b/radio/src/gui/colorlcd/message_dialog.h @@ -23,28 +23,27 @@ #include "dialog.h" #include "static.h" -class MessageDialog: public Dialog { - public: - MessageDialog(Window * parent, const char * title, const char * message, const char * info = ""); +class MessageDialog : public Dialog +{ + public: + MessageDialog(Window* parent, const char* title, const char* message, + const char* info = "", const int lineHeight = PAGE_LINE_HEIGHT, + const WindowFlags windowFlags = 0, + const LcdFlags textFlags = CENTERED); + // Attn.: FONT(XXL) is not supported by MessageDialog - void setInfoText(std::string text) - { - infoWidget->setText(std::move(text)); - } - - protected: - StaticText * messageWidget; - StaticText * infoWidget; + void setInfoText(std::string text) { infoWidget->setText(std::move(text)); } + protected: + StaticText* messageWidget; + StaticText* infoWidget; + LcdFlags textFlags; #if defined(DEBUG_WINDOWS) - std::string getName() const override - { - return "MessageDialog"; - } + std::string getName() const override { return "MessageDialog"; } #endif #if defined(HARDWARE_KEYS) - void onEvent(event_t event) override; + void onEvent(event_t event) override; #endif }; diff --git a/radio/src/gui/colorlcd/model_inputs.cpp b/radio/src/gui/colorlcd/model_inputs.cpp index 06080ad4e..62a24d2a8 100644 --- a/radio/src/gui/colorlcd/model_inputs.cpp +++ b/radio/src/gui/colorlcd/model_inputs.cpp @@ -337,7 +337,7 @@ void CommonInputOrMixButton::drawFlightModes(BitmapBuffer *dc, void CommonInputOrMixButton::paint(BitmapBuffer * dc) { dc->drawSolidFilledRect(0, 0, width(), height(), - /*hasFocus() ? FOCUS_BGCOLOR :*/ FIELD_BGCOLOR); + isActive() ? HIGHLIGHT_COLOR : FIELD_BGCOLOR); paintBody(dc); if (!hasFocus()) @@ -397,6 +397,7 @@ class InputLineButton : public CommonInputOrMixButton if (line.flightModes) { drawFlightModes(dc, line.flightModes, textColor); } + } }; diff --git a/radio/src/gui/colorlcd/model_select.cpp b/radio/src/gui/colorlcd/model_select.cpp index a9cdd89fb..909b2cc5c 100644 --- a/radio/src/gui/colorlcd/model_select.cpp +++ b/radio/src/gui/colorlcd/model_select.cpp @@ -210,14 +210,21 @@ class ModelCategoryPageBody : public FormWindow update(); } - void update(int selected = 0) + void update(int selected = -1) { clear(); + if (selected < 0) { + auto model = modelslist.getCurrentModel(); + selected = category->getModelIndex(model); + if (selected < 0) selected = 0; + } + int index = 0; coord_t y = MODEL_CELL_PADDING; coord_t x = MODEL_CELL_PADDING; + ModelButton* selectButton = nullptr; for (auto &model : *category) { auto button = new ModelButton( this, {x, y, MODEL_SELECT_CELL_WIDTH, MODEL_SELECT_CELL_HEIGHT}, @@ -237,7 +244,7 @@ class ModelCategoryPageBody : public FormWindow storageCheck(true); modelslist.setCurrentModel(model); - update(); // modelslist.getModelIndex(modelCell)); + update(); }); } menu->addLine(STR_CREATE_MODEL, getCreateModelAction()); @@ -264,7 +271,7 @@ class ModelCategoryPageBody : public FormWindow .c_str(), [=] { modelslist.removeModel(category, model); - update(index > 0 ? index - 1 : 0); + update(index < category->size() - 1 ? index : index - 1); }); }); } @@ -275,7 +282,7 @@ class ModelCategoryPageBody : public FormWindow }); if (selected == index) { - button->setFocus(SET_FOCUS_DEFAULT); + selectButton = button; } index++; @@ -299,6 +306,8 @@ class ModelCategoryPageBody : public FormWindow if (category->empty()) { setFocus(); + } else if (selectButton) { + selectButton->setFocus(); } } @@ -368,4 +377,9 @@ ModelSelectMenu::ModelSelectMenu(): for (auto category: modelslist.getCategories()) { addTab(new ModelCategoryPage(category)); } + + int idx = modelslist.getCurrentCategoryIdx(); + if (idx >= 0) { + setCurrentTab(idx); + } } diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index b7817d2c7..1d21d125f 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -41,6 +41,27 @@ std::string switchWarninglabel(swsrc_t index) 1); } +class RssiDialog : public MessageDialog +{ + public: + RssiDialog(Window* parent, const char* title, const char* message, + const char* info = "", const int lineHeight = PAGE_LINE_HEIGHT, + const WindowFlags windowFlags = 0, + const LcdFlags textFlags = CENTERED) : + MessageDialog(parent, title, message, info, lineHeight, windowFlags, + textFlags) + { + } + + virtual void checkEvents() + { + char buf[10]; + sprintf(buf, "%d", (int)TELEMETRY_RSSI()); + setInfoText(buf); + MessageDialog::checkEvents(); + } +}; + class ChannelFailsafeBargraph: public Window { public: ChannelFailsafeBargraph(Window * parent, const rect_t & rect, uint8_t moduleIdx, uint8_t channel): @@ -840,6 +861,13 @@ class ModuleWindow : public FormGroup { } else { moduleState[moduleIdx].mode = MODULE_MODE_RANGECHECK; + auto rssiDialog = new RssiDialog( + this, "Range Test", "RSSI:", "", 50, REFRESH_ALWAYS, + DEFAULT_COLOR | CENTERED | FONT(BOLD) | FONT(XL)); + rssiDialog->setCloseHandler([this]() { + rangeButton->check(false); + moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + }); return 1; } }); diff --git a/radio/src/gui/colorlcd/radio_hardware.cpp b/radio/src/gui/colorlcd/radio_hardware.cpp index 36f9a52c5..60f1fbe94 100644 --- a/radio/src/gui/colorlcd/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio_hardware.cpp @@ -286,7 +286,7 @@ void RadioHardwarePage::build(FormWindow * window) auxSerialInit(g_eeGeneral.auxSerialMode, modelTelemetryProtocol()); SET_DIRTY(); }); - aux->setAvailableHandler([=](int value) { return isAuxModeAvailable; }); + aux->setAvailableHandler(isAuxModeAvailable); grid.nextLine(); #endif @@ -300,7 +300,7 @@ void RadioHardwarePage::build(FormWindow * window) aux2SerialInit(g_eeGeneral.aux2SerialMode, modelTelemetryProtocol()); SET_DIRTY(); }); - aux2->setAvailableHandler([=](int value) { return isAux2ModeAvailable; }); + aux2->setAvailableHandler(isAux2ModeAvailable); grid.nextLine(); #endif diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index bbf93de8a..438989eb0 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -222,7 +222,7 @@ enum SwashType { #define IS_MANUAL_RESET_TIMER(idx) (g_model.timers[idx].persistent == 2) #if !defined(PCBSKY9X) -#define TIMER_COUNTDOWN_START(x) (g_model.timers[x].countdownStart > 0 ? 5 : 10 - g_model.timers[x].countdownStart * 10) +#define TIMER_COUNTDOWN_START(x) (g_model.timers[x].countdownStart == 0 ? 20 : (g_model.timers[x].countdownStart == 1 ? 30 : (g_model.timers[x].countdownStart == -1 ? 10 : 5))) #else #define TIMER_COUNTDOWN_START(x) 10 #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index e934bcdcb..6ea3dec47 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -694,11 +694,9 @@ void checkMultiLowPower() #if defined(STM32) static void checkRTCBattery() { - if (isVBatBridgeEnabled()) { - if (getRTCBatteryVoltage() < 200) { - ALERT(STR_BATTERY, STR_WARN_RTC_BATTERY_LOW, AU_ERROR); - } - disableVBatBridge(); + GET_ADC_IF_MIXER_NOT_RUNNING(); + if (getRTCBatteryVoltage() < 200) { + ALERT(STR_BATTERY, STR_WARN_RTC_BATTERY_LOW, AU_ERROR); } } #endif @@ -719,17 +717,6 @@ static void checkFailsafe() #else #define checkFailsafe() #endif -void checkRSSIAlarmsDisabled() -{ - if (g_model.rssiAlarms.disabled) { -#if !defined(HARDWARE_INTERNAL_MODULE) - if (!isModuleMultimoduleDSM2(EXTERNAL_MODULE)) -#else - if (!isModuleMultimoduleDSM2(INTERNAL_MODULE) && !isModuleMultimoduleDSM2(EXTERNAL_MODULE)) -#endif - ALERT(STR_RSSIALARM_WARN, STR_NO_RSSIALARM, AU_ERROR); - } -} #if defined(GUI) void checkAll() @@ -745,15 +732,17 @@ void checkAll() checkSwitches(); checkFailsafe(); - checkRSSIAlarmsDisabled(); #if defined(SDCARD) && !defined(RADIOMASTER_RTF_RELEASE) checkSDVersion(); #endif #if defined(STM32) - if (!g_eeGeneral.disableRtcWarning) + if (isVBatBridgeEnabled() && !g_eeGeneral.disableRtcWarning) { + // only done once at board start checkRTCBattery(); + } + disableVBatBridge(); #endif #if defined(COLORLCD) diff --git a/radio/src/storage/modelslist.cpp b/radio/src/storage/modelslist.cpp index 1ba806284..f6cf61609 100644 --- a/radio/src/storage/modelslist.cpp +++ b/radio/src/storage/modelslist.cpp @@ -240,6 +240,19 @@ void ModelsCategory::moveModel(ModelCell * model, int8_t step) erase(current); } +int ModelsCategory::getModelIndex(const ModelCell* model) +{ + int idx = 0; + for (auto m : *this) { + if (model == m) + return idx; + + ++idx; + } + + return -1; +} + void ModelsCategory::save(FIL * file) { #if !defined(SDCARD_YAML) @@ -389,6 +402,22 @@ void ModelsList::setCurrentCategory(ModelsCategory * cat) currentCategory = cat; } +int ModelsList::getCurrentCategoryIdx() const +{ + if (!currentCategory) + return -1; + + int idx = 0; + for (auto cat : categories) { + if (currentCategory == cat) + return idx; + + ++idx; + } + + return -1; +} + void ModelsList::setCurrentModel(ModelCell * cell) { currentModel = cell; diff --git a/radio/src/storage/modelslist.h b/radio/src/storage/modelslist.h index f9bde8302..0991fc78e 100644 --- a/radio/src/storage/modelslist.h +++ b/radio/src/storage/modelslist.h @@ -80,6 +80,8 @@ public: void removeModel(ModelCell * model); void moveModel(ModelCell * model, int8_t step); + int getModelIndex(const ModelCell* model); + void save(FIL * file); }; @@ -118,6 +120,7 @@ public: { return currentCategory; } + int getCurrentCategoryIdx() const; void setCurrentModel(ModelCell * cell); diff --git a/radio/src/targets/horus/tp_gt911.cpp b/radio/src/targets/horus/tp_gt911.cpp index 624cac3f8..d176b5b71 100644 --- a/radio/src/targets/horus/tp_gt911.cpp +++ b/radio/src/targets/horus/tp_gt911.cpp @@ -711,40 +711,56 @@ void touchPanelRead() if (!touchEventOccured) return; - touchEventOccured = false; - I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1); + touchEventOccured = 0; + + uint32_t startReadStatus = RTOS_GET_MS(); + do { + if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1)) { + TRACE("GT911 I2C read error"); + return; + } + + if (state & 0x80u) { + // ready + break; + } + RTOS_WAIT_MS(1); + } while(RTOS_GET_MS() - startReadStatus < GT911_TIMEOUT); + TRACE("touch state = 0x%x", state); - if ((state & 0x80u) == 0x00) { - // not ready - return; - } + if (state & 0x80u) { + uint8_t pointsCount = (state & 0x0Fu); - uint8_t pointsCount = (state & 0x0Fu); - - if (pointsCount > 0 && pointsCount < GT911_MAX_TP) { - I2C_GT911_ReadRegister(GT911_READ_XY_REG + 1, touchData.data, pointsCount * sizeof(TouchPoint)); - if (touchState.event == TE_NONE || touchState.event == TE_UP || touchState.event == TE_SLIDE_END) { - touchState.event = TE_DOWN; - touchState.startX = touchState.x = touchData.points[0].x; - touchState.startY = touchState.y = touchData.points[0].y; - } - else { - touchState.deltaX = touchData.points[0].x - touchState.x; - touchState.deltaY = touchData.points[0].y - touchState.y; - if (touchState.event == TE_SLIDE || abs(touchState.deltaX) >= SLIDE_RANGE || abs(touchState.deltaY) >= SLIDE_RANGE) { - touchState.event = TE_SLIDE; - touchState.x = touchData.points[0].x; - touchState.y = touchData.points[0].y; + if (pointsCount > 0 && pointsCount <= GT911_MAX_TP) { + if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG + 1, touchData.data, + pointsCount * sizeof(TouchPoint))) { + TRACE("GT911 I2C read error"); + return; + } + if (touchState.event == TE_NONE || touchState.event == TE_UP || + touchState.event == TE_SLIDE_END) { + touchState.event = TE_DOWN; + touchState.startX = touchState.x = touchData.points[0].x; + touchState.startY = touchState.y = touchData.points[0].y; + } else { + touchState.deltaX = touchData.points[0].x - touchState.x; + touchState.deltaY = touchData.points[0].y - touchState.y; + if (touchState.event == TE_SLIDE || + abs(touchState.deltaX) >= SLIDE_RANGE || + abs(touchState.deltaY) >= SLIDE_RANGE) { + touchState.event = TE_SLIDE; + touchState.x = touchData.points[0].x; + touchState.y = touchData.points[0].y; + } + } + } else { + if (touchState.event == TE_SLIDE) { + touchState.event = TE_SLIDE_END; + } else if (touchState.event == TE_DOWN) { + touchState.event = TE_UP; + } else if (touchState.event != TE_SLIDE_END) { + touchState.event = TE_NONE; } - } - } - else { - if (touchState.event == TE_SLIDE) { - touchState.event = TE_SLIDE_END; - } else if (touchState.event == TE_DOWN) { - touchState.event = TE_UP; - } else if (touchState.event != TE_SLIDE_END){ - touchState.event = TE_NONE; } } diff --git a/radio/src/targets/horus/tp_gt911.h b/radio/src/targets/horus/tp_gt911.h index edbf3fd57..1a3371d31 100644 --- a/radio/src/targets/horus/tp_gt911.h +++ b/radio/src/targets/horus/tp_gt911.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef _FT5X06_H_ -#define _FT5X06_H_ +#pragma once #define HAS_TOUCH_PANEL() touchGT911Flag == true @@ -29,6 +28,8 @@ extern bool touchPanelInit(); void touchPanelRead(); bool touchPanelEventOccured(); +#define GT911_TIMEOUT 20 // 20ms + #define GT911_MAX_TP 5 #define GT911_CFG_NUMER 0x6C @@ -81,5 +82,3 @@ PACK(struct TouchData { #define TPINT_LOW() do { TOUCH_INT_GPIO->BSRRH = TOUCH_INT_GPIO_PIN; } while(0) #define TPINT_HIGH() do { TOUCH_INT_GPIO->BSRRL = TOUCH_INT_GPIO_PIN; } while(0) - -#endif // _FT5X06_H_ \ No newline at end of file