Explorar o código

Merge pull request #1243 from mkbel/simplify_EEPROM_M500

Simplify eeprom m500
PavelSindler %!s(int64=5) %!d(string=hai) anos
pai
achega
866d6758c3

+ 156 - 274
Firmware/ConfigurationStore.cpp

@@ -1,3 +1,5 @@
+//! @file
+
 #include "Marlin.h"
 #include "planner.h"
 #include "temperature.h"
@@ -9,145 +11,69 @@
 #include "mesh_bed_leveling.h"
 #endif
 
+M500_conf cs;
+
+//! @brief Write data to EEPROM
+//! @param pos destination in EEPROM, 0 is start
+//! @param value value to be written
+//! @param size size of type pointed by value
+//! @param name name of variable written, used only for debug input if DEBUG_EEPROM_WRITE defined
+//! @retval true success
+//! @retval false failed
 #ifdef DEBUG_EEPROM_WRITE
-#define EEPROM_WRITE_VAR(pos, value) _EEPROM_writeData(pos, (uint8_t*)&value, sizeof(value), #value)
-static void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size, char* name)
+static bool EEPROM_writeData(uint8_t* pos, uint8_t* value, uint8_t size, const char* name)
 #else //DEBUG_EEPROM_WRITE
-#define EEPROM_WRITE_VAR(pos, value) _EEPROM_writeData(pos, (uint8_t*)&value, sizeof(value))
-static void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size)
+static bool EEPROM_writeData(uint8_t* pos, uint8_t* value, uint8_t size, const char*)
 #endif //DEBUG_EEPROM_WRITE
 {
 #ifdef DEBUG_EEPROM_WRITE
 	printf_P(PSTR("EEPROM_WRITE_VAR addr=0x%04x size=0x%02hhx name=%s\n"), pos, size, name);
 #endif //DEBUG_EEPROM_WRITE
-	while (size--) {
-		uint8_t * const p = (uint8_t * const)pos;
-		uint8_t v = *value;
-		// EEPROM has only ~100,000 write cycles,
-		// so only write bytes that have changed!
-		if (v != eeprom_read_byte(p)) {
-			eeprom_write_byte(p, v);
-			if (eeprom_read_byte(p) != v) {
-				SERIAL_ECHOLNPGM("EEPROM Error");
-				return;
-			}
-		}
+	while (size--)
+	{
+
+        eeprom_update_byte(pos, *value);
+        if (eeprom_read_byte(pos) != *value) {
+            SERIAL_ECHOLNPGM("EEPROM Error");
+            return false;
+        }
+
 		pos++;
 		value++;
-	};
-
+	}
+    return true;
 }
 
 #ifdef DEBUG_EEPROM_READ
-#define EEPROM_READ_VAR(pos, value) _EEPROM_readData(pos, (uint8_t*)&value, sizeof(value), #value)
-static void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size, char* name)
+static void EEPROM_readData(uint8_t* pos, uint8_t* value, uint8_t size, const char* name)
 #else //DEBUG_EEPROM_READ
-#define EEPROM_READ_VAR(pos, value) _EEPROM_readData(pos, (uint8_t*)&value, sizeof(value))
-static void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
+static void EEPROM_readData(uint8_t* pos, uint8_t* value, uint8_t size, const char*)
 #endif //DEBUG_EEPROM_READ
 {
 #ifdef DEBUG_EEPROM_READ
 	printf_P(PSTR("EEPROM_READ_VAR addr=0x%04x size=0x%02hhx name=%s\n"), pos, size, name);
 #endif //DEBUG_EEPROM_READ
-    do
+    while(size--)
     {
-        *value = eeprom_read_byte((unsigned char*)pos);
+        *value = eeprom_read_byte(pos);
         pos++;
         value++;
-    }while(--size);
+    }
 }
 
-//======================================================================================
-#define EEPROM_OFFSET 20
-// IMPORTANT:  Whenever there are changes made to the variables stored in EEPROM
-// in the functions below, also increment the version number. This makes sure that
-// the default values are used whenever there is a change to the data, to prevent
-// wrong data being written to the variables.
-// ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
-
 #define EEPROM_VERSION "V2"
 
 #ifdef EEPROM_SETTINGS
-void Config_StoreSettings(uint16_t offset) 
+void Config_StoreSettings()
 {
-  char ver[4]= "000";
-  int i = offset;
-  EEPROM_WRITE_VAR(i,ver); // invalidate data first 
-  EEPROM_WRITE_VAR(i,axis_steps_per_unit);
-  EEPROM_WRITE_VAR(i,max_feedrate_normal);
-  EEPROM_WRITE_VAR(i,max_acceleration_units_per_sq_second_normal);
-  EEPROM_WRITE_VAR(i,acceleration);
-  EEPROM_WRITE_VAR(i,retract_acceleration);
-  EEPROM_WRITE_VAR(i,minimumfeedrate);
-  EEPROM_WRITE_VAR(i,mintravelfeedrate);
-  EEPROM_WRITE_VAR(i,minsegmenttime);
-  EEPROM_WRITE_VAR(i,max_jerk[X_AXIS]);
-  EEPROM_WRITE_VAR(i,max_jerk[Y_AXIS]);
-  EEPROM_WRITE_VAR(i,max_jerk[Z_AXIS]);
-  EEPROM_WRITE_VAR(i,max_jerk[E_AXIS]);
-  EEPROM_WRITE_VAR(i,add_homing);
-/*  EEPROM_WRITE_VAR(i,plaPreheatHotendTemp);
-  EEPROM_WRITE_VAR(i,plaPreheatHPBTemp);
-  EEPROM_WRITE_VAR(i,plaPreheatFanSpeed);
-  EEPROM_WRITE_VAR(i,absPreheatHotendTemp);
-  EEPROM_WRITE_VAR(i,absPreheatHPBTemp);
-  EEPROM_WRITE_VAR(i,absPreheatFanSpeed);
-*/
+  strcpy(cs.version,"000"); //!< invalidate data first @TODO use erase to save one erase cycle
   
-  EEPROM_WRITE_VAR(i,zprobe_zoffset);
-  #ifdef PIDTEMP
-    EEPROM_WRITE_VAR(i,Kp);
-    EEPROM_WRITE_VAR(i,Ki);
-    EEPROM_WRITE_VAR(i,Kd);
-  #else
-		float dummy = 3000.0f;
-    EEPROM_WRITE_VAR(i,dummy);
-		dummy = 0.0f;
-    EEPROM_WRITE_VAR(i,dummy);
-    EEPROM_WRITE_VAR(i,dummy);
-  #endif
-  #ifdef PIDTEMPBED
-	EEPROM_WRITE_VAR(i, bedKp);
-	EEPROM_WRITE_VAR(i, bedKi);
-	EEPROM_WRITE_VAR(i, bedKd);
-  #endif
-
-  int lcd_contrast = 0;
-  EEPROM_WRITE_VAR(i,lcd_contrast);
-
-  #ifdef FWRETRACT
-  EEPROM_WRITE_VAR(i,autoretract_enabled);
-  EEPROM_WRITE_VAR(i,retract_length);
-  #if EXTRUDERS > 1
-  EEPROM_WRITE_VAR(i,retract_length_swap);
-  #endif
-  EEPROM_WRITE_VAR(i,retract_feedrate);
-  EEPROM_WRITE_VAR(i,retract_zlift);
-  EEPROM_WRITE_VAR(i,retract_recover_length);
-  #if EXTRUDERS > 1
-  EEPROM_WRITE_VAR(i,retract_recover_length_swap);
-  #endif
-  EEPROM_WRITE_VAR(i,retract_recover_feedrate);
-  #endif
-
-  // Save filament sizes
-  EEPROM_WRITE_VAR(i, volumetric_enabled);
-  EEPROM_WRITE_VAR(i, filament_size[0]);
-  #if EXTRUDERS > 1
-  EEPROM_WRITE_VAR(i, filament_size[1]);
-  #if EXTRUDERS > 2
-  EEPROM_WRITE_VAR(i, filament_size[2]);
-  #endif
-  #endif
-
+  if (EEPROM_writeData(reinterpret_cast<uint8_t*>(EEPROM_M500_base),reinterpret_cast<uint8_t*>(&cs),sizeof(cs),0), "cs, invalid version")
+  {
+      strcpy(cs.version,EEPROM_VERSION); //!< validate data if write succeed
+      EEPROM_writeData(reinterpret_cast<uint8_t*>(EEPROM_M500_base->version), reinterpret_cast<uint8_t*>(cs.version), sizeof(cs.version), "cs.version valid");
+  }
 
-
-  EEPROM_WRITE_VAR(i,max_feedrate_silent);
-  EEPROM_WRITE_VAR(i,max_acceleration_units_per_sq_second_silent);
-
-  char ver2[4]=EEPROM_VERSION;
-  i=offset;
-  EEPROM_WRITE_VAR(i,ver2); // validate data
   SERIAL_ECHO_START;
   SERIAL_ECHOLNPGM("Settings Stored");
 }
@@ -168,14 +94,14 @@ void Config_PrintSettings(uint8_t level)
 		"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s),  Z=maximum Z jerk (mm/s),  E=maximum E jerk (mm/s)\n%S  M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n"
 		"%SHome offset (mm):\n%S  M206 X%.2f Y%.2f Z%.2f\n"
 		),
