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 */
199199typedef 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
0 commit comments