Skip to content

Commit

Permalink
⚡️ Load/init (most) settings after showing boot-screen (MarlinFirmwar…
Browse files Browse the repository at this point in the history
…e#27199)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Co-authored-by: Peter Ellens <ellensp@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 27, 2024
1 parent 11f90de commit cb6fd13
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 21 deletions.
9 changes: 7 additions & 2 deletions Marlin/src/MarlinCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,14 +1334,19 @@ void setup() {
SETUP_RUN(card.mount()); // Mount media with settings before first_load
#endif

SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults)
// This also updates variables in the planner, elsewhere
// Prepare some LCDs to display early
#if HAS_EARLY_LCD_SETTINGS
SETUP_RUN(settings.load_lcd_state());
#endif

#if ALL(HAS_WIRED_LCD, SHOW_BOOTSCREEN)
SETUP_RUN(ui.show_bootscreen());
const millis_t bootscreen_ms = millis();
#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)
SETUP_RUN(probe.tare_init());
#endif
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/inc/Conditionals_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -3384,6 +3384,10 @@
#define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2)
#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

#if BUTTONS_EXIST(EN1, EN2, ENC)
Expand Down
86 changes: 68 additions & 18 deletions Marlin/src/module/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 EEPROM_OFFSETOF(FIELD) (EEPROM_OFFSET + offsetof(SettingsData, FIELD))

#if ENABLED(DEBUG_EEPROM_READWRITE)
#define _FIELD_TEST(FIELD) \
SERIAL_ECHOLNPGM("Field: " STRINGIFY(FIELD)); \
EEPROM_ASSERT( \
eeprom_error || eeprom_index == offsetof(SettingsData, FIELD) + EEPROM_OFFSET, \
eeprom_error || eeprom_index == EEPROM_OFFSETOF(FIELD), \
"Field " STRINGIFY(FIELD) " mismatch." \
)
#else
Expand All @@ -797,7 +799,7 @@ void MarlinSettings::postprocess() {
#define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V)
#endif

const char version[4] = EEPROM_VERSION;
constexpr char version_str[4] = EEPROM_VERSION;

#if ENABLED(EEPROM_INIT_NOW)
constexpr uint32_t strhash32(const char *s, const uint32_t h=0) {
Expand Down Expand Up @@ -827,14 +829,14 @@ void MarlinSettings::postprocess() {
*/
bool MarlinSettings::save() {
float dummyf = 0;
MString<3> ver(F("ERR"));

if (!EEPROM_START(EEPROM_OFFSET)) return false;

EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;

// 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)
EEPROM_SKIP(build_hash); // Skip the hash slot which will be written later
Expand Down Expand Up @@ -1765,7 +1767,7 @@ void MarlinSettings::postprocess() {
// Write the EEPROM header
eeprom_index = EEPROM_OFFSET;

EEPROM_WRITE(version);
EEPROM_WRITE(version_str);
#if ENABLED(EEPROM_INIT_NOW)
EEPROM_WRITE(build_hash);
#endif
Expand Down Expand Up @@ -1797,29 +1799,39 @@ void MarlinSettings::postprocess() {
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
*/
EEPROM_Error MarlinSettings::_load() {
EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;

if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error;

char stored_ver[4];
EEPROM_READ_ALWAYS(stored_ver);
const EEPROM_Error check = check_version();
if (check == ERR_EEPROM_VERSION) return eeprom_error;

uint16_t stored_crc;

do { // A block to break out of on error

// Version has to match or defaults are used
if (strncmp(version, stored_ver, 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 ")");
eeprom_error = ERR_EEPROM_VERSION;
if (check == ERR_EEPROM_VERSION) {
eeprom_error = check;
break;
}

Expand Down Expand Up @@ -2880,8 +2892,7 @@ void MarlinSettings::postprocess() {
}
else if (!validating) {
DEBUG_ECHO_START();
DEBUG_ECHO(version);
DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_total, " bytes; crc ", working_crc, ")");
DEBUG_ECHOLN(version_str, F(" stored settings retrieved ("), eeprom_total, F(" bytes; crc "), working_crc, ')');
TERN_(HOST_EEPROM_CHITCHAT, hostui.notify(F("Stored settings retrieved")));
}

Expand Down Expand Up @@ -2967,6 +2978,26 @@ void MarlinSettings::postprocess() {
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() {
if (validate()) {
const EEPROM_Error err = _load();
Expand Down Expand Up @@ -3117,6 +3148,25 @@ void MarlinSettings::postprocess() {

#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
*/
Expand Down
20 changes: 19 additions & 1 deletion Marlin/src/module/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
ERR_EEPROM_VERSION,
ERR_EEPROM_SIZE,
ERR_EEPROM_CRC,
ERR_EEPROM_CORRUPT
ERR_EEPROM_CORRUPT,
ERR_EEPROM_NOPROM
};
#endif

Expand Down Expand Up @@ -66,11 +67,24 @@ class MarlinSettings {
static bool load(); // Return 'true' if data was loaded ok
static bool validate(); // Return 'true' if EEPROM data is ok

static EEPROM_Error check_version();

static void first_load() {
static bool loaded = false;
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
// That can store is enabled
static uint16_t meshes_start_index();
Expand All @@ -93,6 +107,10 @@ class MarlinSettings {

#endif // !EEPROM_SETTINGS

#if HAS_EARLY_LCD_SETTINGS
static void load_lcd_state();
#endif

#if DISABLED(DISABLE_M503)
static void report(const bool forReplay=false);
#else
Expand Down

0 comments on commit cb6fd13

Please sign in to comment.