-		echomagic, echomagic, axis_steps_per_unit[X_AXIS], axis_steps_per_unit[Y_AXIS], axis_steps_per_unit[Z_AXIS], axis_steps_per_unit[E_AXIS],
-		echomagic, echomagic, max_feedrate_normal[X_AXIS], max_feedrate_normal[Y_AXIS], max_feedrate_normal[Z_AXIS], max_feedrate_normal[E_AXIS],
-		echomagic, echomagic, max_feedrate_silent[X_AXIS], max_feedrate_silent[Y_AXIS], max_feedrate_silent[Z_AXIS], max_feedrate_silent[E_AXIS],
-		echomagic, echomagic, max_acceleration_units_per_sq_second_normal[X_AXIS], max_acceleration_units_per_sq_second_normal[Y_AXIS], max_acceleration_units_per_sq_second_normal[Z_AXIS], max_acceleration_units_per_sq_second_normal[E_AXIS],
-		echomagic, echomagic, max_acceleration_units_per_sq_second_silent[X_AXIS], max_acceleration_units_per_sq_second_silent[Y_AXIS], max_acceleration_units_per_sq_second_silent[Z_AXIS], max_acceleration_units_per_sq_second_silent[E_AXIS],
-		echomagic, echomagic, acceleration, retract_acceleration,
-		echomagic, echomagic, minimumfeedrate, mintravelfeedrate, minsegmenttime, max_jerk[X_AXIS], max_jerk[Y_AXIS], max_jerk[Z_AXIS], max_jerk[E_AXIS],
-		echomagic, echomagic, add_homing[X_AXIS], add_homing[Y_AXIS], add_homing[Z_AXIS]
+		echomagic, echomagic, cs.axis_steps_per_unit[X_AXIS], cs.axis_steps_per_unit[Y_AXIS], cs.axis_steps_per_unit[Z_AXIS], cs.axis_steps_per_unit[E_AXIS],
+		echomagic, echomagic, cs.max_feedrate_normal[X_AXIS], cs.max_feedrate_normal[Y_AXIS], cs.max_feedrate_normal[Z_AXIS], cs.max_feedrate_normal[E_AXIS],
+		echomagic, echomagic, cs.max_feedrate_silent[X_AXIS], cs.max_feedrate_silent[Y_AXIS], cs.max_feedrate_silent[Z_AXIS], cs.max_feedrate_silent[E_AXIS],
+		echomagic, echomagic, cs.max_acceleration_units_per_sq_second_normal[X_AXIS], cs.max_acceleration_units_per_sq_second_normal[Y_AXIS], cs.max_acceleration_units_per_sq_second_normal[Z_AXIS], cs.max_acceleration_units_per_sq_second_normal[E_AXIS],
+		echomagic, echomagic, cs.max_acceleration_units_per_sq_second_silent[X_AXIS], cs.max_acceleration_units_per_sq_second_silent[Y_AXIS], cs.max_acceleration_units_per_sq_second_silent[Z_AXIS], cs.max_acceleration_units_per_sq_second_silent[E_AXIS],
+		echomagic, echomagic, cs.acceleration, cs.retract_acceleration,
+		echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
+		echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS]
 #else //TMC2130
 	printf_P(PSTR(
 		"%SSteps per unit:\n%S  M92 X%.2f Y%.2f Z%.2f E%.2f\n"
@@ -185,21 +111,21 @@ void Config_PrintSettings(uint8_t level)
 		"%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s),  Z=maximum Z jerk (mm/s),  E=maximum E jerk (mm/s)\n%S  M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n"
 		"%SHome offset (mm):\n%S  M206 X%.2f Y%.2f Z%.2f\n"
 		),
-		echomagic, echomagic, axis_steps_per_unit[X_AXIS], axis_steps_per_unit[Y_AXIS], axis_steps_per_unit[Z_AXIS], axis_steps_per_unit[E_AXIS],
+		echomagic, echomagic, cs.axis_steps_per_unit[X_AXIS], cs.axis_steps_per_unit[Y_AXIS], cs.axis_steps_per_unit[Z_AXIS], cs.axis_steps_per_unit[E_AXIS],
 		echomagic, echomagic, max_feedrate[X_AXIS], max_feedrate[Y_AXIS], max_feedrate[Z_AXIS], max_feedrate[E_AXIS],
 		echomagic, echomagic, max_acceleration_units_per_sq_second[X_AXIS], max_acceleration_units_per_sq_second[Y_AXIS], max_acceleration_units_per_sq_second[Z_AXIS], max_acceleration_units_per_sq_second[E_AXIS],
-		echomagic, echomagic, acceleration, retract_acceleration,
-		echomagic, echomagic, minimumfeedrate, mintravelfeedrate, minsegmenttime, max_jerk[X_AXIS], max_jerk[Y_AXIS], max_jerk[Z_AXIS], max_jerk[E_AXIS],
-		echomagic, echomagic, add_homing[X_AXIS], add_homing[Y_AXIS], add_homing[Z_AXIS]
+		echomagic, echomagic, cs.acceleration, cs.retract_acceleration,
+		echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
+		echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS]
 #endif //TMC2130
 	);
 #ifdef PIDTEMP
 	printf_P(PSTR("%SPID settings:\n%S   M301 P%.2f I%.2f D%.2f\n"),
-		echomagic, echomagic, Kp, unscalePID_i(Ki), unscalePID_d(Kd));
+		echomagic, echomagic, cs.Kp, unscalePID_i(cs.Ki), unscalePID_d(cs.Kd));
 #endif
 #ifdef PIDTEMPBED
 	printf_P(PSTR("%SPID heatbed settings:\n%S   M304 P%.2f I%.2f D%.2f\n"),
-		echomagic, echomagic, bedKp, unscalePID_i(bedKi), unscalePID_d(bedKd));
+		echomagic, echomagic, cs.bedKp, unscalePID_i(cs.bedKi), unscalePID_d(cs.bedKd));
 #endif
 #ifdef FWRETRACT
 	printf_P(PSTR(
@@ -207,23 +133,23 @@ void Config_PrintSettings(uint8_t level)
 		"%SRecover: S=Extra length (mm) F:Speed (mm/m)\n%S   M208 S%.2f F%.2f\n"
 		"%SAuto-Retract: S=0 to disable, 1 to interpret extrude-only moves as retracts or recoveries\n%S   M209 S%d\n"
 		),
-		echomagic, echomagic, retract_length, retract_feedrate*60, retract_zlift,
-		echomagic, echomagic, retract_recover_length, retract_recover_feedrate*60,
-		echomagic, echomagic, (autoretract_enabled ? 1 : 0)
+		echomagic, echomagic, cs.retract_length, cs.retract_feedrate*60, cs.retract_zlift,
+		echomagic, echomagic, cs.retract_recover_length, cs.retract_recover_feedrate*60,
+		echomagic, echomagic, (cs.autoretract_enabled ? 1 : 0)
 	);
 #if EXTRUDERS > 1
 	printf_P(PSTR("%SMulti-extruder settings:\n%S   Swap retract length (mm):    %.2f\n%S   Swap rec. addl. length (mm): %.2f\n"),
 		echomagic, echomagic, retract_length_swap, echomagic, retract_recover_length_swap);
 #endif
