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).
This commit is contained in:
Yuri D'Elia 2020-06-23 16:40:39 +02:00
parent 50a09824fd
commit f1efce7e52

View File

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