Force 32-bit math in abs()

In AVR the labs() function takes a 32-bit signed int parameter. On
the PC it's at least 64-bits and maybe more.  When we have a 32-bit
unsigned value we're taking the labs() of, coercing it to 32-bits
first turns our high-bit into a sign, but coercing it to 64-bits
does not.  This causes all our negative values to appear to be
really big positive ones.

Create a new function abs32() which always coerces its argument to
a int32_t first before return the abs value.  Use that function
whereved needed in dda.c.

This fixes a problem on the simulator which caused negative
direction movements to "never" end.
This commit is contained in:
Phil Hord 2013-11-12 00:30:34 -05:00 committed by Markus Hitter
parent c86a51bd5c
commit f7ba1e467b
1 changed files with 13 additions and 10 deletions

23
dda.c
View File

@ -28,6 +28,9 @@
#include "heater.h"
#endif
/* 32-bit-specific abs fn coerces argument to 32-bit signed value first */
#define abs32(x) labs((int32_t)(x))
/*
position tracking
*/
@ -111,18 +114,18 @@ void dda_create(DDA *dda, TARGET *target, DDA *prev_dda) {
// TODO TODO: We should really make up a loop for all axes.
// Think of what happens when a sixth axis (multi colour extruder)
// appears?
x_delta_um = (uint32_t)labs(target->X - startpoint.X);
y_delta_um = (uint32_t)labs(target->Y - startpoint.Y);
z_delta_um = (uint32_t)labs(target->Z - startpoint.Z);
x_delta_um = (uint32_t)abs32(target->X - startpoint.X);
y_delta_um = (uint32_t)abs32(target->Y - startpoint.Y);
z_delta_um = (uint32_t)abs32(target->Z - startpoint.Z);
steps = um_to_steps_x(target->X);
dda->x_delta = labs(steps - startpoint_steps.X);
dda->x_delta = abs32(steps - startpoint_steps.X);
startpoint_steps.X = steps;
steps = um_to_steps_y(target->Y);
dda->y_delta = labs(steps - startpoint_steps.Y);
dda->y_delta = abs32(steps - startpoint_steps.Y);
startpoint_steps.Y = steps;
steps = um_to_steps_z(target->Z);
dda->z_delta = labs(steps - startpoint_steps.Z);
dda->z_delta = abs32(steps - startpoint_steps.Z);
startpoint_steps.Z = steps;
dda->x_direction = (target->X >= startpoint.X)?1:0;
@ -130,14 +133,14 @@ void dda_create(DDA *dda, TARGET *target, DDA *prev_dda) {
dda->z_direction = (target->Z >= startpoint.Z)?1:0;
if (target->e_relative) {
e_delta_um = labs(target->E);
dda->e_delta = labs(um_to_steps_e(target->E));
e_delta_um = abs32(target->E);
dda->e_delta = abs32(um_to_steps_e(target->E));
dda->e_direction = (target->E >= 0)?1:0;
}
else {
e_delta_um = (uint32_t)labs(target->E - startpoint.E);
e_delta_um = (uint32_t)abs32(target->E - startpoint.E);
steps = um_to_steps_e(target->E);
dda->e_delta = labs(steps - startpoint_steps.E);
dda->e_delta = abs32(steps - startpoint_steps.E);
startpoint_steps.E = steps;
dda->e_direction = (target->E >= startpoint.E)?1:0;
}