️ Load/init (most) settings after showing boot-screen (#27199)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Co-authored-by: Peter Ellens <ellensp@users.noreply.github.com>
This commit is contained in:
David Buezas
2024-06-28 01:37:35 +02:00
committed by GitHub
parent 11f90de873
commit cb6fd130ba
4 changed files with 98 additions and 21 deletions

View File

@@ -1334,14 +1334,19 @@ void setup() {
SETUP_RUN(card.mount()); // Mount media with settings before first_load SETUP_RUN(card.mount()); // Mount media with settings before first_load
#endif #endif
SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults) // Prepare some LCDs to display early
// This also updates variables in the planner, elsewhere #if HAS_EARLY_LCD_SETTINGS
SETUP_RUN(settings.load_lcd_state());
#endif
#if ALL(HAS_WIRED_LCD, SHOW_BOOTSCREEN) #if ALL(HAS_WIRED_LCD, SHOW_BOOTSCREEN)
SETUP_RUN(ui.show_bootscreen()); SETUP_RUN(ui.show_bootscreen());
const millis_t bootscreen_ms = millis(); const millis_t bootscreen_ms = millis();
#endif #endif
SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults)
// This also updates variables in the planner, elsewhere
#if ENABLED(PROBE_TARE) #if ENABLED(PROBE_TARE)
SETUP_RUN(probe.tare_init()); SETUP_RUN(probe.tare_init());
#endif #endif

View File

@@ -3384,6 +3384,10 @@
#define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2)
#endif #endif
#endif #endif
// Prepare the LCD to show the bootscreen early in setup
#if ENABLED(SHOW_BOOTSCREEN) && ANY(HAS_LCD_CONTRAST, HAS_LCD_BRIGHTNESS)
#define HAS_EARLY_LCD_SETTINGS 1
#endif
#endif #endif
#if BUTTONS_EXIST(EN1, EN2, ENC) #if BUTTONS_EXIST(EN1, EN2, ENC)

View File

