Skip to content

Commit e65e38a

Browse files
tombrazierthinkyhead
authored andcommitted
🐛 Fix AVR maths used by Stepper (#25338)
1 parent 9d56b7f commit e65e38a

File tree

3 files changed

+24
-22
lines changed

3 files changed

+24
-22
lines changed

Marlin/src/HAL/AVR/math.h

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@
2727

2828
// intRes = longIn1 * longIn2 >> 24
2929
// uses:
30-
// A[tmp] to store 0
31-
// B[tmp] to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
32-
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
33-
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
34-
// B A are bits 24-39 and are the returned value
35-
// C B A is longIn1
36-
// D C B A is longIn2
30+
// r1, r0 for the result of mul.
31+
// [tmp1] to store 0.
32+
// [tmp2] to store bits 16-23 of the 56 bit result. The top bit of [tmp2] is used for rounding.
33+
// Note that the lower two bytes and the upper two bytes of the 56 bit result are not calculated.
34+
// This can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
35+
// [intRes] (A B) is bits 24-39 and is the returned value.
36+
// [longIn1] (C B A) is a 24 bit parameter.
37+
// [longIn2] (D C B A) is a 32 bit parameter.
3738
//
3839
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
3940
uint8_t tmp1;
@@ -66,11 +67,9 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
6667
A("add %[tmp2], r1")
6768
A("adc %A[intRes], %[tmp1]")
6869
A("adc %B[intRes], %[tmp1]")
69-
A("lsr %[tmp2]")
70-
A("adc %A[intRes], %[tmp1]")
71-
A("adc %B[intRes], %[tmp1]")
7270
A("mul %D[longIn2], %A[longIn1]")
73-
A("add %A[intRes], r0")
71+
A("lsl %[tmp2]")
72+
A("adc %A[intRes], r0")
7473
A("adc %B[intRes], r1")
7574
A("mul %D[longIn2], %B[longIn1]")
7675
A("add %B[intRes], r0")
@@ -85,22 +84,25 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
8584
return intRes;
8685
}
8786

88-
// intRes = intIn1 * intIn2 >> 16
87+
// intRes = intIn1 * intIn2 >> 8
8988
// uses:
90-
// r26 to store 0
91-
// r27 to store the byte 1 of the 24 bit result
92-
FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
89+
// r1, r0 for the result of mul. After the second mul, r0 holds bits 0-7 of the 24 bit result and
90+
// the top bit of r0 is used for rounding.
91+
// [tmp] to store 0.
92+
// [intRes] (A B) is bits 8-15 and is the returned value.
93+
// [charIn1] is an 8 bit parameter.
94+
// [intIn2] (B A) is a 16 bit parameter.
95+
//
96+
FORCE_INLINE static uint16_t MultiU8X16toH16(uint8_t charIn1, uint16_t intIn2) {
9397
uint8_t tmp;
9498
uint16_t intRes;
9599
__asm__ __volatile__ (
96100
A("clr %[tmp]")
97101
A("mul %[charIn1], %B[intIn2]")
98102
A("movw %A[intRes], r0")
99103
A("mul %[charIn1], %A[intIn2]")
100-
A("add %A[intRes], r1")
101-
A("adc %B[intRes], %[tmp]")
102-
A("lsr r0")
103-
A("adc %A[intRes], %[tmp]")
104+
A("lsl r0")
105+
A("adc %A[intRes], r1")
104106
A("adc %B[intRes], %[tmp]")
105107
A("clr r1")
106108
: [intRes] "=&r" (intRes),

Marlin/src/module/stepper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,7 @@ uint32_t Stepper::calc_timer_interval(uint32_t step_rate) {
20622062
const uint8_t rate_mod_256 = (step_rate & 0x00FF);
20632063
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)][0]),
20642064
gain = uint16_t(pgm_read_word(table_address + 2));
2065-
return uint16_t(pgm_read_word(table_address)) - MultiU16X8toH16(rate_mod_256, gain);
2065+
return uint16_t(pgm_read_word(table_address)) - MultiU8X16toH16(rate_mod_256, gain);
20662066
}
20672067
else { // lower step rates
20682068
uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);

Marlin/src/module/stepper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@
114114
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
115115

116116
// The base ISR
117-
#define ISR_BASE_CYCLES 1000UL
117+
#define ISR_BASE_CYCLES 996UL
118118

119119
// Linear advance base time is 32 cycles
120120
#if ENABLED(LIN_ADVANCE)
121-
#define ISR_LA_BASE_CYCLES 32UL
121+
#define ISR_LA_BASE_CYCLES 30UL
122122
#else
123123
#define ISR_LA_BASE_CYCLES 0UL
124124
#endif

0 commit comments

Comments
 (0)