diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index f3c2ff1d6..2f8fc6dfc 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -110,9 +110,22 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even Stepper::advance; #endif - #define ADV_RATE(T, L) (e_steps[TOOL_E_INDEX] ? (T) * (L) / abs(e_steps[TOOL_E_INDEX]) : ADV_NEVER) + /** + * See https://github.com/MarlinFirmware/Marlin/issues/5699#issuecomment-309264382 + * + * This fix isn't perfect and may lose steps - but better than locking up completely + * in future the planner should slow down if advance stepping rate would be too high + */ + FORCE_INLINE uint16_t adv_rate(const int steps, const uint16_t timer, const uint8_t loops) { + if (steps) { + const uint16_t rate = (timer * loops) / abs(steps); + //return constrain(rate, 1, ADV_NEVER - 1) + return rate ? rate : 1; + } + return ADV_NEVER; + } -#endif +#endif // ADVANCE || LIN_ADVANCE long Stepper::acceleration_time, Stepper::deceleration_time; @@ -743,7 +756,7 @@ void Stepper::isr() { #endif // ADVANCE or LIN_ADVANCE #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) - eISR_Rate = ADV_RATE(timer, step_loops); + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); #endif } else if (step_events_completed > (uint32_t)current_block->decelerate_after) { @@ -797,7 +810,7 @@ void Stepper::isr() { #endif // ADVANCE or LIN_ADVANCE #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) - eISR_Rate = ADV_RATE(timer, step_loops); + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); #endif } else { @@ -807,7 +820,7 @@ void Stepper::isr() { if (current_block->use_advance_lead) current_estep_rate[TOOL_E_INDEX] = final_estep_rate; - eISR_Rate = ADV_RATE(OCR1A_nominal, step_loops_nominal); + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], OCR1A_nominal, step_loops_nominal); #endif