-	if (volumetric_enabled) {
+	if (cs.volumetric_enabled) {
 		printf_P(PSTR("%SFilament settings:\n%S   M200 D%.2f\n"),
-			echomagic, echomagic, filament_size[0]);
+			echomagic, echomagic, cs.filament_size[0]);
 #if EXTRUDERS > 1
 		printf_P(PSTR("%S   M200 T1 D%.2f\n"),
-			echomagic, echomagic, filament_size[1]);
+			echomagic, echomagic, cs.filament_size[1]);
 #if EXTRUDERS > 2
 		printf_P(PSTR("%S   M200 T1 D%.2f\n"),
-			echomagic, echomagic, filament_size[2]);
+			echomagic, echomagic, cs.filament_size[2]);
 #endif
 #endif
     } else {
@@ -241,102 +167,112 @@ void Config_PrintSettings(uint8_t level)
 
 
 #ifdef EEPROM_SETTINGS
-bool Config_RetrieveSettings(uint16_t offset)
-{
-    int i=offset;
-	bool previous_settings_retrieved = true;
-    char stored_ver[4];
-    char ver[4]=EEPROM_VERSION;
-    EEPROM_READ_VAR(i,stored_ver); //read stored version
-    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
-    if (strncmp(ver,stored_ver,3) == 0)
-    {
-        // version number match
-        EEPROM_READ_VAR(i,axis_steps_per_unit);
-        EEPROM_READ_VAR(i,max_feedrate_normal);
-        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second_normal);
-        
-        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
-        
-        EEPROM_READ_VAR(i,acceleration);
-        EEPROM_READ_VAR(i,retract_acceleration);
-        EEPROM_READ_VAR(i,minimumfeedrate);
-        EEPROM_READ_VAR(i,mintravelfeedrate);
-        EEPROM_READ_VAR(i,minsegmenttime);
-        EEPROM_READ_VAR(i,max_jerk[X_AXIS]);
-        EEPROM_READ_VAR(i,max_jerk[Y_AXIS]);
-		EEPROM_READ_VAR(i,max_jerk[Z_AXIS]);
-		EEPROM_READ_VAR(i,max_jerk[E_AXIS]);
-		if (max_jerk[X_AXIS] > DEFAULT_XJERK) max_jerk[X_AXIS] = DEFAULT_XJERK;
-		if (max_jerk[Y_AXIS] > DEFAULT_YJERK) max_jerk[Y_AXIS] = DEFAULT_YJERK;
-        EEPROM_READ_VAR(i,add_homing);
-	/*
-        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
-        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
-        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
-        EEPROM_READ_VAR(i,absPreheatHotendTemp);
-        EEPROM_READ_VAR(i,absPreheatHPBTemp);
-        EEPROM_READ_VAR(i,absPreheatFanSpeed);
-        */
-
-        
-        EEPROM_READ_VAR(i,zprobe_zoffset);
-        #ifndef PIDTEMP
-        float Kp,Ki,Kd;
-        #endif
-        // do not need to scale PID values as the values in EEPROM are already scaled		
-        EEPROM_READ_VAR(i,Kp);
-        EEPROM_READ_VAR(i,Ki);
-        EEPROM_READ_VAR(i,Kd);
-		#ifdef PIDTEMPBED
-		EEPROM_READ_VAR(i, bedKp);
-		EEPROM_READ_VAR(i, bedKi);
-		EEPROM_READ_VAR(i, bedKd);
-		#endif
 
-		int lcd_contrast;
-		EEPROM_READ_VAR(i,lcd_contrast);
+static_assert (EXTRUDERS == 1, "ConfigurationStore M500_conf not implemented for more extruders, fix filament_size array size.");
+static_assert (NUM_AXIS == 4, "ConfigurationStore M500_conf not implemented for more axis."
+        "Fix axis_steps_per_unit max_feedrate_normal max_acceleration_units_per_sq_second_normal max_jerk max_feedrate_silent"
+        " max_acceleration_units_per_sq_second_silent array size.");
+#ifdef ENABLE_AUTO_BED_LEVELING
+static_assert (false, "zprobe_zoffset was not initialized in printers in field to -(Z_PROBE_OFFSET_FROM_EXTRUDER), so it contains"
+        "0.0, if this is not acceptable, increment EEPROM_VERSION to force use default_conf");
+#endif
 
-		#ifdef FWRETRACT
-		EEPROM_READ_VAR(i,autoretract_enabled);
-		EEPROM_READ_VAR(i,retract_length);
-		#if EXTRUDERS > 1
-		EEPROM_READ_VAR(i,retract_length_swap);
-		#endif
-		EEPROM_READ_VAR(i,retract_feedrate);
-		EEPROM_READ_VAR(i,retract_zlift);
-		EEPROM_READ_VAR(i,retract_recover_length);
-		#if EXTRUDERS > 1
-		EEPROM_READ_VAR(i,retract_recover_length_swap);
-		#endif
-		EEPROM_READ_VAR(i,retract_recover_feedrate);
-		#endif
+static_assert (sizeof(M500_conf) == 188, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, "
+        "or if you added members in the end of struct, ensure that historically uninitialized values will be initialized."
+        "If this is caused by change to more then 8bit processor, decide whether make this struct packed to save EEPROM,"
+        "leave as it is to keep fast code, or reorder struct members to pack more tightly.");
 
-		EEPROM_READ_VAR(i, volumetric_enabled);
-		EEPROM_READ_VAR(i, filament_size[0]);
+static const M500_conf default_conf PROGMEM =
+{
+    EEPROM_VERSION,
+    DEFAULT_AXIS_STEPS_PER_UNIT,
+    DEFAULT_MAX_FEEDRATE,
+    DEFAULT_MAX_ACCELERATION,
+    DEFAULT_ACCELERATION,
+    DEFAULT_RETRACT_ACCELERATION,
+    DEFAULT_MINIMUMFEEDRATE,
+    DEFAULT_MINTRAVELFEEDRATE,
+    DEFAULT_MINSEGMENTTIME,
+    {DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_EJERK},
+    {0,0,0},
+    -(Z_PROBE_OFFSET_FROM_EXTRUDER),
+    DEFAULT_Kp,
+    DEFAULT_Ki*PID_dT,
+    DEFAULT_Kd/PID_dT,
+    DEFAULT_bedKp,
+    DEFAULT_bedKi*PID_dT,
+    DEFAULT_bedKd/PID_dT,
+    0,
+    false,
+    RETRACT_LENGTH,
+    RETRACT_FEEDRATE,
+    RETRACT_ZLIFT,
+    RETRACT_RECOVER_LENGTH,
+    RETRACT_RECOVER_FEEDRATE,
+    false,
+    {DEFAULT_NOMINAL_FILAMENT_DIA,
 #if EXTRUDERS > 1
-		EEPROM_READ_VAR(i, filament_size[1]);
+    DEFAULT_NOMINAL_FILAMENT_DIA,
 #if EXTRUDERS > 2
-		EEPROM_READ_VAR(i, filament_size[2]);
+    DEFAULT_NOMINAL_FILAMENT_DIA,
 #endif
 #endif
+    },
+    DEFAULT_MAX_FEEDRATE_SILENT,
+    DEFAULT_MAX_ACCELERATION_SILENT,
+};
+
+//! @brief Read M500 configuration
+//! @retval true Succeeded. Stored settings retrieved or default settings retrieved in case EEPROM has been erased.
+//! @retval false Failed. Default settings has been retrieved, because of older version or corrupted data.
+bool Config_RetrieveSettings()
+{
+	bool previous_settings_retrieved = true;
+    char ver[4]=EEPROM_VERSION;
+    EEPROM_readData(reinterpret_cast<uint8_t*>(EEPROM_M500_base->version), reinterpret_cast<uint8_t*>(cs.version), sizeof(cs.version), "cs.version"); //read stored version
+    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << cs.version << "]");
+    if (strncmp(ver,cs.version,3) == 0)  // version number match
+    {
 
-    calculate_extruder_multipliers();
+        EEPROM_readData(reinterpret_cast<uint8_t*>(EEPROM_M500_base), reinterpret_cast<uint8_t*>(&cs), sizeof(cs), "cs");
 
-        EEPROM_READ_VAR(i,max_feedrate_silent);  
-        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second_silent);
+        
+		if (cs.max_jerk[X_AXIS] > DEFAULT_XJERK) cs.max_jerk[X_AXIS] = DEFAULT_XJERK;
+		if (cs.max_jerk[Y_AXIS] > DEFAULT_YJERK) cs.max_jerk[Y_AXIS] = DEFAULT_YJERK;
+        calculate_extruder_multipliers();
+
+
+		//if max_feedrate_silent and max_acceleration_units_per_sq_second_silent were never stored to eeprom, use default values:
+        {
+            const uint32_t erased = 0xffffffff;
+            bool initialized = false;
+            for (uint8_t i = 0; i < (sizeof(cs.max_feedrate_silent)/sizeof(cs.max_feedrate_silent[0])); ++i)
+            {
+                for(uint8_t j = 0; j < sizeof(float); ++j)
+                {
+                    if(0xff != reinterpret_cast<uint8_t*>(&(cs.max_feedrate_silent[i]))[j]) initialized = true;
+                }
+                if(erased != cs.max_acceleration_units_per_sq_second_silent[i]) initialized = true;
+            }
+            if (!initialized)
+            {
+                memcpy_P(&cs.max_feedrate_silent,&default_conf.max_feedrate_silent, sizeof(cs.max_feedrate_silent));
+                memcpy_P(&cs.max_acceleration_units_per_sq_second_silent,&default_conf.max_acceleration_units_per_sq_second_silent,
+                        sizeof(cs.max_acceleration_units_per_sq_second_silent));
+            }
+        }
 
 #ifdef TMC2130
 		for (uint8_t j = X_AXIS; j <= Y_AXIS; j++)
 		{
-			if (max_feedrate_normal[j] > NORMAL_MAX_FEEDRATE_XY)
-				max_feedrate_normal[j] = NORMAL_MAX_FEEDRATE_XY;
-			if (max_feedrate_silent[j] > SILENT_MAX_FEEDRATE_XY)
-				max_feedrate_silent[j] = SILENT_MAX_FEEDRATE_XY;
-			if (max_acceleration_units_per_sq_second_normal[j] > NORMAL_MAX_ACCEL_XY)
-				max_acceleration_units_per_sq_second_normal[j] = NORMAL_MAX_ACCEL_XY;
-			if (max_acceleration_units_per_sq_second_silent[j] > SILENT_MAX_ACCEL_XY)
-				max_acceleration_units_per_sq_second_silent[j] = SILENT_MAX_ACCEL_XY;
+			if (cs.max_feedrate_normal[j] > NORMAL_MAX_FEEDRATE_XY)
+				cs.max_feedrate_normal[j] = NORMAL_MAX_FEEDRATE_XY;
+			if (cs.max_feedrate_silent[j] > SILENT_MAX_FEEDRATE_XY)
+				cs.max_feedrate_silent[j] = SILENT_MAX_FEEDRATE_XY;
+			if (cs.max_acceleration_units_per_sq_second_normal[j] > NORMAL_MAX_ACCEL_XY)
+				cs.max_acceleration_units_per_sq_second_normal[j] = NORMAL_MAX_ACCEL_XY;
+			if (cs.max_acceleration_units_per_sq_second_silent[j] > SILENT_MAX_ACCEL_XY)
+				cs.max_acceleration_units_per_sq_second_silent[j] = SILENT_MAX_ACCEL_XY;
 		}
 #endif //TMC2130
 
@@ -352,9 +288,10 @@ bool Config_RetrieveSettings(uint16_t offset)
         Config_ResetDefault();
 		//Return false to inform user that eeprom version was changed and firmware is using default hardcoded settings now.
 		//In case that storing to eeprom was not used yet, do not inform user that hardcoded settings are used.
-		if (eeprom_read_byte((uint8_t *)offset) != 0xFF ||
-			eeprom_read_byte((uint8_t *)offset + 1) != 0xFF ||
-			eeprom_read_byte((uint8_t *)offset + 2) != 0xFF) {
+		if (eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[0]))) != 0xFF ||
+			eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[1]))) != 0xFF ||
+			eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[2]))) != 0xFF)
+		{
 			previous_settings_retrieved = false;
 		}
     }
@@ -367,73 +304,18 @@ bool Config_RetrieveSettings(uint16_t offset)
 
 void Config_ResetDefault()
 {
-    float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT;
-    float tmp2[]=DEFAULT_MAX_FEEDRATE;
-    long tmp3[]=DEFAULT_MAX_ACCELERATION;
-    float tmp4[]=DEFAULT_MAX_FEEDRATE_SILENT;
-    long tmp5[]=DEFAULT_MAX_ACCELERATION_SILENT;
-    for (short i=0;i<4;i++) 
-    {
-        axis_steps_per_unit[i]=tmp1[i];  
-        max_feedrate_normal[i]=tmp2[i];  
-        max_acceleration_units_per_sq_second_normal[i]=tmp3[i];
-        max_feedrate_silent[i]=tmp4[i];  
-        max_acceleration_units_per_sq_second_silent[i]=tmp5[i];
-    }
+    memcpy_P(&cs,&default_conf, sizeof(cs));
 
 	// steps per sq second need to be updated to agree with the units per sq second
     reset_acceleration_rates();
     
-    acceleration=DEFAULT_ACCELERATION;
-    retract_acceleration=DEFAULT_RETRACT_ACCELERATION;
-    minimumfeedrate=DEFAULT_MINIMUMFEEDRATE;
-    minsegmenttime=DEFAULT_MINSEGMENTTIME;       
-    mintravelfeedrate=DEFAULT_MINTRAVELFEEDRATE;
-    max_jerk[X_AXIS] = DEFAULT_XJERK;
-    max_jerk[Y_AXIS] = DEFAULT_YJERK;
-    max_jerk[Z_AXIS] = DEFAULT_ZJERK;
-    max_jerk[E_AXIS] = DEFAULT_EJERK;
-    add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0;
-
-#ifdef ENABLE_AUTO_BED_LEVELING
-    zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER;
-#endif
 #ifdef PIDTEMP
-    Kp = DEFAULT_Kp;
-    Ki = scalePID_i(DEFAULT_Ki);
-    Kd = scalePID_d(DEFAULT_Kd);
-    
-    // call updatePID (similar to when we have processed M301)
     updatePID();
-    
 #ifdef PID_ADD_EXTRUSION_RATE
-    Kc = DEFAULT_Kc;
+    Kc = DEFAULT_Kc; //this is not stored by Config_StoreSettings
 #endif//PID_ADD_EXTRUSION_RATE
 #endif//PIDTEMP
 
-#ifdef FWRETRACT
-	autoretract_enabled = false;
-	retract_length = RETRACT_LENGTH;
-#if EXTRUDERS > 1
-	retract_length_swap = RETRACT_LENGTH_SWAP;
-#endif
-	retract_feedrate = RETRACT_FEEDRATE;
-	retract_zlift = RETRACT_ZLIFT;
-	retract_recover_length = RETRACT_RECOVER_LENGTH;
-#if EXTRUDERS > 1
-	retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
-#endif
-	retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE;
-#endif
-
-	volumetric_enabled = false;
-	filament_size[0] = DEFAULT_NOMINAL_FILAMENT_DIA;
-#if EXTRUDERS > 1
-	filament_size[1] = DEFAULT_NOMINAL_FILAMENT_DIA;
-#if EXTRUDERS > 2
-	filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA;
-#endif
-#endif
 	calculate_extruder_multipliers();
 
 SERIAL_ECHO_START;

+ 39 - 2
Firmware/ConfigurationStore.h

@@ -3,6 +3,43 @@
 #define EEPROM_SETTINGS
 
 #include "Configuration.h"
+#include <stdint.h>
+#include <avr/eeprom.h>
+
+typedef struct
+{
+    char version[4];
+    float axis_steps_per_unit[4];
+    float max_feedrate_normal[4];
+    unsigned long max_acceleration_units_per_sq_second_normal[4];
+    float acceleration; //!< Normal acceleration mm/s^2  THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
+    float retract_acceleration; //!< mm/s^2 filament pull-pack and push-forward while standing still in the other axis M204 TXXXX
+    float minimumfeedrate;
+    float mintravelfeedrate;
+    unsigned long minsegmenttime;
+    float max_jerk[4]; //!< Jerk is a maximum immediate velocity change.
+    float add_homing[3];
+    float zprobe_zoffset;
+    float Kp;
+    float Ki;
+    float Kd;
+    float bedKp;
+    float bedKi;
+    float bedKd;
+    int lcd_contrast; //!< unused
+    bool autoretract_enabled;
+    float retract_length;
+    float retract_feedrate;
+    float retract_zlift;
+    float retract_recover_length;
+    float retract_recover_feedrate;
+    bool volumetric_enabled;
+    float filament_size[1]; //!< cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
+    float max_feedrate_silent[4]; //!< max speeds for silent mode
+    unsigned long max_acceleration_units_per_sq_second_silent[4];
+} M500_conf;
+
+extern M500_conf cs;
 
 void Config_ResetDefault();
 
@@ -13,8 +50,8 @@ FORCE_INLINE void Config_PrintSettings() {}
 #endif
 
 #ifdef EEPROM_SETTINGS
-void Config_StoreSettings(uint16_t offset);
-bool Config_RetrieveSettings(uint16_t offset);
+void Config_StoreSettings();
+bool Config_RetrieveSettings();
 #else
 FORCE_INLINE void Config_StoreSettings() {}
 FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); }

