Skip to content

Commit

Permalink
move non-inline to cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Jul 25, 2022
1 parent 3bb7a64 commit 5e472b6
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 69 deletions.
71 changes: 67 additions & 4 deletions Marlin/src/module/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,69 @@ void Stepper::pulse_phase_isr() {
} while (--events_to_do);
}

// Calculate timer interval, with all limits applied.
uint32_t Stepper::calc_timer_interval(uint32_t step_rate) {
#ifdef CPU_32_BIT
// In case of high-performance processor, it is able to calculate in real-time
return uint32_t(STEPPER_TIMER_RATE) / step_rate;
#else
// AVR is able to keep up at 30khz Stepping ISR rate.
constexpr uint32_t min_step_rate = (F_CPU) / 500000U;
if (step_rate <= min_step_rate) {
step_rate = 0;
uintptr_t table_address = (uintptr_t)&speed_lookuptable_slow[0][0];
return uint16_t(pgm_read_word(table_address));
}
else {
step_rate -= min_step_rate; // Correct for minimal speed
if (step_rate >= (8 * 256)) { // higher step rate
const uint8_t rate_mod_256 = (step_rate & 0x00FF);
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)][0]),
gain = uint16_t(pgm_read_word(table_address + 2));
return uint16_t(pgm_read_word(table_address)) - MultiU16X8toH16(rate_mod_256, gain);
}
else { // lower step rates
uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);
table_address += (step_rate >> 1) & 0xFFFC;
return uint16_t(pgm_read_word(table_address))
- ((uint16_t(pgm_read_word(table_address + 2)) * uint8_t(step_rate & 0x0007)) >> 3);
}
}
#endif
}

// Get the timer interval and the number of loops to perform per tick
uint32_t Stepper::calc_timer_interval(uint32_t step_rate, uint8_t &loops) {
uint8_t multistep = 1;
#if DISABLED(DISABLE_MULTI_STEPPING)

// The stepping frequency limits for each multistepping rate
static const uint32_t limit[] PROGMEM = {
( MAX_STEP_ISR_FREQUENCY_1X ),
( MAX_STEP_ISR_FREQUENCY_2X >> 1),
( MAX_STEP_ISR_FREQUENCY_4X >> 2),
( MAX_STEP_ISR_FREQUENCY_8X >> 3),
( MAX_STEP_ISR_FREQUENCY_16X >> 4),
( MAX_STEP_ISR_FREQUENCY_32X >> 5),
( MAX_STEP_ISR_FREQUENCY_64X >> 6),
(MAX_STEP_ISR_FREQUENCY_128X >> 7)
};

// Select the proper multistepping
uint8_t idx = 0;
while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
step_rate >>= 1;
multistep <<= 1;
++idx;
};
#else
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
#endif
loops = multistep;

return calc_timer_interval(step_rate);
}

