Skip to content
This repository has been archived by the owner on Mar 5, 2023. It is now read-only.

Commit

Permalink
✨ Option to reset EEPROM on first run (MarlinFirmware#23276)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
  • Loading branch information
ellensp and thinkyhead committed Dec 25, 2021
1 parent 5360428 commit 7b21355
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 20 deletions.
1 change: 1 addition & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -1837,6 +1837,7 @@
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
//#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
#endif

//
Expand Down
76 changes: 57 additions & 19 deletions Marlin/src/module/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*/

// Change EEPROM version if the structure changes
#define EEPROM_VERSION "V85"
#define EEPROM_VERSION "V86"
#define EEPROM_OFFSET 100

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

//
// DISTINCT_E_FACTORS
//
uint8_t esteppers; // DISTINCT_AXES - LINEAR_AXES
uint8_t e_factors; // DISTINCT_AXES - LINEAR_AXES

//
// Planner settings
//
planner_settings_t planner_settings;

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

//
// Home Offset
//
xyz_pos_t home_offset; // M206 XYZ / M665 TPZ

//
// Hotend Offset
//
#if HAS_HOTEND_OFFSET
xyz_pos_t hotend_offset[HOTENDS - 1]; // M218 XYZ
#endif
Expand Down Expand Up @@ -649,13 +661,24 @@ void MarlinSettings::postprocess() {

const char version[4] = EEPROM_VERSION;

#if ENABLED(EEPROM_INIT_NOW)
constexpr uint32_t strhash32(const char *s, const uint32_t h=0) {
return *s ? strhash32(s + 1, ((h + *s) << (*s & 3)) ^ *s) : h;
}
constexpr uint32_t build_hash = strhash32(__DATE__ __TIME__);
#endif

bool MarlinSettings::eeprom_error, MarlinSettings::validating;
int MarlinSettings::eeprom_index;
uint16_t MarlinSettings::working_crc;

bool MarlinSettings::size_error(const uint16_t size) {
if (size != datasize()) {
DEBUG_ERROR_MSG("EEPROM datasize error.");
DEBUG_ERROR_MSG("EEPROM datasize error."
#if ENABLED(MARLIN_DEV_MODE)
" (Actual:", size, " Expected:", datasize(), ")"
#endif
);
return true;
}
return false;
Expand All @@ -675,13 +698,17 @@ void MarlinSettings::postprocess() {
// Write or Skip version. (Flash doesn't allow rewrite without erase.)
TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver);

EEPROM_SKIP(working_crc); // Skip the checksum slot
#if ENABLED(EEPROM_INIT_NOW)
EEPROM_SKIP(build_hash); // Skip the hash slot
#endif

EEPROM_SKIP(working_crc); // Skip the checksum slot

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

const uint8_t esteppers = COUNT(planner.settings.axis_steps_per_mm) - LINEAR_AXES;
_FIELD_TEST(esteppers);
EEPROM_WRITE(esteppers);
const uint8_t e_factors = DISTINCT_AXES - (LINEAR_AXES);
_FIELD_TEST(e_factors);
EEPROM_WRITE(e_factors);

//
// Planner Motion
Expand Down Expand Up @@ -1494,6 +1521,9 @@ void MarlinSettings::postprocess() {
eeprom_index = EEPROM_OFFSET;

EEPROM_WRITE(version);
#if ENABLED(EEPROM_INIT_NOW)
EEPROM_WRITE(build_hash);
#endif
EEPROM_WRITE(final_crc);

// Report storage size
Expand Down Expand Up @@ -1527,9 +1557,6 @@ void MarlinSettings::postprocess() {
char stored_ver[4];
EEPROM_READ_ALWAYS(stored_ver);

uint16_t stored_crc;
EEPROM_READ_ALWAYS(stored_crc);

// Version has to match or defaults are used
if (strncmp(version, stored_ver, 3) != 0) {
if (stored_ver[3] != '\0') {
Expand All @@ -1543,31 +1570,42 @@ void MarlinSettings::postprocess() {
eeprom_error = true;
}
else {

// Optionally reset on the first boot after flashing
#if ENABLED(EEPROM_INIT_NOW)
uint32_t stored_hash;
EEPROM_READ_ALWAYS(stored_hash);
if (stored_hash != build_hash) { EEPROM_FINISH(); return true; }
#endif

uint16_t stored_crc;
EEPROM_READ_ALWAYS(stored_crc);

float dummyf = 0;
working_crc = 0; // Init to 0. Accumulated by EEPROM_READ

_FIELD_TEST(esteppers);
_FIELD_TEST(e_factors);

// Number of esteppers may change
uint8_t esteppers;
EEPROM_READ_ALWAYS(esteppers);
// Number of e_factors may change
uint8_t e_factors;
EEPROM_READ_ALWAYS(e_factors);

//
// Planner Motion
//
{
// Get only the number of E stepper parameters previously stored
// Any steppers added later are set to their defaults
uint32_t tmp1[LINEAR_AXES + esteppers];
float tmp2[LINEAR_AXES + esteppers];
feedRate_t tmp3[LINEAR_AXES + esteppers];
uint32_t tmp1[LINEAR_AXES + e_factors];
float tmp2[LINEAR_AXES + e_factors];
feedRate_t tmp3[LINEAR_AXES + e_factors];
EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2
EEPROM_READ(planner.settings.min_segment_time_us);
EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm
EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s

if (!validating) LOOP_DISTINCT_AXES(i) {
const bool in = (i < esteppers + LINEAR_AXES);
const bool in = (i < e_factors + LINEAR_AXES);
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
Expand Down Expand Up @@ -2496,7 +2534,7 @@ void MarlinSettings::postprocess() {
return success;
}
reset();
#if ENABLED(EEPROM_AUTO_INIT)
#if EITHER(EEPROM_AUTO_INIT, EEPROM_INIT_NOW)
(void)save();
SERIAL_ECHO_MSG("EEPROM Initialized");
#endif
Expand Down
11 changes: 10 additions & 1 deletion buildroot/share/PlatformIO/scripts/preflight-checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,19 @@ def sanity_check_target():
#
# Give warnings on every build
#
warnfile = os.path.join(env['PROJECT_BUILD_DIR'], build_env, "src", "src", "inc", "Warnings.cpp.o")
srcpath = os.path.join(env['PROJECT_BUILD_DIR'], build_env, "src", "src")
warnfile = os.path.join(srcpath, "inc", "Warnings.cpp.o")
if os.path.exists(warnfile):
os.remove(warnfile)

#
# Rebuild 'settings.cpp' for EEPROM_INIT_NOW
#
if 'EEPROM_INIT_NOW' in env['MARLIN_FEATURES']:
setfile = os.path.join(srcpath, "module", "settings.cpp.o")
if os.path.exists(setfile):
os.remove(setfile)

#
# Check for old files indicating an entangled Marlin (mixing old and new code)
#
Expand Down

0 comments on commit 7b21355

Please sign in to comment.