Numerous UBL-related changes:

* relocated ubl state to config. store:
 * removed a number of ubl state variables and padding which were largely unused - saved 58 bytes of both SRAM and EEPROM;
 * modified ubl sanity_check - no longer checks removed state variables that were otherwise unused, where checking didn't seem to accomplish anything, ultimately;
 * removed pre_initialized state, saving 64 bytes of SRAM;
 * removed automatic saving of UBL state after UBL activation/deactivation;
* consolidated multiple GRID_MAX_POINTS_X/Y to 'Global Leveling' section of EEPROM;
* minor update to G29 Sx notes/instructions;
* renamed mesh load and save parameter to 'slot' from 'm' for clarity;
2.0.x
Brian 8 years ago committed by Roxy-3D
parent f1a4758cef
commit f41fb2b635

@ -666,6 +666,10 @@
#define UBL_MESH_MAX_X (X_MAX_POS - (UBL_MESH_INSET)) #define UBL_MESH_MAX_X (X_MAX_POS - (UBL_MESH_INSET))
#define UBL_MESH_MIN_Y (Y_MIN_POS + UBL_MESH_INSET) #define UBL_MESH_MIN_Y (Y_MIN_POS + UBL_MESH_INSET)
#define UBL_MESH_MAX_Y (Y_MAX_POS - (UBL_MESH_INSET)) #define UBL_MESH_MAX_Y (Y_MAX_POS - (UBL_MESH_INSET))
// If this is defined, the currently active mesh will be saved in the
// current slot on M500.
#define UBL_SAVE_ACTIVE_ON_M500
#endif #endif
// @section extras // @section extras

@ -8282,7 +8282,6 @@ void quickstop_stepper() {
} }
ubl.load_mesh(storage_slot); ubl.load_mesh(storage_slot);
if (storage_slot != ubl.state.eeprom_storage_slot) ubl.store_state();
ubl.state.eeprom_storage_slot = storage_slot; ubl.state.eeprom_storage_slot = storage_slot;
} }
#endif // AUTO_BED_LEVELING_UBL #endif // AUTO_BED_LEVELING_UBL