// This is the last half of the stepper interrupt: This one processes and
// properly schedules blocks from the planner. This is executed after creating
// the step pulses, so it is not time critical, as pulses are already done.
Expand Down Expand Up @@ -1953,7 +2016,7 @@ uint32_t Stepper::block_phase_isr() {
// acc_step_rate is in steps/second

// step_rate to timer interval and steps per stepper isr
interval = calc_timer_interval(acc_step_rate << oversampling_factor, &steps_per_isr);
interval = calc_timer_interval(acc_step_rate << oversampling_factor, steps_per_isr);
acceleration_time += interval;

#if ENABLED(LIN_ADVANCE)
Expand Down Expand Up @@ -2023,7 +2086,7 @@ uint32_t Stepper::block_phase_isr() {
#endif

// step_rate to timer interval and steps per stepper isr
interval = calc_timer_interval(step_rate << oversampling_factor, &steps_per_isr);
interval = calc_timer_interval(step_rate << oversampling_factor, steps_per_isr);
deceleration_time += interval;

#if ENABLED(LIN_ADVANCE)
Expand Down Expand Up @@ -2082,7 +2145,7 @@ uint32_t Stepper::block_phase_isr() {
// Calculate the ticks_nominal for this nominal speed, if not done yet
if (ticks_nominal < 0) {
// step_rate to timer interval and loops for the nominal speed
ticks_nominal = calc_timer_interval(current_block->nominal_rate << oversampling_factor, &steps_per_isr);
ticks_nominal = calc_timer_interval(current_block->nominal_rate << oversampling_factor, steps_per_isr);
}

// The timer interval is just the nominal value for the nominal speed
Expand Down Expand Up @@ -2384,7 +2447,7 @@ uint32_t Stepper::block_phase_isr() {
#endif

// Calculate the initial timer interval
interval = calc_timer_interval(current_block->initial_rate << oversampling_factor, &steps_per_isr);
interval = calc_timer_interval(current_block->initial_rate << oversampling_factor, steps_per_isr);
acceleration_time += interval;

#if ENABLED(LIN_ADVANCE)
Expand Down
68 changes: 3 additions & 65 deletions Marlin/src/module/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -631,71 +631,9 @@ friend class GcodeSuite;
// Set the current position in steps
static void _set_position(const abce_long_t &spos);

static uint32_t calc_timer_interval(uint32_t step_rate) {
uint32_t interval;

#ifdef CPU_32_BIT
// In case of high-performance processor, it is able to calculate in real-time
interval = uint32_t(STEPPER_TIMER_RATE) / step_rate;
#else
constexpr uint32_t min_step_rate = (F_CPU) / 500000U;
if (step_rate <= min_step_rate) {
step_rate = 0;
uintptr_t table_address = (uintptr_t)&speed_lookuptable_slow[0][0];
interval = uint16_t(pgm_read_word(table_address));
}
else {
step_rate -= min_step_rate; // Correct for minimal speed
if (step_rate >= (8 * 256)) { // higher step rate
const uint8_t rate_mod_256 = (step_rate & 0x00FF);
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)][0]),
gain = uint16_t(pgm_read_word(table_address + 2));
interval = uint16_t(pgm_read_word(table_address)) - MultiU16X8toH16(rate_mod_256, gain);
}
else { // lower step rates
uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);
table_address += ((step_rate) >> 1) & 0xFFFC;
interval = uint16_t(pgm_read_word(table_address))
- ((uint16_t(pgm_read_word(table_address + 2)) * uint8_t(step_rate & 0x0007)) >> 3);
}
// (there is no need to limit the interval here. All limits have been
// applied above, and AVR is able to keep up at 30khz Stepping ISR rate)
}
#endif

return interval;
}

static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t * const loops) {
uint8_t multistep = 1;
#if DISABLED(DISABLE_MULTI_STEPPING)

// The stepping frequency limits for each multistepping rate
static const uint32_t limit[] PROGMEM = {
( MAX_STEP_ISR_FREQUENCY_1X ),
( MAX_STEP_ISR_FREQUENCY_2X >> 1),
( MAX_STEP_ISR_FREQUENCY_4X >> 2),
( MAX_STEP_ISR_FREQUENCY_8X >> 3),
( MAX_STEP_ISR_FREQUENCY_16X >> 4),
( MAX_STEP_ISR_FREQUENCY_32X >> 5),
( MAX_STEP_ISR_FREQUENCY_64X >> 6),
(MAX_STEP_ISR_FREQUENCY_128X >> 7)
};

// Select the proper multistepping
uint8_t idx = 0;
while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
step_rate >>= 1;
multistep <<= 1;
++idx;
};
#else
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
#endif
*loops = multistep;

return calc_timer_interval(step_rate);
}
// Calculate timing interval for the given step rate
static uint32_t calc_timer_interval(uint32_t step_rate);
static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t &loops);

#if ENABLED(S_CURVE_ACCELERATION)
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);
Expand Down

0 comments on commit 5e472b6

Please sign in to comment.