+ 2 - 8
Firmware/Marlin.h

@@ -269,17 +269,13 @@ extern float homing_feedrate[];
 extern bool axis_relative_modes[];
 extern int feedmultiply;
 extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
-extern bool volumetric_enabled;
 extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
-extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
 extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
 extern float current_position[NUM_AXIS] ;
 extern float destination[NUM_AXIS] ;
-extern float add_homing[3];
 extern float min_pos[3];
 extern float max_pos[3];
 extern bool axis_known_position[3];
-extern float zprobe_zoffset;
 extern int fanSpeed;
 extern void homeaxis(int axis, uint8_t cnt = 1, uint8_t* pstep = 0);
 extern int8_t lcd_change_fil_state;
@@ -290,10 +286,9 @@ extern unsigned char fanSpeedSoftPwm;
 #endif
 
 #ifdef FWRETRACT
-extern bool autoretract_enabled;
 extern bool retracted[EXTRUDERS];
-extern float retract_length, retract_length_swap, retract_feedrate, retract_zlift;
-extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
+extern float retract_length_swap;
+extern float retract_recover_length_swap;
 #endif
 
 #ifdef HOST_KEEPALIVE_FEATURE
@@ -390,7 +385,6 @@ float temp_comp_interpolation(float temperature);
 void temp_compensation_apply();
 void temp_compensation_start();
 void show_fw_version_warnings();
-void erase_eeprom_section(uint16_t offset, uint16_t bytes);
 uint8_t check_printer_version();
 
 #ifdef PINDA_THERMISTOR

+ 98 - 121
Firmware/Marlin_main.cpp

@@ -235,15 +235,7 @@ char dir_names[3][9];
 
 bool sortAlpha = false;
 
-bool volumetric_enabled = false;
-float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA
-  #if EXTRUDERS > 1
-      , DEFAULT_NOMINAL_FILAMENT_DIA
-    #if EXTRUDERS > 2
-       , DEFAULT_NOMINAL_FILAMENT_DIA
-    #endif
-  #endif
-};
+
 float extruder_multiplier[EXTRUDERS] = {1.0
   #if EXTRUDERS > 1
     , 1.0
@@ -260,13 +252,9 @@ float current_position[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0 };
 #define _z current_position[Z_AXIS]
 #define _e current_position[E_AXIS]
 
-
-float add_homing[3]={0,0,0};
-
 float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
 float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
 bool axis_known_position[3] = {false, false, false};
-float zprobe_zoffset;
 
 // Extruder offset
 #if EXTRUDERS > 1
@@ -282,7 +270,6 @@ uint8_t active_extruder = 0;
 int fanSpeed=0;
 
 #ifdef FWRETRACT
-  bool autoretract_enabled=false;
   bool retracted[EXTRUDERS]={false
     #if EXTRUDERS > 1
     , false
@@ -300,13 +287,8 @@ int fanSpeed=0;
   #endif
   };
 
-  float retract_length = RETRACT_LENGTH;
   float retract_length_swap = RETRACT_LENGTH_SWAP;
-  float retract_feedrate = RETRACT_FEEDRATE;
-  float retract_zlift = RETRACT_ZLIFT;
-  float retract_recover_length = RETRACT_RECOVER_LENGTH;
   float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
-  float retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE;
 #endif
 
   #ifdef PS_DEFAULT_OFF
@@ -884,11 +866,6 @@ uint8_t check_printer_version()
 	return version_changed;
 }
 
-void erase_eeprom_section(uint16_t offset, uint16_t bytes)
-{
-	for (unsigned int i = offset; i < (offset+bytes); i++) eeprom_write_byte((uint8_t*)i, 0xFF);
-}
-
 #ifdef BOOTAPP
 #include "bootapp.h" //bootloader support
 #endif //BOOTAPP
@@ -1205,7 +1182,7 @@ void setup()
 	bool previous_settings_retrieved = false; 
 	uint8_t hw_changed = check_printer_version();
 	if (!(hw_changed & 0b10)) { //if printer version wasn't changed, check for eeprom version and retrieve settings from eeprom in case that version wasn't changed
-		previous_settings_retrieved = Config_RetrieveSettings(EEPROM_OFFSET);
+		previous_settings_retrieved = Config_RetrieveSettings();
 	} 
 	else { //printer version was changed so use default settings 
 		Config_ResetDefault();
@@ -1503,7 +1480,7 @@ void setup()
 
   if (!previous_settings_retrieved) {
 	  lcd_show_fullscreen_message_and_wait_P(_i("Old settings found. Default PID, Esteps etc. will be set.")); //if EEPROM version or printer type was changed, inform user that default setting were loaded////MSG_DEFAULT_SETTINGS_LOADED c=20 r=4
-	  erase_eeprom_section(EEPROM_OFFSET, 156); 							   //erase M500 part of eeprom
+	  Config_StoreSettings();
   }
   if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1) {
 	  lcd_wizard(WizState::Run);
@@ -1871,9 +1848,9 @@ XYZ_CONSTS_FROM_CONFIG(float, home_retract_mm, HOME_RETRACT_MM);
 XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
 
 static void axis_is_at_home(int axis) {
-  current_position[axis] = base_home_pos(axis) + add_homing[axis];
-  min_pos[axis] =          base_min_pos(axis) + add_homing[axis];
-  max_pos[axis] =          base_max_pos(axis) + add_homing[axis];
+  current_position[axis] = base_home_pos(axis) + cs.add_homing[axis];
+  min_pos[axis] =          base_min_pos(axis) + cs.add_homing[axis];
+  max_pos[axis] =          base_max_pos(axis) + cs.add_homing[axis];
 }
 
 
@@ -1924,7 +1901,7 @@ static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
     current_position[Z_AXIS] = corrected_position.z;
 
     // put the bed at 0 so we don't go below it.
-    current_position[Z_AXIS] = zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure
+    current_position[Z_AXIS] = cs.zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure
 
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 }
@@ -1952,7 +1929,7 @@ static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float
     current_position[Z_AXIS] = corrected_position.z;
 
     // put the bed at 0 so we don't go below it.
-    current_position[Z_AXIS] = zprobe_zoffset;
+    current_position[Z_AXIS] = cs.zprobe_zoffset;
 
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 
@@ -2284,13 +2261,13 @@ void refresh_cmd_timeout(void)
       destination[Y_AXIS]=current_position[Y_AXIS];
       destination[Z_AXIS]=current_position[Z_AXIS];
       destination[E_AXIS]=current_position[E_AXIS];
-      current_position[E_AXIS]+=(swapretract?retract_length_swap:retract_length)*float(extrudemultiply)*0.01f;
+      current_position[E_AXIS]+=(swapretract?retract_length_swap:cs.retract_length)*float(extrudemultiply)*0.01f;
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate=retract_feedrate*60;
+      feedrate=cs.retract_feedrate*60;
       retracted[active_extruder]=true;
       prepare_move();
-      current_position[Z_AXIS]-=retract_zlift;
+      current_position[Z_AXIS]-=cs.retract_zlift;
       plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
       prepare_move();
       feedrate = oldFeedrate;
@@ -2299,12 +2276,12 @@ void refresh_cmd_timeout(void)
       destination[Y_AXIS]=current_position[Y_AXIS];
       destination[Z_AXIS]=current_position[Z_AXIS];
       destination[E_AXIS]=current_position[E_AXIS];
-      current_position[Z_AXIS]+=retract_zlift;
+      current_position[Z_AXIS]+=cs.retract_zlift;
       plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
-      current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(retract_length+retract_recover_length))*float(extrudemultiply)*0.01f;
+      current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(cs.retract_length+cs.retract_recover_length))*float(extrudemultiply)*0.01f;
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate=retract_recover_feedrate*60;
+      feedrate=cs.retract_recover_feedrate*60;
       retracted[active_extruder]=false;
       prepare_move();
       feedrate = oldFeedrate;
@@ -2554,10 +2531,10 @@ void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, long home_
 
 
       if(home_x_axis && home_x_value != 0)
-        current_position[X_AXIS]=home_x_value+add_homing[X_AXIS];
+        current_position[X_AXIS]=home_x_value+cs.add_homing[X_AXIS];
 
       if(home_y_axis && home_y_value != 0)
-        current_position[Y_AXIS]=home_y_value+add_homing[Y_AXIS];
+        current_position[Y_AXIS]=home_y_value+cs.add_homing[Y_AXIS];
 
       #if Z_HOME_DIR < 0                      // If homing towards BED do Z last
         #ifndef Z_SAFE_HOMING
@@ -2653,10 +2630,10 @@ void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, long home_
       #endif // Z_HOME_DIR < 0
 
       if(home_z_axis && home_z_value != 0)
-        current_position[Z_AXIS]=home_z_value+add_homing[Z_AXIS];
+        current_position[Z_AXIS]=home_z_value+cs.add_homing[Z_AXIS];
       #ifdef ENABLE_AUTO_BED_LEVELING
         if(home_z)
-          current_position[Z_AXIS] += zprobe_zoffset;  //Add Z_Probe offset (the distance is negative)
+          current_position[Z_AXIS] += cs.zprobe_zoffset;  //Add Z_Probe offset (the distance is negative)
       #endif
       
       // Set the planner and stepper routine positions.
@@ -2913,13 +2890,13 @@ void gcode_M114()
 	SERIAL_PROTOCOL(current_position[E_AXIS]);
 
 	SERIAL_PROTOCOLRPGM(_n(" Count X: "));////MSG_COUNT_X c=0 r=0
-	SERIAL_PROTOCOL(float(st_get_position(X_AXIS)) / axis_steps_per_unit[X_AXIS]);
+	SERIAL_PROTOCOL(float(st_get_position(X_AXIS)) / cs.axis_steps_per_unit[X_AXIS]);
 	SERIAL_PROTOCOLPGM(" Y:");
-	SERIAL_PROTOCOL(float(st_get_position(Y_AXIS)) / axis_steps_per_unit[Y_AXIS]);
+	SERIAL_PROTOCOL(float(st_get_position(Y_AXIS)) / cs.axis_steps_per_unit[Y_AXIS]);
 	SERIAL_PROTOCOLPGM(" Z:");
-	SERIAL_PROTOCOL(float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS]);
+	SERIAL_PROTOCOL(float(st_get_position(Z_AXIS)) / cs.axis_steps_per_unit[Z_AXIS]);
 	SERIAL_PROTOCOLPGM(" E:");
-	SERIAL_PROTOCOL(float(st_get_position(E_AXIS)) / axis_steps_per_unit[E_AXIS]);
+	SERIAL_PROTOCOL(float(st_get_position(E_AXIS)) / cs.axis_steps_per_unit[E_AXIS]);
 
 	SERIAL_PROTOCOLLN("");
 }
