| 
					
				 | 
			
			
				@@ -124,8 +124,9 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   static uint16_t main_Rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   static uint16_t eISR_Rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  static uint16_t eISR_Err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  static volatile uint16_t current_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  static uint16_t current_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   static uint16_t final_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   static uint16_t max_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   static uint32_t LA_decelerate_after; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -355,14 +356,13 @@ FORCE_INLINE void stepper_next_block() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         final_adv_steps = current_block->final_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         max_adv_steps = current_block->max_adv_steps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e_step_loops = current_block->advance_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        LA_phase = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        nextAdvanceISR = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        eISR_Rate = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        e_steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e_step_loops = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        LA_phase = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         current_adv_steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextAdvanceISR = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    LA_phase = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (current_block->flag & BLOCK_FLAG_DDA_LOWRES) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -707,6 +707,39 @@ FORCE_INLINE void stepper_tick_highres() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+FORCE_INLINE void advance_spread(uint16_t timer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(eISR_Err > timer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // advance-step skipped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        eISR_Err -= timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        eISR_Rate = timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        nextAdvanceISR = timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // at least one step 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint8_t ticks = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t block = current_block->advance_rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint16_t max_t = timer - eISR_Err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (block < max_t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ++ticks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        block += current_block->advance_rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (block > timer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        eISR_Err += block - timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        eISR_Err -= timer - block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eISR_Rate = timer / ticks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextAdvanceISR = eISR_Rate / 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 FORCE_INLINE void isr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   //WRITE_NC(LOGIC_ANALYZER_CH0, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -741,11 +774,10 @@ FORCE_INLINE void isr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         acceleration_time += timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (current_block->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (step_events_completed.wide <= (unsigned long int)step_loops) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // First acceleration loop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                eISR_Rate = current_block->advance_rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                nextAdvanceISR = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bool first = (step_events_completed.wide <= (unsigned long int)step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (first) eISR_Err = current_block->advance_rate / 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (first || nextAdvanceISR != ADV_NEVER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                advance_spread(timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -763,10 +795,20 @@ FORCE_INLINE void isr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         deceleration_time += timer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (current_block->use_advance_lead) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // First deceleration loop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                eISR_Rate = current_block->advance_rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                nextAdvanceISR = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bool first = (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (first) eISR_Err = current_block->advance_rate / 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (first || nextAdvanceISR != ADV_NEVER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                advance_spread(timer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (step_loops == e_step_loops) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    LA_phase = (eISR_Rate > main_Rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // avoid overflow through division (TODO: this can be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // improved as both step_loops and e_step_loops are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // currently guaranteed to be powers of two) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    LA_phase = (eISR_Rate / step_loops > main_Rate / e_step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -779,6 +821,11 @@ FORCE_INLINE void isr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           step_loops_nominal = step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         _NEXT_ISR(OCR1A_nominal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef LIN_ADVANCE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (current_block->use_advance_lead && nextAdvanceISR != ADV_NEVER) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            advance_spread(OCR1A_nominal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       //WRITE_NC(LOGIC_ANALYZER_CH1, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -816,48 +863,26 @@ FORCE_INLINE void advance_isr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (step_events_completed.wide > LA_decelerate_after && current_adv_steps > final_adv_steps) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // decompression 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e_steps -= e_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current_adv_steps -= e_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        nextAdvanceISR = eISR_Rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(nextAdvanceISR == ADV_NEVER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            LA_phase = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            e_step_loops = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(current_adv_steps > e_step_loops) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            current_adv_steps -= e_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (step_loops == e_step_loops) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                LA_phase = (eISR_Rate > main_Rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // avoid overflow through division (TODO: this can be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // improved as both step_loops and e_step_loops are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // guaranteed to be powers of two) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                LA_phase = (eISR_Rate / step_loops > main_Rate / e_step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            current_adv_steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        nextAdvanceISR = eISR_Rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else if (step_events_completed.wide < LA_decelerate_after && current_adv_steps < max_adv_steps) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // compression 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e_steps += e_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         current_adv_steps += e_step_loops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         nextAdvanceISR = eISR_Rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        LA_phase = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(nextAdvanceISR == ADV_NEVER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            e_step_loops = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // advance steps completed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         nextAdvanceISR = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        eISR_Rate = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         LA_phase = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e_step_loops = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define LA_FREQ_MDIV 8 // divider for the advance frequency for maximum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       // time allotted to merge regular and advance 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       // ticks (stick to a power-of-two) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 FORCE_INLINE void advance_isr_scheduler() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Integrate the final timer value, accounting for scheduling adjustments 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(nextAdvanceISR && nextAdvanceISR != ADV_NEVER) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -884,8 +909,8 @@ FORCE_INLINE void advance_isr_scheduler() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Run the next advance isr if triggered now or soon enough 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    bool eisr = nextAdvanceISR < (TCNT1 + eISR_Rate / LA_FREQ_MDIV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Run the next advance isr if triggered 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool eisr = !nextAdvanceISR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (eisr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LA_DEBUG_LOGIC 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -899,23 +924,24 @@ FORCE_INLINE void advance_isr_scheduler() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Tick E steps if any 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (e_steps && (LA_phase < 0 || LA_phase == eisr)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        uint8_t max_ticks = max(e_step_loops, step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint8_t max_ticks = (eisr? e_step_loops: step_loops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         max_ticks = min(abs(e_steps), max_ticks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef FILAMENT_SENSOR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fsensor_counter += max_ticks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         WRITE(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while(max_ticks--) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        do 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             WRITE_NC(E0_STEP_PIN, !INVERT_E_STEP_PIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             e_steps += (e_steps < 0)? 1: -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             WRITE_NC(E0_STEP_PIN, INVERT_E_STEP_PIN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while(--max_ticks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // Schedule the next closest tick, ignoring advance if scheduled too 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // soon in order to avoid skewing the regular stepper acceleration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + TCNT1 + eISR_Rate / LA_FREQ_MDIV) < nextMainISR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + TCNT1 + 40) < nextMainISR) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         OCR1A = nextAdvanceISR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         OCR1A = nextMainISR; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1162,7 +1188,6 @@ void st_init() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   nextMainISR = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   nextAdvanceISR = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   main_Rate = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  eISR_Rate = ADV_NEVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   e_steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   e_step_loops = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   LA_phase = -1; 
			 |