diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 9c21c4fd29..1161734372 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -593,8 +593,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L /** * Instant Freeze */ -#if ENABLED(FREEZE_FEATURE) && !(PIN_EXISTS(FREEZE) && defined(FREEZE_STATE)) - #error "FREEZE_FEATURE requires both FREEZE_PIN and FREEZE_STATE." +#if ENABLED(FREEZE_FEATURE) && !(PIN_EXISTS(FREEZE) && defined(FREEZE_STATE) && defined(FREEZE_JERK)) + #error "FREEZE_FEATURE requires FREEZE_PIN, FREEZE_STATE and FREEZE_JERK." #endif /** diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 82dc63f0ed..d0dc32731e 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -2453,15 +2453,17 @@ hal_timer_t Stepper::block_phase_isr() { // acc_step_rate is in steps/second - // step_rate to timer interval and steps per stepper isr #if ENABLED(FREEZE_FEATURE) if(frozen_time) check_frozen_time(acc_step_rate); #endif + + // step_rate to timer interval and steps per stepper isr interval = calc_multistep_timer_interval(acc_step_rate << oversampling_factor); acceleration_time += interval; deceleration_time = 0; // Reset since we're doing acceleration first. + #if ENABLED(FREEZE_FEATURE) - if(frozen_pin && !frozen_solid) frozen_time += interval * 2; + check_frozen_pin(0, interval); #endif #if ENABLED(NONLINEAR_EXTRUSION) @@ -2525,21 +2527,16 @@ hal_timer_t Stepper::block_phase_isr() { #endif - // step_rate to timer interval and steps per stepper isr #if ENABLED(FREEZE_FEATURE) if(frozen_time) check_frozen_time(step_rate); #endif + + // step_rate to timer interval and steps per stepper isr interval = calc_multistep_timer_interval(step_rate << oversampling_factor); deceleration_time += interval; + #if ENABLED(FREEZE_FEATURE) - if(!frozen_pin) { - if(frozen_time) { - if(frozen_time > interval * 2) frozen_time -= interval * 2; - else frozen_time = 0; - } - - frozen_solid = false; - } + check_frozen_pin(1, interval); #endif #if ENABLED(NONLINEAR_EXTRUSION) @@ -2596,11 +2593,13 @@ hal_timer_t Stepper::block_phase_isr() { ) { uint32_t step_rate = current_block->nominal_rate; - // step_rate to timer interval and loops for the nominal speed #if ENABLED(FREEZE_FEATURE) if(frozen_time) check_frozen_time(step_rate); #endif + + // step_rate to timer interval and loops for the nominal speed ticks_nominal = calc_multistep_timer_interval(step_rate << oversampling_factor); + // Prepare for deceleration IF_DISABLED(S_CURVE_ACCELERATION, acc_step_rate = step_rate); deceleration_time = ticks_nominal / 2; @@ -2633,14 +2632,7 @@ hal_timer_t Stepper::block_phase_isr() { interval = ticks_nominal; #if ENABLED(FREEZE_FEATURE) - if(frozen_pin) { - if(!frozen_solid) frozen_time += ticks_nominal; - } else { - if (frozen_time > ticks_nominal) frozen_time -= ticks_nominal; - else frozen_time = 0; - - frozen_solid = false; - } + check_frozen_pin(2, interval); #endif } } @@ -2882,12 +2874,19 @@ hal_timer_t Stepper::block_phase_isr() { } #endif - // Calculate the initial timer interval uint32_t step_rate = current_block->initial_rate; + #if ENABLED(FREEZE_FEATURE) if(frozen_time) check_frozen_time(step_rate); #endif + + // Calculate the initial timer interval interval = calc_multistep_timer_interval(step_rate << oversampling_factor); + + #if ENABLED(FREEZE_FEATURE) + check_frozen_pin(0, interval); + #endif + // Initialize ac/deceleration time as if half the time passed. acceleration_time = deceleration_time = interval / 2; @@ -4575,4 +4574,41 @@ void Stepper::check_frozen_time(uint32_t &step_rate) { frozen_solid = step_rate < (current_block->acceleration_steps_per_s2 / current_block->acceleration * FREEZE_JERK); } +void Stepper::check_frozen_pin(uint8_t type, uint32_t interval) { + switch(type) { + case 0: //acceleration + if(frozen_pin && !frozen_solid) frozen_time += interval * 2; + break; + + case 1: //deceleration + if(!frozen_pin) { + if(frozen_time) { + if(frozen_time > interval * 2) frozen_time -= interval * 2; + else frozen_time = 0; + } + + frozen_solid = false; + } + break; + + case 2: //cruise + if(frozen_pin) { + if(!frozen_solid) frozen_time += interval; + } else { + if(frozen_time) { + if (frozen_time > interval) { + frozen_time -= interval; + } + else { + frozen_time = 0; + ticks_nominal = 0; //Reset ticks_nominal to allow for recalculation of interval at nominal_rate + } + } + + frozen_solid = false; + } + break; + } +} + #endif \ No newline at end of file diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index f102af8a23..9ee6077677 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -339,6 +339,7 @@ class Stepper { static bool frozen_solid; // Are we stopped? static uint32_t frozen_time; // How stepper ticks passed static void check_frozen_time(uint32_t &step_rate); + static void check_frozen_pin(uint8_t type, uint32_t interval); #endif #if ENABLED(NONLINEAR_EXTRUSION)