mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-01-22 17:52:57 +00:00
🔧 Minimum Stepper Pulse in Nanoseconds (#27113)
This commit is contained in:
parent
0169cde8a4
commit
65c19f82b9
8 changed files with 113 additions and 174 deletions
|
@ -2556,27 +2556,28 @@
|
|||
//#define MINIMUM_STEPPER_PRE_DIR_DELAY 650
|
||||
|
||||
/**
|
||||
* Minimum stepper driver pulse width (in µs)
|
||||
* 0 : Smallest possible width the MCU can produce, compatible with TMC2xxx drivers
|
||||
* 0 : Minimum 500ns for LV8729, adjusted in stepper.h
|
||||
* 1 : Minimum for A4988 and A5984 stepper drivers
|
||||
* 2 : Minimum for DRV8825 stepper drivers
|
||||
* 3 : Minimum for TB6600 stepper drivers
|
||||
* 30 : Minimum for TB6560 stepper drivers
|
||||
* Minimum stepper driver pulse width (in ns)
|
||||
* If undefined, these defaults (from Conditionals_adv.h) apply:
|
||||
* 100 : Minimum for TMC2xxx stepper drivers
|
||||
* 500 : Minimum for LV8729
|
||||
* 1000 : Minimum for A4988 and A5984 stepper drivers
|
||||
* 2000 : Minimum for DRV8825 stepper drivers
|
||||
* 3000 : Minimum for TB6600 stepper drivers
|
||||
* 30000 : Minimum for TB6560 stepper drivers
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
//#define MINIMUM_STEPPER_PULSE 2
|
||||
//#define MINIMUM_STEPPER_PULSE_NS 2000
|
||||
|
||||
/**
|
||||
* Maximum stepping rate (in Hz) the stepper driver allows
|
||||
* If undefined, defaults to 1MHz / (2 * MINIMUM_STEPPER_PULSE)
|
||||
* If undefined, these defaults (from Conditionals_adv.h) apply:
|
||||
* 5000000 : Maximum for TMC2xxx stepper drivers
|
||||
* 1000000 : Maximum for LV8729 stepper driver
|
||||
* 500000 : Maximum for A4988 stepper driver
|
||||
* 250000 : Maximum for DRV8825 stepper driver
|
||||
* 150000 : Maximum for TB6600 stepper driver
|
||||
* 15000 : Maximum for TB6560 stepper driver
|
||||
* 500000 : Maximum for A4988 stepper driver
|
||||
* 250000 : Maximum for DRV8825 stepper driver
|
||||
* 150000 : Maximum for TB6600 stepper driver
|
||||
* 15000 : Maximum for TB6560 stepper driver
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
typedef uint32_t hal_timer_t;
|
||||
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFE
|
||||
|
||||
#define GPT_TIMER_RATE F_BUS_ACTUAL // 150MHz
|
||||
#define GPT_TIMER_RATE (F_CPU / 4) // 150MHz (Can't use F_BUS_ACTUAL because it's extern volatile)
|
||||
|
||||
#define GPT1_TIMER_PRESCALE 2
|
||||
#define GPT2_TIMER_PRESCALE 10
|
||||
|
||||
#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 75MHz
|
||||
#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 15MHz
|
||||
#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 150MHz / 2 = 75MHz
|
||||
#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 150MHz / 10 = 15MHz
|
||||
|
||||
#ifndef MF_TIMER_STEP
|
||||
#define MF_TIMER_STEP 0 // Timer Index for Stepper
|
||||
|
@ -57,7 +57,8 @@ typedef uint32_t hal_timer_t;
|
|||
#define TEMP_TIMER_RATE 1000000
|
||||
#define TEMP_TIMER_FREQUENCY 1000
|
||||
|
||||
#define STEPPER_TIMER_RATE GPT1_TIMER_RATE
|
||||
#define HAL_TIMER_RATE GPT1_TIMER_RATE
|
||||
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
|
||||
#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US)
|
||||
|
||||
|
|
|
@ -55,9 +55,6 @@
|
|||
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000UL) // 16 or 20 on AVR
|
||||
#endif
|
||||
|
||||
// Nanoseconds per cycle
|
||||
#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
|
||||
|
||||
// Macros to make a string from a macro
|
||||
#define STRINGIFY_(M) #M
|
||||
#define STRINGIFY(M) STRINGIFY_(M)
|
||||
|
|
|
@ -641,6 +641,8 @@
|
|||
#error "PROBE_PT_[123]_[XY] is now defined using PROBE_PT_[123] with an array { x, y }."
|
||||
#elif defined(SQUARE_WAVE_STEPPING)
|
||||
#error "SQUARE_WAVE_STEPPING is now EDGE_STEPPING."
|
||||
#elif defined(MINIMUM_STEPPER_PULSE)
|
||||
#error "MINIMUM_STEPPER_PULSE (in µs) is now MINIMUM_STEPPER_PULSE_NS. Multiply old MINIMUM_STEPPER_PULSE x 1000!"
|
||||
#elif defined(FAN_PIN)
|
||||
#error "FAN_PIN is now FAN0_PIN."
|
||||
#elif defined(X_MIN_ENDSTOP_INVERTING) || defined(Y_MIN_ENDSTOP_INVERTING) || defined(Z_MIN_ENDSTOP_INVERTING) \
|
||||
|
|
|
@ -1198,21 +1198,21 @@
|
|||
#define MINIMUM_STEPPER_PRE_DIR_DELAY MINIMUM_STEPPER_POST_DIR_DELAY
|
||||
#endif
|
||||
|
||||
#ifndef MINIMUM_STEPPER_PULSE
|
||||
#ifndef MINIMUM_STEPPER_PULSE_NS
|
||||
#if HAS_DRIVER(TB6560)
|
||||
#define MINIMUM_STEPPER_PULSE 30
|
||||
#define MINIMUM_STEPPER_PULSE_NS 30000
|
||||
#elif HAS_DRIVER(TB6600)
|
||||
#define MINIMUM_STEPPER_PULSE 3
|
||||
#define MINIMUM_STEPPER_PULSE_NS 3000
|
||||
#elif HAS_DRIVER(DRV8825)
|
||||
#define MINIMUM_STEPPER_PULSE 2
|
||||
#define MINIMUM_STEPPER_PULSE_NS 2000
|
||||
#elif HAS_DRIVER(A4988) || HAS_DRIVER(A5984)
|
||||
#define MINIMUM_STEPPER_PULSE 1
|
||||
#elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE
|
||||
#define MINIMUM_STEPPER_PULSE 0
|
||||
#define MINIMUM_STEPPER_PULSE_NS 1000
|
||||
#elif HAS_DRIVER(LV8729)
|
||||
#define MINIMUM_STEPPER_PULSE 0
|
||||
#define MINIMUM_STEPPER_PULSE_NS 500
|
||||
#elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE
|
||||
#define MINIMUM_STEPPER_PULSE_NS 100
|
||||
#else
|
||||
#define MINIMUM_STEPPER_PULSE 2
|
||||
// Expecting MAXIMUM_STEPPER_RATE to be defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1230,7 +1230,7 @@
|
|||
#elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE
|
||||
#define MAXIMUM_STEPPER_RATE 5000000
|
||||
#else
|
||||
#define MAXIMUM_STEPPER_RATE 250000
|
||||
// Expecting MINIMUM_STEPPER_PULSE_NS to be defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -519,16 +519,15 @@ xyze_int8_t Stepper::count_direction{0};
|
|||
#define E_APPLY_DIR(FWD,Q) do{ if (FWD) { FWD_E_DIR(stepper_extruder); } else { REV_E_DIR(stepper_extruder); } }while(0)
|
||||
#endif
|
||||
|
||||
#define CYCLES_TO_NS(CYC) (1000UL * (CYC) / ((F_CPU) / 1000000))
|
||||
#define NS_PER_PULSE_TIMER_TICK (1000000000UL / (STEPPER_TIMER_RATE))
|
||||
constexpr uint32_t cycles_to_ns(const uint32_t CYC) { return 1000UL * (CYC) / ((F_CPU) / 1000000); }
|
||||
constexpr uint32_t ns_per_pulse_timer_tick = 1000000000UL / (STEPPER_TIMER_RATE);
|
||||
|
||||
// Round up when converting from ns to timer ticks
|
||||
#define NS_TO_PULSE_TIMER_TICKS(NS) (((NS) + (NS_PER_PULSE_TIMER_TICK) / 2) / (NS_PER_PULSE_TIMER_TICK))
|
||||
constexpr hal_timer_t ns_to_pulse_timer_ticks(const uint32_t ns) { return (ns + ns_per_pulse_timer_tick / 2) / ns_per_pulse_timer_tick; }
|
||||
|
||||
#define TIMER_SETUP_NS (CYCLES_TO_NS(TIMER_READ_ADD_AND_STORE_CYCLES))
|
||||
|
||||
#define PULSE_HIGH_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_HIGH_NS - _MIN(_MIN_PULSE_HIGH_NS, TIMER_SETUP_NS)))
|
||||
#define PULSE_LOW_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_LOW_NS - _MIN(_MIN_PULSE_LOW_NS, TIMER_SETUP_NS)))
|
||||
constexpr uint32_t timer_setup_ns = cycles_to_ns(timer_read_add_and_store_cycles);
|
||||
constexpr hal_timer_t PULSE_HIGH_TICK_COUNT = ns_to_pulse_timer_ticks(_min_pulse_high_ns - _MIN(_min_pulse_high_ns, timer_setup_ns));
|
||||
constexpr hal_timer_t PULSE_LOW_TICK_COUNT = ns_to_pulse_timer_ticks(_min_pulse_low_ns - _MIN(_min_pulse_low_ns, timer_setup_ns));
|
||||
|
||||
#define USING_TIMED_PULSE() hal_timer_t start_pulse_count = 0
|
||||
#define START_TIMED_PULSE() (start_pulse_count = HAL_timer_get_count(MF_TIMER_PULSE))
|
||||
|
@ -1720,7 +1719,7 @@ void Stepper::isr() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE
|
||||
#if MINIMUM_STEPPER_PULSE_NS || MAXIMUM_STEPPER_RATE
|
||||
#define ISR_PULSE_CONTROL 1
|
||||
#endif
|
||||
#if ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM)
|
||||
|
@ -2080,7 +2079,7 @@ void Stepper::pulse_phase_isr() {
|
|||
|
||||
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
|
||||
|
||||
// TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s
|
||||
// TODO: need to deal with MINIMUM_STEPPER_PULSE_NS over i2s
|
||||
#if ISR_MULTI_STEPS
|
||||
START_TIMED_PULSE();
|
||||
AWAIT_HIGH_PULSE();
|
||||
|
@ -2256,25 +2255,25 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
|
|||
|
||||
// The stepping frequency limits for each multistepping rate
|
||||
static const uint32_t limit[] PROGMEM = {
|
||||
( MAX_STEP_ISR_FREQUENCY_1X )
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(1)) >> 1)
|
||||
max_step_isr_frequency_sh(0)
|
||||
, max_step_isr_frequency_sh(1)
|
||||
#if MULTISTEPPING_LIMIT >= 4
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(2)) >> 2)
|
||||
, max_step_isr_frequency_sh(2)
|
||||
#endif
|
||||
#if MULTISTEPPING_LIMIT >= 8
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(3)) >> 3)
|
||||
, max_step_isr_frequency_sh(3)
|
||||
#endif
|
||||
#if MULTISTEPPING_LIMIT >= 16
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(4)) >> 4)
|
||||
, max_step_isr_frequency_sh(4)
|
||||
#endif
|
||||
#if MULTISTEPPING_LIMIT >= 32
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(5)) >> 5)
|
||||
, max_step_isr_frequency_sh(5)
|
||||
#endif
|
||||
#if MULTISTEPPING_LIMIT >= 64
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(6)) >> 6)
|
||||
, max_step_isr_frequency_sh(6)
|
||||
#endif
|
||||
#if MULTISTEPPING_LIMIT >= 128
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(7)) >> 7)
|
||||
, max_step_isr_frequency_sh(7)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2702,9 +2701,9 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
// Decide if axis smoothing is possible
|
||||
if (stepper.adaptive_step_smoothing_enabled) {
|
||||
uint32_t max_rate = current_block->nominal_rate; // Get the step event rate
|
||||
while (max_rate < MIN_STEP_ISR_FREQUENCY) { // As long as more ISRs are possible...
|
||||
while (max_rate < min_step_isr_frequency) { // As long as more ISRs are possible...
|
||||
max_rate <<= 1; // Try to double the rate
|
||||
if (max_rate < MIN_STEP_ISR_FREQUENCY) // Don't exceed the estimated ISR limit
|
||||
if (max_rate < min_step_isr_frequency) // Don't exceed the estimated ISR limit
|
||||
++oversampling_factor; // Increase the oversampling (used for left-shift)
|
||||
}
|
||||
}
|
||||
|
@ -3737,8 +3736,8 @@ void Stepper::report_positions() {
|
|||
#define _READ_DIR(AXIS) AXIS ##_DIR_READ()
|
||||
#define _APPLY_DIR(AXIS, FWD) AXIS ##_APPLY_DIR(FWD, true)
|
||||
|
||||
#if MINIMUM_STEPPER_PULSE
|
||||
#define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND)
|
||||
#if MINIMUM_STEPPER_PULSE_NS
|
||||
#define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE_NS) * CYCLES_PER_MICROSECOND / 1000)
|
||||
#else
|
||||
#define STEP_PULSE_CYCLES 0
|
||||
#endif
|
||||
|
@ -3761,7 +3760,7 @@ void Stepper::report_positions() {
|
|||
#else
|
||||
#define _SAVE_START() NOOP
|
||||
#if EXTRA_CYCLES_BABYSTEP > 0
|
||||
#define _PULSE_WAIT() DELAY_NS(EXTRA_CYCLES_BABYSTEP * NANOSECONDS_PER_CYCLE)
|
||||
#define _PULSE_WAIT() DELAY_CYCLES(EXTRA_CYCLES_BABYSTEP)
|
||||
#elif ENABLED(DELTA)
|
||||
#define _PULSE_WAIT() DELAY_US(2);
|
||||
#elif STEP_PULSE_CYCLES > 0
|
||||
|
|
|
@ -146,12 +146,12 @@ constexpr ena_mask_t enable_overlap[] = {
|
|||
TERN0(INPUT_SHAPING_Y, _ISDMF[Y_AXIS] * _ISDASU[Y_AXIS]) +
|
||||
TERN0(INPUT_SHAPING_Z, _ISDMF[Z_AXIS] * _ISDASU[Z_AXIS]);
|
||||
#if defined(__AVR__) || !defined(ADAPTIVE_STEP_SMOOTHING)
|
||||
// MIN_STEP_ISR_FREQUENCY is known at compile time on AVRs and any reduction in SRAM is welcome
|
||||
// min_step_isr_frequency is known at compile time on AVRs and any reduction in SRAM is welcome
|
||||
template<unsigned int INDEX=DISTINCT_AXES> constexpr float max_isr_rate() {
|
||||
return _MAX(_ISDMF[ISALIM(INDEX - 1, _ISDMF)] * _ISDASU[ISALIM(INDEX - 1, _ISDASU)], max_isr_rate<INDEX - 1>());
|
||||
}
|
||||
template<> constexpr float max_isr_rate<0>() {
|
||||
return TERN0(ADAPTIVE_STEP_SMOOTHING, MIN_STEP_ISR_FREQUENCY);
|
||||
return TERN0(ADAPTIVE_STEP_SMOOTHING, min_step_isr_frequency);
|
||||
}
|
||||
constexpr float max_step_rate = _MIN(max_isr_rate(), max_shaped_rate);
|
||||
#else
|
||||
|
|
|
@ -40,184 +40,123 @@
|
|||
* take longer, pulses will be longer. For example the SKR Pro
|
||||
* (stm32f407zgt6) requires ~60 cyles.
|
||||
*/
|
||||
#define TIMER_READ_ADD_AND_STORE_CYCLES 34UL
|
||||
constexpr uint32_t timer_read_add_and_store_cycles = 34UL;
|
||||
|
||||
// The base ISR
|
||||
#define ISR_BASE_CYCLES 770UL
|
||||
constexpr uint32_t isr_base_cycles = 770UL;
|
||||
|
||||
// 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
|
||||
constexpr uint32_t isr_la_base_cycles = TERN0(LIN_ADVANCE, 64UL);
|
||||
|
||||
// S curve interpolation adds 40 cycles
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
#ifdef STM32G0B1xx
|
||||
#define ISR_S_CURVE_CYCLES 500UL
|
||||
#else
|
||||
#define ISR_S_CURVE_CYCLES 40UL
|
||||
#endif
|
||||
#else
|
||||
#define ISR_S_CURVE_CYCLES 0UL
|
||||
#endif
|
||||
constexpr uint32_t isr_s_curve_cycles = TERN0(S_CURVE_ACCELERATION, TERN(STM32G0B1xx, 500UL, 40UL));
|
||||
|
||||
// Input shaping base time
|
||||
#if HAS_ZV_SHAPING
|
||||
#define ISR_SHAPING_BASE_CYCLES 180UL
|
||||
#else
|
||||
#define ISR_SHAPING_BASE_CYCLES 0UL
|
||||
#endif
|
||||
constexpr uint32_t isr_shaping_base_cycles = TERN0(HAS_ZV_SHAPING, 180UL);
|
||||
|
||||
// Stepper Loop base cycles
|
||||
#define ISR_LOOP_BASE_CYCLES 4UL
|
||||
constexpr uint32_t isr_loop_base_cycles = 4UL;
|
||||
|
||||
// And each stepper (start + stop pulse) takes in worst case
|
||||
#define ISR_STEPPER_CYCLES 100UL
|
||||
constexpr uint32_t isr_stepper_cycles = 100UL;
|
||||
|
||||
#else
|
||||
|
||||
// Cycles to perform actions in START_TIMED_PULSE
|
||||
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
|
||||
constexpr uint32_t timer_read_add_and_store_cycles = 13UL;
|
||||
|
||||
// The base ISR
|
||||
#define ISR_BASE_CYCLES 882UL
|
||||
constexpr uint32_t isr_base_cycles = 882UL;
|
||||
|
||||
// Linear advance base time is 32 cycles
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#define ISR_LA_BASE_CYCLES 30UL
|
||||
#else
|
||||
#define ISR_LA_BASE_CYCLES 0UL
|
||||
#endif
|
||||
constexpr uint32_t isr_la_base_cycles = TERN0(LIN_ADVANCE, 30UL);
|
||||
|
||||
// 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
|
||||
constexpr uint32_t isr_s_curve_cycles = TERN0(S_CURVE_ACCELERATION, 160UL);
|
||||
|
||||
// Input shaping base time
|
||||
#if HAS_ZV_SHAPING
|
||||
#define ISR_SHAPING_BASE_CYCLES 290UL
|
||||
#else
|
||||
#define ISR_SHAPING_BASE_CYCLES 0UL
|
||||
#endif
|
||||
constexpr uint32_t isr_shaping_base_cycles = TERN0(HAS_ZV_SHAPING, 290UL);
|
||||
|
||||
// Stepper Loop base cycles
|
||||
#define ISR_LOOP_BASE_CYCLES 32UL
|
||||
constexpr uint32_t isr_loop_base_cycles = 32UL;
|
||||
|
||||
// And each stepper (start + stop pulse) takes in worst case
|
||||
#define ISR_STEPPER_CYCLES 60UL
|
||||
constexpr uint32_t isr_stepper_cycles = 60UL;
|
||||
|
||||
#endif
|
||||
|
||||
// If linear advance is disabled, 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
|
||||
constexpr uint32_t isr_mixing_stepper_cycles = (0UL
|
||||
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
|
||||
+ (MIXING_STEPPERS) * isr_stepper_cycles
|
||||
#endif
|
||||
);
|
||||
|
||||
// Add time for each stepper
|
||||
#if HAS_X_STEP
|
||||
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_Y_STEP
|
||||
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_Z_STEP
|
||||
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_I_STEP
|
||||
#define ISR_I_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_J_STEP
|
||||
#define ISR_J_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_K_STEP
|
||||
#define ISR_K_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
#define ISR_U_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
#define ISR_V_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
#define ISR_W_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES // E is always interpolated, even for mixing extruders
|
||||
#endif
|
||||
|
||||
// And the total minimum loop time, not including the base
|
||||
#define _PLUS_AXIS_CYCLES(A) + (ISR_##A##_STEPPER_CYCLES)
|
||||
#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_MAP(_PLUS_AXIS_CYCLES))
|
||||
|
||||
// Calculate the minimum MPU cycles needed per pulse to enforce, limited to the max stepper rate
|
||||
#define _MIN_STEPPER_PULSE_CYCLES(N) _MAX(uint32_t((F_CPU) / (MAXIMUM_STEPPER_RATE)), ((F_CPU) / 500000UL) * (N))
|
||||
#if MINIMUM_STEPPER_PULSE
|
||||
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(uint32_t(MINIMUM_STEPPER_PULSE))
|
||||
#elif HAS_DRIVER(LV8729)
|
||||
#define MIN_STEPPER_PULSE_CYCLES uint32_t((((F_CPU) - 1) / 2000000) + 1) // 0.5µs, aka 500ns
|
||||
#else
|
||||
#define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1UL)
|
||||
#endif
|
||||
// And the total minimum loop time, for all steppers, not including the base
|
||||
constexpr uint32_t min_isr_loop_cycles = isr_mixing_stepper_cycles + LOGICAL_AXES * isr_stepper_cycles;
|
||||
|
||||
// Calculate the minimum pulse times (high and low)
|
||||
#if MINIMUM_STEPPER_PULSE && MAXIMUM_STEPPER_RATE
|
||||
constexpr uint32_t _MIN_STEP_PERIOD_NS = 1000000000UL / MAXIMUM_STEPPER_RATE;
|
||||
constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
|
||||
constexpr uint32_t _MIN_PULSE_LOW_NS = _MAX((_MIN_STEP_PERIOD_NS - _MIN(_MIN_STEP_PERIOD_NS, _MIN_PULSE_HIGH_NS)), _MIN_PULSE_HIGH_NS);
|
||||
#elif MINIMUM_STEPPER_PULSE
|
||||
// Assume 50% duty cycle
|
||||
constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
|
||||
constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
|
||||
#elif MAXIMUM_STEPPER_RATE
|
||||
// Assume 50% duty cycle
|
||||
constexpr uint32_t _MIN_PULSE_HIGH_NS = 500000000UL / MAXIMUM_STEPPER_RATE;
|
||||
constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
|
||||
#if defined(MINIMUM_STEPPER_PULSE_NS) && defined(MAXIMUM_STEPPER_RATE)
|
||||
constexpr uint32_t _min_step_period_ns = 1000000000UL / (MAXIMUM_STEPPER_RATE),
|
||||
_min_pulse_high_ns = MINIMUM_STEPPER_PULSE_NS,
|
||||
_min_pulse_low_ns = _MAX(_min_step_period_ns - _MIN(_min_step_period_ns, _min_pulse_high_ns), _min_pulse_high_ns);
|
||||
#elif defined(MINIMUM_STEPPER_PULSE_NS)
|
||||
// Assume equal high and low pulse durations
|
||||
constexpr uint32_t _min_pulse_high_ns = MINIMUM_STEPPER_PULSE_NS,
|
||||
_min_pulse_low_ns = _min_pulse_high_ns;
|
||||
#elif defined(MAXIMUM_STEPPER_RATE)
|
||||
// Assume equal high and low pulse durations
|
||||
constexpr uint32_t _min_pulse_high_ns = 500000000UL / MAXIMUM_STEPPER_RATE,
|
||||
_min_pulse_low_ns = _min_pulse_high_ns;
|
||||
#else
|
||||
#error "Expected at least one of MINIMUM_STEPPER_PULSE or MAXIMUM_STEPPER_RATE to be defined"
|
||||
#error "At least one of MINIMUM_STEPPER_PULSE_NS or MAXIMUM_STEPPER_RATE must be defined"
|
||||
#endif
|
||||
|
||||
// Calculate the minimum MPU cycles needed per pulse to enforce
|
||||
constexpr uint32_t min_stepper_pulse_cycles = _min_pulse_high_ns * CYCLES_PER_MICROSECOND / 1000;
|
||||
|
||||
// The loop takes the base time plus the time for all the bresenham logic for 1 << R pulses plus the time
|
||||
// between pulses for ((1 << R) - 1) pulses. But the user could be enforcing a minimum time so the loop time is:
|
||||
#define ISR_LOOP_CYCLES(R) ((ISR_LOOP_BASE_CYCLES + MIN_ISR_LOOP_CYCLES + MIN_STEPPER_PULSE_CYCLES) * ((1UL << R) - 1) + _MAX(MIN_ISR_LOOP_CYCLES, MIN_STEPPER_PULSE_CYCLES))
|
||||
constexpr uint32_t isr_loop_cycles(const int R) { return ((isr_loop_base_cycles + min_isr_loop_cycles + min_stepper_pulse_cycles) * ((1UL << R) - 1) + _MAX(min_isr_loop_cycles, min_stepper_pulse_cycles)); }
|
||||
|
||||
// Model input shaping as an extra loop call
|
||||
#define ISR_SHAPING_LOOP_CYCLES(R) (TERN0(HAS_ZV_SHAPING, (ISR_LOOP_BASE_CYCLES + TERN0(INPUT_SHAPING_X, ISR_X_STEPPER_CYCLES) + TERN0(INPUT_SHAPING_Y, ISR_Y_STEPPER_CYCLES) + TERN0(INPUT_SHAPING_Z, ISR_Z_STEPPER_CYCLES)) << R))
|
||||
constexpr uint32_t isr_shaping_loop_cycles(const int R) {
|
||||
return (
|
||||
#if HAS_ZV_SHAPING
|
||||
isr_loop_base_cycles
|
||||
+ isr_stepper_cycles * COUNT_ENABLED(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z)
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
) << R;
|
||||
}
|
||||
|
||||
// If linear advance is enabled, then it is handled separately
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
// Estimate the minimum LA loop time
|
||||
#if ENABLED(MIXING_EXTRUDER) // ToDo: ???
|
||||
constexpr uint32_t min_isr_la_loop_cycles = (isr_stepper_cycles
|
||||
// ToDo: ???
|
||||
// HELP ME: What is what?
|
||||
// Directions are set up for MIXING_STEPPERS - like before.
|
||||
// Finding the right stepper may last up to MIXING_STEPPERS loops in get_next_stepper().
|
||||
// These loops are a bit faster than advancing a bresenham counter.
|
||||
// Always only one E stepper is stepped.
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||
#else
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
* TERN1(MIXING_EXTRUDER, (MIXING_STEPPERS))
|
||||
);
|
||||
|
||||
// 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
|
||||
|
||||
// The real LA loop time will be the larger minimum (pulse or loop)
|
||||
constexpr uint32_t isr_la_loop_cycles = TERN0(LIN_ADVANCE, _MAX(min_stepper_pulse_cycles, min_isr_la_loop_cycles));
|
||||
|
||||
// Estimate the total ISR execution time in cycles given a step-per-ISR shift multiplier
|
||||
#define ISR_EXECUTION_CYCLES(R) ((ISR_BASE_CYCLES + ISR_S_CURVE_CYCLES + ISR_SHAPING_BASE_CYCLES + ISR_LOOP_CYCLES(R) + ISR_SHAPING_LOOP_CYCLES(R) + ISR_LA_BASE_CYCLES + ISR_LA_LOOP_CYCLES) >> R)
|
||||
constexpr uint32_t isr_execution_cycles(const int R) { return (isr_base_cycles + isr_s_curve_cycles + isr_shaping_base_cycles + isr_loop_cycles(R) + isr_shaping_loop_cycles(R) + isr_la_base_cycles + isr_la_loop_cycles) >> R; }
|
||||
|
||||
// The maximum allowable stepping frequency when doing 1x stepping (in Hz)
|
||||
#define MAX_STEP_ISR_FREQUENCY_1X ((F_CPU) / ISR_EXECUTION_CYCLES(0))
|
||||
constexpr uint32_t max_step_isr_frequency_1x = (F_CPU) / isr_execution_cycles(0);
|
||||
constexpr uint32_t max_step_isr_frequency_sh(const int S) { return ((F_CPU) / isr_execution_cycles(S)) >> S; }
|
||||
|
||||
// The minimum step ISR rate used by ADAPTIVE_STEP_SMOOTHING to target 50% CPU usage
|
||||
// This does not account for the possibility of multi-stepping.
|
||||
#define MIN_STEP_ISR_FREQUENCY (MAX_STEP_ISR_FREQUENCY_1X >> 1)
|
||||
constexpr uint32_t min_step_isr_frequency = max_step_isr_frequency_1x >> 1;
|
||||
|
|
Loading…
Reference in a new issue