@@ -3720,7 +3697,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 			total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
 		}
           #ifdef FWRETRACT
-            if(autoretract_enabled)
+            if(cs.autoretract_enabled)
             if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
               float echange=destination[E_AXIS]-current_position[E_AXIS];
 
@@ -3937,7 +3914,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
             // The following code correct the Z height difference from z-probe position and hotend tip position.
             // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
             // When the bed is uneven, this height must be corrected.
-            real_z = float(st_get_position(Z_AXIS))/axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
+            real_z = float(st_get_position(Z_AXIS))/cs.axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
             x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER;
             y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
             z_tmp = current_position[Z_AXIS];
@@ -4143,7 +4120,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 					lcd_temp_cal_show_result(find_z_result);
 					break;
 				}
-				z_shift = (int)((current_position[Z_AXIS] - zero_z)*axis_steps_per_unit[Z_AXIS]);
+				z_shift = (int)((current_position[Z_AXIS] - zero_z)*cs.axis_steps_per_unit[Z_AXIS]);
 
 				printf_P(_N("\nPINDA temperature: %.1f Z shift (mm): %.3f"), current_temperature_pinda, current_position[Z_AXIS] - zero_z);
 
@@ -4230,7 +4207,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 			plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
 			st_synchronize();
 			find_bed_induction_sensor_point_z(-1.f);
-			z_shift = (int)((current_position[Z_AXIS] - zero_z)*axis_steps_per_unit[Z_AXIS]);
+			z_shift = (int)((current_position[Z_AXIS] - zero_z)*cs.axis_steps_per_unit[Z_AXIS]);
 
 			printf_P(_N("\nTemperature: %d  Z shift (mm): %.3f\n"), t_c, current_position[Z_AXIS] - zero_z);
 
@@ -4735,7 +4712,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
              plan_set_e_position(current_position[E_AXIS]);
            }
            else {
-		current_position[i] = code_value()+add_homing[i];
+		current_position[i] = code_value()+cs.add_homing[i];
             plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
            }
         }
@@ -5690,15 +5667,15 @@ Sigma_Exit:
           if(i == 3) { // E
             float value = code_value();
             if(value < 20.0) {
-              float factor = axis_steps_per_unit[i] / value; // increase e constants if M92 E14 is given for netfab.
-              max_jerk[E_AXIS] *= factor;
+              float factor = cs.axis_steps_per_unit[i] / value; // increase e constants if M92 E14 is given for netfab.
+              cs.max_jerk[E_AXIS] *= factor;
               max_feedrate[i] *= factor;
               axis_steps_per_sqr_second[i] *= factor;
             }
-            axis_steps_per_unit[i] = value;
+            cs.axis_steps_per_unit[i] = value;
           }
           else {
-            axis_steps_per_unit[i] = code_value();
+            cs.axis_steps_per_unit[i] = code_value();
           }
         }
       }
@@ -5848,18 +5825,18 @@ Sigma_Exit:
 			// setting any extruder filament size disables volumetric on the assumption that
 			// slicers either generate in extruder values as cubic mm or as as filament feeds
 			// for all extruders
-		    volumetric_enabled = false;
+		    cs.volumetric_enabled = false;
 		  } else {
-            filament_size[extruder] = (float)code_value();
+            cs.filament_size[extruder] = (float)code_value();
 			// make sure all extruders have some sane value for the filament size
-			filament_size[0] = (filament_size[0] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[0]);
+			cs.filament_size[0] = (cs.filament_size[0] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : cs.filament_size[0]);
             #if EXTRUDERS > 1
-			filament_size[1] = (filament_size[1] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[1]);
+			cs.filament_size[1] = (cs.filament_size[1] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : cs.filament_size[1]);
             #if EXTRUDERS > 2
-			filament_size[2] = (filament_size[2] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : filament_size[2]);
+			cs.filament_size[2] = (cs.filament_size[2] == 0.0 ? DEFAULT_NOMINAL_FILAMENT_DIA : cs.filament_size[2]);
             #endif
             #endif
-			volumetric_enabled = true;
+			cs.volumetric_enabled = true;
 		  }
         } else {
           //reserved for setting filament diameter via UFID or filament measuring device
@@ -5883,8 +5860,8 @@ Sigma_Exit:
 					if (val_silent > SILENT_MAX_ACCEL_XY)
 						val_silent = SILENT_MAX_ACCEL_XY;
 				}
-				max_acceleration_units_per_sq_second_normal[i] = val;
-				max_acceleration_units_per_sq_second_silent[i] = val_silent;
+				cs.max_acceleration_units_per_sq_second_normal[i] = val;
+				cs.max_acceleration_units_per_sq_second_silent[i] = val_silent;
 #else //TMC2130
 				max_acceleration_units_per_sq_second[i] = val;
 #endif //TMC2130
@@ -5896,7 +5873,7 @@ Sigma_Exit:
     #if 0 // Not used for Sprinter/grbl gen6
     case 202: // M202
       for(int8_t i=0; i < NUM_AXIS; i++) {
-        if(code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i];
+        if(code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value() * cs.axis_steps_per_unit[i];
       }
       break;
     #endif
@@ -5915,8 +5892,8 @@ Sigma_Exit:
 					if (val_silent > SILENT_MAX_FEEDRATE_XY)
 						val_silent = SILENT_MAX_FEEDRATE_XY;
 				}
-				max_feedrate_normal[i] = val;
-				max_feedrate_silent[i] = val_silent;
+				cs.max_feedrate_normal[i] = val;
+				cs.max_feedrate_silent[i] = val_silent;
 #else //TMC2130
 				max_feedrate[i] = val;
 #endif //TMC2130
@@ -5932,16 +5909,16 @@ Sigma_Exit:
           // Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware,
           // and it is also generated by Slic3r to control acceleration per extrusion type
           // (there is a separate acceleration settings in Slicer for perimeter, first layer etc).
-          acceleration = code_value();
+          cs.acceleration = code_value();
           // Interpret the T value as retract acceleration in the old Marlin format.
           if(code_seen('T'))
