🐛 Fix AVR maths used by Stepper (#25338)
This commit is contained in:
parent
9d56b7f073
commit
e65e38afaf
@ -27,13 +27,14 @@
|
|||||||
|
|
||||||
// intRes = longIn1 * longIn2 >> 24
|
// intRes = longIn1 * longIn2 >> 24
|
||||||
// uses:
|
// uses:
|
||||||
// A[tmp] to store 0
|
// r1, r0 for the result of mul.
|
||||||
// B[tmp] to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
|
// [tmp1] to store 0.
|
||||||
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
|
// [tmp2] to store bits 16-23 of the 56 bit result. The top bit of [tmp2] is used for rounding.
|
||||||
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
|
// Note that the lower two bytes and the upper two bytes of the 56 bit result are not calculated.
|
||||||
// B A are bits 24-39 and are the returned value
|
// This can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
|
||||||
// C B A is longIn1
|
// [intRes] (A B) is bits 24-39 and is the returned value.
|
||||||
// D C B A is longIn2
|
// [longIn1] (C B A) is a 24 bit parameter.
|
||||||
|
// [longIn2] (D C B A) is a 32 bit parameter.
|
||||||
//
|
//
|
||||||
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
|
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
|
||||||
uint8_t tmp1;
|
uint8_t tmp1;
|
||||||
@ -66,11 +67,9 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
|
|||||||
A("add %[tmp2], r1")
|
A("add %[tmp2], r1")
|
||||||
A("adc %A[intRes], %[tmp1]")
|
A("adc %A[intRes], %[tmp1]")
|
||||||
A("adc %B[intRes], %[tmp1]")
|
A("adc %B[intRes], %[tmp1]")
|
||||||
A("lsr %[tmp2]")
|
|
||||||
A("adc %A[intRes], %[tmp1]")
|
|
||||||
A("adc %B[intRes], %[tmp1]")
|
|
||||||
A("mul %D[longIn2], %A[longIn1]")
|
A("mul %D[longIn2], %A[longIn1]")
|
||||||
A("add %A[intRes], r0")
|
A("lsl %[tmp2]")
|
||||||
|
A("adc %A[intRes], r0")
|
||||||
A("adc %B[intRes], r1")
|
A("adc %B[intRes], r1")
|
||||||
A("mul %D[longIn2], %B[longIn1]")
|
A("mul %D[longIn2], %B[longIn1]")
|
||||||
A("add %B[intRes], r0")
|
A("add %B[intRes], r0")
|
||||||
@ -85,11 +84,16 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
|
|||||||
return intRes;
|
return intRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// intRes = intIn1 * intIn2 >> 16
|
// intRes = intIn1 * intIn2 >> 8
|
||||||
// uses:
|
// uses:
|
||||||
// r26 to store 0
|
// r1, r0 for the result of mul. After the second mul, r0 holds bits 0-7 of the 24 bit result and
|
||||||
// r27 to store the byte 1 of the 24 bit result
|
// the top bit of r0 is used for rounding.
|
||||||
FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
|
// [tmp] to store 0.
|
||||||
|
// [intRes] (A B) is bits 8-15 and is the returned value.
|
||||||
|
// [charIn1] is an 8 bit parameter.
|
||||||
|
// [intIn2] (B A) is a 16 bit parameter.
|
||||||
|
//
|
||||||
|
FORCE_INLINE static uint16_t MultiU8X16toH16(uint8_t charIn1, uint16_t intIn2) {
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
uint16_t intRes;
|
uint16_t intRes;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
@ -97,10 +101,8 @@ FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
|
|||||||
A("mul %[charIn1], %B[intIn2]")
|
A("mul %[charIn1], %B[intIn2]")
|
||||||
A("movw %A[intRes], r0")
|
A("movw %A[intRes], r0")
|
||||||
A("mul %[charIn1], %A[intIn2]")
|
A("mul %[charIn1], %A[intIn2]")
|
||||||
A("add %A[intRes], r1")
|
A("lsl r0")
|
||||||
A("adc %B[intRes], %[tmp]")
|
A("adc %A[intRes], r1")
|
||||||
A("lsr r0")
|
|
||||||
A("adc %A[intRes], %[tmp]")
|
|
||||||
A("adc %B[intRes], %[tmp]")
|
A("adc %B[intRes], %[tmp]")
|
||||||
A("clr r1")
|
A("clr r1")
|
||||||
: [intRes] "=&r" (intRes),
|
: [intRes] "=&r" (intRes),
|
||||||
|
@ -2062,7 +2062,7 @@ uint32_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
|||||||
const uint8_t rate_mod_256 = (step_rate & 0x00FF);
|
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]),
|
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));
|
gain = uint16_t(pgm_read_word(table_address + 2));
|
||||||
return uint16_t(pgm_read_word(table_address)) - MultiU16X8toH16(rate_mod_256, gain);
|
return uint16_t(pgm_read_word(table_address)) - MultiU8X16toH16(rate_mod_256, gain);
|
||||||
}
|
}
|
||||||
else { // lower step rates
|
else { // lower step rates
|
||||||
uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);
|
uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);
|
||||||
|
@ -114,11 +114,11 @@
|
|||||||
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
|
#define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
|
||||||
|
|
||||||
// The base ISR
|
// The base ISR
|
||||||
#define ISR_BASE_CYCLES 1000UL
|
#define ISR_BASE_CYCLES 996UL
|
||||||
|
|
||||||
// Linear advance base time is 32 cycles
|
// Linear advance base time is 32 cycles
|
||||||
#if ENABLED(LIN_ADVANCE)
|
#if ENABLED(LIN_ADVANCE)
|
||||||
#define ISR_LA_BASE_CYCLES 32UL
|
#define ISR_LA_BASE_CYCLES 30UL
|
||||||
#else
|
#else
|
||||||
#define ISR_LA_BASE_CYCLES 0UL
|
#define ISR_LA_BASE_CYCLES 0UL
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user