@ -36,7 +36,7 @@
* *
*/ */
#define EEPROM_VERSION "V35" #define EEPROM_VERSION "V36"
// Change EEPROM version if these are changed: // Change EEPROM version if these are changed:
#define EEPROM_OFFSET 100 #define EEPROM_OFFSET 100
@ -72,7 +72,7 @@
* 224 mbl.z_offset (float) * 224 mbl.z_offset (float)
* 228 GRID_MAX_POINTS_X (uint8_t) * 228 GRID_MAX_POINTS_X (uint8_t)
* 229 GRID_MAX_POINTS_Y (uint8_t) * 229 GRID_MAX_POINTS_Y (uint8_t)
* 230 G29 S3 XYZ z_values[][] (float x9, up to float x 81) +288 * 230 G29 S3 XYZ z_values[][] (float x9, up to float x81) +288
* *
* HAS_BED_PROBE: 4 bytes * HAS_BED_PROBE: 4 bytes
* 266 M851 zprobe_zoffset (float) * 266 M851 zprobe_zoffset (float)
@ -87,6 +87,11 @@
* 312 G29 L F bilinear_start (int x2) * 312 G29 L F bilinear_start (int x2)
* 316 z_values[][] (float x9, up to float x256) +988 * 316 z_values[][] (float x9, up to float x256) +988
* *
* AUTO_BED_LEVELING_UBL: 6 bytes
* 324 G29 A ubl.state.active (bool)
* 325 G29 Z ubl.state.z_offset (float)
* 329 G29 S ubl.state.eeprom_storage_slot (int8_t)
*
* DELTA: 48 bytes * DELTA: 48 bytes
* 348 M666 XYZ endstop_adj (float x3) * 348 M666 XYZ endstop_adj (float x3)
* 360 M665 R delta_radius (float) * 360 M665 R delta_radius (float)
@ -322,15 +327,15 @@ void MarlinSettings::postprocess() {
#endif #endif
// //
// General Leveling // Global Leveling
// //
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
EEPROM_WRITE(planner.z_fade_height); const float zfh = planner.z_fade_height;
#else #else
dummy = 10.0; const float zfh = 10.0;
EEPROM_WRITE(dummy);
#endif #endif
EEPROM_WRITE(zfh);
// //
// Mesh Bed Leveling // Mesh Bed Leveling
@ -349,8 +354,7 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(mesh_num_x); EEPROM_WRITE(mesh_num_x);
EEPROM_WRITE(mesh_num_y); EEPROM_WRITE(mesh_num_y);
EEPROM_WRITE(mbl.z_values); EEPROM_WRITE(mbl.z_values);
#else #else // For disabled MBL write a default mesh
// For disabled MBL write a default mesh
const bool leveling_is_on = false; const bool leveling_is_on = false;
dummy = 0.0f; dummy = 0.0f;
const uint8_t mesh_num_x = 3, mesh_num_y = 3; const uint8_t mesh_num_x = 3, mesh_num_y = 3;
@ -405,6 +409,19 @@ void MarlinSettings::postprocess() {
for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummy); for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummy);
#endif // AUTO_BED_LEVELING_BILINEAR #endif // AUTO_BED_LEVELING_BILINEAR
#if ENABLED(AUTO_BED_LEVELING_UBL)
EEPROM_WRITE(ubl.state.active);
EEPROM_WRITE(ubl.state.z_offset);
EEPROM_WRITE(ubl.state.eeprom_storage_slot);
#else
const bool ubl_active = 0;
dummy = 0.0f;
const int8_t eeprom_slot = -1;
EEPROM_WRITE(ubl_active);
EEPROM_WRITE(dummy);
EEPROM_WRITE(eeprom_slot);
#endif //AUTO_BED_LEVELING_UBL
// 9 floats for DELTA / Z_DUAL_ENDSTOPS // 9 floats for DELTA / Z_DUAL_ENDSTOPS
#if ENABLED(DELTA) #if ENABLED(DELTA)
EEPROM_WRITE(endstop_adj); // 3 floats EEPROM_WRITE(endstop_adj); // 3 floats
@ -608,8 +625,7 @@ void MarlinSettings::postprocess() {
SERIAL_ECHOLNPGM(" bytes)"); SERIAL_ECHOLNPGM(" bytes)");
} }
#if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(UBL_SAVE_ACTIVE_ON_M500)
ubl.store_state();
if (ubl.state.eeprom_storage_slot >= 0) if (ubl.state.eeprom_storage_slot >= 0)
ubl.store_mesh(ubl.state.eeprom_storage_slot); ubl.store_mesh(ubl.state.eeprom_storage_slot);
#endif #endif
@ -693,7 +709,7 @@ void MarlinSettings::postprocess() {
#endif #endif
// //
// General Leveling // Global Leveling
// //
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
@ -769,6 +785,18 @@ void MarlinSettings::postprocess() {
for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy); for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy);
} }
#if ENABLED(AUTO_BED_LEVELING_UBL)
EEPROM_READ(ubl.state.active);
EEPROM_READ(ubl.state.z_offset);
EEPROM_READ(ubl.state.eeprom_storage_slot);
#else
bool dummyb;
uint8_t dummyui8;
EEPROM_READ(dummyb);
EEPROM_READ(dummy);
EEPROM_READ(dummyui8);
#endif //AUTO_BED_LEVELING_UBL
#if ENABLED(DELTA) #if ENABLED(DELTA)
EEPROM_READ(endstop_adj); // 3 floats EEPROM_READ(endstop_adj); // 3 floats
EEPROM_READ(delta_radius); // 1 float EEPROM_READ(delta_radius); // 1 float
@ -951,27 +979,16 @@ void MarlinSettings::postprocess() {
ubl.eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it ubl.eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
// can float up or down a little bit without // can float up or down a little bit without
// disrupting the Unified Bed Leveling data // disrupting the Unified Bed Leveling data
ubl.load_state();
SERIAL_ECHOPGM(" UBL "); SERIAL_ECHOPGM(" UBL ");
if (!ubl.state.active) SERIAL_ECHO("not "); if (!ubl.state.active) SERIAL_ECHO("not ");
SERIAL_ECHOLNPGM("active!"); SERIAL_ECHOLNPGM("active!");
if (!ubl.sanity_check()) { if (!ubl.sanity_check()) {
int tmp_mesh; // We want to preserve whether the UBL System is Active SERIAL_ECHOLNPGM("\nUnified Bed Leveling system initialized.\n");
bool tmp_active; // If it is, we want to preserve the Mesh that is being used.
tmp_mesh = ubl.state.eeprom_storage_slot;
tmp_active = ubl.state.active;
SERIAL_ECHOLNPGM("\nInitializing Bed Leveling State to current firmware settings.\n");
ubl.state = ubl.pre_initialized; // Initialize with the pre_initialized data structure
ubl.state.eeprom_storage_slot = tmp_mesh; // But then restore some data we don't want mangled
ubl.state.active = tmp_active;
} }
else { else {
SERIAL_PROTOCOLPGM("?Unable to enable Unified Bed Leveling.\n"); SERIAL_PROTOCOLPGM("?Unable to enable Unified Bed Leveling system.\n");
ubl.state = ubl.pre_initialized;
ubl.reset(); ubl.reset();
ubl.store_state();
} }
if (ubl.state.eeprom_storage_slot >= 0) { if (ubl.state.eeprom_storage_slot >= 0) {
@ -985,6 +1002,7 @@ void MarlinSettings::postprocess() {
} }
#endif #endif
} }
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
report(); report();
#endif #endif
@ -1190,6 +1208,10 @@ void MarlinSettings::reset() {
planner.advance_ed_ratio = LIN_ADVANCE_E_D_RATIO; planner.advance_ed_ratio = LIN_ADVANCE_E_D_RATIO;
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_UBL)
ubl.reset();
#endif
postprocess(); postprocess();
SERIAL_ECHO_START; SERIAL_ECHO_START;