-            retract_acceleration = code_value();
+            cs.retract_acceleration = code_value();
         } else {
           // New acceleration format, compatible with the upstream Marlin.
           if(code_seen('P'))
-            acceleration = code_value();
+            cs.acceleration = code_value();
           if(code_seen('R'))
-            retract_acceleration = code_value();
+            cs.retract_acceleration = code_value();
           if(code_seen('T')) {
             // Interpret the T value as the travel acceleration in the new Marlin format.
             //FIXME Prusa3D firmware currently does not support travel acceleration value independent from the extruding acceleration value.
@@ -5952,21 +5929,21 @@ Sigma_Exit:
       break;
     case 205: //M205 advanced settings:  minimum travel speed S=while printing T=travel only,  B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk
     {
-      if(code_seen('S')) minimumfeedrate = code_value();
-      if(code_seen('T')) mintravelfeedrate = code_value();
-      if(code_seen('B')) minsegmenttime = code_value() ;
-      if(code_seen('X')) max_jerk[X_AXIS] = max_jerk[Y_AXIS] = code_value();
-      if(code_seen('Y')) max_jerk[Y_AXIS] = code_value();
-      if(code_seen('Z')) max_jerk[Z_AXIS] = code_value();
-      if(code_seen('E')) max_jerk[E_AXIS] = code_value();
-		if (max_jerk[X_AXIS] > DEFAULT_XJERK) max_jerk[X_AXIS] = DEFAULT_XJERK;
-		if (max_jerk[Y_AXIS] > DEFAULT_YJERK) max_jerk[Y_AXIS] = DEFAULT_YJERK;
+      if(code_seen('S')) cs.minimumfeedrate = code_value();
+      if(code_seen('T')) cs.mintravelfeedrate = code_value();
+      if(code_seen('B')) cs.minsegmenttime = code_value() ;
+      if(code_seen('X')) cs.max_jerk[X_AXIS] = cs.max_jerk[Y_AXIS] = code_value();
+      if(code_seen('Y')) cs.max_jerk[Y_AXIS] = code_value();
+      if(code_seen('Z')) cs.max_jerk[Z_AXIS] = code_value();
+      if(code_seen('E')) cs.max_jerk[E_AXIS] = code_value();
+		if (cs.max_jerk[X_AXIS] > DEFAULT_XJERK) cs.max_jerk[X_AXIS] = DEFAULT_XJERK;
+		if (cs.max_jerk[Y_AXIS] > DEFAULT_YJERK) cs.max_jerk[Y_AXIS] = DEFAULT_YJERK;
     }
     break;
     case 206: // M206 additional homing offset
       for(int8_t i=0; i < 3; i++)
       {
-        if(code_seen(axis_codes[i])) add_homing[i] = code_value();
+        if(code_seen(axis_codes[i])) cs.add_homing[i] = code_value();
       }
       break;
     #ifdef FWRETRACT
@@ -5974,26 +5951,26 @@ Sigma_Exit:
     {
       if(code_seen('S'))
       {
-        retract_length = code_value() ;
+        cs.retract_length = code_value() ;
       }
       if(code_seen('F'))
       {
-        retract_feedrate = code_value()/60 ;
+        cs.retract_feedrate = code_value()/60 ;
       }
       if(code_seen('Z'))
       {
-        retract_zlift = code_value() ;
+        cs.retract_zlift = code_value() ;
       }
     }break;
     case 208: // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
     {
       if(code_seen('S'))
       {
-        retract_recover_length = code_value() ;
+        cs.retract_recover_length = code_value() ;
       }
       if(code_seen('F'))
       {
-        retract_recover_feedrate = code_value()/60 ;
+        cs.retract_recover_feedrate = code_value()/60 ;
       }
     }break;
     case 209: // M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
@@ -6005,7 +5982,7 @@ Sigma_Exit:
         {
           case 0: 
           {
-            autoretract_enabled=false;
+            cs.autoretract_enabled=false;
             retracted[0]=false;
             #if EXTRUDERS > 1
               retracted[1]=false;
@@ -6016,7 +5993,7 @@ Sigma_Exit:
           }break;
           case 1: 
           {
-            autoretract_enabled=true;
+            cs.autoretract_enabled=true;
             retracted[0]=false;
             #if EXTRUDERS > 1
               retracted[1]=false;
@@ -6207,9 +6184,9 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
     #ifdef PIDTEMP
     case 301: // M301
       {
-        if(code_seen('P')) Kp = code_value();
-        if(code_seen('I')) Ki = scalePID_i(code_value());
-        if(code_seen('D')) Kd = scalePID_d(code_value());
+        if(code_seen('P')) cs.Kp = code_value();
+        if(code_seen('I')) cs.Ki = scalePID_i(code_value());
+        if(code_seen('D')) cs.Kd = scalePID_d(code_value());
 
         #ifdef PID_ADD_EXTRUSION_RATE
         if(code_seen('C')) Kc = code_value();
@@ -6218,11 +6195,11 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
         updatePID();
         SERIAL_PROTOCOLRPGM(_T(MSG_OK));
         SERIAL_PROTOCOL(" p:");
-        SERIAL_PROTOCOL(Kp);
+        SERIAL_PROTOCOL(cs.Kp);
         SERIAL_PROTOCOL(" i:");
-        SERIAL_PROTOCOL(unscalePID_i(Ki));
+        SERIAL_PROTOCOL(unscalePID_i(cs.Ki));
         SERIAL_PROTOCOL(" d:");
-        SERIAL_PROTOCOL(unscalePID_d(Kd));
+        SERIAL_PROTOCOL(unscalePID_d(cs.Kd));
         #ifdef PID_ADD_EXTRUSION_RATE
         SERIAL_PROTOCOL(" c:");
         //Kc does not have scaling applied above, or in resetting defaults
@@ -6235,18 +6212,18 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
     #ifdef PIDTEMPBED
     case 304: // M304
       {
-        if(code_seen('P')) bedKp = code_value();
-        if(code_seen('I')) bedKi = scalePID_i(code_value());
-        if(code_seen('D')) bedKd = scalePID_d(code_value());
+        if(code_seen('P')) cs.bedKp = code_value();
+        if(code_seen('I')) cs.bedKi = scalePID_i(code_value());
+        if(code_seen('D')) cs.bedKd = scalePID_d(code_value());
 
         updatePID();
        	SERIAL_PROTOCOLRPGM(_T(MSG_OK));
         SERIAL_PROTOCOL(" p:");
-        SERIAL_PROTOCOL(bedKp);
+        SERIAL_PROTOCOL(cs.bedKp);
         SERIAL_PROTOCOL(" i:");
-        SERIAL_PROTOCOL(unscalePID_i(bedKi));
+        SERIAL_PROTOCOL(unscalePID_i(cs.bedKi));
         SERIAL_PROTOCOL(" d:");
-        SERIAL_PROTOCOL(unscalePID_d(bedKd));
+        SERIAL_PROTOCOL(unscalePID_d(cs.bedKd));
         SERIAL_PROTOCOLLN("");
       }
       break;
@@ -6328,12 +6305,12 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 
     case 500: // M500 Store settings in EEPROM
     {
-        Config_StoreSettings(EEPROM_OFFSET);
+        Config_StoreSettings();
     }
     break;
     case 501: // M501 Read settings from EEPROM
     {
-        Config_RetrieveSettings(EEPROM_OFFSET);
+        Config_RetrieveSettings();
     }
     break;
     case 502: // M502 Revert to default settings
@@ -6370,7 +6347,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
         value = code_value();
         if ((Z_PROBE_OFFSET_RANGE_MIN <= value) && (value <= Z_PROBE_OFFSET_RANGE_MAX))
         {
-          zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp
+          cs.zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp
           SERIAL_ECHO_START;
           SERIAL_ECHOLNRPGM(CAT4(MSG_ZPROBE_ZOFFSET, " ", _T(MSG_OK),PSTR("")));
           SERIAL_PROTOCOLLN("");
@@ -6390,7 +6367,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
       {
           SERIAL_ECHO_START;
           SERIAL_ECHOLNRPGM(CAT2(MSG_ZPROBE_ZOFFSET, PSTR(" : ")));
-          SERIAL_ECHO(-zprobe_zoffset);
+          SERIAL_ECHO(-cs.zprobe_zoffset);
           SERIAL_PROTOCOLLN("");
       }
       break;
@@ -6540,7 +6517,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 			for (uint8_t i = 0; i < 6; i++)
 			{
 				if(i>0) EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + (i-1) * 2, &usteps);
-				float mm = ((float)usteps) / axis_steps_per_unit[Z_AXIS];
+				float mm = ((float)usteps) / cs.axis_steps_per_unit[Z_AXIS];
 				i == 0 ? SERIAL_PROTOCOLPGM("n/a") : SERIAL_PROTOCOL(i - 1);
 				SERIAL_PROTOCOLPGM(", ");
 				SERIAL_PROTOCOL(35 + (i * 5));
@@ -6583,7 +6560,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 					{
 						usteps = 0;
 						if (i>0) EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + (i - 1) * 2, &usteps);
-						float mm = ((float)usteps) / axis_steps_per_unit[Z_AXIS];
+						float mm = ((float)usteps) / cs.axis_steps_per_unit[Z_AXIS];
 						i == 0 ? SERIAL_PROTOCOLPGM("n/a") : SERIAL_PROTOCOL(i - 1);
 						SERIAL_PROTOCOLPGM(", ");
 						SERIAL_PROTOCOL(35 + (i * 5));
@@ -6732,13 +6709,13 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 				if (res_new > res)
 				{
 					uint16_t fac = (res_new / res);
-					axis_steps_per_unit[axis] *= fac;
+					cs.axis_steps_per_unit[axis] *= fac;
 					position[E_AXIS] *= fac;
 				}
 				else
 				{
 					uint16_t fac = (res / res_new);
-					axis_steps_per_unit[axis] /= fac;
+					cs.axis_steps_per_unit[axis] /= fac;
 					position[E_AXIS] /= fac;
 				}
 			}
@@ -7147,7 +7124,7 @@ void clamp_to_software_endstops(float target[3])
         float negative_z_offset = 0;
         #ifdef ENABLE_AUTO_BED_LEVELING
             if (Z_PROBE_OFFSET_FROM_EXTRUDER < 0) negative_z_offset = negative_z_offset + Z_PROBE_OFFSET_FROM_EXTRUDER;
-            if (add_homing[Z_AXIS] < 0) negative_z_offset = negative_z_offset + add_homing[Z_AXIS];
+            if (cs.add_homing[Z_AXIS] < 0) negative_z_offset = negative_z_offset + cs.add_homing[Z_AXIS];
         #endif
         if (target[Z_AXIS] < min_pos[Z_AXIS]+negative_z_offset) target[Z_AXIS] = min_pos[Z_AXIS]+negative_z_offset;
     }
@@ -7455,8 +7432,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s
      float oldepos=current_position[E_AXIS];
      float oldedes=destination[E_AXIS];
      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
-                      destination[E_AXIS]+EXTRUDER_RUNOUT_EXTRUDE*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS],
-                      EXTRUDER_RUNOUT_SPEED/60.*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS], active_extruder);
+                      destination[E_AXIS]+EXTRUDER_RUNOUT_EXTRUDE*EXTRUDER_RUNOUT_ESTEPS/cs.axis_steps_per_unit[E_AXIS],
+                      EXTRUDER_RUNOUT_SPEED/60.*EXTRUDER_RUNOUT_ESTEPS/cs.axis_steps_per_unit[E_AXIS], active_extruder);
      current_position[E_AXIS]=oldepos;
      destination[E_AXIS]=oldedes;
      plan_set_e_position(oldepos);
@@ -7661,7 +7638,7 @@ void save_statistics(unsigned long _total_filament_used, unsigned long _total_pr
 
 float calculate_extruder_multiplier(float diameter) {
   float out = 1.f;
-  if (volumetric_enabled && diameter > 0.f) {
+  if (cs.volumetric_enabled && diameter > 0.f) {
     float area = M_PI * diameter * diameter * 0.25;
     out = 1.f / area;
   }
@@ -7671,11 +7648,11 @@ float calculate_extruder_multiplier(float diameter) {
 }
 
 void calculate_extruder_multipliers() {
-	extruder_multiplier[0] = calculate_extruder_multiplier(filament_size[0]);
+	extruder_multiplier[0] = calculate_extruder_multiplier(cs.filament_size[0]);
 #if EXTRUDERS > 1
-	extruder_multiplier[1] = calculate_extruder_multiplier(filament_size[1]);
+	extruder_multiplier[1] = calculate_extruder_multiplier(cs.filament_size[1]);
 #if EXTRUDERS > 2
-	extruder_multiplier[2] = calculate_extruder_multiplier(filament_size[2]);
+	extruder_multiplier[2] = calculate_extruder_multiplier(cs.filament_size[2]);
 #endif
 #endif
 }
@@ -8035,10 +8012,10 @@ void temp_compensation_apply() {
 		if (target_temperature_bed % 10 == 0 && target_temperature_bed >= 60 && target_temperature_bed <= 100) {
 			i_add = (target_temperature_bed - 60) / 10;
 			EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + i_add * 2, &z_shift);
-			z_shift_mm = z_shift / axis_steps_per_unit[Z_AXIS];
+			z_shift_mm = z_shift / cs.axis_steps_per_unit[Z_AXIS];
 		}else {
 			//interpolation
-			z_shift_mm = temp_comp_interpolation(target_temperature_bed) / axis_steps_per_unit[Z_AXIS];
+			z_shift_mm = temp_comp_interpolation(target_temperature_bed) / cs.axis_steps_per_unit[Z_AXIS];
 		}
 		printf_P(_N("\nZ shift applied:%.3f\n"), z_shift_mm);
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] - z_shift_mm, current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
@@ -8121,7 +8098,7 @@ float temp_compensation_pinda_thermistor_offset(float temperature_pinda)
 {
 	if (!temp_cal_active) return 0;
 	if (!calibration_status_pinda()) return 0;
-	return temp_comp_interpolation(temperature_pinda) / axis_steps_per_unit[Z_AXIS];
+	return temp_comp_interpolation(temperature_pinda) / cs.axis_steps_per_unit[Z_AXIS];
 }
 #endif //PINDA_THERMISTOR
 
@@ -8237,7 +8214,7 @@ void uvlo_()
 		plan_buffer_line(
       current_position[X_AXIS], 
       current_position[Y_AXIS], 
-      current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / axis_steps_per_unit[Z_AXIS], 
+      current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS], 
       current_position[E_AXIS] - default_retraction,
       40, active_extruder);
     
@@ -8247,7 +8224,7 @@ void uvlo_()
     plan_buffer_line(
                      current_position[X_AXIS],
                      current_position[Y_AXIS],
-                     current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / axis_steps_per_unit[Z_AXIS],
+                     current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS],
                      current_position[E_AXIS] - default_retraction,
                      40, active_extruder);
     st_synchronize();
@@ -8339,7 +8316,7 @@ plan_buffer_line(
      current_position[X_AXIS], 
      current_position[Y_AXIS], 
 //     current_position[Z_AXIS]+float((1024-z_microsteps+7)>>4)/axis_steps_per_unit[Z_AXIS], 
-     current_position[Z_AXIS]+UVLO_Z_AXIS_SHIFT+float((1024-z_microsteps+7)>>4)/axis_steps_per_unit[Z_AXIS], 
+     current_position[Z_AXIS]+UVLO_Z_AXIS_SHIFT+float((1024-z_microsteps+7)>>4)/cs.axis_steps_per_unit[Z_AXIS], 
      current_position[E_AXIS],
      40, active_extruder);
 st_synchronize();
@@ -8463,10 +8440,10 @@ void recover_machine_state_after_power_panic(bool bTiny)
   // The current position after power panic is moved to the next closest 0th full step.
   if(bTiny)
     current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z)) + 
-    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS)) + 7) >> 4) / axis_steps_per_unit[Z_AXIS];
+    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS];
   else
     current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) + 
