mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
42
source/Core/Threads/UI/logic/CJC.cpp
Normal file
42
source/Core/Threads/UI/logic/CJC.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#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.
|
||||
|
||||
// While we wait for the pre-start checks to finish, we cant run CJC (as the pre-start checks control the tip)
|
||||
if (preStartChecks() == 0) {
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL);
|
||||
return OperatingMode::CJCCalibration;
|
||||
}
|
||||
|
||||
if (!isTipDisconnected() && abs(int(TipThermoModel::getTipInC() - getHandleTemperature(0) / 10)) < 10) {
|
||||
// Take 16 samples, only sample
|
||||
if (cxt->scratch_state.state1 < 16) {
|
||||
if ((xTaskGetTickCount() - cxt->scratch_state.state4) > TICKS_100MS) {
|
||||
cxt->scratch_state.state3 += getTipRawTemp(1);
|
||||
cxt->scratch_state.state1++;
|
||||
cxt->scratch_state.state4 = xTaskGetTickCount();
|
||||
}
|
||||
ui_draw_cjc_sampling(cxt->scratch_state.state1 / 4);
|
||||
return OperatingMode::CJCCalibration;
|
||||
}
|
||||
|
||||
// If the thermo-couple at the end of the tip, and the handle are at
|
||||
// equilibrium, then the output should be zero, as there is no temperature
|
||||
// differential.
|
||||
|
||||
uint16_t setOffset = TipThermoModel::convertTipRawADCTouV(cxt->scratch_state.state3 / 16, true);
|
||||
setSettingValue(SettingsOptions::CalibrationOffset, setOffset);
|
||||
if (warnUser(translatedString(Tr->CalibrationDone), buttons)) {
|
||||
// Preventing to repeat calibration at boot automatically (only one shot).
|
||||
setSettingValue(SettingsOptions::CalibrateCJC, 0);
|
||||
saveSettings();
|
||||
return OperatingMode::InitialisationDone;
|
||||
}
|
||||
return OperatingMode::CJCCalibration;
|
||||
}
|
||||
// Cant run calibration without the tip and for temps to be close
|
||||
return OperatingMode::StartupWarnings;
|
||||
}
|
||||
20
source/Core/Threads/UI/logic/DebugMenu.cpp
Normal file
20
source/Core/Threads/UI/logic/DebugMenu.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
OperatingMode showDebugMenu(const ButtonState buttons, guiContext *cxt) {
|
||||
|
||||
ui_draw_debug_menu(cxt->scratch_state.state1);
|
||||
|
||||
if (buttons == BUTTON_B_SHORT) {
|
||||
cxt->transitionMode = TransitionAnimation::Down;
|
||||
return OperatingMode::HomeScreen;
|
||||
} else if (buttons == BUTTON_F_SHORT) {
|
||||
cxt->scratch_state.state1++;
|
||||
#ifdef HALL_SENSOR
|
||||
cxt->scratch_state.state1 = cxt->scratch_state.state1 % 17;
|
||||
#else
|
||||
cxt->scratch_state.state1 = cxt->scratch_state.state1 % 16;
|
||||
#endif
|
||||
}
|
||||
return OperatingMode::DebugMenuReadout; // Stay in debug menu
|
||||
}
|
||||
72
source/Core/Threads/UI/logic/HomeScreen.cpp
Normal file
72
source/Core/Threads/UI/logic/HomeScreen.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
#include "Buttons.hpp"
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
bool showExitMenuTransition = false;
|
||||
|
||||
OperatingMode handleHomeButtons(const ButtonState buttons, guiContext *cxt) {
|
||||
if (buttons != BUTTON_NONE && cxt->scratch_state.state1 == 0) {
|
||||
return OperatingMode::HomeScreen; // Ignore button press
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 1;
|
||||
}
|
||||
switch (buttons) {
|
||||
case BUTTON_NONE:
|
||||
// Do nothing
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
break;
|
||||
|
||||
case BUTTON_B_LONG:
|
||||
cxt->transitionMode = TransitionAnimation::Up;
|
||||
return OperatingMode::DebugMenuReadout;
|
||||
break;
|
||||
case BUTTON_F_LONG:
|
||||
#ifdef PROFILE_SUPPORT
|
||||
if (!isTipDisconnected()) {
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::SolderingProfile;
|
||||
} else {
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
#else
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::TemperatureAdjust;
|
||||
#endif
|
||||
break;
|
||||
case BUTTON_F_SHORT:
|
||||
if (!isTipDisconnected()) {
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::Soldering;
|
||||
}
|
||||
break;
|
||||
case BUTTON_B_SHORT:
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::SettingsMenu;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
|
||||
OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt) {
|
||||
|
||||
currentTempTargetDegC = 0; // ensure tip is off
|
||||
getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0);
|
||||
uint32_t tipTemp = TipThermoModel::getTipInC();
|
||||
|
||||
// Setup LCD Cursor location
|
||||
if (OLED::getRotation()) {
|
||||
OLED::setCursor(50, 0);
|
||||
} else {
|
||||
OLED::setCursor(-1, 0);
|
||||
}
|
||||
if (getSettingValue(SettingsOptions::DetailedIDLE)) {
|
||||
ui_draw_homescreen_detailed(tipTemp);
|
||||
} else {
|
||||
ui_draw_homescreen_simplified(tipTemp);
|
||||
}
|
||||
return handleHomeButtons(buttons, cxt);
|
||||
}
|
||||
5
source/Core/Threads/UI/logic/OperatingModes.cpp
Normal file
5
source/Core/Threads/UI/logic/OperatingModes.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Thomas White on 3/02/2023.
|
||||
//
|
||||
|
||||
#include "OperatingModes.h"
|
||||
90
source/Core/Threads/UI/logic/OperatingModes.h
Normal file
90
source/Core/Threads/UI/logic/OperatingModes.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef OPERATING_MODES_H_
|
||||
#define OPERATING_MODES_H_
|
||||
|
||||
extern "C" {
|
||||
#include "FreeRTOSConfig.h"
|
||||
}
|
||||
#include "Buttons.hpp"
|
||||
#include "OLED.hpp"
|
||||
#include "OperatingModeUtilities.h"
|
||||
#include "Settings.h"
|
||||
#include "TipThermoModel.h"
|
||||
#include "Translation.h"
|
||||
#include "Types.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "configuration.h"
|
||||
#include "history.hpp"
|
||||
#include "main.hpp"
|
||||
#include "power.hpp"
|
||||
#include "settingsGUI.hpp"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#ifdef POW_PD
|
||||
#include "USBPD.h"
|
||||
#include "pd.h"
|
||||
#endif
|
||||
#if POW_PD_EXT == 2
|
||||
#include "FS2711.hpp"
|
||||
#include "FS2711_defines.h"
|
||||
#endif
|
||||
|
||||
enum class OperatingMode {
|
||||
StartupLogo = 0, // Showing the startup logo
|
||||
CJCCalibration, // Cold Junction Calibration
|
||||
StartupWarnings, // Startup checks and warnings
|
||||
InitialisationDone, // Special state we use just before we to home screen at first startup. Allows jumping to extra startup states
|
||||
HomeScreen, // Home/Idle screen that is the main launchpad to other modes
|
||||
Soldering, // Main soldering operating mode
|
||||
SolderingProfile, // Soldering by following a profile, used for reflow for example
|
||||
Sleeping, // Sleep state holds iron at lower sleep temp
|
||||
Hibernating, // Like sleeping but keeps heater fully off until woken
|
||||
SettingsMenu, // Settings Menu
|
||||
DebugMenuReadout, // Debug metrics
|
||||
TemperatureAdjust, // Set point temperature adjustment
|
||||
UsbPDDebug, // USB PD debugging information
|
||||
ThermalRunaway, // Thermal Runaway warning state.
|
||||
};
|
||||
|
||||
enum class TransitionAnimation {
|
||||
None = 0,
|
||||
Right = 1,
|
||||
Left = 2,
|
||||
Down = 3,
|
||||
Up = 4,
|
||||
};
|
||||
|
||||
// Generic context struct used for gui functions to be able to retain state
|
||||
struct guiContext {
|
||||
TickType_t viewEnterTime; // Set to ticks when this view state was first entered
|
||||
OperatingMode previousMode;
|
||||
TransitionAnimation transitionMode;
|
||||
// Below is scratch state, this is retained over re-draws but blown away on state change
|
||||
struct scratch {
|
||||
uint16_t state1; // 16 bit state scratch
|
||||
uint16_t state2; // 16 bit state scratch
|
||||
uint32_t state3; // 32 bit state scratch
|
||||
uint32_t state4; // 32 bit state scratch
|
||||
uint16_t state5; // 16 bit state scratch
|
||||
uint16_t state6; // 16 bit state scratch
|
||||
|
||||
} scratch_state;
|
||||
};
|
||||
|
||||
// Main functions
|
||||
OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *cxt); // Sleep mode
|
||||
OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt); // Main mode for hot pointy tool
|
||||
OperatingMode gui_solderingTempAdjust(const ButtonState buttons, guiContext *cxt); // For adjusting the setpoint temperature of the iron
|
||||
OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt); // IDLE / Home screen
|
||||
OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt); //
|
||||
|
||||
OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt); // Profile mode for hot likely-not-so-pointy tool
|
||||
OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt); // Used to calibrate the Cold Junction offset
|
||||
OperatingMode showDebugMenu(const ButtonState buttons, guiContext *cxt); // Debugging values
|
||||
OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt); // Debugging menu that shows PD adaptor info
|
||||
OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt); // Shows user warnings if required
|
||||
|
||||
// Common helpers
|
||||
int8_t getPowerSourceNumber(void); // Returns number ID of power source
|
||||
|
||||
extern bool heaterThermalRunaway;
|
||||
#endif
|
||||
275
source/Core/Threads/UI/logic/SettingsMenu.cpp
Normal file
275
source/Core/Threads/UI/logic/SettingsMenu.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
#include "OperatingModes.h"
|
||||
#include "ScrollMessage.hpp"
|
||||
|
||||
#define HELP_TEXT_TIMEOUT_TICKS (TICKS_SECOND * 3)
|
||||
/*
|
||||
* The settings menu is the most complex bit of GUI code we have
|
||||
* The menu consists of a two tier menu
|
||||
* Main menu -> Categories
|
||||
* Secondary menu -> Settings
|
||||
*
|
||||
* For each entry in the menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints two small lines (or one line for CJK) of short description for
|
||||
* setting items and prepares cursor after it.
|
||||
* @param settingsItemIndex Index of the setting item.
|
||||
* @param cursorCharPosition Custom cursor char position to set after printing
|
||||
* description.
|
||||
*/
|
||||
static void printShortDescription(SettingsItemIndex settingsItemIndex, uint16_t cursorCharPosition) {
|
||||
// print short description (default single line, explicit double line)
|
||||
uint8_t shortDescIndex = static_cast<uint8_t>(settingsItemIndex);
|
||||
OLED::printWholeScreen(translatedString(Tr->SettingsShortNames[shortDescIndex]));
|
||||
|
||||
// prepare cursor for value
|
||||
// make room for scroll indicator
|
||||
OLED::setCursor(cursorCharPosition * FONT_12_WIDTH - 2, 0);
|
||||
}
|
||||
|
||||
// Render a menu, based on the position given
|
||||
// This will either draw the menu item, or the help text depending on how long its been since button press
|
||||
void render_menu(const menuitem *item, guiContext *cxt) {
|
||||
// If recent interaction or not help text draw the entry
|
||||
if ((xTaskGetTickCount() - lastButtonTime < HELP_TEXT_TIMEOUT_TICKS) || item->description == 0) {
|
||||
|
||||
if (item->shortDescriptionSize > 0) {
|
||||
printShortDescription(item->shortDescriptionIndex, item->shortDescriptionSize);
|
||||
}
|
||||
item->draw();
|
||||
} else {
|
||||
|
||||
uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
|
||||
*isRenderingHelp = 1;
|
||||
// Draw description
|
||||
const char *description = translatedString(Tr->SettingsDescriptions[item->description - 1]);
|
||||
drawScrollingText(description, (xTaskGetTickCount() - lastButtonTime) - HELP_TEXT_TIMEOUT_TICKS);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getMenuLength(const menuitem *menu, const uint16_t stop) {
|
||||
// walk this menu to find the length
|
||||
uint16_t counter = 0;
|
||||
for (uint16_t pos = 0; pos < stop; pos++) {
|
||||
// End of list
|
||||
if (menu[pos].draw == nullptr) {
|
||||
return counter;
|
||||
}
|
||||
// Otherwise increment for each visible item (null == always, or if not check function)
|
||||
if (menu[pos].isVisible == nullptr || menu[pos].isVisible()) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
OperatingMode moveToNextEntry(guiContext *cxt) {
|
||||
uint16_t *mainEntry = &(cxt->scratch_state.state1);
|
||||
uint16_t *subEntry = &(cxt->scratch_state.state2);
|
||||
uint16_t *currentMenuLength = &(cxt->scratch_state.state5);
|
||||
uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
|
||||
|
||||
if (*isRenderingHelp) {
|
||||
*isRenderingHelp = 0;
|
||||
} else {
|
||||
*currentMenuLength = 0; // Reset menu length
|
||||
// Scroll down
|
||||
// We can increment freely _once_
|
||||
cxt->transitionMode = TransitionAnimation::Down;
|
||||
if (*subEntry == 0) {
|
||||
(*mainEntry) += 1;
|
||||
|
||||
if (rootSettingsMenu[*mainEntry].draw == nullptr) {
|
||||
// We are off the end of the menu now
|
||||
saveSettings();
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
// Check if visible
|
||||
if (rootSettingsMenu[*mainEntry].isVisible != nullptr && !rootSettingsMenu[*mainEntry].isVisible()) {
|
||||
// We need to move on as this one isn't visible
|
||||
return moveToNextEntry(cxt);
|
||||
}
|
||||
} else {
|
||||
(*subEntry) += 1;
|
||||
|
||||
// If the new entry is null, we need to exit
|
||||
if (subSettingsMenus[*mainEntry][(*subEntry) - 1].draw == nullptr) {
|
||||
(*subEntry) = 0; // Reset back to the main menu
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
// Have to break early to avoid the below check underflowing
|
||||
return OperatingMode::SettingsMenu;
|
||||
}
|
||||
// Check if visible
|
||||
if (subSettingsMenus[*mainEntry][(*subEntry) - 1].isVisible != nullptr && !subSettingsMenus[*mainEntry][(*subEntry) - 1].isVisible()) {
|
||||
// We need to move on as this one isn't visible
|
||||
return moveToNextEntry(cxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return OperatingMode::SettingsMenu;
|
||||
}
|
||||
|
||||
OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt) {
|
||||
// Render out the current settings menu
|
||||
// State 1 -> Root menu
|
||||
// State 2 -> Sub entry
|
||||
// Draw main entry if sub-entry is 0, otherwise draw sub-entry
|
||||
|
||||
uint16_t *mainEntry = &(cxt->scratch_state.state1);
|
||||
uint16_t *subEntry = &(cxt->scratch_state.state2);
|
||||
uint32_t *autoRepeatAcceleration = &(cxt->scratch_state.state3);
|
||||
uint32_t *autoRepeatTimer = &(cxt->scratch_state.state4);
|
||||
uint16_t *currentMenuLength = &(cxt->scratch_state.state5);
|
||||
uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
|
||||
|
||||
const menuitem *currentMenu;
|
||||
// Draw the currently on screen item
|
||||
uint16_t currentScreen;
|
||||
if (*subEntry == 0) {
|
||||
// Drawing main menu
|
||||
currentMenu = rootSettingsMenu;
|
||||
currentScreen = *mainEntry;
|
||||
} else {
|
||||
// Drawing sub menu
|
||||
currentMenu = subSettingsMenus[*mainEntry];
|
||||
currentScreen = (*subEntry) - 1;
|
||||
}
|
||||
render_menu(&(currentMenu[currentScreen]), cxt);
|
||||
|
||||
// Update the cached menu length if unknown
|
||||
if (*currentMenuLength == 0) {
|
||||
// We walk the current menu to find the length
|
||||
*currentMenuLength = getMenuLength(currentMenu, 128 /* Max length of any menu*/);
|
||||
}
|
||||
|
||||
if (*isRenderingHelp == 0) {
|
||||
// Draw scroll
|
||||
|
||||
// Get virtual pos by counting entries from start to _here_
|
||||
uint16_t currentVirtualPosition = getMenuLength(currentMenu, currentScreen + 1);
|
||||
if (currentVirtualPosition > 0) {
|
||||
currentVirtualPosition--;
|
||||
}
|
||||
// The height of the indicator is screen res height / total menu entries
|
||||
uint8_t indicatorHeight = OLED_HEIGHT / *currentMenuLength;
|
||||
|
||||
if (indicatorHeight == 0) {
|
||||
indicatorHeight = 1; // always at least 1 pixel
|
||||
}
|
||||
|
||||
uint16_t position = (OLED_HEIGHT * (uint16_t)currentVirtualPosition) / *currentMenuLength;
|
||||
|
||||
bool showScrollbar = true;
|
||||
|
||||
// Store if its the last option for this setting
|
||||
bool isLastOptionForSetting = false;
|
||||
if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
|
||||
isLastOptionForSetting = isLastSettingValue(currentMenu[currentScreen].autoSettingOption);
|
||||
}
|
||||
|
||||
// Last settings menu entry, reset scroll show back so it flashes
|
||||
if (isLastOptionForSetting) {
|
||||
showScrollbar = false;
|
||||
}
|
||||
|
||||
// Or Flash it
|
||||
showScrollbar |= (xTaskGetTickCount() % (TICKS_SECOND / 4) < (TICKS_SECOND / 8));
|
||||
|
||||
if (showScrollbar) {
|
||||
OLED::drawScrollIndicator((uint8_t)position, indicatorHeight);
|
||||
}
|
||||
}
|
||||
// Now handle user button input
|
||||
|
||||
auto callIncrementHandler = [&]() {
|
||||
if (currentMenu[currentScreen].incrementHandler != nullptr) {
|
||||
currentMenu[currentScreen].incrementHandler();
|
||||
} else if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
|
||||
nextSettingValue(currentMenu[currentScreen].autoSettingOption);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//
|
||||
OperatingMode newMode = OperatingMode::SettingsMenu;
|
||||
switch (buttons) {
|
||||
case BUTTON_NONE:
|
||||
(*autoRepeatAcceleration) = 0; // reset acceleration
|
||||
(*autoRepeatTimer) = 0; // reset acceleration
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
if (*subEntry == 0) {
|
||||
saveSettings();
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::HomeScreen;
|
||||
} else {
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
*subEntry = 0;
|
||||
return OperatingMode::SettingsMenu;
|
||||
}
|
||||
break;
|
||||
|
||||
case BUTTON_F_LONG:
|
||||
if (xTaskGetTickCount() + (*autoRepeatAcceleration) > (*autoRepeatTimer) + PRESS_ACCEL_INTERVAL_MAX) {
|
||||
callIncrementHandler();
|
||||
// Update the check for if its the last version
|
||||
bool isLastOptionForSetting = false;
|
||||
if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
|
||||
isLastOptionForSetting = isLastSettingValue(currentMenu[currentScreen].autoSettingOption);
|
||||
}
|
||||
|
||||
if (isLastOptionForSetting) {
|
||||
(*autoRepeatTimer) = TICKS_SECOND * 2;
|
||||
} else {
|
||||
(*autoRepeatTimer) = 0;
|
||||
}
|
||||
(*autoRepeatTimer) += xTaskGetTickCount();
|
||||
(*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
|
||||
*currentMenuLength = 0; // Reset incase menu visible changes
|
||||
}
|
||||
break;
|
||||
case BUTTON_F_SHORT:
|
||||
// Increment setting
|
||||
if (*isRenderingHelp) {
|
||||
*isRenderingHelp = 0;
|
||||
} else {
|
||||
*currentMenuLength = 0; // Reset incase menu visible changes
|
||||
if (*subEntry == 0) {
|
||||
// In a root menu, if its null handler we enter the menu
|
||||
if (currentMenu[currentScreen].incrementHandler != nullptr) {
|
||||
currentMenu[currentScreen].incrementHandler();
|
||||
} else {
|
||||
(*subEntry) += 1;
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
}
|
||||
} else {
|
||||
callIncrementHandler();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BUTTON_B_LONG:
|
||||
if (xTaskGetTickCount() + (*autoRepeatAcceleration) > (*autoRepeatTimer) + PRESS_ACCEL_INTERVAL_MAX) {
|
||||
(*autoRepeatTimer) = xTaskGetTickCount();
|
||||
(*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
/* Fall through*/
|
||||
case BUTTON_B_SHORT:
|
||||
// Increment menu item
|
||||
|
||||
newMode = moveToNextEntry(cxt);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((PRESS_ACCEL_INTERVAL_MAX - (*autoRepeatAcceleration)) < PRESS_ACCEL_INTERVAL_MIN) {
|
||||
(*autoRepeatAcceleration) = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
|
||||
}
|
||||
|
||||
// Otherwise we stay put for next render iteration
|
||||
return newMode;
|
||||
}
|
||||
118
source/Core/Threads/UI/logic/ShowStartupWarnings.cpp
Normal file
118
source/Core/Threads/UI/logic/ShowStartupWarnings.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#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
|
||||
|
||||
switch (cxt->scratch_state.state1) {
|
||||
case 0: // Settings reset warning
|
||||
if (settingsWereReset) {
|
||||
if (warnUser(translatedString(Tr->SettingsResetMessage), buttons)) {
|
||||
settingsWereReset = false;
|
||||
cxt->scratch_state.state1 = 1;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 1;
|
||||
}
|
||||
break;
|
||||
case 1: // Device validations
|
||||
#ifdef DEVICE_HAS_VALIDATION_SUPPORT
|
||||
if (getDeviceValidationStatus()) {
|
||||
// Warn user this device might be counterfeit
|
||||
if (warnUser(translatedString(Tr->DeviceFailedValidationWarning), buttons)) {
|
||||
cxt->scratch_state.state1 = 2;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 2;
|
||||
}
|
||||
#else
|
||||
cxt->scratch_state.state1 = 2;
|
||||
#endif
|
||||
break;
|
||||
case 2: // Accelerometer detection
|
||||
#ifdef NO_ACCEL
|
||||
cxt->scratch_state.state1 = 3;
|
||||
#else
|
||||
if (DetectedAccelerometerVersion == AccelType::Scanning) {
|
||||
break;
|
||||
}
|
||||
// Display alert if accelerometer is not detected
|
||||
if (DetectedAccelerometerVersion == AccelType::None) {
|
||||
if (getSettingValue(SettingsOptions::AccelMissingWarningCounter) < 2) {
|
||||
|
||||
if (warnUser(translatedString(Tr->NoAccelerometerMessage), buttons)) {
|
||||
cxt->scratch_state.state1 = 3;
|
||||
nextSettingValue(SettingsOptions::AccelMissingWarningCounter);
|
||||
saveSettings();
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 3;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case 3:
|
||||
|
||||
#ifdef POW_PD
|
||||
// We expect pd to be present
|
||||
if (!USBPowerDelivery::fusbPresent()) {
|
||||
if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
|
||||
if (warnUser(translatedString(Tr->NoPowerDeliveryMessage), buttons)) {
|
||||
nextSettingValue(SettingsOptions::PDMissingWarningCounter);
|
||||
saveSettings();
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
#else
|
||||
#if POW_PD_EXT == 1
|
||||
if (!hub238_probe()) {
|
||||
if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
|
||||
if (warnUser(translatedString(Tr->NoPowerDeliveryMessage), buttons)) {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
nextSettingValue(SettingsOptions::PDMissingWarningCounter);
|
||||
saveSettings();
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
#else
|
||||
#if POW_PD_EXT == 2
|
||||
if (!FS2711::probe()) {
|
||||
if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
|
||||
if (warnUser(translatedString(Tr->NoPowerDeliveryMessage), buttons)) {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
nextSettingValue(SettingsOptions::PDMissingWarningCounter);
|
||||
saveSettings();
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
} else {
|
||||
cxt->scratch_state.state1 = 4;
|
||||
}
|
||||
#else
|
||||
cxt->scratch_state.state1 = 4;
|
||||
#endif /*POW_PD_EXT==1*/
|
||||
#endif /*POW_PD_EXT==2*/
|
||||
#endif /*POW_PD*/
|
||||
|
||||
break;
|
||||
default:
|
||||
// We are off the end, warnings done
|
||||
return OperatingMode::StartupLogo;
|
||||
}
|
||||
|
||||
return OperatingMode::StartupWarnings; // Stay in warnings
|
||||
}
|
||||
51
source/Core/Threads/UI/logic/Sleep.cpp
Normal file
51
source/Core/Threads/UI/logic/Sleep.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *cxt) {
|
||||
#ifdef NO_SLEEP_MODE
|
||||
return OperatingMode::Soldering;
|
||||
#endif
|
||||
// Drop to sleep temperature and display until movement or button press
|
||||
|
||||
// user moved or pressed a button, go back to soldering
|
||||
// If in the first two seconds we disable this to let accelerometer warm up
|
||||
|
||||
#ifdef POW_DC
|
||||
if (checkForUnderVoltage()) {
|
||||
return OperatingMode::HomeScreen; // return non-zero on error
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cxt->scratch_state.state4) {
|
||||
// Hibernating mode
|
||||
currentTempTargetDegC = 0;
|
||||
} else {
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp)));
|
||||
} else {
|
||||
currentTempTargetDegC = min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp));
|
||||
}
|
||||
}
|
||||
// draw the lcd
|
||||
uint16_t tipTemp = getSettingValue(SettingsOptions::TemperatureInF) ? TipThermoModel::getTipInF() : TipThermoModel::getTipInC();
|
||||
|
||||
if (getSettingValue(SettingsOptions::DetailedSoldering)) {
|
||||
ui_draw_soldering_detailed_sleep(tipTemp);
|
||||
} else {
|
||||
ui_draw_soldering_basic_sleep(tipTemp);
|
||||
}
|
||||
|
||||
if (!shouldBeSleeping()) {
|
||||
return cxt->previousMode;
|
||||
}
|
||||
|
||||
if (shouldShutdown()) {
|
||||
// shutdown
|
||||
currentTempTargetDegC = 0;
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
if (cxt->scratch_state.state4) {
|
||||
return OperatingMode::Hibernating;
|
||||
} else {
|
||||
return OperatingMode::Sleeping;
|
||||
}
|
||||
}
|
||||
160
source/Core/Threads/UI/logic/Soldering.cpp
Normal file
160
source/Core/Threads/UI/logic/Soldering.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
|
||||
#include "OperatingModes.h"
|
||||
#include "SolderingCommon.h"
|
||||
#include "ui_drawing.hpp"
|
||||
// State 1 = button locking (0:unlocked+released, 1:unlocked, 2:locked, 3:locked+released)
|
||||
// State 2 = boost mode
|
||||
// State 3 = buzzer timer
|
||||
|
||||
OperatingMode handleSolderingButtons(const ButtonState buttons, guiContext *cxt) {
|
||||
if (cxt->scratch_state.state1 >= 2) {
|
||||
// Buttons are currently locked
|
||||
switch (buttons) {
|
||||
case BUTTON_F_LONG:
|
||||
if (getSettingValue(SettingsOptions::BoostTemp) && (getSettingValue(SettingsOptions::LockingMode) == lockingMode_t::BOOST)) {
|
||||
cxt->scratch_state.state2 = 1;
|
||||
}
|
||||
break;
|
||||
case BUTTON_BOTH_LONG:
|
||||
if (cxt->scratch_state.state1 == 3) {
|
||||
// Unlocking
|
||||
if (warnUser(translatedString(Tr->UnlockingKeysString), buttons)) {
|
||||
cxt->scratch_state.state1 = 1;
|
||||
}
|
||||
} else {
|
||||
warnUser(translatedString(Tr->WarningKeysLockedString), buttons);
|
||||
}
|
||||
break;
|
||||
case BUTTON_NONE:
|
||||
cxt->scratch_state.state1 = 3;
|
||||
break;
|
||||
default: // Do nothing and display a lock warning
|
||||
warnUser(translatedString(Tr->WarningKeysLockedString), buttons);
|
||||
break;
|
||||
}
|
||||
return OperatingMode::Soldering;
|
||||
}
|
||||
// otherwise we are unlocked
|
||||
switch (buttons) {
|
||||
case BUTTON_NONE:
|
||||
cxt->scratch_state.state2 = 0;
|
||||
cxt->scratch_state.state1 = 0;
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
/*Fall through*/
|
||||
case BUTTON_B_LONG:
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::HomeScreen;
|
||||
case BUTTON_F_LONG:
|
||||
// if boost mode is enabled turn it on
|
||||
if (getSettingValue(SettingsOptions::BoostTemp)) {
|
||||
cxt->scratch_state.state2 = 1;
|
||||
}
|
||||
break;
|
||||
case BUTTON_F_SHORT:
|
||||
case BUTTON_B_SHORT:
|
||||
cxt->transitionMode = TransitionAnimation::Left;
|
||||
return OperatingMode::TemperatureAdjust;
|
||||
case BUTTON_BOTH_LONG:
|
||||
if (getSettingValue(SettingsOptions::LockingMode)) {
|
||||
// Lock buttons
|
||||
if (cxt->scratch_state.state1 == 0) {
|
||||
if (warnUser(translatedString(Tr->LockingKeysString), buttons)) {
|
||||
cxt->scratch_state.state1 = 2;
|
||||
}
|
||||
} else {
|
||||
// FIXME should be WarningKeysUnlockedString
|
||||
warnUser(translatedString(Tr->UnlockingKeysString), buttons);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return OperatingMode::Soldering;
|
||||
}
|
||||
|
||||
OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) {
|
||||
/*
|
||||
* * Soldering (gui_solderingMode)
|
||||
* -> Main loop where we draw temp, and animations
|
||||
* --> User presses buttons and they goto the temperature adjust screen
|
||||
* ---> Display the current setpoint temperature
|
||||
* ---> Use buttons to change forward and back on temperature
|
||||
* ---> Both buttons or timeout for exiting
|
||||
* --> Long hold front button to enter boost mode
|
||||
* ---> Just temporarily sets the system into the alternate temperature for
|
||||
* PID control
|
||||
* --> Long hold back button to exit
|
||||
* --> Double button to exit
|
||||
* --> Long hold double button to toggle key lock
|
||||
*/
|
||||
|
||||
// Update the setpoints for the temperature
|
||||
if (cxt->scratch_state.state2) {
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::BoostTemp));
|
||||
} else {
|
||||
currentTempTargetDegC = (getSettingValue(SettingsOptions::BoostTemp));
|
||||
}
|
||||
} else {
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::SolderingTemp));
|
||||
} else {
|
||||
currentTempTargetDegC = (getSettingValue(SettingsOptions::SolderingTemp));
|
||||
}
|
||||
}
|
||||
|
||||
// Update status
|
||||
int error = currentTempTargetDegC - TipThermoModel::getTipInC();
|
||||
if (error >= -10 && error <= 10) {
|
||||
// converged
|
||||
if (!cxt->scratch_state.state5) {
|
||||
setBuzzer(true);
|
||||
cxt->scratch_state.state3 = xTaskGetTickCount() + TICKS_SECOND / 3;
|
||||
cxt->scratch_state.state5 = true;
|
||||
}
|
||||
setStatusLED(LED_HOT);
|
||||
} else {
|
||||
setStatusLED(LED_HEATING);
|
||||
cxt->scratch_state.state5 = false;
|
||||
}
|
||||
if (cxt->scratch_state.state3 != 0 && xTaskGetTickCount() >= cxt->scratch_state.state3) {
|
||||
setBuzzer(false);
|
||||
}
|
||||
|
||||
// Draw in the screen details
|
||||
if (getSettingValue(SettingsOptions::DetailedSoldering)) {
|
||||
|
||||
ui_draw_soldering_power_status(cxt->scratch_state.state2);
|
||||
|
||||
} else {
|
||||
ui_draw_soldering_basic_status(cxt->scratch_state.state2);
|
||||
}
|
||||
// Check if we should bail due to undervoltage for example
|
||||
if (checkExitSoldering()) {
|
||||
setBuzzer(false);
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
#ifdef NO_SLEEP_MODE
|
||||
|
||||
if (shouldShutdown()) {
|
||||
// shutdown
|
||||
currentTempTargetDegC = 0;
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
#endif
|
||||
if (shouldBeSleeping()) {
|
||||
return OperatingMode::Sleeping;
|
||||
}
|
||||
|
||||
if (heaterThermalRunaway) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunaway = false;
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::ThermalRunaway;
|
||||
}
|
||||
return handleSolderingButtons(buttons, cxt);
|
||||
}
|
||||
177
source/Core/Threads/UI/logic/SolderingProfile.cpp
Normal file
177
source/Core/Threads/UI/logic/SolderingProfile.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#include "OperatingModes.h"
|
||||
#include "SolderingCommon.h"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt) {
|
||||
/*
|
||||
* * Soldering
|
||||
* -> Main loop where we draw temp, and animations
|
||||
* --> Long hold back button to exit
|
||||
* --> Double button to exit
|
||||
*/
|
||||
|
||||
uint16_t tipTemp = 0;
|
||||
|
||||
// If this is during init, start at preheat
|
||||
if (cxt->scratch_state.state1 == 0) {
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePreheatTemp);
|
||||
}
|
||||
uint16_t phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfilePreheatSpeed);
|
||||
uint16_t profileCurrentTargetTemp = 0;
|
||||
|
||||
switch (buttons) {
|
||||
case BUTTON_BOTH:
|
||||
case BUTTON_B_LONG:
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return OperatingMode::HomeScreen; // exit on back long hold
|
||||
case BUTTON_F_LONG:
|
||||
case BUTTON_F_SHORT:
|
||||
case BUTTON_B_SHORT:
|
||||
case BUTTON_NONE:
|
||||
// Not used yet
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
tipTemp = TipThermoModel::getTipInF();
|
||||
} else {
|
||||
tipTemp = TipThermoModel::getTipInC();
|
||||
}
|
||||
// If time of entering is unknown; then we start now
|
||||
if (cxt->scratch_state.state3 == 0) {
|
||||
cxt->scratch_state.state3 = xTaskGetTickCount();
|
||||
}
|
||||
|
||||
// if start temp is unknown (preheat), we're setting it now
|
||||
if (cxt->scratch_state.state6 == 0) {
|
||||
cxt->scratch_state.state6 = tipTemp;
|
||||
// if this is hotter than the preheat temperature, we should fail
|
||||
if (cxt->scratch_state.state6 >= cxt->scratch_state.state5) {
|
||||
warnUser(translatedString(Tr->TooHotToStartProfileWarning), buttons);
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
}
|
||||
uint16_t phaseElapsedSeconds = (xTaskGetTickCount() - cxt->scratch_state.state3) / TICKS_SECOND;
|
||||
|
||||
// Have we finished this phase?
|
||||
// Check if we have hit our temperature target in either direction.
|
||||
bool phaseTargetReached = false;
|
||||
if (cxt->scratch_state.state6 < cxt->scratch_state.state5 && tipTemp >= cxt->scratch_state.state5) {
|
||||
phaseTargetReached = true;
|
||||
} else if (cxt->scratch_state.state6 > cxt->scratch_state.state5 && tipTemp <= cxt->scratch_state.state5) {
|
||||
phaseTargetReached = true;
|
||||
} else if (tipTemp == cxt->scratch_state.state5) {
|
||||
phaseTargetReached = true;
|
||||
}
|
||||
|
||||
// If we both hit the temperature target and enough time has passed, phase complete.
|
||||
if (phaseElapsedSeconds >= cxt->scratch_state.state2 && phaseTargetReached) {
|
||||
cxt->scratch_state.state1++;
|
||||
cxt->scratch_state.state6 = cxt->scratch_state.state5;
|
||||
cxt->scratch_state.state3 = xTaskGetTickCount();
|
||||
phaseElapsedSeconds = 0;
|
||||
if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
|
||||
// done with all phases, lets go to cooldown
|
||||
cxt->scratch_state.state2 = 0;
|
||||
cxt->scratch_state.state5 = 0;
|
||||
phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed);
|
||||
} else {
|
||||
// set up next phase
|
||||
switch (cxt->scratch_state.state1) {
|
||||
case 1:
|
||||
cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase1Duration);
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase1Temp);
|
||||
break;
|
||||
case 2:
|
||||
cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase2Duration);
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase2Temp);
|
||||
break;
|
||||
case 3:
|
||||
cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase3Duration);
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase3Temp);
|
||||
break;
|
||||
case 4:
|
||||
cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase4Duration);
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase4Temp);
|
||||
break;
|
||||
case 5:
|
||||
cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase5Duration);
|
||||
cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase5Temp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
|
||||
phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state5 - cxt->scratch_state.state6);
|
||||
} else {
|
||||
phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state6 - cxt->scratch_state.state5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cooldown phase done?
|
||||
if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
|
||||
if (TipThermoModel::getTipInC() < 55) {
|
||||
// we're done, let the buzzer beep too
|
||||
setStatusLED(LED_STANDBY);
|
||||
if (cxt->scratch_state.state4 == 0) {
|
||||
setBuzzer(true);
|
||||
cxt->scratch_state.state4 = xTaskGetTickCount() + TICKS_SECOND / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// determine current target temp
|
||||
if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
|
||||
profileCurrentTargetTemp = cxt->scratch_state.state6 + ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
|
||||
if (profileCurrentTargetTemp > cxt->scratch_state.state5) {
|
||||
profileCurrentTargetTemp = cxt->scratch_state.state5;
|
||||
}
|
||||
} else if (cxt->scratch_state.state6 > cxt->scratch_state.state5) {
|
||||
profileCurrentTargetTemp = cxt->scratch_state.state6 - ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
|
||||
// Chance of an overflow when ramping up is basically zero, but chance of an underflow here is quite high. If the target underflowed, snap it back.
|
||||
if (profileCurrentTargetTemp < cxt->scratch_state.state5 || profileCurrentTargetTemp > cxt->scratch_state.state6) {
|
||||
profileCurrentTargetTemp = cxt->scratch_state.state5;
|
||||
}
|
||||
} else {
|
||||
profileCurrentTargetTemp = cxt->scratch_state.state5;
|
||||
}
|
||||
|
||||
// Draw in the screen details
|
||||
if (getSettingValue(SettingsOptions::DetailedSoldering)) {
|
||||
ui_draw_soldering_profile_advanced(tipTemp, profileCurrentTargetTemp, phaseElapsedSeconds, cxt->scratch_state.state1, cxt->scratch_state.state2);
|
||||
ui_draw_soldering_power_status(false);
|
||||
} else {
|
||||
ui_draw_soldering_basic_status(false);
|
||||
}
|
||||
|
||||
// Update the setpoints for the temperature
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp);
|
||||
} else {
|
||||
currentTempTargetDegC = profileCurrentTargetTemp;
|
||||
}
|
||||
|
||||
if (checkExitSoldering() || (cxt->scratch_state.state4 != 0 && xTaskGetTickCount() >= cxt->scratch_state.state4)) {
|
||||
setBuzzer(false);
|
||||
return OperatingMode::HomeScreen;
|
||||
}
|
||||
if (heaterThermalRunaway) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
heaterThermalRunaway = false;
|
||||
return OperatingMode::ThermalRunaway;
|
||||
}
|
||||
|
||||
// Update LED status
|
||||
if (cxt->scratch_state.state1 == 0) {
|
||||
setStatusLED(LED_HEATING);
|
||||
} else if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
|
||||
setStatusLED(LED_COOLING_STILL_HOT);
|
||||
} else {
|
||||
setStatusLED(LED_HOT);
|
||||
}
|
||||
return OperatingMode::SolderingProfile;
|
||||
}
|
||||
92
source/Core/Threads/UI/logic/TemperatureAdjust.cpp
Normal file
92
source/Core/Threads/UI/logic/TemperatureAdjust.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
OperatingMode gui_solderingTempAdjust(const ButtonState buttonIn, guiContext *cxt) {
|
||||
|
||||
currentTempTargetDegC = 0; // Turn off heater while adjusting temp
|
||||
uint16_t *waitForRelease = &(cxt->scratch_state.state1);
|
||||
uint32_t *autoRepeatTimer = &(cxt->scratch_state.state3);
|
||||
uint16_t *autoRepeatAcceleration = &(cxt->scratch_state.state2);
|
||||
ButtonState buttons = buttonIn;
|
||||
if (*waitForRelease == 0) {
|
||||
// When we first enter we wait for the user to release buttons before enabling changes
|
||||
if (buttons != BUTTON_NONE) {
|
||||
buttons = BUTTON_NONE;
|
||||
} else {
|
||||
(*waitForRelease)++;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t delta = 0;
|
||||
switch (buttons) {
|
||||
case BUTTON_NONE:
|
||||
// stay
|
||||
(*autoRepeatAcceleration) = 0;
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
// exit
|
||||
saveSettings();
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return cxt->previousMode;
|
||||
case BUTTON_B_LONG:
|
||||
if (xTaskGetTickCount() - (*autoRepeatTimer) + (*autoRepeatAcceleration) > PRESS_ACCEL_INTERVAL_MAX) {
|
||||
delta = -getSettingValue(SettingsOptions::TempChangeLongStep);
|
||||
(*autoRepeatTimer) = xTaskGetTickCount();
|
||||
(*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
|
||||
}
|
||||
break;
|
||||
case BUTTON_B_SHORT:
|
||||
delta = -getSettingValue(SettingsOptions::TempChangeShortStep);
|
||||
break;
|
||||
case BUTTON_F_LONG:
|
||||
if (xTaskGetTickCount() - (*autoRepeatTimer) + (*autoRepeatAcceleration) > PRESS_ACCEL_INTERVAL_MAX) {
|
||||
delta = getSettingValue(SettingsOptions::TempChangeLongStep);
|
||||
(*autoRepeatTimer) = xTaskGetTickCount();
|
||||
(*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
|
||||
}
|
||||
break;
|
||||
case BUTTON_F_SHORT:
|
||||
delta = getSettingValue(SettingsOptions::TempChangeShortStep);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((PRESS_ACCEL_INTERVAL_MAX - (*autoRepeatAcceleration)) < PRESS_ACCEL_INTERVAL_MIN) {
|
||||
(*autoRepeatAcceleration) = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
|
||||
}
|
||||
// If buttons are flipped; flip the delta
|
||||
if (getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled)) {
|
||||
delta = -delta;
|
||||
}
|
||||
if (delta != 0) {
|
||||
// constrain between the set temp limits, i.e. 10-450 C
|
||||
int16_t newTemp = getSettingValue(SettingsOptions::SolderingTemp);
|
||||
newTemp += delta;
|
||||
// Round to nearest increment of delta
|
||||
delta = abs(delta);
|
||||
newTemp = (newTemp / delta) * delta;
|
||||
|
||||
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
||||
if (newTemp > MAX_TEMP_F) {
|
||||
newTemp = MAX_TEMP_F;
|
||||
} else if (newTemp < MIN_TEMP_F) {
|
||||
newTemp = MIN_TEMP_F;
|
||||
}
|
||||
} else {
|
||||
if (newTemp > MAX_TEMP_C) {
|
||||
newTemp = MAX_TEMP_C;
|
||||
} else if (newTemp < MIN_TEMP_C) {
|
||||
newTemp = MIN_TEMP_C;
|
||||
}
|
||||
}
|
||||
setSettingValue(SettingsOptions::SolderingTemp, (uint16_t)newTemp);
|
||||
}
|
||||
ui_draw_temperature_change();
|
||||
|
||||
if (xTaskGetTickCount() - lastButtonTime > (TICKS_SECOND * 3)) {
|
||||
saveSettings();
|
||||
cxt->transitionMode = TransitionAnimation::Right;
|
||||
return cxt->previousMode; // exit if user just doesn't press anything for a bit
|
||||
}
|
||||
return OperatingMode::TemperatureAdjust; // Stay in temp adjust
|
||||
}
|
||||
50
source/Core/Threads/UI/logic/USBPDDebug_FS2711.cpp
Normal file
50
source/Core/Threads/UI/logic/USBPDDebug_FS2711.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "FS2711.hpp"
|
||||
#include "OperatingModes.h"
|
||||
#include "stdbool.h"
|
||||
#include "ui_drawing.hpp"
|
||||
#if POW_PD_EXT == 2
|
||||
#ifdef HAS_POWER_DEBUG_MENU
|
||||
|
||||
OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt) {
|
||||
// Print out the USB-PD state
|
||||
// Basically this is like the Debug menu, but instead we want to print out the PD status
|
||||
uint16_t *screen = &(cxt->scratch_state.state1);
|
||||
|
||||
if (*screen > 7) {
|
||||
*screen = 0;
|
||||
}
|
||||
if (*screen == 0) {
|
||||
// Print the PD Debug state
|
||||
fs2711_state_t state = FS2711::debug_get_state();
|
||||
|
||||
ui_draw_usb_pd_debug_state(0, state.pdo_num);
|
||||
} else {
|
||||
|
||||
// Print out the Proposed power options one by one
|
||||
uint16_t max_voltage = FS2711::debug_pdo_max_voltage(*screen - 1);
|
||||
if (max_voltage == 0) {
|
||||
*screen += 1;
|
||||
} else {
|
||||
uint16_t min_voltage = FS2711::debug_pdo_min_voltage(*screen - 1);
|
||||
uint16_t current = FS2711::debug_pdo_source_current(*screen - 1);
|
||||
uint16_t pdo_type = FS2711::debug_pdo_type(*screen - 1);
|
||||
if (pdo_type != 1) {
|
||||
min_voltage = 0;
|
||||
}
|
||||
|
||||
ui_draw_usb_pd_debug_pdo(*screen, min_voltage / 1000, max_voltage / 1000, current * 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
OLED::refresh();
|
||||
|
||||
if (buttons == BUTTON_B_SHORT) {
|
||||
return OperatingMode::InitialisationDone;
|
||||
} else if (buttons == BUTTON_F_SHORT) {
|
||||
*screen++;
|
||||
}
|
||||
|
||||
return OperatingMode::UsbPDDebug;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
75
source/Core/Threads/UI/logic/USBPDDebug_FUSB.cpp
Normal file
75
source/Core/Threads/UI/logic/USBPDDebug_FUSB.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
#ifdef POW_PD
|
||||
#include "pd.h"
|
||||
#ifdef HAS_POWER_DEBUG_MENU
|
||||
OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt) {
|
||||
// Print out the USB-PD state
|
||||
// Basically this is like the Debug menu, but instead we want to print out the PD status
|
||||
uint16_t *screen = &(cxt->scratch_state.state1);
|
||||
|
||||
if ((*screen) == 0) {
|
||||
// Print the PD state machine
|
||||
uint8_t vbusState = 0;
|
||||
if (USBPowerDelivery::fusbPresent()) {
|
||||
if (USBPowerDelivery::negotiationComplete() || (xTaskGetTickCount() > (TICKS_SECOND * 10))) {
|
||||
if (!USBPowerDelivery::isVBUSConnected()) {
|
||||
vbusState = 2;
|
||||
} else {
|
||||
vbusState = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ui_draw_usb_pd_debug_state(vbusState, USBPowerDelivery::getStateNumber());
|
||||
} else {
|
||||
// Print out the Proposed power options one by one
|
||||
auto lastCaps = USBPowerDelivery::getLastSeenCapabilities();
|
||||
bool sourceIsEPRCapable = lastCaps[0] & PD_PDO_SRC_FIXED_EPR_CAPABLE;
|
||||
if (((*screen) - 1) < 11) {
|
||||
int voltage_mv = 0;
|
||||
int min_voltage = 0;
|
||||
int current_a_x100 = 0;
|
||||
int wattage = 0;
|
||||
|
||||
if ((lastCaps[(*screen) - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
||||
voltage_mv = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(lastCaps[(*screen) - 1])); // voltage in mV units
|
||||
current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(lastCaps[(*screen) - 1]); // current in 10mA units
|
||||
} else if ((lastCaps[(*screen) - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED) {
|
||||
if (sourceIsEPRCapable) {
|
||||
if ((lastCaps[(*screen) - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_AVS) {
|
||||
voltage_mv = PD_PAV2MV(PD_APDO_AVS_MAX_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
// Last value is wattage
|
||||
wattage = PD_APDO_AVS_MAX_POWER_GET(lastCaps[(*screen) - 1]);
|
||||
} else if (((lastCaps[(*screen) - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS)) {
|
||||
voltage_mv = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
current_a_x100 = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(lastCaps[(*screen) - 1])); // max current in 10mA units
|
||||
}
|
||||
} else {
|
||||
// Doesn't have EPR support. So treat as PPS
|
||||
// https://github.com/Ralim/IronOS/issues/1906
|
||||
voltage_mv = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[(*screen) - 1]));
|
||||
current_a_x100 = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(lastCaps[(*screen) - 1])); // max current in 10mA units
|
||||
}
|
||||
}
|
||||
// Skip not used entries
|
||||
if (voltage_mv == 0) {
|
||||
(*screen) += 1;
|
||||
} else {
|
||||
ui_draw_usb_pd_debug_pdo(*screen, min_voltage / 1000, voltage_mv / 1000, current_a_x100, wattage);
|
||||
}
|
||||
} else {
|
||||
(*screen) = 0;
|
||||
}
|
||||
}
|
||||
if (buttons == BUTTON_B_SHORT) {
|
||||
return OperatingMode::InitialisationDone;
|
||||
} else if (buttons == BUTTON_F_SHORT) {
|
||||
(*screen) += 1;
|
||||
}
|
||||
return OperatingMode::UsbPDDebug;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
37
source/Core/Threads/UI/logic/USBPDDebug_HUSB238.cpp
Normal file
37
source/Core/Threads/UI/logic/USBPDDebug_HUSB238.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "HUB238.hpp"
|
||||
#include "OperatingModes.h"
|
||||
#include "ui_drawing.hpp"
|
||||
#if POW_PD_EXT == 1
|
||||
#ifdef HAS_POWER_DEBUG_MENU
|
||||
OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt) {
|
||||
// Print out the USB-PD state
|
||||
// Basically this is like the Debug menu, but instead we want to print out the PD status
|
||||
uint16_t *screen = &(cxt->scratch_state.state1);
|
||||
|
||||
if (*screen > 6) {
|
||||
*screen = 0;
|
||||
}
|
||||
if (*screen == 0) {
|
||||
// Print the PD Debug state
|
||||
uint16_t temp = hub238_debug_state();
|
||||
ui_draw_usb_pd_debug_state(0, temp);
|
||||
} else {
|
||||
|
||||
// Print out the Proposed power options one by one
|
||||
const uint8_t voltages[] = {5, 9, 12, 15, 18, 20};
|
||||
uint16_t voltage = voltages[*screen - 1];
|
||||
uint16_t currentx100 = hub238_getVoltagePDOCurrent(voltage);
|
||||
|
||||
ui_draw_usb_pd_debug_pdo(*screen, 0, voltage, currentx100, 0);
|
||||
}
|
||||
|
||||
if (buttons == BUTTON_B_SHORT) {
|
||||
return OperatingMode::InitialisationDone;
|
||||
} else if (buttons == BUTTON_F_SHORT) {
|
||||
*screen++;
|
||||
}
|
||||
|
||||
return OperatingMode::UsbPDDebug;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
10
source/Core/Threads/UI/logic/utils/GUIDelay.cpp
Normal file
10
source/Core/Threads/UI/logic/utils/GUIDelay.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#include "OperatingModeUtilities.h"
|
||||
|
||||
void GUIDelay() {
|
||||
// Called in all UI looping tasks,
|
||||
// This limits the re-draw rate to the LCD and also lets the DMA run
|
||||
// As the gui task can very easily fill this bus with transactions, which will
|
||||
// prevent the movement detection from running
|
||||
vTaskDelay(5 * TICKS_10MS);
|
||||
}
|
||||
16
source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h
Normal file
16
source/Core/Threads/UI/logic/utils/OperatingModeUtilities.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef OPERATING_MODE_UTILITIES_H_
|
||||
#define OPERATING_MODE_UTILITIES_H_
|
||||
#include "Buttons.hpp"
|
||||
#include "OLED.hpp"
|
||||
#include <stdbool.h>
|
||||
|
||||
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
|
||||
98
source/Core/Threads/UI/logic/utils/SolderingCommon.cpp
Normal file
98
source/Core/Threads/UI/logic/utils/SolderingCommon.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// Created by laura on 24.04.23.
|
||||
//
|
||||
|
||||
#include "SolderingCommon.h"
|
||||
#include "OperatingModes.h"
|
||||
#include "Types.h"
|
||||
#include "configuration.h"
|
||||
#include "history.hpp"
|
||||
#include "ui_drawing.hpp"
|
||||
|
||||
extern bool heaterThermalRunaway;
|
||||
|
||||
bool checkExitSoldering(void) {
|
||||
#ifdef POW_DC
|
||||
// Undervoltage test
|
||||
if (checkForUnderVoltage()) {
|
||||
lastButtonTime = xTaskGetTickCount();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCEL_EXITS_ON_MOVEMENT
|
||||
// If the accel works in reverse where movement will cause exiting the soldering mode
|
||||
if (getSettingValue(Sensitivity)) {
|
||||
if (lastMovementTime) {
|
||||
if (lastMovementTime > TICKS_SECOND * 10) {
|
||||
// If we have moved recently; in the last second
|
||||
// Then exit soldering mode
|
||||
|
||||
// Movement occurred in last update
|
||||
if (((TickType_t)(xTaskGetTickCount() - lastMovementTime)) < (TickType_t)(TICKS_SECOND / 5)) {
|
||||
currentTempTargetDegC = 0;
|
||||
lastMovementTime = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we have tripped thermal runaway, turn off heater and show warning
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t getPowerSourceNumber(void) {
|
||||
int8_t sourceNumber = 0;
|
||||
if (getIsPoweredByDCIN()) {
|
||||
sourceNumber = 0;
|
||||
} else {
|
||||
// We are not powered via DC, so want to display the appropriate state for PD or QC
|
||||
bool poweredbyPD = false;
|
||||
bool pdHasVBUSConnected = false;
|
||||
#ifdef POW_PD
|
||||
if (USBPowerDelivery::fusbPresent()) {
|
||||
// We are PD capable
|
||||
if (USBPowerDelivery::negotiationComplete()) {
|
||||
// We are powered via PD
|
||||
poweredbyPD = true;
|
||||
#ifdef VBUS_MOD_TEST
|
||||
pdHasVBUSConnected = USBPowerDelivery::isVBUSConnected();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if POW_PD_EXT == 2
|
||||
if (FS2711::has_run_selection()) {
|
||||
poweredbyPD = true;
|
||||
// FS2711IC has VBUS always connected
|
||||
pdHasVBUSConnected = true;
|
||||
}
|
||||
#endif
|
||||
if (poweredbyPD) {
|
||||
if (pdHasVBUSConnected) {
|
||||
sourceNumber = 2;
|
||||
} else {
|
||||
sourceNumber = 3;
|
||||
}
|
||||
} else {
|
||||
sourceNumber = 1;
|
||||
}
|
||||
}
|
||||
return sourceNumber;
|
||||
}
|
||||
|
||||
// Returns temperature of the tip in *C/*F (based on user settings)
|
||||
TemperatureType_t getTipTemp(void) {
|
||||
#ifdef FILTER_DISPLAYED_TIP_TEMP
|
||||
static history<TemperatureType_t, FILTER_DISPLAYED_TIP_TEMP> Filter_Temp;
|
||||
TemperatureType_t reading = getSettingValue(SettingsOptions::TemperatureInF) ? TipThermoModel::getTipInF() : TipThermoModel::getTipInC();
|
||||
Filter_Temp.update(reading);
|
||||
return Filter_Temp.average();
|
||||
|
||||
#else
|
||||
return getSettingValue(SettingsOptions::TemperatureInF) ? TipThermoModel::getTipInF() : TipThermoModel::getTipInC();
|
||||
#endif
|
||||
}
|
||||
9
source/Core/Threads/UI/logic/utils/SolderingCommon.h
Normal file
9
source/Core/Threads/UI/logic/utils/SolderingCommon.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "Types.h"
|
||||
#include <stdint.h>
|
||||
#ifndef SOLDERING_COMMON_H_
|
||||
#define SOLDERING_COMMON_H_
|
||||
|
||||
bool checkExitSoldering();
|
||||
TemperatureType_t getTipTemp(void);
|
||||
|
||||
#endif // SOLDERING_COMMON_H_
|
||||
25
source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp
Normal file
25
source/Core/Threads/UI/logic/utils/checkUndervoltage.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#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
|
||||
bool checkForUnderVoltage(void) {
|
||||
if (!getIsPoweredByDCIN()) {
|
||||
return false;
|
||||
}
|
||||
uint16_t v = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0);
|
||||
|
||||
// Dont check for first 2 seconds while the ADC stabilizes and the DMA fills
|
||||
// the buffer
|
||||
if (xTaskGetTickCount() > (TICKS_SECOND * 2)) {
|
||||
if ((v < lookupVoltageLevel())) {
|
||||
currentTempTargetDegC = 0;
|
||||
ui_draw_warning_undervoltage();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
19
source/Core/Threads/UI/logic/utils/getSleepTimeout.cpp
Normal file
19
source/Core/Threads/UI/logic/utils/getSleepTimeout.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "OperatingModeUtilities.h"
|
||||
|
||||
#ifndef NO_SLEEP_MODE
|
||||
|
||||
uint32_t getSleepTimeout(void) {
|
||||
|
||||
if (getSettingValue(SettingsOptions::Sensitivity) && getSettingValue(SettingsOptions::SleepTime)) {
|
||||
|
||||
uint32_t sleepThres = 0;
|
||||
if (getSettingValue(SettingsOptions::SleepTime) < 6) {
|
||||
sleepThres = getSettingValue(SettingsOptions::SleepTime) * 10 * 1000;
|
||||
} else {
|
||||
sleepThres = (getSettingValue(SettingsOptions::SleepTime) - 5) * 60 * 1000;
|
||||
}
|
||||
return sleepThres;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
11
source/Core/Threads/UI/logic/utils/min.cpp
Normal file
11
source/Core/Threads/UI/logic/utils/min.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
#include "OperatingModeUtilities.h"
|
||||
#include <stdint.h>
|
||||
uint16_t min(uint16_t a, uint16_t b) {
|
||||
if (a > b) {
|
||||
return b;
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
24
source/Core/Threads/UI/logic/utils/shouldDeviceShutdown.cpp
Normal file
24
source/Core/Threads/UI/logic/utils/shouldDeviceShutdown.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "OperatingModeUtilities.h"
|
||||
|
||||
extern TickType_t lastMovementTime;
|
||||
extern TickType_t lastHallEffectSleepStart;
|
||||
#include "Buttons.hpp"
|
||||
|
||||
bool shouldShutdown(void) {
|
||||
if (getSettingValue(SettingsOptions::ShutdownTime)) { // only allow shutdown exit if time > 0
|
||||
if (lastMovementTime) {
|
||||
if (((TickType_t)(xTaskGetTickCount() - lastMovementTime)) > (TickType_t)(getSettingValue(SettingsOptions::ShutdownTime) * TICKS_MIN)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (lastHallEffectSleepStart) {
|
||||
if (((TickType_t)(xTaskGetTickCount() - lastHallEffectSleepStart)) > (TickType_t)(getSettingValue(SettingsOptions::ShutdownTime) * TICKS_MIN)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getButtonState() == BUTTON_B_LONG) { // allow also if back button is pressed long
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
45
source/Core/Threads/UI/logic/utils/shouldDeviceSleep.cpp
Normal file
45
source/Core/Threads/UI/logic/utils/shouldDeviceSleep.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "Buttons.hpp"
|
||||
#include "OperatingModeUtilities.h"
|
||||
|
||||
TickType_t lastHallEffectSleepStart = 0;
|
||||
extern TickType_t lastMovementTime;
|
||||
|
||||
bool shouldBeSleeping() {
|
||||
#ifndef NO_SLEEP_MODE
|
||||
// Return true if the iron should be in sleep mode
|
||||
if (getSettingValue(SettingsOptions::Sensitivity) && getSettingValue(SettingsOptions::SleepTime)) {
|
||||
// In auto start we are asleep until movement
|
||||
if (lastMovementTime == 0 && lastButtonTime == 0) {
|
||||
return true;
|
||||
}
|
||||
if (lastMovementTime > 0 || lastButtonTime > 0) {
|
||||
if (((xTaskGetTickCount() - lastMovementTime) > getSleepTimeout()) && ((xTaskGetTickCount() - lastButtonTime) > getSleepTimeout())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HALL_SENSOR
|
||||
// If the hall effect sensor is enabled in the build, check if its over
|
||||
// threshold, and if so then we force sleep
|
||||
if (getHallSensorFitted() && lookupHallEffectThreshold()) {
|
||||
int16_t hallEffectStrength = getRawHallEffect();
|
||||
if (hallEffectStrength < 0) {
|
||||
hallEffectStrength = -hallEffectStrength;
|
||||
}
|
||||
// Have absolute value of measure of magnetic field strength
|
||||
if (hallEffectStrength > lookupHallEffectThreshold()) {
|
||||
if (lastHallEffectSleepStart == 0) {
|
||||
lastHallEffectSleepStart = xTaskGetTickCount();
|
||||
}
|
||||
if ((xTaskGetTickCount() - lastHallEffectSleepStart) > TICKS_SECOND) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
lastHallEffectSleepStart = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user