@ -57,7 +57,7 @@
} }
} }
ubl_state unified_bed_leveling::state, unified_bed_leveling::pre_initialized; ubl_state unified_bed_leveling::state;
float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y],
unified_bed_leveling::last_specified_z; unified_bed_leveling::last_specified_z;
@ -78,59 +78,46 @@
reset(); reset();
} }
void unified_bed_leveling::store_state() { void unified_bed_leveling::load_mesh(const int16_t slot) {
const uint16_t i = UBL_LAST_EEPROM_INDEX;
eeprom_write_block((void *)&ubl.state, (void *)i, sizeof(state));
}
void unified_bed_leveling::load_state() {
const uint16_t i = UBL_LAST_EEPROM_INDEX;
eeprom_read_block((void *)&ubl.state, (void *)i, sizeof(state));
if (sanity_check())
SERIAL_PROTOCOLLNPGM("?In load_state() sanity_check() failed.\n");
}
void unified_bed_leveling::load_mesh(const int16_t m) {
int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values); int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
if (m == -1) { if (slot == -1) {
SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n"); SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
reset(); reset();
return; return;
} }
if (!WITHIN(m, 0, j - 1) || eeprom_start <= 0) { if (!WITHIN(slot, 0, j - 1) || eeprom_start <= 0) {
SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n"); SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
return; return;
} }
j = UBL_LAST_EEPROM_INDEX - (m + 1) * sizeof(z_values); j = UBL_LAST_EEPROM_INDEX - (slot + 1) * sizeof(z_values);
eeprom_read_block((void *)&z_values, (void *)j, sizeof(z_values)); eeprom_read_block((void *)&z_values, (void *)j, sizeof(z_values));
SERIAL_PROTOCOLPAIR("Mesh loaded from slot ", m); SERIAL_PROTOCOLPAIR("Mesh loaded from slot ", slot);
SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j)); SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j));
} }
void unified_bed_leveling::store_mesh(const int16_t m) { void unified_bed_leveling::store_mesh(const int16_t slot) {
int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values); int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
if (!WITHIN(m, 0, j - 1) || eeprom_start <= 0) { if (!WITHIN(slot, 0, j - 1) || eeprom_start <= 0) {
SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n"); SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
SERIAL_PROTOCOL(m); SERIAL_PROTOCOL(slot);
SERIAL_PROTOCOLLNPGM(" mesh slots available.\n"); SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
SERIAL_PROTOCOLLNPAIR("E2END : ", E2END); SERIAL_PROTOCOLLNPAIR("E2END : ", E2END);
SERIAL_PROTOCOLLNPAIR("k : ", (int)UBL_LAST_EEPROM_INDEX); SERIAL_PROTOCOLLNPAIR("k : ", (int)UBL_LAST_EEPROM_INDEX);
SERIAL_PROTOCOLLNPAIR("j : ", j); SERIAL_PROTOCOLLNPAIR("j : ", j);
SERIAL_PROTOCOLLNPAIR("m : ", m); SERIAL_PROTOCOLLNPAIR("m : ", slot);
SERIAL_EOL; SERIAL_EOL;
return; return;
} }
j = UBL_LAST_EEPROM_INDEX - (m + 1) * sizeof(z_values); j = UBL_LAST_EEPROM_INDEX - (slot + 1) * sizeof(z_values);
eeprom_write_block((const void *)&z_values, (void *)j, sizeof(z_values)); eeprom_write_block((const void *)&z_values, (void *)j, sizeof(z_values));
SERIAL_PROTOCOLPAIR("Mesh saved in slot ", m); SERIAL_PROTOCOLPAIR("Mesh saved in slot ", slot);
SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j)); SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j));
} }
@ -227,49 +214,12 @@
bool unified_bed_leveling::sanity_check() { bool unified_bed_leveling::sanity_check() {
uint8_t error_flag = 0; uint8_t error_flag = 0;
if (state.n_x != GRID_MAX_POINTS_X) {
SERIAL_PROTOCOLLNPGM("?GRID_MAX_POINTS_X set wrong\n");
error_flag++;
}
if (state.n_y != GRID_MAX_POINTS_Y) {
SERIAL_PROTOCOLLNPGM("?GRID_MAX_POINTS_Y set wrong\n");
error_flag++;
}
if (state.mesh_x_min != UBL_MESH_MIN_X) {
SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_X set wrong\n");
error_flag++;
}
if (state.mesh_y_min != UBL_MESH_MIN_Y) {
SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_Y set wrong\n");
error_flag++;
}
if (state.mesh_x_max != UBL_MESH_MAX_X) {
SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_X set wrong\n");
error_flag++;
}
if (state.mesh_y_max != UBL_MESH_MAX_Y) {
SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_Y set wrong\n");
error_flag++;
}
if (state.mesh_x_dist != MESH_X_DIST) {
SERIAL_PROTOCOLLNPGM("?MESH_X_DIST set wrong\n");
error_flag++;
}
if (state.mesh_y_dist != MESH_Y_DIST) {
SERIAL_PROTOCOLLNPGM("?MESH_Y_DIST set wrong\n");
error_flag++;
}
const int j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values); const int j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
if (j < 1) { if (j < 1) {
SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n"); SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
error_flag++; error_flag++;
} }
// SERIAL_PROTOCOLPGM("?sanity_check() return value: ");
// SERIAL_PROTOCOL(error_flag);
// SERIAL_EOL;
return !!error_flag; return !!error_flag;
} }