-    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / axis_steps_per_unit[Z_AXIS];
+    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS];
   if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS)) {
 	  current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
 	  sprintf_P(cmd, PSTR("G92 E"));

+ 5 - 2
Firmware/eeprom.h

@@ -182,7 +182,10 @@
 // Magic string, indicating that the current or the previous firmware running was the Prusa3D firmware.
 #define EEPROM_FIRMWARE_PRUSA_MAGIC 0
 
-#define EEPROM_OFFSET 20 //offset for storing settings using M500
-//#define EEPROM_OFFSET 
+#ifdef __cplusplus
+#include "ConfigurationStore.h"
+static M500_conf * const EEPROM_M500_base = reinterpret_cast<M500_conf*>(20); //offset for storing settings using M500
+#endif
+
 
 #endif // EEPROM_H

+ 2 - 1
Firmware/fsensor.cpp

@@ -10,6 +10,7 @@
 #include "fastio.h"
 #include "cmdqueue.h"
 #include "ultralcd.h"
+#include "ConfigurationStore.h"
 
 //! @name Basic parameters
 //! @{
@@ -118,7 +119,7 @@ void fsensor_init(void)
     printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
 	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
-	fsensor_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * axis_steps_per_unit[E_AXIS]);
+	fsensor_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * cs.axis_steps_per_unit[E_AXIS]);
 
 	if (!pat9125)
 	{

+ 2 - 2
Firmware/mesh_bed_calibration.cpp

@@ -3020,7 +3020,7 @@ void babystep_apply()
 {
     babystep_load();
 #ifdef BABYSTEP_LOADZ_BY_PLANNER
-    shift_z(- float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
+    shift_z(- float(babystepLoadZ) / float(cs.axis_steps_per_unit[Z_AXIS]));
 #else
     babystepsTodoZadd(babystepLoadZ);
 #endif /* BABYSTEP_LOADZ_BY_PLANNER */
@@ -3029,7 +3029,7 @@ void babystep_apply()
 void babystep_undo()
 {
 #ifdef BABYSTEP_LOADZ_BY_PLANNER
-      shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS]));
+      shift_z(float(babystepLoadZ) / float(cs.axis_steps_per_unit[Z_AXIS]));
 #else
       babystepsTodoZsubtract(babystepLoadZ);
 #endif /* BABYSTEP_LOADZ_BY_PLANNER */

+ 46 - 60
Firmware/planner.cpp

@@ -57,6 +57,7 @@
 #include "temperature.h"
 #include "ultralcd.h"
 #include "language.h"
+#include "ConfigurationStore.h"
 
 #ifdef MESH_BED_LEVELING
 #include "mesh_bed_leveling.h"
@@ -71,27 +72,12 @@
 //=============================public variables ============================
 //===========================================================================
 
-unsigned long minsegmenttime;
-
 // Use M203 to override by software
-float max_feedrate_normal[NUM_AXIS];       // max speeds for normal mode
-float max_feedrate_silent[NUM_AXIS];       // max speeds for silent mode
-float* max_feedrate = max_feedrate_normal;
+float* max_feedrate = cs.max_feedrate_normal;
 
-// Use M92 to override by software
-float axis_steps_per_unit[NUM_AXIS];
 
 // Use M201 to override by software
-unsigned long max_acceleration_units_per_sq_second_normal[NUM_AXIS];
-unsigned long max_acceleration_units_per_sq_second_silent[NUM_AXIS];
-unsigned long* max_acceleration_units_per_sq_second = max_acceleration_units_per_sq_second_normal;
-
-float minimumfeedrate;
-float acceleration;         // Normal acceleration mm/s^2  THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
-float retract_acceleration; //  mm/s^2   filament pull-pack and push-forward  while standing still in the other axis M204 TXXXX
-// Jerk is a maximum immediate velocity change.
-float max_jerk[NUM_AXIS];
-float mintravelfeedrate;
+unsigned long* max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_normal;
 unsigned long axis_steps_per_sqr_second[NUM_AXIS];
 
 #ifdef ENABLE_AUTO_BED_LEVELING
@@ -623,9 +609,9 @@ void planner_abort_hard()
         else {
             float t = float(step_events_completed) / float(current_block->step_event_count);
             float vec[3] = { 
-              current_block->steps_x / axis_steps_per_unit[X_AXIS],
-              current_block->steps_y / axis_steps_per_unit[Y_AXIS],
-              current_block->steps_z / axis_steps_per_unit[Z_AXIS]
+              current_block->steps_x / cs.axis_steps_per_unit[X_AXIS],
+              current_block->steps_y / cs.axis_steps_per_unit[Y_AXIS],
+              current_block->steps_z / cs.axis_steps_per_unit[Z_AXIS]
             };
             float pos1[3], pos2[3];
             for (int8_t i = 0; i < 3; ++ i) {
@@ -743,18 +729,18 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
   // Calculate target position in absolute steps
   //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
   long target[4];
-  target[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);
-  target[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
+  target[X_AXIS] = lround(x*cs.axis_steps_per_unit[X_AXIS]);
+  target[Y_AXIS] = lround(y*cs.axis_steps_per_unit[Y_AXIS]);
 #ifdef MESH_BED_LEVELING
     if (mbl.active){
-        target[Z_AXIS] = lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]);
+        target[Z_AXIS] = lround((z+mbl.get_z(x, y))*cs.axis_steps_per_unit[Z_AXIS]);
     }else{
-        target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
+        target[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
     }
 #else
-    target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
+    target[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
 #endif // ENABLE_MESH_BED_LEVELING
-  target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
+  target[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
   
 #ifdef LIN_ADVANCE
     const float mm_D_float = sqrt(sq(x - position_float[X_AXIS]) + sq(y - position_float[Y_AXIS]));
@@ -776,7 +762,7 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
     }
     
     #ifdef PREVENT_LENGTHY_EXTRUDE
-    if(labs(target[E_AXIS]-position[E_AXIS])>axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
+    if(labs(target[E_AXIS]-position[E_AXIS])>cs.axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
     {
       position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
 #ifdef LIN_ADVANCE
@@ -915,11 +901,11 @@ block->steps_y.wide = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-p
 
   if (block->steps_e.wide == 0)
   {
-    if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate;
+    if(feed_rate<cs.mintravelfeedrate) feed_rate=cs.mintravelfeedrate;
   }
   else
   {
-    if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate;
+    if(feed_rate<cs.minimumfeedrate) feed_rate=cs.minimumfeedrate;
   } 
 
 /* This part of the code calculates the total length of the movement. 
@@ -931,17 +917,17 @@ Having the real displacement of the head, we can calculate the total movement le
 */ 
   #ifndef COREXY
     float delta_mm[4];
-    delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
-    delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
+    delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/cs.axis_steps_per_unit[X_AXIS];
+    delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/cs.axis_steps_per_unit[Y_AXIS];
   #else
     float delta_mm[6];
-    delta_mm[X_HEAD] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
-    delta_mm[Y_HEAD] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
-    delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[X_AXIS];
-    delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS];
+    delta_mm[X_HEAD] = (target[X_AXIS]-position[X_AXIS])/cs.axis_steps_per_unit[X_AXIS];
+    delta_mm[Y_HEAD] = (target[Y_AXIS]-position[Y_AXIS])/cs.axis_steps_per_unit[Y_AXIS];
+    delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/cs.axis_steps_per_unit[X_AXIS];
+    delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/cs.axis_steps_per_unit[Y_AXIS];
   #endif
-  delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
-  delta_mm[E_AXIS] = (target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS];
+  delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/cs.axis_steps_per_unit[Z_AXIS];
+  delta_mm[E_AXIS] = (target[E_AXIS]-position[E_AXIS])/cs.axis_steps_per_unit[E_AXIS];
   if ( block->steps_x.wide <=dropsegments && block->steps_y.wide <=dropsegments && block->steps_z.wide <=dropsegments )
   {
     block->millimeters = fabs(delta_mm[E_AXIS]);
@@ -968,9 +954,9 @@ Having the real displacement of the head, we can calculate the total movement le
   if (moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE >> 1)) {
       // segment time in micro seconds
       unsigned long segment_time = lround(1000000.0/inverse_second);
-      if (segment_time < minsegmenttime)
+      if (segment_time < cs.minsegmenttime)
           // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
-          inverse_second=1000000.0/(segment_time+lround(2*(minsegmenttime-segment_time)/moves_queued));
+          inverse_second=1000000.0/(segment_time+lround(2*(cs.minsegmenttime-segment_time)/moves_queued));
   }
 #endif // SLOWDOWN
 
@@ -1008,11 +994,11 @@ Having the real displacement of the head, we can calculate the total movement le
   float steps_per_mm = block->step_event_count.wide/block->millimeters;
   if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0)
   {
-    block->acceleration_st = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
+    block->acceleration_st = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
   }
   else
   {
-    block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
+    block->acceleration_st = ceil(cs.acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
     // Limit acceleration per axis
     //FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
     if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
@@ -1051,20 +1037,20 @@ Having the real displacement of the head, we can calculate the total movement le
   bool  limited = false;
   for (uint8_t axis = 0; axis < 4; ++ axis) {
       float jerk = fabs(current_speed[axis]);
-      if (jerk > max_jerk[axis]) {
+      if (jerk > cs.max_jerk[axis]) {
           // The actual jerk is lower, if it has been limited by the XY jerk.
           if (limited) {
               // Spare one division by a following gymnastics:
               // Instead of jerk *= safe_speed / block->nominal_speed,
               // multiply max_jerk[axis] by the divisor.
               jerk *= safe_speed;
-              float mjerk = max_jerk[axis] * block->nominal_speed;
+              float mjerk = cs.max_jerk[axis] * block->nominal_speed;
               if (jerk > mjerk) {
                   safe_speed *= mjerk / jerk;
                   limited = true;
               }
           } else {
-              safe_speed = max_jerk[axis];
+              safe_speed = cs.max_jerk[axis];
               limited = true;
           }
       }
@@ -1117,8 +1103,8 @@ Having the real displacement of the head, we can calculate the total movement le
                       (v_entry - v_exit) :
                       // axis reversal
                       max(- v_exit, v_entry));
-          if (jerk > max_jerk[axis]) {
-              v_factor *= max_jerk[axis] / jerk;
+          if (jerk > cs.max_jerk[axis]) {
+              v_factor *= cs.max_jerk[axis] / jerk;
               limited = true;
           }
       }
@@ -1188,7 +1174,7 @@ Having the real displacement of the head, we can calculate the total movement le
                           extruder_advance_k
                           * ((advance_ed_ratio < 0.000001) ? de_float / mm_D_float : advance_ed_ratio) // Use the fixed ratio, if set
                           * (block->nominal_speed / (float)block->nominal_rate)
-                          * axis_steps_per_unit[E_AXIS] * 256.0
+                          * cs.axis_steps_per_unit[E_AXIS] * 256.0
                           );
 #endif
     
@@ -1263,16 +1249,16 @@ void plan_set_position(float x, float y, float z, const float &e)
         y = world2machine_rotation_and_skew[1][0] * tmpx + world2machine_rotation_and_skew[1][1] * tmpy + world2machine_shift[1];
     }
 
-  position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);
-  position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
+  position[X_AXIS] = lround(x*cs.axis_steps_per_unit[X_AXIS]);
+  position[Y_AXIS] = lround(y*cs.axis_steps_per_unit[Y_AXIS]);
 #ifdef MESH_BED_LEVELING
   position[Z_AXIS] = mbl.active ? 
-    lround((z+mbl.get_z(x, y))*axis_steps_per_unit[Z_AXIS]) :
-    lround(z*axis_steps_per_unit[Z_AXIS]);
+    lround((z+mbl.get_z(x, y))*cs.axis_steps_per_unit[Z_AXIS]) :
+    lround(z*cs.axis_steps_per_unit[Z_AXIS]);
 #else
-  position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
+  position[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
 #endif // ENABLE_MESH_BED_LEVELING
-  position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
+  position[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
 #ifdef LIN_ADVANCE
   position_float[X_AXIS] = x;
   position_float[Y_AXIS] = y;
@@ -1293,7 +1279,7 @@ void plan_set_z_position(const float &z)
 	#ifdef LIN_ADVANCE
 	position_float[Z_AXIS] = z;
 	#endif
-    position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
+    position[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
     st_set_position(position[X_AXIS], position[Y_AXIS], position[Z_AXIS], position[E_AXIS]);
 }
 
@@ -1302,7 +1288,7 @@ void plan_set_e_position(const float &e)
   #ifdef LIN_ADVANCE
   position_float[E_AXIS] = e;
   #endif
-  position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);  
+  position[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);  
   st_set_e_position(position[E_AXIS]);
 }
 
@@ -1317,7 +1303,7 @@ void set_extrude_min_temp(float temp)
 void reset_acceleration_rates()
 {
 	for(int8_t i=0; i < NUM_AXIS; i++)
-        axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
+        axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * cs.axis_steps_per_unit[i];
 }
 
 #ifdef TMC2130
@@ -1325,13 +1311,13 @@ void update_mode_profile()
 {
 	if (tmc2130_mode == TMC2130_MODE_NORMAL)
 	{
-		max_feedrate = max_feedrate_normal;
-		max_acceleration_units_per_sq_second = max_acceleration_units_per_sq_second_normal;
+		max_feedrate = cs.max_feedrate_normal;
+		max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_normal;
 	}
 	else if (tmc2130_mode == TMC2130_MODE_SILENT)
 	{
-		max_feedrate = max_feedrate_silent;
-		max_acceleration_units_per_sq_second = max_acceleration_units_per_sq_second_silent;
+		max_feedrate = cs.max_feedrate_silent;
+		max_acceleration_units_per_sq_second = cs.max_acceleration_units_per_sq_second_silent;
 	}
 	reset_acceleration_rates();
 }

+ 0 - 15
Firmware/planner.h

@@ -158,27 +158,12 @@ extern bool e_active();
 
 void check_axes_activity();
 
-extern unsigned long minsegmenttime;
-
 // Use M203 to override by software
-extern float max_feedrate_normal[NUM_AXIS];
-extern float max_feedrate_silent[NUM_AXIS];
 extern float* max_feedrate;
 
-// Use M92 to override by software
-extern float axis_steps_per_unit[NUM_AXIS];
 
 // Use M201 to override by software
-extern unsigned long max_acceleration_units_per_sq_second_normal[NUM_AXIS];
-extern unsigned long max_acceleration_units_per_sq_second_silent[NUM_AXIS];
 extern unsigned long* max_acceleration_units_per_sq_second; 
-
-extern float minimumfeedrate;
-extern float acceleration;         // Normal acceleration mm/s^2  THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
-extern float retract_acceleration; //  mm/s^2   filament pull-pack and push-forward  while standing still in the other axis M204 TXXXX
-// Jerk is a maximum immediate velocity change.
-extern float max_jerk[NUM_AXIS];
-extern float mintravelfeedrate;
 extern unsigned long axis_steps_per_sqr_second[NUM_AXIS];
 
 extern long position[NUM_AXIS];

+ 5 - 4
Firmware/stepper.cpp

@@ -42,6 +42,7 @@ int fsensor_counter = 0; //counter for e-steps
 #endif //FILAMENT_SENSOR
 
 #include "mmu.h"
+#include "ConfigurationStore.h"
 
 #ifdef DEBUG_STACK_MONITOR
 uint16_t SP_min = 0x21FF;
@@ -229,15 +230,15 @@ void checkHitEndstops()
    SERIAL_ECHO_START;
    SERIAL_ECHORPGM(_T(MSG_ENDSTOPS_HIT));
    if(endstop_x_hit) {
-     SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/axis_steps_per_unit[X_AXIS]);
+     SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/cs.axis_steps_per_unit[X_AXIS]);
 //     LCD_MESSAGERPGM(CAT2(_T(MSG_ENDSTOPS_HIT), PSTR("X")));
    }
    if(endstop_y_hit) {
-     SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/axis_steps_per_unit[Y_AXIS]);
+     SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/cs.axis_steps_per_unit[Y_AXIS]);
 //     LCD_MESSAGERPGM(CAT2(_T(MSG_ENDSTOPS_HIT), PSTR("Y")));
    }
    if(endstop_z_hit) {
-     SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]);
+     SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/cs.axis_steps_per_unit[Z_AXIS]);
 //     LCD_MESSAGERPGM(CAT2(_T(MSG_ENDSTOPS_HIT),PSTR("Z")));
    }
    SERIAL_ECHOLN("");
