DDA: convert um_to_steps_* to generic implementation.
A generic implementation here will allow callers to pass the target axis in as a parameter so the callers can also be made more generic. Traumflug notes: Split out application of the new implementation in dda.c into its own commit. This actually costs 128 bytes, but as we can access axes from within a loop now, I expect to get more savings elsewhere. Interestingly, binary size is raised by another 18 bytes if um_to_steps(int32_t, enum axis_e) is changed to um_to_steps(enum axis_e, int32_t) even on the 8-bit ATmega. While putting the axis number to the front might be a bit more logical (think of additional parameters, the axis number position would move), NXP application note AN10963 states on page 10ff, 16-bit data should be 16-bit aligned and 32-bit data should be 32-bit aligned for best performance. Well, so let's do it this way.
This commit is contained in:
parent
84cbf2a42a
commit
62bdbd86d6
6
dda.h
6
dda.h
|
|
@ -11,6 +11,12 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#else
|
||||||
|
#define PROGMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
types
|
types
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
20
dda_maths.c
20
dda_maths.c
|
|
@ -8,6 +8,26 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Pre-calculated constant values for axis um <=> steps conversions.
|
||||||
|
|
||||||
|
These should be calculated at run-time once in dda_init() if the
|
||||||
|
STEPS_PER_M_* constants are ever replaced with run-time options.
|
||||||
|
*/
|
||||||
|
const axes_uint32_t PROGMEM axis_qn = {
|
||||||
|
(uint32_t)STEPS_PER_M_X / UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_Y / UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_Z / UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_E / UM_PER_METER
|
||||||
|
};
|
||||||
|
|
||||||
|
const axes_uint32_t PROGMEM axis_qr = {
|
||||||
|
(uint32_t)STEPS_PER_M_X % UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_Y % UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_Z % UM_PER_METER,
|
||||||
|
(uint32_t)STEPS_PER_M_E % UM_PER_METER
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Integer multiply-divide algorithm. Returns the same as muldiv(multiplicand, multiplier, divisor), but also allowing to use precalculated quotients and remainders.
|
Integer multiply-divide algorithm. Returns the same as muldiv(multiplicand, multiplier, divisor), but also allowing to use precalculated quotients and remainders.
|
||||||
|
|
||||||
|
|
|
||||||
32
dda_maths.h
32
dda_maths.h
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "config_wrapper.h"
|
#include "config_wrapper.h"
|
||||||
|
#include "dda.h"
|
||||||
|
|
||||||
// return rounded result of multiplicand * multiplier / divisor
|
// return rounded result of multiplicand * multiplier / divisor
|
||||||
// this version is with quotient and remainder precalculated elsewhere
|
// this version is with quotient and remainder precalculated elsewhere
|
||||||
|
|
@ -18,36 +19,39 @@ inline int32_t muldiv(int32_t multiplicand, uint32_t multiplier,
|
||||||
multiplier % divisor, divisor);
|
multiplier % divisor, divisor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*!
|
||||||
micrometer distance <=> motor step distance conversions
|
Micrometer distance <=> motor step distance conversions.
|
||||||
*/
|
*/
|
||||||
// Like shown in the patch attached to this post:
|
|
||||||
// http://forums.reprap.org/read.php?147,89710,130225#msg-130225 ,
|
#define UM_PER_METER (1000000UL)
|
||||||
// it might be worth pre-calculating muldivQR()'s qn and rn in dda_init()
|
|
||||||
// as soon as STEPS_PER_M_{XYZE} is no longer a compile-time variable.
|
extern const axes_uint32_t PROGMEM axis_qn;
|
||||||
|
extern const axes_uint32_t PROGMEM axis_qr;
|
||||||
|
|
||||||
|
static int32_t um_to_steps(int32_t, enum axis_e) __attribute__ ((always_inline));
|
||||||
|
inline int32_t um_to_steps(int32_t distance, enum axis_e a) {
|
||||||
|
return muldivQR(distance, pgm_read_dword(&axis_qn[a]),
|
||||||
|
pgm_read_dword(&axis_qr[a]), UM_PER_METER);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t um_to_steps_x(int32_t) __attribute__ ((always_inline));
|
static int32_t um_to_steps_x(int32_t) __attribute__ ((always_inline));
|
||||||
inline int32_t um_to_steps_x(int32_t distance) {
|
inline int32_t um_to_steps_x(int32_t distance) {
|
||||||
return muldivQR(distance, STEPS_PER_M_X / 1000000UL,
|
return um_to_steps(distance, X);
|
||||||
STEPS_PER_M_X % 1000000UL, 1000000UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t um_to_steps_y(int32_t) __attribute__ ((always_inline));
|
static int32_t um_to_steps_y(int32_t) __attribute__ ((always_inline));
|
||||||
inline int32_t um_to_steps_y(int32_t distance) {
|
inline int32_t um_to_steps_y(int32_t distance) {
|
||||||
return muldivQR(distance, STEPS_PER_M_Y / 1000000UL,
|
return um_to_steps(distance, Y);
|
||||||
STEPS_PER_M_Y % 1000000UL, 1000000UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t um_to_steps_z(int32_t) __attribute__ ((always_inline));
|
static int32_t um_to_steps_z(int32_t) __attribute__ ((always_inline));
|
||||||
inline int32_t um_to_steps_z(int32_t distance) {
|
inline int32_t um_to_steps_z(int32_t distance) {
|
||||||
return muldivQR(distance, STEPS_PER_M_Z / 1000000UL,
|
return um_to_steps(distance, Z);
|
||||||
STEPS_PER_M_Z % 1000000UL, 1000000UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t um_to_steps_e(int32_t) __attribute__ ((always_inline));
|
static int32_t um_to_steps_e(int32_t) __attribute__ ((always_inline));
|
||||||
inline int32_t um_to_steps_e(int32_t distance) {
|
inline int32_t um_to_steps_e(int32_t distance) {
|
||||||
return muldivQR(distance, STEPS_PER_M_E / 1000000UL,
|
return um_to_steps(distance, E);
|
||||||
STEPS_PER_M_E % 1000000UL, 1000000UL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// approximate 2D distance
|
// approximate 2D distance
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue