| 
					
				 | 
			
			
				@@ -126,8 +126,7 @@ float extrude_min_temp=EXTRUDE_MINTEMP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    float extruder_advance_k = LIN_ADVANCE_K, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    advance_ed_ratio = LIN_ADVANCE_E_D_RATIO, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    float extruder_advance_K = LIN_ADVANCE_K, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     position_float[NUM_AXIS] = { 0 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -402,6 +401,13 @@ void planner_recalculate(const float &safe_final_speed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if ((prev->flag | current->flag) & BLOCK_FLAG_RECALCULATE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // NOTE: Entry and exit factors always > 0 by all previous logic operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  if (current->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    const float comp = current->e_D_ratio * extruder_advance_K * axis_steps_per_unit[E_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    current->max_adv_steps = current->nominal_speed * comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    current->final_adv_steps = next->entry_speed * comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // Reset current only to ensure next trapezoid is computed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 prev->flag &= ~BLOCK_FLAG_RECALCULATE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -415,6 +421,13 @@ void planner_recalculate(const float &safe_final_speed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Last/newest block in buffer. Exit speed is set with safe_final_speed. Always recalculated. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     current = block_buffer + prev_block_index(block_buffer_head); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     calculate_trapezoid_for_block(current, current->entry_speed, safe_final_speed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (current->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const float comp = current->e_D_ratio * extruder_advance_K * axis_steps_per_unit[E_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current->max_adv_steps = current->nominal_speed * comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current->final_adv_steps = safe_final_speed * comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     current->flag &= ~BLOCK_FLAG_RECALCULATE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //    SERIAL_ECHOLNPGM("planner_recalculate - 4"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -748,11 +761,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif // ENABLE_MESH_BED_LEVELING 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   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])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    float de_float = e - position_float[E_AXIS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   #ifdef PREVENT_DANGEROUS_EXTRUDE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if(target[E_AXIS]!=position[E_AXIS]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -761,7 +769,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       position_float[E_AXIS] = e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      de_float = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       SERIAL_ECHO_START; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       SERIAL_ECHOLNRPGM(_n(" cold extrusion prevented"));////MSG_ERR_COLD_EXTRUDE_STOP 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -773,7 +780,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         position_float[E_AXIS] = e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        de_float = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       SERIAL_ECHO_START; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       SERIAL_ECHOLNRPGM(_n(" too long extrusion prevented"));////MSG_ERR_LONG_EXTRUDE_STOP 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1001,10 +1007,50 @@ Having the real displacement of the head, we can calculate the total movement le 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     block->acceleration_st = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      block->use_advance_lead = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     block->acceleration_st = ceil(cs.acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * Use LIN_ADVANCE for blocks if all these are true: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * block->steps_e             : This is a print move, because we checked for X, Y, Z steps before. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * extruder_advance_K : There is an advance factor set. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * delta_mm[E_AXIS] > 0             : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      block->use_advance_lead =  block->steps_e 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              && extruder_advance_K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              && delta_mm[E_AXIS] > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (block->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        block->e_D_ratio = (e - position_float[E_AXIS]) / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sqrt(sq(x - position_float[X_AXIS]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               + sq(y - position_float[Y_AXIS]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               + sq(z - position_float[Z_AXIS])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Check for unusual high e_D ratio to detect if a retract move was combined with the last print move due to min. steps per segment. Never execute this with advance! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // This assumes no one will use a retract length of 0mm < retr_length < ~0.2mm and no one will print 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (block->e_D_ratio > 3.0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          block->use_advance_lead = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const uint32_t max_accel_steps_per_s2 = max_jerk[E_AXIS] / (extruder_advance_K * block->e_D_ratio) * steps_per_mm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          #ifdef LA_DEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (block->acceleration_st > max_accel_steps_per_s2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              SERIAL_ECHOLNPGM("Acceleration limited."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          NOMORE(block->acceleration_st, max_accel_steps_per_s2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 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]) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1037,6 +1083,18 @@ Having the real displacement of the head, we can calculate the total movement le 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (block->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      block->advance_speed = ((F_CPU) * 0.125) / (extruder_advance_K * block->e_D_ratio * block->acceleration * axis_steps_per_unit[E_AXIS]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      #ifdef LA_DEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (extruder_advance_K * block->e_D_ratio * block->acceleration * 2 < block->nominal_speed * block->e_D_ratio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (block->advance_speed < 200) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          SERIAL_ECHOLNPGM("eISR running at > 10kHz."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Start with a safe speed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Safe speed is the speed, from which the machine may halt to stop immediately. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   float safe_speed = block->nominal_speed; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1153,37 +1211,6 @@ Having the real displacement of the head, we can calculate the total movement le 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   previous_nominal_speed = block->nominal_speed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   previous_safe_speed = safe_speed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Use LIN_ADVANCE for blocks if all these are true: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // esteps                                          : We have E steps todo (a printing move) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // block->steps[X_AXIS] || block->steps[Y_AXIS]    : We have a movement in XY direction (i.e., not retract / prime). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // extruder_advance_k                              : There is an advance factor set. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // block->steps[E_AXIS] != block->step_event_count : A problem occurs if the move before a retract is too small. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //                                                   In that case, the retract and move will be executed together. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //                                                   This leads to too many advance steps due to a huge e_acceleration. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //                                                   The math is good, but we must avoid retract moves with advance! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // de_float > 0.0                                  : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    block->use_advance_lead =  block->steps_e.wide 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           && (block->steps_x.wide || block->steps_y.wide) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           && extruder_advance_k 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           && (uint32_t)block->steps_e.wide != block->step_event_count.wide 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           && de_float > 0.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (block->use_advance_lead) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        block->abs_adv_steps_multiplier8 = lround( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          * cs.axis_steps_per_unit[E_AXIS] * 256.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   block->speed_factor = block->nominal_rate / block->nominal_speed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calculate_trapezoid_for_block(block, block->entry_speed, safe_speed); 
			 |