@@ -778,11 +778,13 @@ void MarlinSettings::postprocess() {
#define TWO_BYTE_HASH(A,B) uint16_t((uint16_t(A ^ 0xC3) << 4) ^ (uint16_t(B ^ 0xC3) << 12)) #define TWO_BYTE_HASH(A,B) uint16_t((uint16_t(A ^ 0xC3) << 4) ^ (uint16_t(B ^ 0xC3) << 12))
#define EEPROM_OFFSETOF(FIELD) (EEPROM_OFFSET + offsetof(SettingsData, FIELD))
#if ENABLED(DEBUG_EEPROM_READWRITE) #if ENABLED(DEBUG_EEPROM_READWRITE)
#define _FIELD_TEST(FIELD) \ #define _FIELD_TEST(FIELD) \
SERIAL_ECHOLNPGM("Field: " STRINGIFY(FIELD)); \ SERIAL_ECHOLNPGM("Field: " STRINGIFY(FIELD)); \
EEPROM_ASSERT( \ EEPROM_ASSERT( \
eeprom_error || eeprom_index == offsetof(SettingsData, FIELD) + EEPROM_OFFSET, \ eeprom_error || eeprom_index == EEPROM_OFFSETOF(FIELD), \
"Field " STRINGIFY(FIELD) " mismatch." \ "Field " STRINGIFY(FIELD) " mismatch." \
) )
#else #else
@@ -797,7 +799,7 @@ void MarlinSettings::postprocess() {
#define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V) #define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V)
#endif #endif
const char version[4] = EEPROM_VERSION; constexpr char version_str[4] = EEPROM_VERSION;
#if ENABLED(EEPROM_INIT_NOW) #if ENABLED(EEPROM_INIT_NOW)
constexpr uint32_t strhash32(const char *s, const uint32_t h=0) { constexpr uint32_t strhash32(const char *s, const uint32_t h=0) {
@@ -827,14 +829,14 @@ void MarlinSettings::postprocess() {
*/ */
bool MarlinSettings::save() { bool MarlinSettings::save() {
float dummyf = 0; float dummyf = 0;
MString<3> ver(F("ERR"));
if (!EEPROM_START(EEPROM_OFFSET)) return false; if (!EEPROM_START(EEPROM_OFFSET)) return false;
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
// Write or Skip version. (Flash doesn't allow rewrite without erase.) // Write or Skip version. (Flash doesn't allow rewrite without erase.)
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver); constexpr char dummy_version[] = "ERR";
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(dummy_version);
#if ENABLED(EEPROM_INIT_NOW) #if ENABLED(EEPROM_INIT_NOW)
EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later
@@ -1765,7 +1767,7 @@ void MarlinSettings::postprocess() {
// Write the EEPROM header // Write the EEPROM header
eeprom_index = EEPROM_OFFSET; eeprom_index = EEPROM_OFFSET;
EEPROM_WRITE(version); EEPROM_WRITE(version_str);
#if ENABLED(EEPROM_INIT_NOW) #if ENABLED(EEPROM_INIT_NOW)
EEPROM_WRITE(build_hash); EEPROM_WRITE(build_hash);
#endif #endif
@@ -1797,29 +1799,39 @@ void MarlinSettings::postprocess() {
return success; return success;
} }
EEPROM_Error MarlinSettings::check_version() {
if (!EEPROM_START(EEPROM_OFFSET)) return ERR_EEPROM_NOPROM;
char stored_ver[4];
EEPROM_READ_ALWAYS(stored_ver);
// Version has to match or defaults are used
if (strncmp(stored_ver, version_str, 3) != 0) {
if (stored_ver[3] != '\0') {
stored_ver[0] = '?';
stored_ver[1] = '\0';
}
DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")");
return ERR_EEPROM_VERSION;
}
return ERR_EEPROM_NOERR;
}
/** /**
* M501 - Retrieve Configuration * M501 - Retrieve Configuration
*/ */
EEPROM_Error MarlinSettings::_load() { EEPROM_Error MarlinSettings::_load() {
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR; EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;
if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error; const EEPROM_Error check = check_version();
if (check == ERR_EEPROM_VERSION) return eeprom_error;
char stored_ver[4];
EEPROM_READ_ALWAYS(stored_ver);
uint16_t stored_crc; uint16_t stored_crc;
do { // A block to break out of on error do { // A block to break out of on error
// Version has to match or defaults are used // Version has to match or defaults are used
if (strncmp(version, stored_ver, 3) != 0) { if (check == ERR_EEPROM_VERSION) {
if (stored_ver[3] != '\0') { eeprom_error = check;
stored_ver[0] = '?';
stored_ver[1] = '\0';
}
DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")");
eeprom_error = ERR_EEPROM_VERSION;
break; break;
} }
@@ -2880,8 +2892,7 @@ void MarlinSettings::postprocess() {
} }
else if (!validating) { else if (!validating) {
DEBUG_ECHO_START(); DEBUG_ECHO_START();
DEBUG_ECHO(version); DEBUG_ECHOLN(version_str, F(" stored settings retrieved ("), eeprom_total, F(" bytes; crc "), working_crc, ')');
DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_total, " bytes; crc ", working_crc, ")");
TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved"))); TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved")));
} }
@@ -2967,6 +2978,26 @@ void MarlinSettings::postprocess() {
return (err == ERR_EEPROM_NOERR); return (err == ERR_EEPROM_NOERR);
} }
#if HAS_EARLY_LCD_SETTINGS
#if HAS_LCD_CONTRAST
void MarlinSettings::load_contrast() {
uint8_t lcd_contrast; EEPROM_START(EEPROM_OFFSETOF(lcd_contrast)); EEPROM_READ(lcd_contrast);
DEBUG_ECHOLNPGM("LCD Contrast: ", lcd_contrast);
ui.contrast = lcd_contrast;
}
#endif
#if HAS_LCD_BRIGHTNESS
void MarlinSettings::load_brightness() {
uint8_t lcd_brightness; EEPROM_START(EEPROM_OFFSETOF(lcd_brightness)); EEPROM_READ(lcd_brightness);
DEBUG_ECHOLNPGM("LCD Brightness: ", lcd_brightness);
ui.brightness = lcd_brightness;
}
#endif
#endif // HAS_EARLY_LCD_SETTINGS
bool MarlinSettings::load() { bool MarlinSettings::load() {
if (validate()) { if (validate()) {
const EEPROM_Error err = _load(); const EEPROM_Error err = _load();
@@ -3117,6 +3148,25 @@ void MarlinSettings::postprocess() {
#endif // !EEPROM_SETTINGS #endif // !EEPROM_SETTINGS
#if HAS_EARLY_LCD_SETTINGS
void MarlinSettings::load_lcd_state() {
if (TERN0(EEPROM_SETTINGS, check_version() == ERR_EEPROM_NOERR)) {
#if ENABLED(EEPROM_SETTINGS)
TERN_(HAS_LCD_CONTRAST, load_contrast());
TERN_(HAS_LCD_BRIGHTNESS, load_brightness());
#endif
}
else {
TERN_(HAS_LCD_CONTRAST, ui.contrast = LCD_CONTRAST_DEFAULT);
TERN_(HAS_LCD_BRIGHTNESS, ui.brightness = LCD_BRIGHTNESS_DEFAULT);
}
TERN_(HAS_LCD_CONTRAST, ui.refresh_contrast());
TERN_(HAS_LCD_BRIGHTNESS, ui.refresh_brightness());
}
#endif // HAS_EARLY_LCD_SETTINGS
/** /**
* M502 - Reset Configuration * M502 - Reset Configuration
*/ */

View File

@@ -34,7 +34,8 @@
ERR_EEPROM_VERSION, ERR_EEPROM_VERSION,
ERR_EEPROM_SIZE, ERR_EEPROM_SIZE,
ERR_EEPROM_CRC, ERR_EEPROM_CRC,
ERR_EEPROM_CORRUPT ERR_EEPROM_CORRUPT,
ERR_EEPROM_NOPROM
}; };
#endif #endif
@@ -66,11 +67,24 @@ class MarlinSettings {
static bool load(); // Return 'true' if data was loaded ok static bool load(); // Return 'true' if data was loaded ok
static bool validate(); // Return 'true' if EEPROM data is ok static bool validate(); // Return 'true' if EEPROM data is ok
static EEPROM_Error check_version();
static void first_load() { static void first_load() {
static bool loaded = false; static bool loaded = false;
if (!loaded && load()) loaded = true; if (!loaded && load()) loaded = true;
} }
#if HAS_EARLY_LCD_SETTINGS
// Special cases for LCD contrast and brightness, so
// some LCDs can display bootscreens earlier in setup().
#if HAS_LCD_CONTRAST
static void load_contrast();
#endif
#if HAS_LCD_BRIGHTNESS
static void load_brightness();
#endif
#endif
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled // That can store is enabled
static uint16_t meshes_start_index(); static uint16_t meshes_start_index();
@@ -93,6 +107,10 @@ class MarlinSettings {
#endif // !EEPROM_SETTINGS #endif // !EEPROM_SETTINGS
#if HAS_EARLY_LCD_SETTINGS
static void load_lcd_state();
#endif
#if DISABLED(DISABLE_M503) #if DISABLED(DISABLE_M503)
static void report(const bool forReplay=false); static void report(const bool forReplay=false);
#else #else