@@ -1380,7 +1381,7 @@ void st_get_position_xy(long &x, long &y)
 float st_get_position_mm(uint8_t axis)
 {
   float steper_position_in_steps = st_get_position(axis);
-  return steper_position_in_steps / axis_steps_per_unit[axis];
+  return steper_position_in_steps / cs.axis_steps_per_unit[axis];
 }
 
 

+ 11 - 19
Firmware/temperature.cpp

@@ -39,6 +39,7 @@
 
 #include <avr/wdt.h>
 #include "adc.h"
+#include "ConfigurationStore.h"
 
 
 //===========================================================================
@@ -79,19 +80,10 @@ float current_temperature_bed = 0.0;
   float _Kp, _Ki, _Kd;
   int pid_cycle, pid_number_of_cycles;
   bool pid_tuning_finished = false;
-  float Kp=DEFAULT_Kp;
-  float Ki=(DEFAULT_Ki*PID_dT);
-  float Kd=(DEFAULT_Kd/PID_dT);
   #ifdef PID_ADD_EXTRUSION_RATE
     float Kc=DEFAULT_Kc;
   #endif
 #endif //PIDTEMP
-
-#ifdef PIDTEMPBED
-  float bedKp=DEFAULT_bedKp;
-  float bedKi=(DEFAULT_bedKi*PID_dT);
-  float bedKd=(DEFAULT_bedKd/PID_dT);
-#endif //PIDTEMPBED
   
 #ifdef FAN_SOFT_PWM
   unsigned char fanSpeedSoftPwm;
@@ -421,11 +413,11 @@ void updatePID()
 {
 #ifdef PIDTEMP
   for(int e = 0; e < EXTRUDERS; e++) { 
-     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;  
+     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;  
   }
 #endif
 #ifdef PIDTEMPBED
-  temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;  
+  temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / cs.bedKi;  
 #endif
 }
   
@@ -633,14 +625,14 @@ void manage_heater()
             temp_iState[e] = 0.0;
             pid_reset[e] = false;
           }
-          pTerm[e] = Kp * pid_error[e];
+          pTerm[e] = cs.Kp * pid_error[e];
           temp_iState[e] += pid_error[e];
           temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
-          iTerm[e] = Ki * temp_iState[e];
+          iTerm[e] = cs.Ki * temp_iState[e];
 
           //K1 defined in Configuration.h in the PID settings
           #define K2 (1.0-K1)
-          dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
+          dTerm[e] = (cs.Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
           pid_output = pTerm[e] + iTerm[e] - dTerm[e];
           if (pid_output > PID_MAX) {
             if (pid_error[e] > 0 )  temp_iState[e] -= pid_error[e]; // conditional un-integration
@@ -748,14 +740,14 @@ void manage_heater()
 
     #ifndef PID_OPENLOOP
 		  pid_error_bed = target_temperature_bed - pid_input;
-		  pTerm_bed = bedKp * pid_error_bed;
+		  pTerm_bed = cs.bedKp * pid_error_bed;
 		  temp_iState_bed += pid_error_bed;
 		  temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
-		  iTerm_bed = bedKi * temp_iState_bed;
+		  iTerm_bed = cs.bedKi * temp_iState_bed;
 
 		  //K1 defined in Configuration.h in the PID settings
 		  #define K2 (1.0-K1)
-		  dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
+		  dTerm_bed= (cs.bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
 		  temp_dState_bed = pid_input;
 
 		  pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
@@ -1006,11 +998,11 @@ void tp_init()
     maxttemp[e] = maxttemp[0];
 #ifdef PIDTEMP
     temp_iState_min[e] = 0.0;
-    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
+    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
 #endif //PIDTEMP
 #ifdef PIDTEMPBED
     temp_iState_min_bed = 0.0;
-    temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
+    temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / cs.bedKi;
 #endif //PIDTEMPBED
   }
 

+ 1 - 4
Firmware/temperature.h

@@ -73,7 +73,7 @@ extern int current_voltage_raw_bed;
 
 #ifdef PIDTEMP
   extern int pid_cycle, pid_number_of_cycles;
-  extern float Kp,Ki,Kd,Kc,_Kp,_Ki,_Kd;
+  extern float Kc,_Kp,_Ki,_Kd;
   extern bool pid_tuning_finished;
   float scalePID_i(float i);
   float scalePID_d(float d);
@@ -81,9 +81,6 @@ extern int current_voltage_raw_bed;
   float unscalePID_d(float d);
 
 #endif
-#ifdef PIDTEMPBED
-  extern float bedKp,bedKi,bedKd;
-#endif
   
   
 #ifdef BABYSTEPPING

+ 4 - 4
Firmware/ultralcd.cpp

@@ -2764,9 +2764,9 @@ static void _lcd_babystep(int axis, const char *msg)
 	    if (calibration_status() >= CALIBRATION_STATUS_LIVE_ADJUST)
 			_md->babystepMem[2] = 0;
 
-		_md->babystepMemMM[0] = _md->babystepMem[0]/axis_steps_per_unit[X_AXIS];
-		_md->babystepMemMM[1] = _md->babystepMem[1]/axis_steps_per_unit[Y_AXIS];
-		_md->babystepMemMM[2] = _md->babystepMem[2]/axis_steps_per_unit[Z_AXIS];
+		_md->babystepMemMM[0] = _md->babystepMem[0]/cs.axis_steps_per_unit[X_AXIS];
+		_md->babystepMemMM[1] = _md->babystepMem[1]/cs.axis_steps_per_unit[Y_AXIS];
+		_md->babystepMemMM[2] = _md->babystepMem[2]/cs.axis_steps_per_unit[Z_AXIS];
 		lcd_draw_update = 1;
 		//SERIAL_ECHO("Z baby step: ");
 		//SERIAL_ECHO(_md->babystepMem[2]);
@@ -2789,7 +2789,7 @@ static void _lcd_babystep(int axis, const char *msg)
 				CRITICAL_SECTION_END		
 			}
 		}
-		_md->babystepMemMM[axis] = _md->babystepMem[axis]/axis_steps_per_unit[axis]; 
+		_md->babystepMemMM[axis] = _md->babystepMem[axis]/cs.axis_steps_per_unit[axis]; 
 		delay(50);
 		lcd_encoder = 0;
 		lcd_draw_update = 1;