mirror of
https://github.com/Ralim/IronOS.git
synced 2025-07-23 04:13:01 +02:00
* Minor doc updates * pydoc * Draft tip selection menu * Start linking in manual tip resistance * Enable on Pinecilv1 / TS10x * Fixup drawing tip type * Update Settings.cpp * Rename JBC type * Add translations * Handle one tip type * Refactor header includes * Fixup translation_IT.json * Fixing up includes * Format * Apply suggestions from code review Co-authored-by: discip <53649486+discip@users.noreply.github.com> * Update Documentation/Hardware.md Co-authored-by: discip <53649486+discip@users.noreply.github.com> --------- Co-authored-by: = <=> Co-authored-by: discip <53649486+discip@users.noreply.github.com>
373 lines
19 KiB
C++
373 lines
19 KiB
C++
/*
|
|
* Settings.c
|
|
*
|
|
* Created on: 29 Sep 2016
|
|
* Author: Ralim
|
|
*
|
|
* This file holds the users settings and saves / restores them to the
|
|
* devices flash
|
|
*/
|
|
|
|
#include "Settings.h"
|
|
#include "BSP.h"
|
|
#include "Setup.h"
|
|
#include "Translation.h"
|
|
#include "configuration.h"
|
|
#include <string.h> // for memset
|
|
bool sanitiseSettings();
|
|
|
|
/*
|
|
* Used to constrain the QC 3.0 Voltage selection to suit hardware.
|
|
* We allow a little overvoltage for users who want to push it
|
|
*/
|
|
#ifdef POW_QC_20V
|
|
#define QC_VOLTAGE_MAX 220
|
|
#else
|
|
#define QC_VOLTAGE_MAX 140
|
|
#endif /* POW_QC_20V */
|
|
|
|
/*
|
|
* This struct must be a multiple of 2 bytes as it is saved / restored from
|
|
* flash in uint16_t chunks
|
|
*/
|
|
typedef struct {
|
|
uint16_t versionMarker;
|
|
uint16_t length; // Length of valid bytes following
|
|
uint16_t settingsValues[SettingsOptionsLength];
|
|
// used to make this nicely "good enough" aligned to 32 bytes to make driver code trivial
|
|
uint32_t padding;
|
|
|
|
} systemSettingsType;
|
|
|
|
//~1024 is common programming size, setting threshold to be lower so we have warning
|
|
static_assert(sizeof(systemSettingsType) < 512);
|
|
|
|
// char (*__kaboom)[sizeof(systemSettingsType)] = 1; // Uncomment to print size at compile time
|
|
volatile systemSettingsType systemSettings;
|
|
|
|
// For every setting we need to store the min/max/increment values
|
|
typedef struct {
|
|
const uint16_t min; // Inclusive minimum value
|
|
const uint16_t max; // Inclusive maximum value
|
|
const uint16_t increment; // Standard increment
|
|
const uint16_t defaultValue; // Default vaue after reset
|
|
} SettingConstants;
|
|
|
|
static const SettingConstants settingsConstants[(int)SettingsOptions::SettingsOptionsLength] = {
|
|
//{ min, max, increment, default}
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, SOLDERING_TEMP}, // SolderingTemp
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 150}, // SleepTemp
|
|
{ 0, 15, 1, SLEEP_TIME}, // SleepTime
|
|
{ 0, 4, 1, CUT_OUT_SETTING}, // MinDCVoltageCells
|
|
{ 24, 38, 1, RECOM_VOL_CELL}, // MinVoltageCells
|
|
{ 90, QC_VOLTAGE_MAX, 2, 90}, // QCIdealVoltage
|
|
{ 0, MAX_ORIENTATION_MODE, 1, ORIENTATION_MODE}, // OrientationMode
|
|
{ 0, 9, 1, SENSITIVITY}, // Sensitivity
|
|
{ 0, 1, 1, ANIMATION_LOOP}, // AnimationLoop
|
|
{ 0, settingOffSpeed_t::MAX_VALUE - 1, 1, ANIMATION_SPEED}, // AnimationSpeed
|
|
{ 0, 3, 1, AUTO_START_MODE}, // AutoStartMode
|
|
{ 0, 60, 1, SHUTDOWN_TIME}, // ShutdownTime
|
|
{ 0, 1, 1, COOLING_TEMP_BLINK}, // CoolingTempBlink
|
|
{ 0, 1, 1, DETAILED_IDLE}, // DetailedIDLE
|
|
{ 0, 1, 1, DETAILED_SOLDERING}, // DetailedSoldering
|
|
{ 0, (uint16_t)(HasFahrenheit ? 1 : 0), 1, TEMPERATURE_INF}, // TemperatureInF
|
|
{ 0, 1, 1, DESCRIPTION_SCROLL_SPEED}, // DescriptionScrollSpeed
|
|
{ 0, 2, 1, LOCKING_MODE}, // LockingMode
|
|
{ 0, 99, 1, POWER_PULSE_DEFAULT}, // KeepAwakePulse
|
|
{ 1, POWER_PULSE_WAIT_MAX, 1, POWER_PULSE_WAIT_DEFAULT}, // KeepAwakePulseWait
|
|
{ 1, POWER_PULSE_DURATION_MAX, 1, POWER_PULSE_DURATION_DEFAULT}, // KeepAwakePulseDuration
|
|
{ 360, 900, 1, VOLTAGE_DIV}, // VoltageDiv
|
|
{ 0, MAX_TEMP_F, 10, BOOST_TEMP}, // BoostTemp
|
|
{MIN_CALIBRATION_OFFSET, 2500, 1, CALIBRATION_OFFSET}, // CalibrationOffset
|
|
{ 0, MAX_POWER_LIMIT, POWER_LIMIT_STEPS, POWER_LIMIT}, // PowerLimit
|
|
{ 0, 1, 1, REVERSE_BUTTON_TEMP_CHANGE}, // ReverseButtonTempChangeEnabled
|
|
{ 5, TEMP_CHANGE_LONG_STEP_MAX, 5, TEMP_CHANGE_LONG_STEP}, // TempChangeLongStep
|
|
{ 1, TEMP_CHANGE_SHORT_STEP_MAX, 1, TEMP_CHANGE_SHORT_STEP}, // TempChangeShortStep
|
|
{ 0, 9, 1, 7}, // HallEffectSensitivity
|
|
{ 0, 9, 1, 0}, // AccelMissingWarningCounter
|
|
{ 0, 9, 1, 0}, // PDMissingWarningCounter
|
|
{ 0, 0xFFFF, 0, 41431 /*EN*/}, // UILanguage
|
|
{ 0, 50, 1, 20}, // PDNegTimeout
|
|
{ 0, 1, 1, 0}, // OLEDInversion
|
|
{ MIN_BRIGHTNESS, MAX_BRIGHTNESS, BRIGHTNESS_STEP, DEFAULT_BRIGHTNESS}, // OLEDBrightness
|
|
{ 0, 6, 1, 1}, // LOGOTime
|
|
{ 0, 1, 1, 0}, // CalibrateCJC
|
|
{ 0, 1, 1, 0}, // BluetoothLE
|
|
{ 0, 2, 1, 1}, // USBPDMode
|
|
{ 1, 5, 1, 4}, // ProfilePhases
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 90}, // ProfilePreheatTemp
|
|
{ 1, 10, 1, 1}, // ProfilePreheatSpeed
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 130}, // ProfilePhase1Temp
|
|
{ 10, 180, 5, 90}, // ProfilePhase1Duration
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 140}, // ProfilePhase2Temp
|
|
{ 10, 180, 5, 30}, // ProfilePhase2Duration
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 165}, // ProfilePhase3Temp
|
|
{ 10, 180, 5, 30}, // ProfilePhase3Duration
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 140}, // ProfilePhase4Temp
|
|
{ 10, 180, 5, 30}, // ProfilePhase4Duration
|
|
{ MIN_TEMP_C, MAX_TEMP_F, 5, 90}, // ProfilePhase5Temp
|
|
{ 10, 180, 5, 30}, // ProfilePhase5Duration
|
|
{ 1, 10, 1, 2}, // ProfileCooldownSpeed
|
|
{ 0, 12, 1, 0}, // HallEffectSleepTime
|
|
{ 0, (tipType_t::TIP_TYPE_MAX - 1) > 0 ? (tipType_t::TIP_TYPE_MAX - 1) : 0, 1, 0}, // SolderingTipType
|
|
};
|
|
static_assert((sizeof(settingsConstants) / sizeof(SettingConstants)) == ((int)SettingsOptions::SettingsOptionsLength));
|
|
|
|
void saveSettings() {
|
|
#ifdef CANT_DIRECT_READ_SETTINGS
|
|
// For these devices flash is not 1:1 mapped, so need to read into staging buffer
|
|
systemSettingsType settings;
|
|
flash_read_buffer((uint8_t *)&settings, sizeof(systemSettingsType));
|
|
if (memcmp((void *)&settings, (void *)&systemSettings, sizeof(systemSettingsType))) {
|
|
flash_save_buffer((uint8_t *)&systemSettings, sizeof(systemSettingsType));
|
|
}
|
|
|
|
#else
|
|
if (memcmp((void *)SETTINGS_START_PAGE, (void *)&systemSettings, sizeof(systemSettingsType))) {
|
|
flash_save_buffer((uint8_t *)&systemSettings, sizeof(systemSettingsType));
|
|
}
|
|
|
|
#endif /* CANT_DIRECT_READ_SETTINGS */
|
|
}
|
|
|
|
bool loadSettings() {
|
|
// We read the flash
|
|
flash_read_buffer((uint8_t *)&systemSettings, sizeof(systemSettingsType));
|
|
// Then ensure all values are valid
|
|
return sanitiseSettings();
|
|
}
|
|
|
|
bool sanitiseSettings() {
|
|
// For all settings, need to ensure settings are in a valid range
|
|
// First for any not know about due to array growth, reset them and update the length value
|
|
bool dirty = false;
|
|
if (systemSettings.versionMarker != SETTINGSVERSION) {
|
|
memset((void *)&systemSettings, 0xFF, sizeof(systemSettings));
|
|
systemSettings.versionMarker = SETTINGSVERSION;
|
|
dirty = true;
|
|
}
|
|
if (systemSettings.padding != 0xFFFFFFFF) {
|
|
systemSettings.padding = 0xFFFFFFFF; // Force padding to 0xFFFFFFFF so that rolling forwards / back should be easier
|
|
dirty = true;
|
|
}
|
|
if (systemSettings.length < (int)SettingsOptions::SettingsOptionsLength) {
|
|
dirty = true;
|
|
for (int i = systemSettings.length; i < (int)SettingsOptions::SettingsOptionsLength; i++) {
|
|
systemSettings.settingsValues[i] = 0xFFFF; // Ensure its as if it was erased
|
|
}
|
|
systemSettings.length = (int)SettingsOptions::SettingsOptionsLength;
|
|
}
|
|
for (int i = 0; i < (int)SettingsOptions::SettingsOptionsLength; i++) {
|
|
// Check min max for all settings, if outside the range, move to default
|
|
if (systemSettings.settingsValues[i] < settingsConstants[i].min || systemSettings.settingsValues[i] > settingsConstants[i].max) {
|
|
systemSettings.settingsValues[i] = settingsConstants[i].defaultValue;
|
|
dirty = true;
|
|
}
|
|
}
|
|
if (dirty) {
|
|
saveSettings();
|
|
}
|
|
return dirty;
|
|
}
|
|
|
|
void resetSettings() {
|
|
memset((void *)&systemSettings, 0xFF, sizeof(systemSettingsType));
|
|
sanitiseSettings();
|
|
saveSettings(); // Save defaults
|
|
}
|
|
|
|
void setSettingValue(const enum SettingsOptions option, const uint16_t newValue) {
|
|
const auto constants = settingsConstants[(int)option];
|
|
uint16_t constrainedValue = newValue;
|
|
if (constrainedValue < constants.min) {
|
|
// If less than min, constrain
|
|
constrainedValue = constants.min;
|
|
} else if (constrainedValue > constants.max) {
|
|
// If hit max, constrain
|
|
constrainedValue = constants.max;
|
|
}
|
|
systemSettings.settingsValues[(int)option] = constrainedValue;
|
|
}
|
|
|
|
// Lookup wrapper for ease of use (with typing)
|
|
uint16_t getSettingValue(const enum SettingsOptions option) { return systemSettings.settingsValues[(int)option]; }
|
|
|
|
// Increment by the step size to the next value. If past the end wrap to the minimum
|
|
// Returns true if we are on the _last_ value
|
|
void nextSettingValue(const enum SettingsOptions option) {
|
|
const auto constants = settingsConstants[(int)option];
|
|
if (systemSettings.settingsValues[(int)option] == (constants.max)) {
|
|
// Already at max, wrap to the start
|
|
systemSettings.settingsValues[(int)option] = constants.min;
|
|
} else if (systemSettings.settingsValues[(int)option] >= (constants.max - constants.increment)) {
|
|
// If within one increment of the end, constrain to the end
|
|
systemSettings.settingsValues[(int)option] = constants.max;
|
|
} else {
|
|
// Otherwise increment
|
|
systemSettings.settingsValues[(int)option] += constants.increment;
|
|
}
|
|
}
|
|
|
|
bool isLastSettingValue(const enum SettingsOptions option) {
|
|
const auto constants = settingsConstants[(int)option];
|
|
uint16_t max = constants.max;
|
|
// handle temp unit limitations
|
|
if (option == SettingsOptions::SolderingTemp) {
|
|
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
|
max = MAX_TEMP_F;
|
|
} else {
|
|
max = MAX_TEMP_C;
|
|
}
|
|
} else if (option == SettingsOptions::BoostTemp) {
|
|
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
|
max = MAX_TEMP_F;
|
|
} else {
|
|
max = MAX_TEMP_C;
|
|
}
|
|
} else if (option == SettingsOptions::SleepTemp) {
|
|
if (getSettingValue(SettingsOptions::TemperatureInF)) {
|
|
max = 580;
|
|
} else {
|
|
max = 300;
|
|
}
|
|
} else if (option == SettingsOptions::UILanguage) {
|
|
return isLastLanguageOption();
|
|
}
|
|
return systemSettings.settingsValues[(int)option] > (max - constants.increment);
|
|
}
|
|
// Step backwards on the settings item
|
|
// Return true if we are at the end (min)
|
|
void prevSettingValue(const enum SettingsOptions option) {
|
|
const auto constants = settingsConstants[(int)option];
|
|
if (systemSettings.settingsValues[(int)option] == (constants.min)) {
|
|
// Already at min, wrap to the max
|
|
systemSettings.settingsValues[(int)option] = constants.max;
|
|
} else if (systemSettings.settingsValues[(int)option] <= (constants.min + constants.increment)) {
|
|
// If within one increment of the start, constrain to the start
|
|
systemSettings.settingsValues[(int)option] = constants.min;
|
|
} else {
|
|
// Otherwise decrement
|
|
systemSettings.settingsValues[(int)option] -= constants.increment;
|
|
}
|
|
}
|
|
|
|
uint16_t lookupHallEffectThreshold() {
|
|
// Return the threshold above which the hall effect sensor is "activated"
|
|
// We want this to be roughly exponentially mapped from 0-1000
|
|
switch (getSettingValue(SettingsOptions::HallEffectSensitivity)) {
|
|
case 0:
|
|
return 0;
|
|
case 1:
|
|
return 1000;
|
|
case 2:
|
|
return 750;
|
|
case 3:
|
|
return 500;
|
|
case 4:
|
|
return 250;
|
|
case 5:
|
|
return 150;
|
|
case 6:
|
|
return 100;
|
|
case 7:
|
|
return 75;
|
|
case 8:
|
|
return 50;
|
|
case 9:
|
|
return 25;
|
|
default:
|
|
return 0; // Off
|
|
}
|
|
}
|
|
|
|
// Lookup function for cutoff setting -> X10 voltage
|
|
/*
|
|
* 0=DC
|
|
* 1=3S
|
|
* 2=4S
|
|
* 3=5S
|
|
* 4=6S
|
|
*/
|
|
uint8_t lookupVoltageLevel() {
|
|
auto minVoltageOnCell = getSettingValue(SettingsOptions::MinDCVoltageCells);
|
|
auto minVoltageCellCount = getSettingValue(SettingsOptions::MinVoltageCells);
|
|
if (minVoltageOnCell == 0) {
|
|
return 90; // 9V since iron does not function effectively below this
|
|
} else {
|
|
return (minVoltageOnCell * minVoltageCellCount) + (minVoltageCellCount * 2);
|
|
}
|
|
}
|
|
|
|
const char *lookupTipName() {
|
|
// Get the name string for the current soldering tip
|
|
tipType_t value = (tipType_t)getSettingValue(SettingsOptions::SolderingTipType);
|
|
|
|
switch (value) {
|
|
#ifdef AUTO_TIP_SELECTION
|
|
case tipType_t::TIP_TYPE_AUTO:
|
|
return translatedString(Tr->TipTypeAuto);
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYPE_T12
|
|
case tipType_t::T12_8_OHM:
|
|
return translatedString(Tr->TipTypeT12Long);
|
|
break;
|
|
case tipType_t::T12_6_2_OHM:
|
|
return translatedString(Tr->TipTypeT12Short);
|
|
break;
|
|
case tipType_t::T12_4_OHM:
|
|
return translatedString(Tr->TipTypeT12PTS);
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYE_TS80
|
|
case tipType_t::TS80_4_5_OHM:
|
|
return translatedString(Tr->TipTypeTS80);
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYPE_JBC
|
|
case tipType_t::JBC_210_2_5_OHM:
|
|
return translatedString(Tr->TipTypeJBCC210);
|
|
break;
|
|
#endif
|
|
default:
|
|
return nullptr;
|
|
break;
|
|
}
|
|
}
|
|
// Returns the resistance for the current tip selected by the user or 0 for auto
|
|
uint8_t getUserSelectedTipResistance() {
|
|
tipType_t value = (tipType_t)getSettingValue(SettingsOptions::SolderingTipType);
|
|
|
|
switch (value) {
|
|
#ifdef AUTO_TIP_SELECTION
|
|
case tipType_t::TIP_TYPE_AUTO:
|
|
return 0;
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYPE_T12
|
|
case tipType_t::T12_8_OHM:
|
|
return 80;
|
|
break;
|
|
case tipType_t::T12_6_2_OHM:
|
|
return 62;
|
|
break;
|
|
case tipType_t::T12_4_OHM:
|
|
return 40;
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYE_TS80
|
|
case tipType_t::TS80_4_5_OHM:
|
|
return 45;
|
|
break;
|
|
#endif
|
|
#ifdef TIPTYPE_JBC
|
|
case tipType_t::JBC_210_2_5_OHM:
|
|
return 25;
|
|
break;
|
|
#endif
|
|
default:
|
|
return 0;
|
|
break;
|
|
}
|
|
}
|