From b552447789616ff8c06e4e45b70428ff8b9ad143 Mon Sep 17 00:00:00 2001 From: Phil Hord Date: Mon, 25 Nov 2013 18:06:43 -0500 Subject: [PATCH] DDA: Move axis calculations into loops, part 8. Clean up code to reduce duplication by consolidating code into loops for per-axis actions. Part 8 is, move remaining update_current_position() into a loop. This makes the binary 134 bytes smaller. As it's not critical, no performance test. SIZES ATmega... '168 '328(P) '644(P) '1280 FLASH : 20134 bytes 141% 66% 32% 16% RAM : 2302 bytes 225% 113% 57% 29% EEPROM: 32 bytes 4% 2% 2% 1% --- dda.c | 71 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/dda.c b/dda.c index 029003b..012724c 100644 --- a/dda.c +++ b/dda.c @@ -70,6 +70,20 @@ static const axes_uint32_t PROGMEM maximum_feedrate_P = { MAXIMUM_FEEDRATE_E }; +/*! Find the direction of the 'n' axis +*/ +static char get_direction(DDA *dda, enum axis_e n) { + if (n == X) + return dda->x_direction; + if (n == Y) + return dda->y_direction; + if (n == Z) + return dda->z_direction; + if (n == E) + return dda->e_direction; + return 0; +} + /*! Inititalise DDA movement structures */ void dda_init(void) { @@ -849,48 +863,35 @@ void update_current_position() { DDA *dda = &movebuffer[mb_tail]; enum axis_e i; + // Use smaller values to adjust to avoid overflow in later calculations, + // (STEPS_PER_M_X / 1000) is a bit inaccurate for low STEPS_PER_M numbers. + static const axes_uint32_t PROGMEM steps_per_mm_P = { + ((STEPS_PER_M_X + 500) / 1000), + ((STEPS_PER_M_Y + 500) / 1000), + ((STEPS_PER_M_Z + 500) / 1000), + ((STEPS_PER_M_E + 500) / 1000) + }; + if (queue_empty()) { for (i = X; i < AXIS_COUNT; i++) { current_position.axis[i] = startpoint.axis[i]; } } else if (dda->live) { - if (dda->x_direction) - // (STEPS_PER_M_X / 1000) is a bit inaccurate for low STEPS_PER_M numbers - current_position.axis[X] = dda->endpoint.axis[X] - - // should be: move_state.steps[X] * 1000000 / STEPS_PER_M_X) - // but steps[X] can be like 1000000 already, so we'd overflow - move_state.steps[X] * 1000 / ((STEPS_PER_M_X + 500) / 1000); - else - current_position.axis[X] = dda->endpoint.axis[X] + - move_state.steps[X] * 1000 / ((STEPS_PER_M_X + 500) / 1000); + for (i = X; i < AXIS_COUNT; i++) { + if (get_direction(dda, i)) + current_position.axis[i] = dda->endpoint.axis[i] - + // Should be: move_state.steps[i] * 1000000 / steps_per_m_P[i]) + // but steps[i] can be like 1000000 already, so we'd overflow. + move_state.steps[i] * 1000 / pgm_read_dword(&steps_per_mm_P[i]); + else + current_position.axis[i] = dda->endpoint.axis[i] + + move_state.steps[i] * 1000 / pgm_read_dword(&steps_per_mm_P[i]); + } - if (dda->y_direction) - current_position.axis[Y] = dda->endpoint.axis[Y] - - move_state.steps[Y] * 1000 / ((STEPS_PER_M_Y + 500) / 1000); - else - current_position.axis[Y] = dda->endpoint.axis[Y] + - move_state.steps[Y] * 1000 / ((STEPS_PER_M_Y + 500) / 1000); - - if (dda->z_direction) - current_position.axis[Z] = dda->endpoint.axis[Z] - - move_state.steps[Z] * 1000 / ((STEPS_PER_M_Z + 500) / 1000); - else - current_position.axis[Z] = dda->endpoint.axis[Z] + - move_state.steps[Z] * 1000 / ((STEPS_PER_M_Z + 500) / 1000); - - if (dda->endpoint.e_relative) { - current_position.axis[E] = move_state.steps[E] * 1000 / - ((STEPS_PER_M_E + 500) / 1000); - } - else { - if (dda->e_direction) - current_position.axis[E] = dda->endpoint.axis[E] - - move_state.steps[E] * 1000 / ((STEPS_PER_M_E + 500) / 1000); - else - current_position.axis[E] = dda->endpoint.axis[E] + - move_state.steps[E] * 1000 / ((STEPS_PER_M_E + 500) / 1000); - } + if (dda->endpoint.e_relative) + current_position.axis[E] = + move_state.steps[E] * 1000 / pgm_read_dword(&steps_per_mm_P[E]); // current_position.F is updated in dda_start() }