Skip to content

Commit e9a1be6

Browse files
tombrazierTracy Spiva
authored and
Tracy Spiva
committed
🐛 Avoid step rate overflow (MarlinFirmware#25541)
1 parent de1cfcf commit e9a1be6

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

Marlin/src/module/stepper.cpp

+13-9
Original file line numberDiff line numberDiff line change
@@ -2098,9 +2098,15 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
20982098

20992099
#else
21002100

2101-
// AVR is able to keep up at 30khz Stepping ISR rate.
21022101
constexpr uint32_t min_step_rate = (F_CPU) / 500000U; // i.e., 32 or 40
21032102
if (step_rate >= 0x0800) { // higher step rate
2103+
// AVR is able to keep up at around 65kHz Stepping ISR rate at most.
2104+
// So values for step_rate > 65535 might as well be truncated.
2105+
// Handle it as quickly as possible. i.e., assume highest byte is zero
2106+
// because non-zero would represent a step rate far beyond AVR capabilities.
2107+
if (uint8_t(step_rate >> 16))
2108+
return uint32_t(STEPPER_TIMER_RATE) / 0x10000;
2109+
21042110
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)]);
21052111
const uint16_t base = uint16_t(pgm_read_word(table_address));
21062112
const uint8_t gain = uint8_t(pgm_read_byte(table_address + 2));
@@ -2112,10 +2118,8 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
21122118
return uint16_t(pgm_read_word(table_address))
21132119
- ((uint16_t(pgm_read_word(table_address + 2)) * uint8_t(step_rate & 0x0007)) >> 3);
21142120
}
2115-
else {
2116-
step_rate = 0;
2117-
return uint16_t(pgm_read_word(uintptr_t(speed_lookuptable_slow)));
2118-
}
2121+
2122+
return uint16_t(pgm_read_word(uintptr_t(speed_lookuptable_slow)));
21192123

21202124
#endif // !CPU_32_BIT
21212125
}
@@ -2250,7 +2254,7 @@ hal_timer_t Stepper::block_phase_isr() {
22502254
#if ENABLED(LIN_ADVANCE)
22512255
if (la_active) {
22522256
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
2253-
la_interval = calc_timer_interval(acc_step_rate + la_step_rate) << current_block->la_scaling;
2257+
la_interval = calc_timer_interval((acc_step_rate + la_step_rate) >> current_block->la_scaling);
22542258
}
22552259
#endif
22562260

@@ -2322,7 +2326,7 @@ hal_timer_t Stepper::block_phase_isr() {
23222326
const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
23232327
if (la_step_rate != step_rate) {
23242328
bool reverse_e = la_step_rate > step_rate;
2325-
la_interval = calc_timer_interval(reverse_e ? la_step_rate - step_rate : step_rate - la_step_rate) << current_block->la_scaling;
2329+
la_interval = calc_timer_interval((reverse_e ? la_step_rate - step_rate : step_rate - la_step_rate) >> current_block->la_scaling);
23262330

23272331
if (reverse_e != motor_direction(E_AXIS)) {
23282332
TBI(last_direction_bits, E_AXIS);
@@ -2380,7 +2384,7 @@ hal_timer_t Stepper::block_phase_isr() {
23802384

23812385
#if ENABLED(LIN_ADVANCE)
23822386
if (la_active)
2383-
la_interval = calc_timer_interval(current_block->nominal_rate) << current_block->la_scaling;
2387+
la_interval = calc_timer_interval(current_block->nominal_rate >> current_block->la_scaling);
23842388
#endif
23852389
}
23862390

@@ -2702,7 +2706,7 @@ hal_timer_t Stepper::block_phase_isr() {
27022706
#if ENABLED(LIN_ADVANCE)
27032707
if (la_active) {
27042708
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
2705-
la_interval = calc_timer_interval(current_block->initial_rate + la_step_rate) << current_block->la_scaling;
2709+
la_interval = calc_timer_interval((current_block->initial_rate + la_step_rate) >> current_block->la_scaling);
27062710
}
27072711
#endif
27082712
}

0 commit comments

Comments
 (0)