dda.c: make update_current_position() even smaller.

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.
This commit is contained in:
Markus Hitter 2014-07-04 23:05:09 +02:00
parent b552447789
commit 41e76ca9fe
1 changed files with 16 additions and 19 deletions

35
dda.c
View File

@ -72,16 +72,14 @@ static const axes_uint32_t PROGMEM maximum_feedrate_P = {
/*! Find the direction of the 'n' axis /*! Find the direction of the 'n' axis
*/ */
static char get_direction(DDA *dda, enum axis_e n) { static int8_t get_direction(DDA *dda, enum axis_e n) {
if (n == X) if ((n == X && dda->x_direction) ||
return dda->x_direction; (n == Y && dda->y_direction) ||
if (n == Y) (n == Z && dda->z_direction) ||
return dda->y_direction; (n == E && dda->e_direction))
if (n == Z) return 1;
return dda->z_direction; else
if (n == E) return -1;
return dda->e_direction;
return 0;
} }
/*! Inititalise DDA movement structures /*! Inititalise DDA movement structures
@ -879,19 +877,18 @@ void update_current_position() {
} }
else if (dda->live) { else if (dda->live) {
for (i = X; i < AXIS_COUNT; i++) { for (i = X; i < AXIS_COUNT; i++) {
if (get_direction(dda, i)) current_position.axis[i] = dda->endpoint.axis[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]) // Should be: move_state.steps[i] * 1000000 / steps_per_m_P[i])
// but steps[i] can be like 1000000 already, so we'd overflow. // 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]); // Unfortunately, using muldiv() overwhelms the compiler.
else // Also keep the parens around this term, else results go wrong.
current_position.axis[i] = dda->endpoint.axis[i] + ((move_state.steps[i] * 1000) / pgm_read_dword(&steps_per_mm_P[i]));
move_state.steps[i] * 1000 / pgm_read_dword(&steps_per_mm_P[i]);
} }
if (dda->endpoint.e_relative) if (dda->endpoint.e_relative)
current_position.axis[E] = 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() // current_position.F is updated in dda_start()
} }