From 2b1f3371c763cfbf856ec5e17c1fafafec185af6 Mon Sep 17 00:00:00 2001 From: wurstnase Date: Tue, 5 Jul 2016 08:16:21 +0200 Subject: [PATCH] DDA: get rid of fast_spm. We need the fastest axis instead of its steps. Eleminates also an overflow when ACCELERATION > 596. We save 118 bytes program and 2 bytes data. Reviewer Traumflug's note: I see 100 bytes program and 32 bytes RAM saving on ATmegas here. 16 and 32 on the LPC 1114. Either way: great stuff! --- dda.c | 12 +----------- dda.h | 1 - dda_maths.c | 23 ++++++++++++++++------- dda_maths.h | 2 +- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/dda.c b/dda.c index 11fe3a7..ccb2ce2 100644 --- a/dda.c +++ b/dda.c @@ -49,15 +49,6 @@ TARGET BSS current_position; /// \brief numbers for tracking the current state of movement MOVE_STATE BSS move_state; -/// \var steps_per_m_P -/// \brief motor steps required to advance one meter on each axis -static const axes_uint32_t PROGMEM steps_per_m_P = { - STEPS_PER_M_X, - STEPS_PER_M_Y, - STEPS_PER_M_Z, - STEPS_PER_M_E -}; - /// \var maximum_feedrate_P /// \brief maximum allowed feedrate on each axis static const axes_uint32_t PROGMEM maximum_feedrate_P = { @@ -279,7 +270,6 @@ void dda_create(DDA *dda, const TARGET *target) { dda->fast_axis = i; dda->total_steps = dda->delta[i]; dda->fast_um = delta_um[i]; - dda->fast_spm = pgm_read_dword(&steps_per_m_P[i]); } } @@ -428,7 +418,7 @@ void dda_create(DDA *dda, const TARGET *target) { // Acceleration ramps are based on the fast axis, not the combined speed. dda->rampup_steps = acc_ramp_len(muldiv(dda->fast_um, dda->endpoint.F, distance), - dda->fast_spm); + dda->fast_axis); if (dda->rampup_steps > dda->total_steps / 2) dda->rampup_steps = dda->total_steps / 2; diff --git a/dda.h b/dda.h index 47e2907..18f2fe8 100644 --- a/dda.h +++ b/dda.h @@ -115,7 +115,6 @@ typedef struct { // uint8_t fast_axis; (see below) uint32_t total_steps; ///< steps of the "fast" axis uint32_t fast_um; ///< movement length of this fast axis - uint32_t fast_spm; ///< steps per meter of the fast axis uint32_t c; ///< time until next step, 24.8 fixed point diff --git a/dda_maths.c b/dda_maths.c index dfa750b..cb5c05e 100644 --- a/dda_maths.c +++ b/dda_maths.c @@ -70,7 +70,7 @@ const int32_t muldivQR(int32_t multiplicand, uint32_t qn, uint32_t rn, qn <<= 1; rn <<= 1; if (rn >= divisor) { - qn++; + qn++; rn -= divisor; } } @@ -177,7 +177,7 @@ uint16_t int_sqrt(uint32_t a) { if (y2 > c) z ^= j; } - + x = z << 4; for(i = 0x8; i; i >>= 1) { uint16_t y2; @@ -187,7 +187,7 @@ uint16_t int_sqrt(uint32_t a) { if (y2 > b) x ^= i; } - + x <<= 8; for(i = 0x80; i; i >>= 1) { uint32_t y2; @@ -256,9 +256,19 @@ const uint8_t msbloc (uint32_t v) { return 0; } +/*! + Pre-calculated constant values for acceleration ramp calculations. +*/ +static const axes_uint32_t PROGMEM acc_ramp_div_P = { + (uint32_t)((7200000.0f * ACCELERATION) / STEPS_PER_M_X), + (uint32_t)((7200000.0f * ACCELERATION) / STEPS_PER_M_Y), + (uint32_t)((7200000.0f * ACCELERATION) / STEPS_PER_M_Z), + (uint32_t)((7200000.0f * ACCELERATION) / STEPS_PER_M_E) +}; + /*! Acceleration ramp length in steps. * \param feedrate Target feedrate of the accelerateion. - * \param steps_per_m Steps/m of the axis. + * \param fast_axis Number of the fastest axis. * \return Accelerating steps neccessary to achieve target feedrate. * * s = 1/2 * a * t^2, v = a * t ==> s = v^2 / (2 * a) @@ -268,8 +278,7 @@ const uint8_t msbloc (uint32_t v) { * 2000 to 4096000 steps/m (and higher). The numbers are a few percent * too high at very low acceleration. Test code see commit message. */ -uint32_t acc_ramp_len(uint32_t feedrate, uint32_t steps_per_m) { - return (feedrate * feedrate) / - (((uint32_t)7200000UL * ACCELERATION) / steps_per_m); +uint32_t acc_ramp_len(uint32_t feedrate, uint8_t fast_axis) { + return (feedrate * feedrate) / pgm_read_dword(&acc_ramp_div_P[fast_axis]); } diff --git a/dda_maths.h b/dda_maths.h index b23644f..34a2eda 100644 --- a/dda_maths.h +++ b/dda_maths.h @@ -51,7 +51,7 @@ uint16_t int_inv_sqrt(uint16_t a); const uint8_t msbloc (uint32_t v); // Calculates acceleration ramp length in steps. -uint32_t acc_ramp_len(uint32_t feedrate, uint32_t steps_per_m); +uint32_t acc_ramp_len(uint32_t feedrate, uint8_t fast_axis); // For X axis only, should become obsolete: #define ACCELERATE_RAMP_LEN(speed) (((speed)*(speed)) / (uint32_t)((7200000.0f * ACCELERATION) / (float)STEPS_PER_M_X))