@ -87,27 +87,7 @@
typedef struct { typedef struct {
bool active = false; bool active = false;
float z_offset = 0.0; float z_offset = 0.0;
int8_t eeprom_storage_slot = -1, int8_t eeprom_storage_slot = -1;
n_x = GRID_MAX_POINTS_X,
n_y = GRID_MAX_POINTS_Y;
float mesh_x_min = UBL_MESH_MIN_X,
mesh_y_min = UBL_MESH_MIN_Y,
mesh_x_max = UBL_MESH_MAX_X,
mesh_y_max = UBL_MESH_MAX_Y,
mesh_x_dist = MESH_X_DIST,
mesh_y_dist = MESH_Y_DIST;
// If you change this struct, adjust TOTAL_STRUCT_SIZE
#define TOTAL_STRUCT_SIZE 32 // Total size of the above fields
// padding provides space to add state variables without
// changing the location of data structures in the EEPROM.
// This is for compatibility with future versions to keep
// users from having to regenerate their mesh data.
unsigned char padding[64 - TOTAL_STRUCT_SIZE];
} ubl_state; } ubl_state;
class unified_bed_leveling { class unified_bed_leveling {
@ -117,7 +97,7 @@
public: public:
static ubl_state state, pre_initialized; static ubl_state state;
static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
@ -156,8 +136,6 @@
static void reset(); static void reset();
static void invalidate(); static void invalidate();
static void store_state();
static void load_state();
static void store_mesh(const int16_t); static void store_mesh(const int16_t);
static void load_mesh(const int16_t); static void load_mesh(const int16_t);
@ -351,7 +329,7 @@
extern unified_bed_leveling ubl; extern unified_bed_leveling ubl;
#define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state)) #define UBL_LAST_EEPROM_INDEX E2END
#endif // AUTO_BED_LEVELING_UBL #endif // AUTO_BED_LEVELING_UBL
#endif // UNIFIED_BED_LEVELING_H #endif // UNIFIED_BED_LEVELING_H

@ -247,8 +247,8 @@
* current state of the Unified Bed Leveling system in the EEPROM. * current state of the Unified Bed Leveling system in the EEPROM.
* *
* S # Store Store the current Mesh at the specified location in EEPROM. Activate this location * S # Store Store the current Mesh at the specified location in EEPROM. Activate this location
* for subsequent Load and Store operations. It will also store the current state of * for subsequent Load and Store operations. Valid storage slot numbers begin at 0 and
* the Unified Bed Leveling system in the EEPROM. * extend to a limit related to the available EEPROM storage.
* *
* S -1 Store Store the current Mesh as a print out that is suitable to be feed back into the system * S -1 Store Store the current Mesh as a print out that is suitable to be feed back into the system
* at a later date. The GCode output can be saved and later replayed by the host software * at a later date. The GCode output can be saved and later replayed by the host software
@ -574,8 +574,6 @@
} }
ubl.load_mesh(storage_slot); ubl.load_mesh(storage_slot);
ubl.state.eeprom_storage_slot = storage_slot; ubl.state.eeprom_storage_slot = storage_slot;
if (storage_slot != ubl.state.eeprom_storage_slot)
ubl.store_state();
SERIAL_PROTOCOLLNPGM("Done.\n"); SERIAL_PROTOCOLLNPGM("Done.\n");
} }
@ -609,9 +607,6 @@
} }
ubl.store_mesh(storage_slot); ubl.store_mesh(storage_slot);
ubl.state.eeprom_storage_slot = storage_slot; ubl.state.eeprom_storage_slot = storage_slot;
//
// if (storage_slot != ubl.state.eeprom_storage_slot)
ubl.store_state(); // Always save an updated copy of the UBL State info
SERIAL_PROTOCOLLNPGM("Done.\n"); SERIAL_PROTOCOLLNPGM("Done.\n");
} }
@ -1048,7 +1043,6 @@
if (code_seen('A')) { // Activate the Unified Bed Leveling System if (code_seen('A')) { // Activate the Unified Bed Leveling System
ubl.state.active = 1; ubl.state.active = 1;
SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System activated.\n"); SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System activated.\n");
ubl.store_state();
} }
c_flag = code_seen('C') && code_has_value(); c_flag = code_seen('C') && code_has_value();
@ -1057,7 +1051,6 @@
if (code_seen('D')) { // Disable the Unified Bed Leveling System if (code_seen('D')) { // Disable the Unified Bed Leveling System
ubl.state.active = 0; ubl.state.active = 0;
SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System de-activated.\n"); SERIAL_PROTOCOLLNPGM("Unified Bed Leveling System de-activated.\n");
ubl.store_state();
} }
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)

Loading…
Cancel
Save