diff --git a/dda.h b/dda.h index ce7b3c5..8f04aab 100644 --- a/dda.h +++ b/dda.h @@ -11,6 +11,12 @@ #endif #endif +#ifndef SIMULATOR + #include +#else + #define PROGMEM +#endif + /* types */ diff --git a/dda_maths.c b/dda_maths.c index 908ce59..8294dda 100644 --- a/dda_maths.c +++ b/dda_maths.c @@ -8,6 +8,26 @@ #include #include +/*! + 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. diff --git a/dda_maths.h b/dda_maths.h index 0f25bf7..19dda08 100644 --- a/dda_maths.h +++ b/dda_maths.h @@ -4,6 +4,7 @@ #include #include "config_wrapper.h" +#include "dda.h" // return rounded result of multiplicand * multiplier / divisor // 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); } -/* - 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 , -// 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. + +#define UM_PER_METER (1000000UL) + +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)); inline int32_t um_to_steps_x(int32_t distance) { - return muldivQR(distance, STEPS_PER_M_X / 1000000UL, - STEPS_PER_M_X % 1000000UL, 1000000UL); + return um_to_steps(distance, X); } static int32_t um_to_steps_y(int32_t) __attribute__ ((always_inline)); inline int32_t um_to_steps_y(int32_t distance) { - return muldivQR(distance, STEPS_PER_M_Y / 1000000UL, - STEPS_PER_M_Y % 1000000UL, 1000000UL); + return um_to_steps(distance, Y); } static int32_t um_to_steps_z(int32_t) __attribute__ ((always_inline)); inline int32_t um_to_steps_z(int32_t distance) { - return muldivQR(distance, STEPS_PER_M_Z / 1000000UL, - STEPS_PER_M_Z % 1000000UL, 1000000UL); + return um_to_steps(distance, Z); } static int32_t um_to_steps_e(int32_t) __attribute__ ((always_inline)); inline int32_t um_to_steps_e(int32_t distance) { - return muldivQR(distance, STEPS_PER_M_E / 1000000UL, - STEPS_PER_M_E % 1000000UL, 1000000UL); + return um_to_steps(distance, E); } // approximate 2D distance