diff --git a/source/Core/Inc/settingsGUI.hpp b/source/Core/Inc/settingsGUI.hpp index 6456da2a..4575ce98 100644 --- a/source/Core/Inc/settingsGUI.hpp +++ b/source/Core/Inc/settingsGUI.hpp @@ -36,7 +36,6 @@ typedef struct { } menuitem; void enterSettingsMenu(); -bool warnUser(const char *warning, const ButtonState buttons); extern const menuitem rootSettingsMenu[]; extern const menuitem *subSettingsMenus[]; diff --git a/source/Core/Src/settingsGUI.cpp b/source/Core/Src/settingsGUI.cpp index b9ded285..7ee9c2da 100644 --- a/source/Core/Src/settingsGUI.cpp +++ b/source/Core/Src/settingsGUI.cpp @@ -13,6 +13,7 @@ #include "cmsis_os.h" #include "configuration.h" #include "main.hpp" +#include "ui_drawing.hpp" #ifdef POW_DC static void displayInputVRange(void); diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 654e1d68..e60a50ef 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -26,6 +26,7 @@ extern "C" { #include "settingsGUI.hpp" #include "stdlib.h" #include "string.h" +#include "ui_drawing.hpp" #ifdef POW_PD #include "USBPD.h" #include "pd.h" @@ -216,7 +217,7 @@ void startGUITask(void const *argument) { OLED::setInverseDisplay(getSettingValue(SettingsOptions::OLEDInversion)); bool buttonLockout = false; - renderHomeScreenAssets(); + ui_pre_render_assets(); getTipRawTemp(1); // reset filter memset(&context, 0, sizeof(context)); diff --git a/source/Core/Threads/UI/drawing/mono_96x16/PrintVoltage.cpp b/source/Core/Threads/UI/drawing/mono_96x16/PrintVoltage.cpp new file mode 100644 index 00000000..fa21dd3a --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/PrintVoltage.cpp @@ -0,0 +1 @@ +#include "OperatingModeUtilities.h" diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_cjc_sampling.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_cjc_sampling.cpp new file mode 100644 index 00000000..f9c8de69 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_cjc_sampling.cpp @@ -0,0 +1,11 @@ +#include "ui_drawing.hpp" + +void ui_draw_cjc_sampling(const uint8_t num_dots) { + OLED::setCursor(0, 0); + OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL); + OLED::setCursor(0, 8); + OLED::print(SmallSymbolDot, FontStyle::SMALL); + for (uint8_t x = 0; x < num_dots; x++) { + OLED::print(SmallSymbolDot, FontStyle::SMALL); + } +} \ No newline at end of file diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_debug_menu.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_debug_menu.cpp new file mode 100644 index 00000000..05f1bdeb --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_debug_menu.cpp @@ -0,0 +1,92 @@ +#include "OperatingModes.h" +#include "TipThermoModel.h" +#include "main.hpp" +#include "ui_drawing.hpp" +extern osThreadId GUITaskHandle; +extern osThreadId MOVTaskHandle; +extern osThreadId PIDTaskHandle; + +void ui_draw_debug_menu(const uint8_t item_number) { + OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left) + OLED::print(SmallSymbolVersionNumber, FontStyle::SMALL); // Print version number + OLED::setCursor(0, 8); // second line + OLED::print(DebugMenu[item_number], FontStyle::SMALL); + switch (item_number) { + case 0: // Build Date + break; + case 1: // Device ID + { + uint64_t id = getDeviceID(); +#ifdef DEVICE_HAS_VALIDATION_CODE + // If device has validation code; then we want to take over both lines of the screen + OLED::clearScreen(); // Ensure the buffer starts clean + OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left) + OLED::print(DebugMenu[item_number], FontStyle::SMALL); + OLED::drawHex(getDeviceValidation(), FontStyle::SMALL, 8); + OLED::setCursor(0, 8); // second line +#endif + OLED::drawHex((uint32_t)(id >> 32), FontStyle::SMALL, 8); + OLED::drawHex((uint32_t)(id & 0xFFFFFFFF), FontStyle::SMALL, 8); + } break; + case 2: // ACC Type + OLED::print(AccelTypeNames[(int)DetectedAccelerometerVersion], FontStyle::SMALL); + break; + case 3: // Power Negotiation Status + OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL); + break; + case 4: // Input Voltage + printVoltage(); + break; + case 5: // Temp in °C + OLED::printNumber(TipThermoModel::getTipInC(), 6, FontStyle::SMALL); + break; + case 6: // Handle Temp in °C + OLED::printNumber(getHandleTemperature(0) / 10, 6, FontStyle::SMALL); + OLED::print(SmallSymbolDot, FontStyle::SMALL); + OLED::printNumber(getHandleTemperature(0) % 10, 1, FontStyle::SMALL); + break; + case 7: // Max Temp Limit in °C + OLED::printNumber(TipThermoModel::getTipMaxInC(), 6, FontStyle::SMALL); + break; + case 8: // System Uptime + OLED::printNumber(xTaskGetTickCount() / TICKS_100MS, 8, FontStyle::SMALL); + break; + case 9: // Movement Timestamp + OLED::printNumber(lastMovementTime / TICKS_100MS, 8, FontStyle::SMALL); + break; + case 10: // Tip Resistance in Ω + OLED::printNumber(getTipResistanceX10() / 10, 6, FontStyle::SMALL); // large to pad over so that we cover ID left overs + OLED::print(SmallSymbolDot, FontStyle::SMALL); + OLED::printNumber(getTipResistanceX10() % 10, 1, FontStyle::SMALL); + break; + case 11: // Raw Tip in µV + OLED::printNumber(TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0), true), 8, FontStyle::SMALL); + break; + case 12: // Tip Cold Junction Compensation Offset in µV + OLED::printNumber(getSettingValue(SettingsOptions::CalibrationOffset), 8, FontStyle::SMALL); + break; + case 13: // High Water Mark for GUI + OLED::printNumber(uxTaskGetStackHighWaterMark(GUITaskHandle), 8, FontStyle::SMALL); + break; + case 14: // High Water Mark for Movement Task + OLED::printNumber(uxTaskGetStackHighWaterMark(MOVTaskHandle), 8, FontStyle::SMALL); + break; + case 15: // High Water Mark for PID Task + OLED::printNumber(uxTaskGetStackHighWaterMark(PIDTaskHandle), 8, FontStyle::SMALL); + break; + break; +#ifdef HALL_SENSOR + case 16: // Raw Hall Effect Value + { + int16_t hallEffectStrength = getRawHallEffect(); + if (hallEffectStrength < 0) { + hallEffectStrength = -hallEffectStrength; + } + OLED::printNumber(hallEffectStrength, 6, FontStyle::SMALL); + } break; +#endif + + default: + break; + } +} \ No newline at end of file diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_detailed.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_detailed.cpp new file mode 100644 index 00000000..ec0bf8f7 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_detailed.cpp @@ -0,0 +1,55 @@ +#include "ui_drawing.hpp" + +extern uint8_t buttonAF[sizeof(buttonA)]; +extern uint8_t buttonBF[sizeof(buttonB)]; +extern uint8_t disconnectedTipF[sizeof(disconnectedTip)]; + +void ui_draw_homescreen_detailed(TemperatureType_t tipTemp) { + if (isTipDisconnected()) { + if (OLED::getRotation()) { + // in right handed mode we want to draw over the first part + OLED::drawArea(54, 0, 42, 16, disconnectedTipF); + } else { + OLED::drawArea(0, 0, 42, 16, disconnectedTip); + } + if (OLED::getRotation()) { + OLED::setCursor(-1, 0); + } else { + OLED::setCursor(42, 0); + } + uint32_t Vlt = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); + OLED::printNumber(Vlt / 10, 2, FontStyle::LARGE); + OLED::print(LargeSymbolDot, FontStyle::LARGE); + OLED::printNumber(Vlt % 10, 1, FontStyle::LARGE); + if (OLED::getRotation()) { + OLED::setCursor(48, 8); + } else { + OLED::setCursor(91, 8); + } + OLED::print(SmallSymbolVolts, FontStyle::SMALL); + } else { + if (!(getSettingValue(SettingsOptions::CoolingTempBlink) && (tipTemp > 55) && (xTaskGetTickCount() % 1000 < 300))) { + // Blink temp if setting enable and temp < 55° + // 1000 tick/sec + // OFF 300ms ON 700ms + ui_draw_tip_temperature(true, FontStyle::LARGE); // draw in the temp + } + if (OLED::getRotation()) { + OLED::setCursor(6, 0); + } else { + OLED::setCursor(73, 0); // top right + } + // draw set temp + OLED::printNumber(getSettingValue(SettingsOptions::SolderingTemp), 3, FontStyle::SMALL); + + OLED::printSymbolDeg(FontStyle::SMALL); + + if (OLED::getRotation()) { + OLED::setCursor(0, 8); + } else { + OLED::setCursor(67, 8); // bottom right + } + printVoltage(); // draw voltage then symbol (v) + OLED::print(SmallSymbolVolts, FontStyle::SMALL); + } +} \ No newline at end of file diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_simplified.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_simplified.cpp new file mode 100644 index 00000000..3e4733c5 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_homescreen_simplified.cpp @@ -0,0 +1,59 @@ +#include "ui_drawing.hpp" + +extern uint8_t buttonAF[sizeof(buttonA)]; +extern uint8_t buttonBF[sizeof(buttonB)]; +extern uint8_t disconnectedTipF[sizeof(disconnectedTip)]; + +void ui_draw_homescreen_simplified(TemperatureType_t tipTemp) { + bool tempOnDisplay = false; + bool tipDisconnectedDisplay = false; + if (OLED::getRotation()) { + OLED::drawArea(54, 0, 42, 16, buttonAF); + OLED::drawArea(12, 0, 42, 16, buttonBF); + OLED::setCursor(0, 0); + ui_draw_power_source_icon(); + } else { + OLED::drawArea(0, 0, 42, 16, buttonA); // Needs to be flipped so button ends up + OLED::drawArea(42, 0, 42, 16, buttonB); // on right side of screen + OLED::setCursor(84, 0); + ui_draw_power_source_icon(); + } + tipDisconnectedDisplay = false; + if (tipTemp > 55) { + tempOnDisplay = true; + } else if (tipTemp < 45) { + tempOnDisplay = false; + } + if (isTipDisconnected()) { + tempOnDisplay = false; + tipDisconnectedDisplay = true; + } + if (tempOnDisplay || tipDisconnectedDisplay) { + // draw temp over the start soldering button + // Location changes on screen rotation + if (OLED::getRotation()) { + // in right handed mode we want to draw over the first part + OLED::fillArea(55, 0, 41, 16, 0); // clear the area for the temp + OLED::setCursor(56, 0); + } else { + OLED::fillArea(0, 0, 41, 16, 0); // clear the area + OLED::setCursor(0, 0); + } + // If we have a tip connected draw the temp, if not we leave it blank + if (!tipDisconnectedDisplay) { + // draw in the temp + if (!(getSettingValue(SettingsOptions::CoolingTempBlink) && (xTaskGetTickCount() % 1000 < 300))) { + ui_draw_tip_temperature(false, FontStyle::LARGE); // draw in the temp + } + } else { + // Draw in missing tip symbol + + if (OLED::getRotation()) { + // in right handed mode we want to draw over the first part + OLED::drawArea(54, 0, 42, 16, disconnectedTipF); + } else { + OLED::drawArea(0, 0, 42, 16, disconnectedTip); + } + } + } +} diff --git a/source/Core/Threads/UI/logic/utils/drawPowerSourceIcon.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_power_source_icon.cpp similarity index 96% rename from source/Core/Threads/UI/logic/utils/drawPowerSourceIcon.cpp rename to source/Core/Threads/UI/drawing/mono_96x16/draw_power_source_icon.cpp index c296b533..fd7e07a0 100644 --- a/source/Core/Threads/UI/logic/utils/drawPowerSourceIcon.cpp +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_power_source_icon.cpp @@ -1,6 +1,6 @@ -#include "OperatingModeUtilities.h" +#include "ui_drawing.hpp" -void gui_drawBatteryIcon(void) { +void ui_draw_power_source_icon(void) { #if defined(POW_PD) || defined(POW_QC) || defined(POW_PD_EXT) if (!getIsPoweredByDCIN()) { // On non-DC inputs we replace this symbol with the voltage we are operating on diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_basic_status.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_basic_status.cpp new file mode 100644 index 00000000..1f29acfe --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_basic_status.cpp @@ -0,0 +1,42 @@ +#include "power.hpp" +#include "ui_drawing.hpp" + +void ui_draw_soldering_basic_status(bool boostModeOn) { + OLED::setCursor(0, 0); + // We switch the layout direction depending on the orientation of the oled + if (OLED::getRotation()) { + // battery + ui_draw_power_source_icon(); + // Space out gap between battery <-> temp + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + // Draw current tip temp + ui_draw_tip_temperature(true, FontStyle::LARGE); + + // We draw boost arrow if boosting, + // or else gap temp <-> heat indicator + if (boostModeOn) { + OLED::drawSymbol(2); + } else { + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + } + + // Draw heating/cooling symbols + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); + } else { + // Draw heating/cooling symbols + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); + // We draw boost arrow if boosting, + // or else gap temp <-> heat indicator + if (boostModeOn) { + OLED::drawSymbol(2); + } else { + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + } + // Draw current tip temp + ui_draw_tip_temperature(true, FontStyle::LARGE); + // Space out gap between battery <-> temp + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + + ui_draw_power_source_icon(); + } +} diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_power_status.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_power_status.cpp new file mode 100644 index 00000000..981a30d7 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_power_status.cpp @@ -0,0 +1,32 @@ +#include "power.hpp" +#include "ui_drawing.hpp" + +void ui_draw_soldering_power_status(void) { + if (OLED::getRotation()) { + OLED::setCursor(0, 0); + } else { + OLED::setCursor(67, 0); + } + // Print wattage + { + uint32_t x10Watt = x10WattHistory.average(); + if (x10Watt > 999) { + // If we exceed 99.9W we drop the decimal place to keep it all fitting + OLED::print(SmallSymbolSpace, FontStyle::SMALL); + OLED::printNumber(x10WattHistory.average() / 10, 3, FontStyle::SMALL); + } else { + OLED::printNumber(x10WattHistory.average() / 10, 2, FontStyle::SMALL); + OLED::print(SmallSymbolDot, FontStyle::SMALL); + OLED::printNumber(x10WattHistory.average() % 10, 1, FontStyle::SMALL); + } + OLED::print(SmallSymbolWatts, FontStyle::SMALL); + } + + if (OLED::getRotation()) { + OLED::setCursor(0, 8); + } else { + OLED::setCursor(67, 8); + } + printVoltage(); + OLED::print(SmallSymbolVolts, FontStyle::SMALL); +} \ No newline at end of file diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_sleep_mode.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_sleep_mode.cpp new file mode 100644 index 00000000..f2c02660 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_soldering_sleep_mode.cpp @@ -0,0 +1,34 @@ +#include "ui_drawing.hpp" + +void ui_draw_soldering_detailed_sleep(TemperatureType_t tipTemp) { + + OLED::clearScreen(); + OLED::setCursor(0, 0); + OLED::print(translatedString(Tr->SleepingAdvancedString), FontStyle::SMALL); + OLED::setCursor(0, 8); + OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL); + OLED::printNumber(tipTemp, 3, FontStyle::SMALL); + if (getSettingValue(SettingsOptions::TemperatureInF)) { + OLED::print(SmallSymbolDegF, FontStyle::SMALL); + } else { + OLED::print(SmallSymbolDegC, FontStyle::SMALL); + } + + OLED::print(SmallSymbolSpace, FontStyle::SMALL); + printVoltage(); + OLED::print(SmallSymbolVolts, FontStyle::SMALL); + + OLED::refresh(); +} + +void ui_draw_soldering_basic_sleep(TemperatureType_t tipTemp) { + + OLED::clearScreen(); + OLED::setCursor(0, 0); + + OLED::print(translatedString(Tr->SleepingSimpleString), FontStyle::LARGE); + OLED::printNumber(tipTemp, 3, FontStyle::LARGE); + OLED::printSymbolDeg(FontStyle::EXTRAS); + + OLED::refresh(); +} \ No newline at end of file diff --git a/source/Core/Threads/UI/logic/utils/DrawTipTemperature.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_tip_temperature.cpp similarity index 87% rename from source/Core/Threads/UI/logic/utils/DrawTipTemperature.cpp rename to source/Core/Threads/UI/drawing/mono_96x16/draw_tip_temperature.cpp index 8e3d7498..f9e8b794 100644 --- a/source/Core/Threads/UI/logic/utils/DrawTipTemperature.cpp +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_tip_temperature.cpp @@ -3,7 +3,7 @@ #include "SolderingCommon.h" #include "TipThermoModel.h" -void gui_drawTipTemp(bool symbol, const FontStyle font) { +void ui_draw_tip_temperature(bool symbol, const FontStyle font) { // Draw tip temp handling unit conversion & tolerance near setpoint TemperatureType_t Temp = getTipTemp(); diff --git a/source/Core/Threads/UI/drawing/mono_96x16/draw_warning_undervoltage.cpp b/source/Core/Threads/UI/drawing/mono_96x16/draw_warning_undervoltage.cpp new file mode 100644 index 00000000..acbad78c --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/draw_warning_undervoltage.cpp @@ -0,0 +1,20 @@ + +#include "ui_drawing.hpp" + +void ui_draw_warning_undervoltage(void) { + OLED::clearScreen(); + OLED::setCursor(0, 0); + if (getSettingValue(SettingsOptions::DetailedSoldering)) { + OLED::print(translatedString(Tr->UndervoltageString), FontStyle::SMALL); + OLED::setCursor(0, 8); + OLED::print(translatedString(Tr->InputVoltageString), FontStyle::SMALL); + printVoltage(); + OLED::print(SmallSymbolVolts, FontStyle::SMALL); + } else { + OLED::print(translatedString(Tr->UVLOWarningString), FontStyle::LARGE); + } + + OLED::refresh(); + GUIDelay(); + waitForButtonPress(); +} \ No newline at end of file diff --git a/source/Core/Threads/UI/drawing/mono_96x16/pre_render_assets.cpp b/source/Core/Threads/UI/drawing/mono_96x16/pre_render_assets.cpp new file mode 100644 index 00000000..cb41abd2 --- /dev/null +++ b/source/Core/Threads/UI/drawing/mono_96x16/pre_render_assets.cpp @@ -0,0 +1,17 @@ +#include "ui_drawing.hpp" + +uint8_t buttonAF[sizeof(buttonA)]; +uint8_t buttonBF[sizeof(buttonB)]; +uint8_t disconnectedTipF[sizeof(disconnectedTip)]; + +void ui_pre_render_assets(void) { + // Generate the flipped screen into ram for later use + // flipped is generated by flipping each row + for (int row = 0; row < 2; row++) { + for (int x = 0; x < 42; x++) { + buttonAF[(row * 42) + x] = buttonA[(row * 42) + (41 - x)]; + buttonBF[(row * 42) + x] = buttonB[(row * 42) + (41 - x)]; + disconnectedTipF[(row * 42) + x] = disconnectedTip[(row * 42) + (41 - x)]; + } + } +} \ No newline at end of file diff --git a/source/Core/Threads/UI/logic/utils/printSleepCountdown.cpp b/source/Core/Threads/UI/drawing/mono_96x16/printSleepCountdown.cpp similarity index 100% rename from source/Core/Threads/UI/logic/utils/printSleepCountdown.cpp rename to source/Core/Threads/UI/drawing/mono_96x16/printSleepCountdown.cpp diff --git a/source/Core/Threads/UI/logic/utils/PrintVoltage.cpp b/source/Core/Threads/UI/drawing/mono_96x16/print_voltage.cpp similarity index 88% rename from source/Core/Threads/UI/logic/utils/PrintVoltage.cpp rename to source/Core/Threads/UI/drawing/mono_96x16/print_voltage.cpp index ea7b8911..5b7d9605 100644 --- a/source/Core/Threads/UI/logic/utils/PrintVoltage.cpp +++ b/source/Core/Threads/UI/drawing/mono_96x16/print_voltage.cpp @@ -1,4 +1,4 @@ -#include "OperatingModeUtilities.h" +#include "ui_drawing.hpp" void printVoltage(void) { uint32_t volt = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); diff --git a/source/Core/Threads/UI/logic/utils/ShowWarning.cpp b/source/Core/Threads/UI/drawing/mono_96x16/show_warning.cpp similarity index 100% rename from source/Core/Threads/UI/logic/utils/ShowWarning.cpp rename to source/Core/Threads/UI/drawing/mono_96x16/show_warning.cpp diff --git a/source/Core/Threads/UI/drawing/ui_drawing.hpp b/source/Core/Threads/UI/drawing/ui_drawing.hpp new file mode 100644 index 00000000..443b5883 --- /dev/null +++ b/source/Core/Threads/UI/drawing/ui_drawing.hpp @@ -0,0 +1,26 @@ +#ifndef UI_DRAWING_UI_DRAWING_HPP_ +#define UI_DRAWING_UI_DRAWING_HPP_ +#include "Buttons.hpp" +#include "OLED.hpp" +#include "OperatingModeUtilities.h" +#include "configuration.h" +#include +#include +#include +void ui_draw_warning_undervoltage(void); +void ui_draw_power_source_icon(void); // Draw a single character wide power source icon +void ui_draw_tip_temperature(bool symbol, const FontStyle font); // Draw tip temp, aware of conversions +bool warnUser(const char *warning, const ButtonState buttons); // Print a full screen warning to the user +void ui_draw_cjc_sampling(const uint8_t num_dots); // Draws the CJC info text and progress dots +void ui_draw_debug_menu(const uint8_t item_number); // Draws the debug menu state +void ui_draw_homescreen_detailed(TemperatureType_t tipTemp); // Drawing the home screen -- Detailed mode +void ui_draw_homescreen_simplified(TemperatureType_t tipTemp); // Drawing the home screen -- Simple mode +void ui_pre_render_assets(void); // If any assets need to be pre-rendered into ram +// Soldering mode +void ui_draw_soldering_power_status(void); +void ui_draw_soldering_basic_status(bool boostModeOn); +void ui_draw_soldering_detailed_sleep(TemperatureType_t tipTemp); +void ui_draw_soldering_basic_sleep(TemperatureType_t tipTemp); +// Utils +void printVoltage(void); +#endif // UI_DRAWING_UI_DRAWING_HPP_ \ No newline at end of file diff --git a/source/Core/Threads/UI/logic/CJC.cpp b/source/Core/Threads/UI/logic/CJC.cpp index cacb5eb1..5c0c883b 100644 --- a/source/Core/Threads/UI/logic/CJC.cpp +++ b/source/Core/Threads/UI/logic/CJC.cpp @@ -1,6 +1,6 @@ - - #include "OperatingModes.h" +#include "ui_drawing.hpp" + OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt) { // Calibrate Cold Junction Compensation directly at boot, before internal components get warm. @@ -19,14 +19,7 @@ OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt) { cxt->scratch_state.state1++; cxt->scratch_state.state4 = xTaskGetTickCount(); } - OLED::setCursor(0, 0); - OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL); - OLED::setCursor(0, 8); - OLED::print(SmallSymbolDot, FontStyle::SMALL); - for (uint8_t x = 0; x < (cxt->scratch_state.state1 / 4); x++) { - OLED::print(SmallSymbolDot, FontStyle::SMALL); - } - + ui_draw_cjc_sampling(cxt->scratch_state.state1 / 4); return OperatingMode::CJCCalibration; } diff --git a/source/Core/Threads/UI/logic/DebugMenu.cpp b/source/Core/Threads/UI/logic/DebugMenu.cpp index a33e9ff8..840944bf 100644 --- a/source/Core/Threads/UI/logic/DebugMenu.cpp +++ b/source/Core/Threads/UI/logic/DebugMenu.cpp @@ -1,91 +1,9 @@ #include "OperatingModes.h" -extern osThreadId GUITaskHandle; -extern osThreadId MOVTaskHandle; -extern osThreadId PIDTaskHandle; +#include "ui_drawing.hpp" OperatingMode showDebugMenu(const ButtonState buttons, guiContext *cxt) { - OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left) - OLED::print(SmallSymbolVersionNumber, FontStyle::SMALL); // Print version number - OLED::setCursor(0, 8); // second line - OLED::print(DebugMenu[cxt->scratch_state.state1], FontStyle::SMALL); - switch (cxt->scratch_state.state1) { - case 0: // Build Date - break; - case 1: // Device ID - { - uint64_t id = getDeviceID(); -#ifdef DEVICE_HAS_VALIDATION_CODE - // If device has validation code; then we want to take over both lines of the screen - OLED::clearScreen(); // Ensure the buffer starts clean - OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left) - OLED::print(DebugMenu[cxt->scratch_state.state1], FontStyle::SMALL); - OLED::drawHex(getDeviceValidation(), FontStyle::SMALL, 8); - OLED::setCursor(0, 8); // second line -#endif - OLED::drawHex((uint32_t)(id >> 32), FontStyle::SMALL, 8); - OLED::drawHex((uint32_t)(id & 0xFFFFFFFF), FontStyle::SMALL, 8); - } break; - case 2: // ACC Type - OLED::print(AccelTypeNames[(int)DetectedAccelerometerVersion], FontStyle::SMALL); - break; - case 3: // Power Negotiation Status - OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL); - break; - case 4: // Input Voltage - printVoltage(); - break; - case 5: // Temp in °C - OLED::printNumber(TipThermoModel::getTipInC(), 6, FontStyle::SMALL); - break; - case 6: // Handle Temp in °C - OLED::printNumber(getHandleTemperature(0) / 10, 6, FontStyle::SMALL); - OLED::print(SmallSymbolDot, FontStyle::SMALL); - OLED::printNumber(getHandleTemperature(0) % 10, 1, FontStyle::SMALL); - break; - case 7: // Max Temp Limit in °C - OLED::printNumber(TipThermoModel::getTipMaxInC(), 6, FontStyle::SMALL); - break; - case 8: // System Uptime - OLED::printNumber(xTaskGetTickCount() / TICKS_100MS, 8, FontStyle::SMALL); - break; - case 9: // Movement Timestamp - OLED::printNumber(lastMovementTime / TICKS_100MS, 8, FontStyle::SMALL); - break; - case 10: // Tip Resistance in Ω - OLED::printNumber(getTipResistanceX10() / 10, 6, FontStyle::SMALL); // large to pad over so that we cover ID left overs - OLED::print(SmallSymbolDot, FontStyle::SMALL); - OLED::printNumber(getTipResistanceX10() % 10, 1, FontStyle::SMALL); - break; - case 11: // Raw Tip in µV - OLED::printNumber(TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0), true), 8, FontStyle::SMALL); - break; - case 12: // Tip Cold Junction Compensation Offset in µV - OLED::printNumber(getSettingValue(SettingsOptions::CalibrationOffset), 8, FontStyle::SMALL); - break; - case 13: // High Water Mark for GUI - OLED::printNumber(uxTaskGetStackHighWaterMark(GUITaskHandle), 8, FontStyle::SMALL); - break; - case 14: // High Water Mark for Movement Task - OLED::printNumber(uxTaskGetStackHighWaterMark(MOVTaskHandle), 8, FontStyle::SMALL); - break; - case 15: // High Water Mark for PID Task - OLED::printNumber(uxTaskGetStackHighWaterMark(PIDTaskHandle), 8, FontStyle::SMALL); - break; - break; -#ifdef HALL_SENSOR - case 16: // Raw Hall Effect Value - { - int16_t hallEffectStrength = getRawHallEffect(); - if (hallEffectStrength < 0) { - hallEffectStrength = -hallEffectStrength; - } - OLED::printNumber(hallEffectStrength, 6, FontStyle::SMALL); - } break; -#endif - default: - break; - } + ui_draw_debug_menu(cxt->scratch_state.state1); if (buttons == BUTTON_B_SHORT) { cxt->transitionMode = TransitionAnimation::Down; diff --git a/source/Core/Threads/UI/logic/HomeScreen.cpp b/source/Core/Threads/UI/logic/HomeScreen.cpp index 5672b38d..3be11340 100644 --- a/source/Core/Threads/UI/logic/HomeScreen.cpp +++ b/source/Core/Threads/UI/logic/HomeScreen.cpp @@ -1,24 +1,9 @@ #include "Buttons.hpp" #include "OperatingModes.h" +#include "ui_drawing.hpp" -uint8_t buttonAF[sizeof(buttonA)]; -uint8_t buttonBF[sizeof(buttonB)]; -uint8_t disconnectedTipF[sizeof(disconnectedTip)]; -bool showExitMenuTransition = false; - -void renderHomeScreenAssets(void) { - - // Generate the flipped screen into ram for later use - // flipped is generated by flipping each row - for (int row = 0; row < 2; row++) { - for (int x = 0; x < 42; x++) { - buttonAF[(row * 42) + x] = buttonA[(row * 42) + (41 - x)]; - buttonBF[(row * 42) + x] = buttonB[(row * 42) + (41 - x)]; - disconnectedTipF[(row * 42) + x] = disconnectedTip[(row * 42) + (41 - x)]; - } - } -} +bool showExitMenuTransition = false; OperatingMode handleHomeButtons(const ButtonState buttons, guiContext *cxt) { if (buttons != BUTTON_NONE && cxt->scratch_state.state1 == 0) { @@ -66,108 +51,6 @@ OperatingMode handleHomeButtons(const ButtonState buttons, guiContext *cxt) { return OperatingMode::HomeScreen; } -void drawDetailedHomeScreen(uint32_t tipTemp) { - if (isTipDisconnected()) { - if (OLED::getRotation()) { - // in right handed mode we want to draw over the first part - OLED::drawArea(54, 0, 42, 16, disconnectedTipF); - } else { - OLED::drawArea(0, 0, 42, 16, disconnectedTip); - } - if (OLED::getRotation()) { - OLED::setCursor(-1, 0); - } else { - OLED::setCursor(42, 0); - } - uint32_t Vlt = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); - OLED::printNumber(Vlt / 10, 2, FontStyle::LARGE); - OLED::print(LargeSymbolDot, FontStyle::LARGE); - OLED::printNumber(Vlt % 10, 1, FontStyle::LARGE); - if (OLED::getRotation()) { - OLED::setCursor(48, 8); - } else { - OLED::setCursor(91, 8); - } - OLED::print(SmallSymbolVolts, FontStyle::SMALL); - } else { - if (!(getSettingValue(SettingsOptions::CoolingTempBlink) && (tipTemp > 55) && (xTaskGetTickCount() % 1000 < 300))) { - // Blink temp if setting enable and temp < 55° - // 1000 tick/sec - // OFF 300ms ON 700ms - gui_drawTipTemp(true, FontStyle::LARGE); // draw in the temp - } - if (OLED::getRotation()) { - OLED::setCursor(6, 0); - } else { - OLED::setCursor(73, 0); // top right - } - // draw set temp - OLED::printNumber(getSettingValue(SettingsOptions::SolderingTemp), 3, FontStyle::SMALL); - - OLED::printSymbolDeg(FontStyle::SMALL); - - if (OLED::getRotation()) { - OLED::setCursor(0, 8); - } else { - OLED::setCursor(67, 8); // bottom right - } - printVoltage(); // draw voltage then symbol (v) - OLED::print(SmallSymbolVolts, FontStyle::SMALL); - } -} -void drawSimplifiedHomeScreen(uint32_t tipTemp) { - bool tempOnDisplay = false; - bool tipDisconnectedDisplay = false; - if (OLED::getRotation()) { - OLED::drawArea(54, 0, 42, 16, buttonAF); - OLED::drawArea(12, 0, 42, 16, buttonBF); - OLED::setCursor(0, 0); - gui_drawBatteryIcon(); - } else { - OLED::drawArea(0, 0, 42, 16, buttonA); // Needs to be flipped so button ends up - OLED::drawArea(42, 0, 42, 16, buttonB); // on right side of screen - OLED::setCursor(84, 0); - gui_drawBatteryIcon(); - } - tipDisconnectedDisplay = false; - if (tipTemp > 55) { - tempOnDisplay = true; - } else if (tipTemp < 45) { - tempOnDisplay = false; - } - if (isTipDisconnected()) { - tempOnDisplay = false; - tipDisconnectedDisplay = true; - } - if (tempOnDisplay || tipDisconnectedDisplay) { - // draw temp over the start soldering button - // Location changes on screen rotation - if (OLED::getRotation()) { - // in right handed mode we want to draw over the first part - OLED::fillArea(55, 0, 41, 16, 0); // clear the area for the temp - OLED::setCursor(56, 0); - } else { - OLED::fillArea(0, 0, 41, 16, 0); // clear the area - OLED::setCursor(0, 0); - } - // If we have a tip connected draw the temp, if not we leave it blank - if (!tipDisconnectedDisplay) { - // draw in the temp - if (!(getSettingValue(SettingsOptions::CoolingTempBlink) && (xTaskGetTickCount() % 1000 < 300))) { - gui_drawTipTemp(false, FontStyle::LARGE); // draw in the temp - } - } else { - // Draw in missing tip symbol - - if (OLED::getRotation()) { - // in right handed mode we want to draw over the first part - OLED::drawArea(54, 0, 42, 16, disconnectedTipF); - } else { - OLED::drawArea(0, 0, 42, 16, disconnectedTip); - } - } - } -} OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt) { currentTempTargetDegC = 0; // ensure tip is off @@ -181,9 +64,9 @@ OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt) { OLED::setCursor(-1, 0); } if (getSettingValue(SettingsOptions::DetailedIDLE)) { - drawDetailedHomeScreen(tipTemp); + ui_draw_homescreen_detailed(tipTemp); } else { - drawSimplifiedHomeScreen(tipTemp); + ui_draw_homescreen_simplified(tipTemp); } return handleHomeButtons(buttons, cxt); } diff --git a/source/Core/Threads/UI/logic/OperatingModes.h b/source/Core/Threads/UI/logic/OperatingModes.h index f499b0cc..5387f64a 100644 --- a/source/Core/Threads/UI/logic/OperatingModes.h +++ b/source/Core/Threads/UI/logic/OperatingModes.h @@ -80,8 +80,7 @@ OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt); OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt); // Shows user warnings if required // Common helpers -int8_t getPowerSourceNumber(void); // Returns number ID of power source -void renderHomeScreenAssets(void); // Called to act as start delay and used to render out flipped images for home screen graphics +int8_t getPowerSourceNumber(void); // Returns number ID of power source extern bool heaterThermalRunaway; #endif diff --git a/source/Core/Threads/UI/logic/ShowStartupWarnings.cpp b/source/Core/Threads/UI/logic/ShowStartupWarnings.cpp index b4f8355b..238bac6f 100644 --- a/source/Core/Threads/UI/logic/ShowStartupWarnings.cpp +++ b/source/Core/Threads/UI/logic/ShowStartupWarnings.cpp @@ -1,6 +1,7 @@ #include "FS2711.hpp" #include "HUB238.hpp" #include "OperatingModes.h" +#include "ui_drawing.hpp" OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt) { // Display alert if settings were reset diff --git a/source/Core/Threads/UI/logic/Sleep.cpp b/source/Core/Threads/UI/logic/Sleep.cpp index 36772dbc..dad421ff 100644 --- a/source/Core/Threads/UI/logic/Sleep.cpp +++ b/source/Core/Threads/UI/logic/Sleep.cpp @@ -1,5 +1,5 @@ #include "OperatingModes.h" - +#include "ui_drawing.hpp" OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *cxt) { #ifdef NO_SLEEP_MODE return OperatingMode::Soldering; @@ -28,31 +28,12 @@ OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *c // draw the lcd uint16_t tipTemp = getSettingValue(SettingsOptions::TemperatureInF) ? TipThermoModel::getTipInF() : TipThermoModel::getTipInC(); - OLED::clearScreen(); - OLED::setCursor(0, 0); if (getSettingValue(SettingsOptions::DetailedSoldering)) { - OLED::print(translatedString(Tr->SleepingAdvancedString), FontStyle::SMALL); - OLED::setCursor(0, 8); - OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL); - OLED::printNumber(tipTemp, 3, FontStyle::SMALL); - if (getSettingValue(SettingsOptions::TemperatureInF)) { - OLED::print(SmallSymbolDegF, FontStyle::SMALL); - } else { - OLED::print(SmallSymbolDegC, FontStyle::SMALL); - } - - OLED::print(SmallSymbolSpace, FontStyle::SMALL); - printVoltage(); - OLED::print(SmallSymbolVolts, FontStyle::SMALL); + ui_draw_soldering_detailed_sleep(tipTemp); } else { - OLED::print(LargeSymbolSleep, FontStyle::LARGE); - OLED::printNumber(tipTemp, 3, FontStyle::LARGE); - OLED::printSymbolDeg(FontStyle::EXTRAS); + ui_draw_soldering_basic_sleep(tipTemp); } - OLED::refresh(); - GUIDelay(); - if (!shouldBeSleeping()) { return cxt->previousMode; } diff --git a/source/Core/Threads/UI/logic/Soldering.cpp b/source/Core/Threads/UI/logic/Soldering.cpp index 0a648889..b065a927 100644 --- a/source/Core/Threads/UI/logic/Soldering.cpp +++ b/source/Core/Threads/UI/logic/Soldering.cpp @@ -1,6 +1,7 @@ #include "OperatingModes.h" #include "SolderingCommon.h" +#include "ui_drawing.hpp" // State 1 = button locking // State 2 = boost mode // State 3 = buzzer timer @@ -113,7 +114,7 @@ OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) { OLED::setCursor(-1, 0); } - gui_drawTipTemp(true, FontStyle::LARGE); + ui_draw_tip_temperature(true, FontStyle::LARGE); if (cxt->scratch_state.state2) { // Boost mode is on if (OLED::getRotation()) { @@ -141,10 +142,10 @@ OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) { OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL, 2); } - detailedPowerStatus(); + ui_draw_soldering_power_status(); } else { - basicSolderingStatus(cxt->scratch_state.state2); + ui_draw_soldering_basic_status(cxt->scratch_state.state2); } // Check if we should bail due to undervoltage for example if (checkExitSoldering()) { diff --git a/source/Core/Threads/UI/logic/SolderingProfile.cpp b/source/Core/Threads/UI/logic/SolderingProfile.cpp index 1bbc133f..77ad8333 100644 --- a/source/Core/Threads/UI/logic/SolderingProfile.cpp +++ b/source/Core/Threads/UI/logic/SolderingProfile.cpp @@ -1,6 +1,7 @@ #include "OperatingModes.h" #include "SolderingCommon.h" +#include "ui_drawing.hpp" OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt) { /* @@ -178,10 +179,10 @@ OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cx } } - detailedPowerStatus(); + ui_draw_soldering_power_status(); } else { - basicSolderingStatus(false); + ui_draw_soldering_basic_status(false); } // Update the setpoints for the temperature diff --git a/source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h b/source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h index e204adf3..dccbec2c 100644 --- a/source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h +++ b/source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h @@ -4,16 +4,13 @@ #include "OLED.hpp" #include -void GUIDelay(); // -bool checkForUnderVoltage(void); // -uint32_t getSleepTimeout(void); // -bool shouldBeSleeping(); // -bool shouldShutdown(void); // -void gui_drawTipTemp(bool symbol, const FontStyle font); // -void printVoltage(void); // -bool warnUser(const char *warning, const ButtonState buttons); // -void gui_drawBatteryIcon(void); // -bool checkForUnderVoltage(void); // -uint16_t min(uint16_t a, uint16_t b); // -void printCountdownUntilSleep(int sleepThres); // +void GUIDelay(); // +bool checkForUnderVoltage(void); // +uint32_t getSleepTimeout(void); // +bool shouldBeSleeping(); // +bool shouldShutdown(void); // +void printVoltage(void); // +bool checkForUnderVoltage(void); // +uint16_t min(uint16_t a, uint16_t b); // +void printCountdownUntilSleep(int sleepThres); // #endif \ No newline at end of file diff --git a/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp b/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp index 08371648..9425c90f 100644 --- a/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp +++ b/source/Core/Threads/UI/logic/utils/SolderingCommon.cpp @@ -7,79 +7,10 @@ #include "Types.h" #include "configuration.h" #include "history.hpp" +#include "ui_drawing.hpp" extern bool heaterThermalRunaway; -void detailedPowerStatus() { - if (OLED::getRotation()) { - OLED::setCursor(0, 0); - } else { - OLED::setCursor(67, 0); - } - // Print wattage - { - uint32_t x10Watt = x10WattHistory.average(); - if (x10Watt > 999) { - // If we exceed 99.9W we drop the decimal place to keep it all fitting - OLED::print(SmallSymbolSpace, FontStyle::SMALL); - OLED::printNumber(x10WattHistory.average() / 10, 3, FontStyle::SMALL); - } else { - OLED::printNumber(x10WattHistory.average() / 10, 2, FontStyle::SMALL); - OLED::print(SmallSymbolDot, FontStyle::SMALL); - OLED::printNumber(x10WattHistory.average() % 10, 1, FontStyle::SMALL); - } - OLED::print(SmallSymbolWatts, FontStyle::SMALL); - } - - if (OLED::getRotation()) { - OLED::setCursor(0, 8); - } else { - OLED::setCursor(67, 8); - } - printVoltage(); - OLED::print(SmallSymbolVolts, FontStyle::SMALL); -} - -void basicSolderingStatus(bool boostModeOn) { - OLED::setCursor(0, 0); - // We switch the layout direction depending on the orientation of the oled - if (OLED::getRotation()) { - // battery - gui_drawBatteryIcon(); - // Space out gap between battery <-> temp - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - // Draw current tip temp - gui_drawTipTemp(true, FontStyle::LARGE); - - // We draw boost arrow if boosting, - // or else gap temp <-> heat indicator - if (boostModeOn) { - OLED::drawSymbol(2); - } else { - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - } - - // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); - } else { - // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); - // We draw boost arrow if boosting, - // or else gap temp <-> heat indicator - if (boostModeOn) { - OLED::drawSymbol(2); - } else { - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - } - // Draw current tip temp - gui_drawTipTemp(true, FontStyle::LARGE); - // Space out gap between battery <-> temp - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - - gui_drawBatteryIcon(); - } -} - bool checkExitSoldering(void) { #ifdef POW_DC // Undervoltage test diff --git a/source/Core/Threads/UI/logic/utils/SolderingCommon.h b/source/Core/Threads/UI/logic/utils/SolderingCommon.h index 42f3765e..43d29240 100644 --- a/source/Core/Threads/UI/logic/utils/SolderingCommon.h +++ b/source/Core/Threads/UI/logic/utils/SolderingCommon.h @@ -3,8 +3,6 @@ #ifndef SOLDERING_COMMON_H_ #define SOLDERING_COMMON_H_ -void detailedPowerStatus(); -void basicSolderingStatus(bool boostModeOn); bool checkExitSoldering(); TemperatureType_t getTipTemp(void); diff --git a/source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp b/source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp index 158e8842..7580acd7 100644 --- a/source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp +++ b/source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp @@ -1,6 +1,7 @@ #include "Buttons.hpp" #include "OperatingModeUtilities.h" #include "configuration.h" +#include "ui_drawing.hpp" #ifdef POW_DC extern volatile TemperatureType_t currentTempTargetDegC; // returns true if undervoltage has occured @@ -15,21 +16,7 @@ bool checkForUnderVoltage(void) { if (xTaskGetTickCount() > (TICKS_SECOND * 2)) { if ((v < lookupVoltageLevel())) { currentTempTargetDegC = 0; - OLED::clearScreen(); - OLED::setCursor(0, 0); - if (getSettingValue(SettingsOptions::DetailedSoldering)) { - OLED::print(translatedString(Tr->UndervoltageString), FontStyle::SMALL); - OLED::setCursor(0, 8); - OLED::print(translatedString(Tr->InputVoltageString), FontStyle::SMALL); - printVoltage(); - OLED::print(SmallSymbolVolts, FontStyle::SMALL); - } else { - OLED::print(translatedString(Tr->UVLOWarningString), FontStyle::LARGE); - } - - OLED::refresh(); - GUIDelay(); - waitForButtonPress(); + ui_draw_warning_undervoltage(); return true; } }