From 41e76ca9fec34487c1beebb4ce552ed6923b11da Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Fri, 4 Jul 2014 23:05:09 +0200 Subject: [PATCH] dda.c: make update_current_position() even smaller. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Saves another 24 bytes. SIZES ATmega... '168 '328(P) '644(P) '1280 FLASH : 20110 bytes 141% 66% 32% 16% RAM : 2302 bytes 225% 113% 57% 29% EEPROM: 32 bytes 4% 2% 2% 1% Using muldiv() would be more accurate, but unfortunately, the compiler bails out: static const axes_uint32_t PROGMEM steps_per_mm_P = { ^ dda.c:889:1: error: unable to find a register to spill in class ‘POINTER_REGS’ } ^ dda.c:889:1: error: this is the insn: (insn 81 80 83 6 (set (reg:SI 77 [ D.3086 ]) (mem:SI (post_inc:HI (reg:HI 2 r2 [orig:103 ivtmp.106 ] [103])) [3 MEM[base: _82, offset: 0B]+0 S4 A8])) dda.c:881 94 {*movsi} (expr_list:REG_INC (reg:HI 2 r2 [orig:103 ivtmp.106 ] [103]) (nil))) dda.c:889: confused by earlier errors, bailing out Another one is, calculating this: (int32_t)get_direction(dda, i) * move_state.steps[i] * 1000 / pgm_read_dword(&steps_per_mm_P[i]); produces nonsense values for negative returns from get_direction(). Apparently, the compiler doesn't want to divide negative values??? Odd. Anyways, sufficient parentheses solve the problem. --- dda.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/dda.c b/dda.c index 012724c..ed4876e 100644 --- a/dda.c +++ b/dda.c @@ -72,16 +72,14 @@ static const axes_uint32_t PROGMEM maximum_feedrate_P = { /*! 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; +static int8_t get_direction(DDA *dda, enum axis_e n) { + if ((n == X && dda->x_direction) || + (n == Y && dda->y_direction) || + (n == Z && dda->z_direction) || + (n == E && dda->e_direction)) + return 1; + else + return -1; } /*! Inititalise DDA movement structures @@ -879,19 +877,18 @@ void update_current_position() { } else if (dda->live) { 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]); + current_position.axis[i] = dda->endpoint.axis[i] - + (int32_t)get_direction(dda, 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. + // Unfortunately, using muldiv() overwhelms the compiler. + // Also keep the parens around this term, else results go wrong. + ((move_state.steps[i] * 1000) / pgm_read_dword(&steps_per_mm_P[i])); } if (dda->endpoint.e_relative) current_position.axis[E] = - move_state.steps[E] * 1000 / pgm_read_dword(&steps_per_mm_P[E]); + (move_state.steps[E] * 1000) / pgm_read_dword(&steps_per_mm_P[E]); // current_position.F is updated in dda_start() }