Merge pull request #11011 from thinkyhead/bf1_honor_step_rate

[1.1.x] Ensure good min/max stepper timing
This commit is contained in:
Scott Lahteine 2018-06-12 21:52:48 -05:00 committed by GitHub
commit 91976e3ef4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 214 additions and 169 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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