|  |  | @ -116,8 +116,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    invalidate. |  |  |  |    *                    invalidate. | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   J #   Grid   *   Perform a Grid Based Leveling of the current Mesh using a grid with n points on a side. |  |  |  |    *   J #   Grid   *   Perform a Grid Based Leveling of the current Mesh using a grid with n points on a side. | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    *                    Not specifying a grid size will invoke the 3-Point leveling function. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |    *   j  EEPROM Dump   This function probably goes away after debug is complete. |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   K #   Kompare    Kompare current Mesh with stored Mesh # replacing current Mesh with the result. This |  |  |  |    *   K #   Kompare    Kompare current Mesh with stored Mesh # replacing current Mesh with the result. This | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    command literally performs a diff between two Meshes. |  |  |  |    *                    command literally performs a diff between two Meshes. | 
			
		
	
	
		
		
			
				
					|  |  | @ -264,8 +263,6 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    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 | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    to reconstruct the current mesh on another machine. |  |  |  |    *                    to reconstruct the current mesh on another machine. | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   T     3-Point    Perform a 3 Point Bed Leveling on the current Mesh |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   U     Unlevel    Perform a probe of the outer perimeter to assist in physically leveling unlevel beds. |  |  |  |    *   U     Unlevel    Perform a probe of the outer perimeter to assist in physically leveling unlevel beds. | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    Only used for G29 P1 O U   It will speed up the probing of the edge of the bed.  This |  |  |  |    *                    Only used for G29 P1 O U   It will speed up the probing of the edge of the bed.  This | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    is useful when the entire bed does not need to be probed because it will be adjusted. |  |  |  |    *                    is useful when the entire bed does not need to be probed because it will be adjusted. | 
			
		
	
	
		
		
			
				
					|  |  | @ -276,12 +273,6 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   Y #   *      *   Y Location for this line of commands |  |  |  |    *   Y #   *      *   Y Location for this line of commands | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   Z     Zero   *   Probes to set the Z Height of the nozzle. The entire Mesh can be raised or lowered |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    by just doing a G29 Z |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   Z #   Zero   *   The entire Mesh can be raised or lowered to conform with the specified difference. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    *                    zprobe_zoffset is added to the calculation. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * |  |  |  |    * | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   Release Notes: |  |  |  |    *   Release Notes: | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   You MUST do M502, M500 to initialize the storage. Failure to do this will cause all |  |  |  |    *   You MUST do M502, M500 to initialize the storage. Failure to do this will cause all | 
			
		
	
	
		
		
			
				
					|  |  | @ -329,7 +320,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Don't allow auto-leveling without homing first
 |  |  |  |     // Don't allow auto-leveling without homing first
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!(code_seen('N') && code_value_bool()) && axis_unhomed_error()) // Warning! Use of 'N' flouts established standards.
 |  |  |  |     if (axis_unhomed_error())  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       home_all_axes(); |  |  |  |       home_all_axes(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (g29_parameter_parsing()) return; // abort if parsing the simple parameters causes a problem,
 |  |  |  |     if (g29_parameter_parsing()) return; // abort if parsing the simple parameters causes a problem,
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -353,13 +344,16 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('Q')) { |  |  |  |     if (code_seen('Q')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       const int test_pattern = code_has_value() ? code_value_int() : -1; |  |  |  |       const int test_pattern = code_has_value() ? code_value_int() : -99; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       if (!WITHIN(test_pattern, 0, 2)) { |  |  |  |       if (!WITHIN(test_pattern, -1, 2)) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         SERIAL_PROTOCOLLNPGM("Invalid test_pattern value. (0-2)\n"); |  |  |  |         SERIAL_PROTOCOLLNPGM("Invalid test_pattern value. (0-2)\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_PROTOCOLLNPGM("Loading test_pattern values.\n"); |  |  |  |       SERIAL_PROTOCOLLNPGM("Loading test_pattern values.\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |       switch (test_pattern) { |  |  |  |       switch (test_pattern) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         case -1: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           g29_eeprom_dump(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           break; | 
			
		
	
		
		
			
				
					
					|  |  |  |         case 0: |  |  |  |         case 0: | 
			
		
	
		
		
			
				
					
					|  |  |  |           for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) {   // Create a bowl shape - similar to
 |  |  |  |           for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) {   // Create a bowl shape - similar to
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { // a poorly calibrated Delta.
 |  |  |  |             for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) { // a poorly calibrated Delta.
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -385,9 +379,33 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('J')) { |  |  |  |     if (code_seen('J')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.save_ubl_active_state_and_disable(); |  |  |  |       if (grid_size!=0) {  // if not 0 it is a normal n x n grid being probed
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.tilt_mesh_based_on_probed_grid(code_seen('O') || code_seen('M')); // Warning! Use of 'M' flouts established standards.
 |  |  |  |         ubl.save_ubl_active_state_and_disable(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.restore_ubl_active_state_and_leave(); |  |  |  |         ubl.tilt_mesh_based_on_probed_grid(code_seen('O'));  | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ubl.restore_ubl_active_state_and_leave(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } else { // grid_size==0 which means a 3-Point leveling has been requested
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         float z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if ( isnan(z1) || isnan(z2) || isnan(z3)) {   // probe_pt will return NAN if unreachable
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           SERIAL_ERROR_START; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           SERIAL_ERRORLNPGM("Attempt to probe off the bed."); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           goto LEAVE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       //  We need to adjust z1, z2, z3 by the Mesh Height at these points. Just because they are non-zero doesn't mean
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       //  the Mesh is tilted!  (We need to compensate each probe point by what the Mesh says that location's height is)
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ubl.save_ubl_active_state_and_disable(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         z1 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y)) /* + zprobe_zoffset */ ; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         z2 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y)) /* + zprobe_zoffset */ ; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         z3 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y)) /* + zprobe_zoffset */ ; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ubl.tilt_mesh_based_on_3pts(z1, z2, z3); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ubl.restore_ubl_active_state_and_leave(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('P')) { |  |  |  |     if (code_seen('P')) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -420,7 +438,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |             SERIAL_PROTOCOLLNPGM(").\n"); |  |  |  |             SERIAL_PROTOCOLLNPGM(").\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |           ubl.probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, |  |  |  |           ubl.probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, | 
			
		
	
		
		
			
				
					
					|  |  |  |                             code_seen('O') || code_seen('M'), code_seen('E'), code_seen('U')); // Warning! Use of 'M' flouts established standards.
 |  |  |  |                             code_seen('O'), code_seen('E'), code_seen('U'));  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |           break; |  |  |  |           break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case 2: { |  |  |  |         case 2: { | 
			
		
	
	
		
		
			
				
					|  |  | @ -469,7 +487,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |           manually_probe_remaining_mesh(x_pos, y_pos, height, card_thickness, code_seen('O') || code_seen('M')); // Warning! Use of 'M' flouts established standards.
 |  |  |  |           manually_probe_remaining_mesh(x_pos, y_pos, height, card_thickness, code_seen('O')); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |           SERIAL_PROTOCOLLNPGM("G29 P2 finished."); |  |  |  |           SERIAL_PROTOCOLLNPGM("G29 P2 finished."); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } break; |  |  |  |         } break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -505,7 +523,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |           //
 |  |  |  |           //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |           // Fine Tune (i.e., Edit) the Mesh
 |  |  |  |           // Fine Tune (i.e., Edit) the Mesh
 | 
			
		
	
		
		
			
				
					
					|  |  |  |           //
 |  |  |  |           //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |           fine_tune_mesh(x_pos, y_pos, code_seen('O') || code_seen('M')); // Warning! Use of 'M' flouts established standards.
 |  |  |  |           fine_tune_mesh(x_pos, y_pos, code_seen('O'));  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |           break; |  |  |  |           break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         case 5: ubl.find_mean_mesh_height(); break; |  |  |  |         case 5: ubl.find_mean_mesh_height(); break; | 
			
		
	
	
		
		
			
				
					|  |  | @ -515,43 +533,12 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('T')) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       float z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       if ( isnan(z1) || isnan(z2) || isnan(z3)) {   // probe_pt will return NAN if unreachable
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           SERIAL_ERROR_START; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           SERIAL_ERRORLNPGM("Attempt to probe off the bed."); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           goto LEAVE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       //  We need to adjust z1, z2, z3 by the Mesh Height at these points. Just because they are non-zero doesn't mean
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       //  the Mesh is tilted!  (We need to compensate each probe point by what the Mesh says that location's height is)
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.save_ubl_active_state_and_disable(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       z1 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y)) /* + zprobe_zoffset */ ; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       z2 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y)) /* + zprobe_zoffset */ ; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       z3 -= ubl.get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y)) /* + zprobe_zoffset */ ; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.tilt_mesh_based_on_3pts(z1, z2, z3); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       ubl.restore_ubl_active_state_and_leave(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     //
 |  |  |  |     //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Much of the 'What?' command can be eliminated. But until we are fully debugged, it is
 |  |  |  |     // Much of the 'What?' command can be eliminated. But until we are fully debugged, it is
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // good to have the extra information. Soon... we prune this to just a few items
 |  |  |  |     // good to have the extra information. Soon... we prune this to just a few items
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     //
 |  |  |  |     //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('W')) ubl.g29_what_command(); |  |  |  |     if (code_seen('W')) ubl.g29_what_command(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   |  |  |  |   | 
			
		
	
		
		
			
				
					
					|  |  |  |     //
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // When we are fully debugged, the EEPROM dump command will get deleted also. But
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // right now, it is good to have the extra information. Soon... we prune this.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     //
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('j')) g29_eeprom_dump(); // Warning! Use of lowercase flouts established standards.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     //
 |  |  |  |     //
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // When we are fully debugged, this may go away. But there are some valid
 |  |  |  |     // When we are fully debugged, this may go away. But there are some valid
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // use cases for the users. So we can wait and see what to do with it.
 |  |  |  |     // use cases for the users. So we can wait and see what to do with it.
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -614,9 +601,12 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_PROTOCOLLNPGM("Done.\n"); |  |  |  |       SERIAL_PROTOCOLLNPGM("Done.\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('O') || code_seen('M')) // Warning! Use of 'M' flouts established standards.
 |  |  |  |     if (code_seen('O')) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       ubl.display_map(code_has_value() ? code_value_int() : 0); |  |  |  |       ubl.display_map(code_has_value() ? code_value_int() : 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      * This code may not be needed...   Prepare for its removal... | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('Z')) { |  |  |  |     if (code_seen('Z')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (code_has_value()) |  |  |  |       if (code_has_value()) | 
			
		
	
		
		
			
				
					
					|  |  |  |         ubl.state.z_offset = code_value_float();   // do the simple case. Just lock in the specified value
 |  |  |  |         ubl.state.z_offset = code_value_float();   // do the simple case. Just lock in the specified value
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -669,6 +659,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |         ubl.restore_ubl_active_state_and_leave(); |  |  |  |         ubl.restore_ubl_active_state_and_leave(); | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     LEAVE: |  |  |  |     LEAVE: | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -1069,8 +1060,8 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('J')) { |  |  |  |     if (code_seen('J')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       grid_size = code_has_value() ? code_value_int() : 3; |  |  |  |       grid_size = code_has_value() ? code_value_int() : 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       if (!WITHIN(grid_size, 2, 9)) { |  |  |  |       if (grid_size!=0 && !WITHIN(grid_size, 2, 9)) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         SERIAL_PROTOCOLLNPGM("?Invalid grid size (J) specified (2-9).\n"); |  |  |  |         SERIAL_PROTOCOLLNPGM("?Invalid grid size (J) specified (2-9).\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |         err_flag = true; |  |  |  |         err_flag = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
	
		
		
			
				
					|  |  | @ -1126,43 +1117,9 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); |  |  |  |       SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |       return UBL_ERR; |  |  |  |       return UBL_ERR; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Check if a map type was specified
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('M')) { // Warning! Use of 'M' flouts established standards.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       map_type = code_has_value() ? code_value_int() : 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (!WITHIN(map_type, 0, 1)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return UBL_ERR; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return UBL_OK; |  |  |  |     return UBL_OK; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   /**
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * This function goes away after G29 debug is complete. But for right now, it is a handy |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    * routine to dump binary data structures. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   /*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   void dump(char * const str, const float &f) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     char *ptr; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOL(str); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOL_F(f, 8); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOLPGM("  "); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ptr = (char*)&f; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (uint8_t i = 0; i < 4; i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_PROTOCOLPAIR("  ", hex_byte(*ptr++)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOLPAIR("  isnan()=", isnan(f)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOLPAIR("  isinf()=", isinf(f)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (f == -INFINITY) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_PROTOCOLPGM("  Minus Infinity detected."); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_EOL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   //*/
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   static int ubl_state_at_invocation = 0, |  |  |  |   static int ubl_state_at_invocation = 0, | 
			
		
	
		
		
			
				
					
					|  |  |  |              ubl_state_recursion_chk = 0; |  |  |  |              ubl_state_recursion_chk = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | 
 |