Skip to content

Commit e0bed1e

Browse files
ellenspthinkyhead
andcommitted
✨ Option to reset EEPROM on first run (#23276)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
1 parent d21fa25 commit e0bed1e

File tree

3 files changed

+68
-20
lines changed

3 files changed

+68
-20
lines changed

Marlin/Configuration.h

+1
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,7 @@
18371837
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
18381838
#if ENABLED(EEPROM_SETTINGS)
18391839
//#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
1840+
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
18401841
#endif
18411842

18421843
//

Marlin/src/module/settings.cpp

+57-19
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
*/
3737

3838
// Change EEPROM version if the structure changes
39-
#define EEPROM_VERSION "V85"
39+
#define EEPROM_VERSION "V86"
4040
#define EEPROM_OFFSET 100
4141

4242
// Check the integrity of data offsets.
@@ -198,20 +198,32 @@ static const feedRate_t _DMF[] PROGMEM = DEFAULT_MAX_FEEDRATE;
198198
*/
199199
typedef struct SettingsDataStruct {
200200
char version[4]; // Vnn\0
201+
#if ENABLED(EEPROM_INIT_NOW)
202+
uint32_t build_hash; // Unique build hash
203+
#endif
201204
uint16_t crc; // Data Checksum
202205

203206
//
204207
// DISTINCT_E_FACTORS
205208
//
206-
uint8_t esteppers; // DISTINCT_AXES - LINEAR_AXES
209+
uint8_t e_factors; // DISTINCT_AXES - LINEAR_AXES
207210

211+
//
212+
// Planner settings
213+
//
208214
planner_settings_t planner_settings;
209215

210216
xyze_float_t planner_max_jerk; // M205 XYZE planner.max_jerk
211217
float planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
212218

219+
//
220+
// Home Offset
221+
//
213222
xyz_pos_t home_offset; // M206 XYZ / M665 TPZ
214223

224+
//
225+
// Hotend Offset
226+
//
215227
#if HAS_HOTEND_OFFSET
216228
xyz_pos_t hotend_offset[HOTENDS - 1]; // M218 XYZ
217229
#endif
@@ -649,13 +661,24 @@ void MarlinSettings::postprocess() {
649661

650662
const char version[4] = EEPROM_VERSION;
651663

664+
#if ENABLED(EEPROM_INIT_NOW)
665+
constexpr uint32_t strhash32(const char *s, const uint32_t h=0) {
666+
return *s ? strhash32(s + 1, ((h + *s) << (*s & 3)) ^ *s) : h;
667+
}
668+
constexpr uint32_t build_hash = strhash32(__DATE__ __TIME__);
669+
#endif
670+
652671
bool MarlinSettings::eeprom_error, MarlinSettings::validating;
653672
int MarlinSettings::eeprom_index;
654673
uint16_t MarlinSettings::working_crc;
655674

656675
bool MarlinSettings::size_error(const uint16_t size) {
657676
if (size != datasize()) {
658-
DEBUG_ERROR_MSG("EEPROM datasize error.");
677+
DEBUG_ERROR_MSG("EEPROM datasize error."
678+
#if ENABLED(MARLIN_DEV_MODE)
679+
" (Actual:", size, " Expected:", datasize(), ")"
680+
#endif
681+
);
659682
return true;
660683
}
661684
return false;
@@ -675,13 +698,17 @@ void MarlinSettings::postprocess() {
675698
// Write or Skip version. (Flash doesn't allow rewrite without erase.)
676699
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver);
677700

678-
EEPROM_SKIP(working_crc); // Skip the checksum slot
701+
#if ENABLED(EEPROM_INIT_NOW)
702+
EEPROM_SKIP(build_hash); // Skip the hash slot
703+
#endif
704+
705+
EEPROM_SKIP(working_crc); // Skip the checksum slot
679706

680707
working_crc = 0; // clear before first "real data"
681708

682-
const uint8_t esteppers = COUNT(planner.settings.axis_steps_per_mm) - LINEAR_AXES;
683-
_FIELD_TEST(esteppers);
684-
EEPROM_WRITE(esteppers);
709+
const uint8_t e_factors = DISTINCT_AXES - (LINEAR_AXES);
710+
_FIELD_TEST(e_factors);
711+
EEPROM_WRITE(e_factors);
685712

686713
//
687714
// Planner Motion
@@ -1494,6 +1521,9 @@ void MarlinSettings::postprocess() {
14941521
eeprom_index = EEPROM_OFFSET;
14951522

14961523
EEPROM_WRITE(version);
1524+
#if ENABLED(EEPROM_INIT_NOW)
1525+
EEPROM_WRITE(build_hash);
1526+
#endif
14971527
EEPROM_WRITE(final_crc);
14981528

14991529
// Report storage size
@@ -1527,9 +1557,6 @@ void MarlinSettings::postprocess() {
15271557
char stored_ver[4];
15281558
EEPROM_READ_ALWAYS(stored_ver);
15291559

1530-
uint16_t stored_crc;
1531-
EEPROM_READ_ALWAYS(stored_crc);
1532-
15331560
// Version has to match or defaults are used
15341561
if (strncmp(version, stored_ver, 3) != 0) {
15351562
if (stored_ver[3] != '\0') {
@@ -1543,31 +1570,42 @@ void MarlinSettings::postprocess() {
15431570
eeprom_error = true;
15441571
}
15451572
else {
1573+
1574+
// Optionally reset on the first boot after flashing
1575+
#if ENABLED(EEPROM_INIT_NOW)
1576+
uint32_t stored_hash;
1577+
EEPROM_READ_ALWAYS(stored_hash);
1578+
if (stored_hash != build_hash) { EEPROM_FINISH(); return true; }
1579+
#endif
1580+
1581+
uint16_t stored_crc;
1582+
EEPROM_READ_ALWAYS(stored_crc);
1583+
15461584
float dummyf = 0;
15471585
working_crc = 0; // Init to 0. Accumulated by EEPROM_READ
15481586

1549-
_FIELD_TEST(esteppers);
1587+
_FIELD_TEST(e_factors);
15501588

1551-
// Number of esteppers may change
1552-
uint8_t esteppers;
1553-
EEPROM_READ_ALWAYS(esteppers);
1589+
// Number of e_factors may change
1590+
uint8_t e_factors;
1591+
EEPROM_READ_ALWAYS(e_factors);
15541592

15551593
//
15561594
// Planner Motion
15571595
//
15581596
{
15591597
// Get only the number of E stepper parameters previously stored
15601598
// Any steppers added later are set to their defaults
1561-
uint32_t tmp1[LINEAR_AXES + esteppers];
1562-
float tmp2[LINEAR_AXES + esteppers];
1563-
feedRate_t tmp3[LINEAR_AXES + esteppers];
1599+
uint32_t tmp1[LINEAR_AXES + e_factors];
1600+
float tmp2[LINEAR_AXES + e_factors];
1601+
feedRate_t tmp3[LINEAR_AXES + e_factors];
15641602
EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2
15651603
EEPROM_READ(planner.settings.min_segment_time_us);
15661604
EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm
15671605
EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s
15681606

15691607
if (!validating) LOOP_DISTINCT_AXES(i) {
1570-
const bool in = (i < esteppers + LINEAR_AXES);
1608+
const bool in = (i < e_factors + LINEAR_AXES);
15711609
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
15721610
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
15731611
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
@@ -2496,7 +2534,7 @@ void MarlinSettings::postprocess() {
24962534
return success;
24972535
}
24982536
reset();
2499-
#if ENABLED(EEPROM_AUTO_INIT)
2537+
#if EITHER(EEPROM_AUTO_INIT, EEPROM_INIT_NOW)
25002538
(void)save();
25012539
SERIAL_ECHO_MSG("EEPROM Initialized");
25022540
#endif

buildroot/share/PlatformIO/scripts/preflight-checks.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,19 @@ def sanity_check_target():
8181
#
8282
# Give warnings on every build
8383
#
84-
warnfile = os.path.join(env['PROJECT_BUILD_DIR'], build_env, "src", "src", "inc", "Warnings.cpp.o")
84+
srcpath = os.path.join(env['PROJECT_BUILD_DIR'], build_env, "src", "src")
85+
warnfile = os.path.join(srcpath, "inc", "Warnings.cpp.o")
8586
if os.path.exists(warnfile):
8687
os.remove(warnfile)
8788

89+
#
90+
# Rebuild 'settings.cpp' for EEPROM_INIT_NOW
91+
#
92+
if 'EEPROM_INIT_NOW' in env['MARLIN_FEATURES']:
93+
setfile = os.path.join(srcpath, "module", "settings.cpp.o")
94+
if os.path.exists(setfile):
95+
os.remove(setfile)
96+
8897
#
8998
# Check for old files indicating an entangled Marlin (mixing old and new code)
9099
#

0 commit comments

Comments
 (0)