Merge pull request #11011 from thinkyhead/bf1_honor_step_rate
[1.1.x] Ensure good min/max stepper timing
This commit is contained in:
commit
91976e3ef4
@ -1308,121 +1308,4 @@
|
|||||||
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
|
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Calculate a default maximum stepper rate, if not supplied
|
|
||||||
#ifndef MAXIMUM_STEPPER_RATE
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
|
||||||
#define MAXIMUM_STEPPER_RATE (1000000UL / (2UL * (MINIMUM_STEPPER_PULSE)))
|
|
||||||
#else
|
|
||||||
#define MAXIMUM_STEPPER_RATE 500000UL
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Estimate the amount of time the ISR will take to execute
|
|
||||||
//
|
|
||||||
|
|
||||||
// The base ISR takes 752 cycles
|
|
||||||
#define ISR_BASE_CYCLES 752UL
|
|
||||||
|
|
||||||
// Linear advance base time is 32 cycles
|
|
||||||
#if ENABLED(LIN_ADVANCE)
|
|
||||||
#define ISR_LA_BASE_CYCLES 32UL
|
|
||||||
#else
|
|
||||||
#define ISR_LA_BASE_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// S curve interpolation adds 160 cycles
|
|
||||||
#if ENABLED(S_CURVE_ACCELERATION)
|
|
||||||
#define ISR_S_CURVE_CYCLES 160UL
|
|
||||||
#else
|
|
||||||
#define ISR_S_CURVE_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Stepper Loop base cycles
|
|
||||||
#define ISR_LOOP_BASE_CYCLES 32UL
|
|
||||||
|
|
||||||
// And each stepper takes 88 cycles
|
|
||||||
#define ISR_STEPPER_CYCLES 88UL
|
|
||||||
|
|
||||||
// For each stepper, we add its time
|
|
||||||
#ifdef HAS_X_STEP
|
|
||||||
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
|
||||||
#else
|
|
||||||
#define ISR_X_STEPPER_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For each stepper, we add its time
|
|
||||||
#ifdef HAS_Y_STEP
|
|
||||||
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
|
||||||
#else
|
|
||||||
#define ISR_Y_STEPPER_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For each stepper, we add its time
|
|
||||||
#ifdef HAS_Z_STEP
|
|
||||||
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
|
||||||
#else
|
|
||||||
#define ISR_Z_STEPPER_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// E is always interpolated, even for mixing extruders
|
|
||||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
|
||||||
|
|
||||||
// If linear advance is disabled, then the loop also handles them
|
|
||||||
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
|
|
||||||
#define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * ISR_STEPPER_CYCLES)
|
|
||||||
#else
|
|
||||||
#define ISR_MIXING_STEPPER_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// And the total minimum loop time is, without including the base
|
|
||||||
#define MIN_ISR_LOOP_CYCLES (ISR_X_STEPPER_CYCLES + ISR_Y_STEPPER_CYCLES + ISR_Z_STEPPER_CYCLES + ISR_E_STEPPER_CYCLES + ISR_MIXING_STEPPER_CYCLES)
|
|
||||||
|
|
||||||
// Calculate the minimum MPU cycles needed per pulse to enforce not surpassing the maximum stepper rate
|
|
||||||
#define _MIN_STEPPER_PULSE_CYCLES(N) MAX((F_CPU) / (MAXIMUM_STEPPER_RATE), ((F_CPU) / 500000UL) * (N))
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
|
||||||
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(MINIMUM_STEPPER_PULSE)
|
|
||||||
#else
|
|
||||||
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// But the user could be enforcing a minimum time, so the loop time is
|
|
||||||
#define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES))
|
|
||||||
|
|
||||||
// If linear advance is enabled, then it is handled separately
|
|
||||||
#if ENABLED(LIN_ADVANCE)
|
|
||||||
|
|
||||||
// Estimate the minimum LA loop time
|
|
||||||
#if ENABLED(MIXING_EXTRUDER)
|
|
||||||
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
|
||||||
#else
|
|
||||||
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// And the real loop time
|
|
||||||
#define ISR_LA_LOOP_CYCLES MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LA_LOOP_CYCLES)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define ISR_LA_LOOP_CYCLES 0UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Now estimate the total ISR execution time in cycles given a step per ISR multiplier
|
|
||||||
#define ISR_EXECUTION_CYCLES(rate) (((ISR_BASE_CYCLES + ISR_S_CURVE_CYCLES + (ISR_LOOP_CYCLES * rate) + ISR_LA_BASE_CYCLES + ISR_LA_LOOP_CYCLES)) / rate)
|
|
||||||
|
|
||||||
// The maximum allowable stepping frequency when doing x128-x1 stepping (in Hz)
|
|
||||||
#define MAX_128X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(128))
|
|
||||||
#define MAX_64X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(64))
|
|
||||||
#define MAX_32X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(32))
|
|
||||||
#define MAX_16X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(16))
|
|
||||||
#define MAX_8X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(8))
|
|
||||||
#define MAX_4X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(4))
|
|
||||||
#define MAX_2X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(2))
|
|
||||||
#define MAX_1X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(1))
|
|
||||||
|
|
||||||
// The minimum allowable frequency for step smoothing will be 1/10 of the maximum nominal frequency (in Hz)
|
|
||||||
#define MIN_STEP_ISR_FREQUENCY MAX_1X_STEP_ISR_FREQUENCY
|
|
||||||
|
|
||||||
// Disable multiple steps per ISR
|
|
||||||
//#define DISABLE_MULTI_STEPPING
|
|
||||||
|
|
||||||
#endif // CONDITIONALS_POST_H
|
#endif // CONDITIONALS_POST_H
|
||||||
|
24
Marlin/HAL.h
24
Marlin/HAL.h
@ -95,21 +95,15 @@ inline uint8_t HAL_get_reset_source(void) { return MCUSR; }
|
|||||||
#define TEMP_TIMER_NUM 0
|
#define TEMP_TIMER_NUM 0
|
||||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||||
|
|
||||||
|
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
|
||||||
|
|
||||||
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
|
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
|
||||||
#define HAL_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double
|
|
||||||
#define STEPPER_TIMER_PRESCALE 8
|
#define STEPPER_TIMER_PRESCALE 8
|
||||||
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
|
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double
|
||||||
|
|
||||||
#define TEMP_TIMER_PRESCALE 64
|
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
|
||||||
#define TEMP_TIMER_FREQUENCY ((F_CPU) / float(TEMP_TIMER_PRESCALE) / 256.0)
|
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||||
|
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||||
#define TIMER_OCR_1 OCR1A
|
|
||||||
#define TIMER_COUNTER_1 TCNT1
|
|
||||||
|
|
||||||
#define TIMER_OCR_0 OCR0A
|
|
||||||
#define TIMER_COUNTER_0 TCNT0
|
|
||||||
|
|
||||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
|
||||||
|
|
||||||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
|
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
|
||||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
||||||
@ -150,6 +144,12 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t freque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TIMER_OCR_1 OCR1A
|
||||||
|
#define TIMER_COUNTER_1 TCNT1
|
||||||
|
|
||||||
|
#define TIMER_OCR_0 OCR0A
|
||||||
|
#define TIMER_COUNTER_0 TCNT0
|
||||||
|
|
||||||
#define _CAT(a, ...) a ## __VA_ARGS__
|
#define _CAT(a, ...) a ## __VA_ARGS__
|
||||||
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
|
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
|
||||||
#define HAL_timer_restrain(timer, interval_ticks) NOLESS(_CAT(TIMER_OCR_, timer), _CAT(TIMER_COUNTER_, timer) + interval_ticks)
|
#define HAL_timer_restrain(timer, interval_ticks) NOLESS(_CAT(TIMER_OCR_, timer), _CAT(TIMER_COUNTER_, timer) + interval_ticks)
|
||||||
|
@ -1214,7 +1214,7 @@ void Stepper::isr() {
|
|||||||
* On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
|
* On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
|
||||||
* On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
|
* On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
|
||||||
*/
|
*/
|
||||||
min_ticks = HAL_timer_get_count(STEP_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * 8);
|
min_ticks = HAL_timer_get_count(STEP_TIMER_NUM) + hal_timer_t((STEPPER_TIMER_TICKS_PER_US) * 8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NB: If for some reason the stepper monopolizes the MPU, eventually the
|
* NB: If for some reason the stepper monopolizes the MPU, eventually the
|
||||||
@ -1266,10 +1266,10 @@ void Stepper::stepper_pulse_phase_isr() {
|
|||||||
// Just update the value we will get at the end of the loop
|
// Just update the value we will get at the end of the loop
|
||||||
step_events_completed += events_to_do;
|
step_events_completed += events_to_do;
|
||||||
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
// Get the timer count and estimate the end of the pulse
|
||||||
// Get the timer count and estimate the end of the pulse
|
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t(MIN_PULSE_TICKS);
|
||||||
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
|
||||||
#endif
|
const hal_timer_t added_step_ticks = ADDED_STEP_TICKS;
|
||||||
|
|
||||||
// Take multiple steps per interrupt (For high speed moves)
|
// Take multiple steps per interrupt (For high speed moves)
|
||||||
do {
|
do {
|
||||||
@ -1342,10 +1342,11 @@ void Stepper::stepper_pulse_phase_isr() {
|
|||||||
#if MINIMUM_STEPPER_PULSE
|
#if MINIMUM_STEPPER_PULSE
|
||||||
// Just wait for the requested pulse duration
|
// Just wait for the requested pulse duration
|
||||||
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||||
// Add to the value, the value needed for the pulse end and ensuring the maximum driver rate is enforced
|
|
||||||
pulse_end += hal_timer_t(MIN_STEPPER_PULSE_CYCLES) - hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Add the delay needed to ensure the maximum driver rate is enforced
|
||||||
|
if (signed(added_step_ticks) > 0) pulse_end += hal_timer_t(added_step_ticks);
|
||||||
|
|
||||||
// Pulse stop
|
// Pulse stop
|
||||||
#if HAS_X_STEP
|
#if HAS_X_STEP
|
||||||
PULSE_STOP(X);
|
PULSE_STOP(X);
|
||||||
@ -1373,15 +1374,15 @@ void Stepper::stepper_pulse_phase_isr() {
|
|||||||
// Decrement the count of pending pulses to do
|
// Decrement the count of pending pulses to do
|
||||||
--events_to_do;
|
--events_to_do;
|
||||||
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
// For minimum pulse time wait after stopping pulses also
|
||||||
// For minimum pulse time wait after stopping pulses also
|
if (events_to_do) {
|
||||||
if (events_to_do) {
|
// Just wait for the requested pulse duration
|
||||||
// Just wait for the requested pulse duration
|
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||||
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
#if MINIMUM_STEPPER_PULSE
|
||||||
// Add to the value, the time that the pulse must be active (to be used on the next loop)
|
// Add to the value, the time that the pulse must be active (to be used on the next loop)
|
||||||
pulse_end += hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
pulse_end += hal_timer_t(MIN_PULSE_TICKS);
|
||||||
}
|
#endif
|
||||||
#endif
|
}
|
||||||
|
|
||||||
} while (events_to_do);
|
} while (events_to_do);
|
||||||
}
|
}
|
||||||
@ -1614,7 +1615,7 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
|||||||
uint32_t max_rate = current_block->nominal_rate; // Get the maximum rate (maximum event speed)
|
uint32_t max_rate = current_block->nominal_rate; // Get the maximum rate (maximum event speed)
|
||||||
while (max_rate < MIN_STEP_ISR_FREQUENCY) {
|
while (max_rate < MIN_STEP_ISR_FREQUENCY) {
|
||||||
max_rate <<= 1;
|
max_rate <<= 1;
|
||||||
if (max_rate >= MAX_1X_STEP_ISR_FREQUENCY) break;
|
if (max_rate >= MAX_STEP_ISR_FREQUENCY_1X) break;
|
||||||
++oversampling;
|
++oversampling;
|
||||||
}
|
}
|
||||||
oversampling_factor = oversampling;
|
oversampling_factor = oversampling;
|
||||||
@ -1760,13 +1761,15 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
|||||||
REV_E_DIR(active_extruder);
|
REV_E_DIR(active_extruder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Get the timer count and estimate the end of the pulse
|
||||||
|
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t(MIN_PULSE_TICKS);
|
||||||
|
|
||||||
|
const hal_timer_t added_step_ticks = ADDED_STEP_TICKS;
|
||||||
|
|
||||||
// Step E stepper if we have steps
|
// Step E stepper if we have steps
|
||||||
while (LA_steps) {
|
while (LA_steps) {
|
||||||
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
// Set the STEP pulse ON
|
||||||
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(MIXING_EXTRUDER)
|
#if ENABLED(MIXING_EXTRUDER)
|
||||||
MIXING_STEPPERS_LOOP(j) {
|
MIXING_STEPPERS_LOOP(j) {
|
||||||
// Step mixing steppers (proportionally)
|
// Step mixing steppers (proportionally)
|
||||||
@ -1778,15 +1781,18 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
|||||||
E_STEP_WRITE(active_extruder, !INVERT_E_STEP_PIN);
|
E_STEP_WRITE(active_extruder, !INVERT_E_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Enforce a minimum duration for STEP pulse ON
|
||||||
#if MINIMUM_STEPPER_PULSE
|
#if MINIMUM_STEPPER_PULSE
|
||||||
// Just wait for the requested pulse duration
|
// Just wait for the requested pulse duration
|
||||||
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||||
// Add to the value, the value needed for the pulse end and ensuring the maximum driver rate is enforced
|
|
||||||
pulse_end += hal_timer_t(MIN_STEPPER_PULSE_CYCLES) - hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Add the delay needed to ensure the maximum driver rate is enforced
|
||||||
|
if (signed(added_step_ticks) > 0) pulse_end += hal_timer_t(added_step_ticks);
|
||||||
|
|
||||||
LA_steps < 0 ? ++LA_steps : --LA_steps;
|
LA_steps < 0 ? ++LA_steps : --LA_steps;
|
||||||
|
|
||||||
|
// Set the STEP pulse OFF
|
||||||
#if ENABLED(MIXING_EXTRUDER)
|
#if ENABLED(MIXING_EXTRUDER)
|
||||||
MIXING_STEPPERS_LOOP(j) {
|
MIXING_STEPPERS_LOOP(j) {
|
||||||
if (delta_error_m[j] >= 0) {
|
if (delta_error_m[j] >= 0) {
|
||||||
@ -1798,12 +1804,15 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
|||||||
E_STEP_WRITE(active_extruder, INVERT_E_STEP_PIN);
|
E_STEP_WRITE(active_extruder, INVERT_E_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MINIMUM_STEPPER_PULSE
|
// For minimum pulse time wait before looping
|
||||||
// For minimum pulse time wait before looping
|
// Just wait for the requested pulse duration
|
||||||
// Just wait for the requested pulse duration
|
if (LA_steps) {
|
||||||
if (LA_steps) while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||||
#endif
|
#if MINIMUM_STEPPER_PULSE
|
||||||
|
// Add to the value, the time that the pulse must be active (to be used on the next loop)
|
||||||
|
pulse_end += hal_timer_t(MIN_PULSE_TICKS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
} // LA_steps
|
} // LA_steps
|
||||||
|
|
||||||
return interval;
|
return interval;
|
||||||
|
177
Marlin/stepper.h
177
Marlin/stepper.h
@ -43,15 +43,166 @@
|
|||||||
#ifndef STEPPER_H
|
#ifndef STEPPER_H
|
||||||
#define STEPPER_H
|
#define STEPPER_H
|
||||||
|
|
||||||
|
#include "MarlinConfig.h"
|
||||||
|
|
||||||
|
// Disable multiple steps per ISR
|
||||||
|
//#define DISABLE_MULTI_STEPPING
|
||||||
|
|
||||||
|
//
|
||||||
|
// Estimate the amount of time the Stepper ISR will take to execute
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MINIMUM_STEPPER_PULSE
|
||||||
|
#define MINIMUM_STEPPER_PULSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXIMUM_STEPPER_RATE
|
||||||
|
#if MINIMUM_STEPPER_PULSE
|
||||||
|
#define MAXIMUM_STEPPER_RATE (1000000UL / (2UL * (MINIMUM_STEPPER_PULSE)))
|
||||||
|
#else
|
||||||
|
#define MAXIMUM_STEPPER_RATE 500000UL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CPU_32_BIT
|
||||||
|
|
||||||
|
// The base ISR takes 792 cycles
|
||||||
|
#define ISR_BASE_CYCLES 792UL
|
||||||
|
|
||||||
|
// Linear advance base time is 64 cycles
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
#define ISR_LA_BASE_CYCLES 64UL
|
||||||
|
#else
|
||||||
|
#define ISR_LA_BASE_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// S curve interpolation adds 40 cycles
|
||||||
|
#if ENABLED(S_CURVE_ACCELERATION)
|
||||||
|
#define ISR_S_CURVE_CYCLES 40UL
|
||||||
|
#else
|
||||||
|
#define ISR_S_CURVE_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Stepper Loop base cycles
|
||||||
|
#define ISR_LOOP_BASE_CYCLES 4UL
|
||||||
|
|
||||||
|
// And each stepper takes 16 cycles
|
||||||
|
#define ISR_STEPPER_CYCLES 16UL
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// The base ISR takes 752 cycles
|
||||||
|
#define ISR_BASE_CYCLES 752UL
|
||||||
|
|
||||||
|
// Linear advance base time is 32 cycles
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
#define ISR_LA_BASE_CYCLES 32UL
|
||||||
|
#else
|
||||||
|
#define ISR_LA_BASE_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// S curve interpolation adds 160 cycles
|
||||||
|
#if ENABLED(S_CURVE_ACCELERATION)
|
||||||
|
#define ISR_S_CURVE_CYCLES 160UL
|
||||||
|
#else
|
||||||
|
#define ISR_S_CURVE_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Stepper Loop base cycles
|
||||||
|
#define ISR_LOOP_BASE_CYCLES 32UL
|
||||||
|
|
||||||
|
// And each stepper takes 88 cycles
|
||||||
|
#define ISR_STEPPER_CYCLES 88UL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add time for each stepper
|
||||||
|
#ifdef HAS_X_STEP
|
||||||
|
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||||
|
#else
|
||||||
|
#define ISR_X_STEPPER_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_Y_STEP
|
||||||
|
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||||
|
#else
|
||||||
|
#define ISR_Y_STEPPER_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_Z_STEP
|
||||||
|
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||||
|
#else
|
||||||
|
#define ISR_Z_STEPPER_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// E is always interpolated, even for mixing extruders
|
||||||
|
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||||
|
|
||||||
|
// If linear advance is disabled, then the loop also handles them
|
||||||
|
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
|
||||||
|
#define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||||
|
#else
|
||||||
|
#define ISR_MIXING_STEPPER_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// And the total minimum loop time, not including the base
|
||||||
|
#define MIN_ISR_LOOP_CYCLES (ISR_X_STEPPER_CYCLES + ISR_Y_STEPPER_CYCLES + ISR_Z_STEPPER_CYCLES + ISR_E_STEPPER_CYCLES + ISR_MIXING_STEPPER_CYCLES)
|
||||||
|
|
||||||
|
// Calculate the minimum MPU cycles needed per pulse to enforce, limited to the max stepper rate
|
||||||
|
#define _MIN_STEPPER_PULSE_CYCLES(N) max((F_CPU) / (MAXIMUM_STEPPER_RATE), ((F_CPU) / 500000UL) * (N))
|
||||||
|
#if MINIMUM_STEPPER_PULSE
|
||||||
|
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(MINIMUM_STEPPER_PULSE)
|
||||||
|
#else
|
||||||
|
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MIN_PULSE_TICKS ((PULSE_TIMER_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE))
|
||||||
|
#define ADDED_STEP_TICKS ((MIN_STEPPER_PULSE_CYCLES) / (PULSE_TIMER_PRESCALE) - MIN_PULSE_TICKS)
|
||||||
|
|
||||||
|
// But the user could be enforcing a minimum time, so the loop time is
|
||||||
|
#define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + max(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES))
|
||||||
|
|
||||||
|
// If linear advance is enabled, then it is handled separately
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
|
||||||
|
// Estimate the minimum LA loop time
|
||||||
|
#if ENABLED(MIXING_EXTRUDER)
|
||||||
|
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||||
|
#else
|
||||||
|
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// And the real loop time
|
||||||
|
#define ISR_LA_LOOP_CYCLES max(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LA_LOOP_CYCLES)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define ISR_LA_LOOP_CYCLES 0UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Now estimate the total ISR execution time in cycles given a step per ISR multiplier
|
||||||
|
#define ISR_EXECUTION_CYCLES(R) (((ISR_BASE_CYCLES + ISR_S_CURVE_CYCLES + (ISR_LOOP_CYCLES) * (R) + ISR_LA_BASE_CYCLES + ISR_LA_LOOP_CYCLES)) / (R))
|
||||||
|
|
||||||
|
// The maximum allowable stepping frequency when doing x128-x1 stepping (in Hz)
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_128X ((F_CPU) / ISR_EXECUTION_CYCLES(128))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_64X ((F_CPU) / ISR_EXECUTION_CYCLES(64))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_32X ((F_CPU) / ISR_EXECUTION_CYCLES(32))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_16X ((F_CPU) / ISR_EXECUTION_CYCLES(16))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_8X ((F_CPU) / ISR_EXECUTION_CYCLES(8))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_4X ((F_CPU) / ISR_EXECUTION_CYCLES(4))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_2X ((F_CPU) / ISR_EXECUTION_CYCLES(2))
|
||||||
|
#define MAX_STEP_ISR_FREQUENCY_1X ((F_CPU) / ISR_EXECUTION_CYCLES(1))
|
||||||
|
|
||||||
|
// The minimum allowable frequency for step smoothing will be 1/10 of the maximum nominal frequency (in Hz)
|
||||||
|
#define MIN_STEP_ISR_FREQUENCY MAX_STEP_ISR_FREQUENCY_1X
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stepper class definition
|
||||||
|
//
|
||||||
|
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "speed_lookuptable.h"
|
#include "speed_lookuptable.h"
|
||||||
#include "stepper_indirection.h"
|
#include "stepper_indirection.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
class Stepper;
|
|
||||||
extern Stepper stepper;
|
|
||||||
|
|
||||||
// intRes = intIn1 * intIn2 >> 16
|
// intRes = intIn1 * intIn2 >> 16
|
||||||
// uses:
|
// uses:
|
||||||
// r26 to store 0
|
// r26 to store 0
|
||||||
@ -314,14 +465,14 @@ class Stepper {
|
|||||||
|
|
||||||
// The stepping frequency limits for each multistepping rate
|
// The stepping frequency limits for each multistepping rate
|
||||||
static const uint32_t limit[] PROGMEM = {
|
static const uint32_t limit[] PROGMEM = {
|
||||||
( MAX_1X_STEP_ISR_FREQUENCY ),
|
( MAX_STEP_ISR_FREQUENCY_1X ),
|
||||||
( MAX_2X_STEP_ISR_FREQUENCY >> 1),
|
( MAX_STEP_ISR_FREQUENCY_2X >> 1),
|
||||||
( MAX_4X_STEP_ISR_FREQUENCY >> 2),
|
( MAX_STEP_ISR_FREQUENCY_4X >> 2),
|
||||||
( MAX_8X_STEP_ISR_FREQUENCY >> 3),
|
( MAX_STEP_ISR_FREQUENCY_8X >> 3),
|
||||||
( MAX_16X_STEP_ISR_FREQUENCY >> 4),
|
( MAX_STEP_ISR_FREQUENCY_16X >> 4),
|
||||||
( MAX_32X_STEP_ISR_FREQUENCY >> 5),
|
( MAX_STEP_ISR_FREQUENCY_32X >> 5),
|
||||||
( MAX_64X_STEP_ISR_FREQUENCY >> 6),
|
( MAX_STEP_ISR_FREQUENCY_64X >> 6),
|
||||||
(MAX_128X_STEP_ISR_FREQUENCY >> 7)
|
(MAX_STEP_ISR_FREQUENCY_128X >> 7)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select the proper multistepping
|
// Select the proper multistepping
|
||||||
@ -332,7 +483,7 @@ class Stepper {
|
|||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
NOMORE(step_rate, uint32_t(MAX_1X_STEP_ISR_FREQUENCY));
|
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
|
||||||
#endif
|
#endif
|
||||||
*loops = multistep;
|
*loops = multistep;
|
||||||
|
|
||||||
@ -373,4 +524,6 @@ class Stepper {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Stepper stepper;
|
||||||
|
|
||||||
#endif // STEPPER_H
|
#endif // STEPPER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user