Browse Source

Handle LA termination with double/quad stepping properly

Before PR #2591 LA was automatically capped during cruising or
deceleration. However we now rely on reaching the current pressure state
exactly to stop. When dual/quad stepping inside the eISR we might incur
in oscillating behavior if we do not handle it correctly.

This might be the cause behind #2757

This now changes e_step_loops to be a phase-local variable, so we now
reset it each phase too (instead of per-segment).
Yuri D'Elia 3 years ago
parent
commit
f1efce7e52
1 changed files with 14 additions and 7 deletions
  1. 14 7
      Firmware/stepper.cpp

+ 14 - 7
Firmware/stepper.cpp

@@ -348,10 +348,7 @@ FORCE_INLINE void stepper_next_block()
 
 #ifdef LIN_ADVANCE
     if (current_block->use_advance_lead) {
-        e_step_loops = current_block->advance_step_loops;
         target_adv_steps = current_block->max_adv_steps;
-    } else {
-        e_step_loops = 1;
     }
     e_steps = 0;
     nextAdvanceISR = ADV_NEVER;
@@ -871,7 +868,10 @@ FORCE_INLINE void isr() {
             nextAdvanceISR = ADV_NEVER;
         }
         else {
+            // reset error and iterations per loop for this phase
             eISR_Err = current_block->advance_rate / 4;
+            e_step_loops = current_block->advance_step_loops;
+
             if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
                 // LA could reverse the direction of extrusion in this phase
                 LA_phase = 0;
@@ -929,15 +929,22 @@ FORCE_INLINE void isr() {
 FORCE_INLINE void advance_isr() {
     if (current_adv_steps > target_adv_steps) {
         // decompression
+        if (e_step_loops != 1) {
+            uint16_t d_steps = current_adv_steps - target_adv_steps;
+            if (d_steps < e_step_loops)
+                e_step_loops = d_steps;
+        }
         e_steps -= e_step_loops;
         if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
-        if(current_adv_steps > e_step_loops)
-            current_adv_steps -= e_step_loops;
-        else
-            current_adv_steps = 0;
+        current_adv_steps -= e_step_loops;
     }
     else if (current_adv_steps < target_adv_steps) {
         // compression
+        if (e_step_loops != 1) {
+            uint16_t d_steps = target_adv_steps - current_adv_steps;
+            if (d_steps < e_step_loops)
+                e_step_loops = d_steps;
+        }
         e_steps += e_step_loops;
         if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
         current_adv_steps += e_step_loops;