| 
					
				 | 
			
			
				@@ -304,10 +304,11 @@ uint8_t saved_filament_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // that they can be used later for various logical checks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define X_COORD_INVALID (X_MIN_POS-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define Y_COORD_INVALID (Y_MIN_POS-1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define SAVED_TARGET_UNSET X_COORD_INVALID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-float saved_target[NUM_AXIS] = {SAVED_TARGET_UNSET, 0, 0, 0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define SAVED_START_POSITION_UNSET X_COORD_INVALID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+float saved_start_position[NUM_AXIS] = {SAVED_START_POSITION_UNSET, 0, 0, 0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint16_t saved_segment_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // save/restore printing in case that mmu was not responding  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 bool mmu_print_saved = false; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -445,7 +446,6 @@ AutoReportFeatures autoReportFeatures; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //=============================Routines====================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //=========================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void get_arc_coordinates(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool setTargetedHotend(int code, uint8_t &extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void print_time_remaining_init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void wait_for_heater(long codenum, uint8_t extruder); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4648,18 +4648,8 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case 0: // G0 -> G1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case 1: // G1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            get_coordinates(); // For X Y Z E F 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // When recovering from a previous print move, restore the originally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // calculated target position on the first USB/SD command. This accounts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // properly for relative moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if ((saved_target[0] != SAVED_TARGET_UNSET) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_SDCARD) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                memcpy(destination, saved_target, sizeof(destination)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                saved_target[0] = SAVED_TARGET_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint16_t start_segment_idx = restore_interrupted_gcode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get_coordinates(); // For X Y Z E F 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4680,7 +4670,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif //FWRETRACT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        prepare_move(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        prepare_move(start_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //ClearToSend(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4705,21 +4695,24 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	  - `F` - The feedrate per minute of the move between the starting point and ending point (if supplied) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 2:  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        get_arc_coordinates(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        prepare_arc_move(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // ------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 3:  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        get_arc_coordinates(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        prepare_arc_move(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint16_t start_segment_idx = restore_interrupted_gcode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef SF_ARC_FIX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bool relative_mode_backup = relative_mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        relative_mode = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get_coordinates(); // For X Y Z E F 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef SF_ARC_FIX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        relative_mode=relative_mode_backup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        offset[0] = code_seen('I') ? code_value() : 0.f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        offset[1] = code_seen('J') ? code_value() : 0.f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        prepare_arc_move((gcode_in_progress == 2), start_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /*! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	### G4 - Dwell <a href="https://reprap.org/wiki/G-code#G4:_Dwell">G4: Dwell</a> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9426,8 +9419,7 @@ void update_currents() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif //MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void get_coordinates() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void get_coordinates() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bool seen[4]={false,false,false,false}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for(int8_t i=0; i < NUM_AXIS; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(code_seen(axis_codes[i])) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9464,31 +9456,6 @@ void get_coordinates() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void get_arc_coordinates() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef SF_ARC_FIX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   bool relative_mode_backup = relative_mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   relative_mode = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   get_coordinates(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef SF_ARC_FIX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   relative_mode=relative_mode_backup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   if(code_seen('I')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     offset[0] = code_value(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     offset[0] = 0.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   if(code_seen('J')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     offset[1] = code_value(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     offset[1] = 0.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void clamp_to_software_endstops(float target[3]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef DEBUG_DISABLE_SWLIMITS 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9510,59 +9477,70 @@ void clamp_to_software_endstops(float target[3]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint16_t restore_interrupted_gcode() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // When recovering from a previous print move, restore the originally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // calculated start position on the first USB/SD command. This accounts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // properly for relative moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (saved_start_position[0] != SAVED_START_POSITION_UNSET) && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_SDCARD) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        memcpy(current_position, saved_start_position, sizeof(current_position)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        saved_start_position[0] = SAVED_START_POSITION_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return saved_segment_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return 1; //begin with the first segment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef MESH_BED_LEVELING 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder, uint16_t start_segment_idx = 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         float dx = x - current_position[X_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         float dy = y - current_position[Y_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int n_segments = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint16_t n_segments = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (mbl.active) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             float len = fabs(dx) + fabs(dy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (len > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Split to 3cm segments or shorter. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                n_segments = int(ceil(len / 30.f)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                n_segments = uint16_t(ceil(len / 30.f)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (n_segments > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // In a multi-segment move explicitly set the final target in the plan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // as the move will be recalculated in it's entirety 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            float gcode_target[NUM_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gcode_target[X_AXIS] = x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gcode_target[Y_AXIS] = y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gcode_target[Z_AXIS] = z; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            gcode_target[E_AXIS] = e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (n_segments > 1 && start_segment_idx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             float dz = z - current_position[Z_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             float de = e - current_position[E_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (int i = 1; i < n_segments; ++ i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (uint16_t i = start_segment_idx; i < n_segments; ++ i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 float t = float(i) / float(n_segments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 plan_buffer_line(current_position[X_AXIS] + t * dx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  current_position[Y_AXIS] + t * dy, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  current_position[Z_AXIS] + t * dz, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  current_position[E_AXIS] + t * de, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 feed_rate, extruder, gcode_target); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 feed_rate, extruder, current_position, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (planner_aborted) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // The rest of the path. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        plan_buffer_line(x, y, z, e, feed_rate, extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        plan_buffer_line(x, y, z, e, feed_rate, extruder, current_position); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif  // MESH_BED_LEVELING 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void prepare_move() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void prepare_move(uint16_t start_segment_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   clamp_to_software_endstops(destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   previous_millis_cmd.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Do not use feedmultiply for E or Z only moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if((current_position[X_AXIS] == destination[X_AXIS]) && (current_position[Y_AXIS] == destination[Y_AXIS])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       plan_buffer_line_destinationXYZE(feedrate/60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef MESH_BED_LEVELING 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder, start_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      plan_buffer_line_destinationXYZE(feedrate*feedmultiply*(1./(60.f*100.f))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -9571,10 +9549,10 @@ void prepare_move() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   set_current_to_destination(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void prepare_arc_move(bool isclockwise) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void prepare_arc_move(bool isclockwise, uint16_t start_segment_idx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Trace the arc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mc_arc(current_position, destination, offset, feedrate * feedmultiply / 60 / 100.0, r, isclockwise, active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mc_arc(current_position, destination, offset, feedrate * feedmultiply / 60 / 100.0, r, isclockwise, active_extruder, start_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // As far as the parser is concerned, the position is now == target. In reality the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // motion control system might still be processing the action and the real tool position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // in any intermediate location. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -10934,13 +10912,15 @@ void uvlo_() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint16_t feedrate_bckp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (current_block && !pos_invalid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        memcpy(saved_target, current_block->gcode_target, sizeof(saved_target)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        memcpy(saved_start_position, current_block->gcode_start_position, sizeof(saved_start_position)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         feedrate_bckp = current_block->gcode_feedrate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        saved_segment_idx = current_block->segment_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        saved_target[0] = SAVED_TARGET_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        saved_start_position[0] = SAVED_START_POSITION_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         feedrate_bckp = feedrate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        saved_segment_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // From this point on and up to the print recovery, Z should not move during X/Y travels and 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11039,10 +11019,12 @@ void uvlo_() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	eeprom_update_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL), cs.travel_acceleration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Store the saved target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4), saved_target[X_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4), saved_target[Y_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4), saved_target[Z_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4), saved_target[E_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+0*4), saved_start_position[X_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+1*4), saved_start_position[Y_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+2*4), saved_start_position[Z_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+3*4), saved_start_position[E_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eeprom_update_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX, saved_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	eeprom_update_float((float*)(EEPROM_UVLO_LA_K), extruder_advance_K); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11312,10 +11294,12 @@ bool recover_machine_state_after_power_panic() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // 9) Recover the saved target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  saved_target[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  saved_target[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  saved_target[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  saved_target[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  saved_start_position[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+0*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  saved_start_position[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+1*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  saved_start_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+2*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  saved_start_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+3*4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  saved_segment_idx = eeprom_read_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   extruder_advance_K = eeprom_read_float((float*)EEPROM_UVLO_LA_K); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11557,13 +11541,16 @@ void stop_and_save_print_to_ram(float z_move, float e_move) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bool pos_invalid = XY_NO_RESTORE_FLAG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (current_block && !pos_invalid) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      memcpy(saved_target, current_block->gcode_target, sizeof(saved_target)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      memcpy(saved_start_position, current_block->gcode_start_position, sizeof(saved_start_position)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       saved_feedrate2 = current_block->gcode_feedrate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      saved_segment_idx = current_block->segment_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // printf_P(PSTR("stop_and_save_print_to_ram: %f, %f, %f, %f, %u\n"), saved_start_position[0], saved_start_position[1], saved_start_position[2], saved_start_position[3], saved_segment_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      saved_target[0] = SAVED_TARGET_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      saved_start_position[0] = SAVED_START_POSITION_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       saved_feedrate2 = feedrate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      saved_segment_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	planner_abort_hard(); //abort printing 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11710,7 +11697,7 @@ void restore_print_from_ram_and_continue(float e_move) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void cancel_saved_printing() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    saved_target[0] = SAVED_TARGET_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    saved_start_position[0] = SAVED_START_POSITION_UNSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     saved_printing_type = PRINTING_TYPE_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     saved_printing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |