Use the new muldiv() to replace um_to_steps..().
This gets rid of overflows at micrometer to step conversion as much as possible within 31 bits. It also opens the door to get STEPS_PER_M configurable at runtime. This also costs 290 bytes, unfortunately.
This commit is contained in:
parent
9359350fcc
commit
0068ed1e26
19
dda.c
19
dda.c
|
|
@ -9,6 +9,7 @@
|
|||
#include <math.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "dda_maths.h"
|
||||
#include "timer.h"
|
||||
#include "serial.h"
|
||||
#include "sermsg.h"
|
||||
|
|
@ -188,10 +189,10 @@ void dda_init(void) {
|
|||
This is needed for example after homing or a G92. The new location must be in startpoint already.
|
||||
*/
|
||||
void dda_new_startpoint(void) {
|
||||
um_to_steps_x(startpoint_steps.X, startpoint.X);
|
||||
um_to_steps_y(startpoint_steps.Y, startpoint.Y);
|
||||
um_to_steps_z(startpoint_steps.Z, startpoint.Z);
|
||||
um_to_steps_e(startpoint_steps.E, startpoint.E);
|
||||
startpoint_steps.X = um_to_steps_x(startpoint.X);
|
||||
startpoint_steps.Y = um_to_steps_y(startpoint.Y);
|
||||
startpoint_steps.Z = um_to_steps_z(startpoint.Z);
|
||||
startpoint_steps.E = um_to_steps_e(startpoint.E);
|
||||
}
|
||||
|
||||
/*! CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue
|
||||
|
|
@ -226,13 +227,13 @@ void dda_create(DDA *dda, TARGET *target) {
|
|||
y_delta_um = (uint32_t)labs(target->Y - startpoint.Y);
|
||||
z_delta_um = (uint32_t)labs(target->Z - startpoint.Z);
|
||||
|
||||
um_to_steps_x(steps, target->X);
|
||||
steps = um_to_steps_x(target->X);
|
||||
dda->x_delta = labs(steps - startpoint_steps.X);
|
||||
startpoint_steps.X = steps;
|
||||
um_to_steps_y(steps, target->Y);
|
||||
steps = um_to_steps_y(target->Y);
|
||||
dda->y_delta = labs(steps - startpoint_steps.Y);
|
||||
startpoint_steps.Y = steps;
|
||||
um_to_steps_z(steps, target->Z);
|
||||
steps = um_to_steps_z(target->Z);
|
||||
dda->z_delta = labs(steps - startpoint_steps.Z);
|
||||
startpoint_steps.Z = steps;
|
||||
|
||||
|
|
@ -242,12 +243,12 @@ void dda_create(DDA *dda, TARGET *target) {
|
|||
|
||||
if (target->e_relative) {
|
||||
e_delta_um = labs(target->E);
|
||||
um_to_steps_e(dda->e_delta, e_delta_um);
|
||||
dda->e_delta = 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);
|
||||
um_to_steps_e(steps, target->E);
|
||||
steps = um_to_steps_e(target->E);
|
||||
dda->e_delta = labs(steps - startpoint_steps.E);
|
||||
startpoint_steps.E = steps;
|
||||
dda->e_direction = (target->E >= startpoint.E)?1:0;
|
||||
|
|
|
|||
75
dda.h
75
dda.h
|
|
@ -5,81 +5,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
micrometer to steps conversion
|
||||
|
||||
handle a few cases to avoid overflow while keeping reasonable accuracy
|
||||
input is up to 20 bits, so we can multiply by 4096 at most
|
||||
*/
|
||||
#if STEPS_PER_M_X >= 4096000
|
||||
#define um_to_steps_x(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_X / 10000L) + 50L) / 100L; } while (0)
|
||||
#elif STEPS_PER_M_X >= 409600
|
||||
#define um_to_steps_x(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_X / 1000L) + 500L) / 1000L; } while (0)
|
||||
#elif STEPS_PER_M_X >= 40960
|
||||
#define um_to_steps_x(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_X / 100L) + 5000L) / 10000L; } while (0)
|
||||
#elif STEPS_PER_M_X >= 4096
|
||||
#define um_to_steps_x(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_X / 10L) + 50000L) / 100000L; } while (0)
|
||||
#else
|
||||
#define um_to_steps_x(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_X / 1L) + 500000L) / 1000000L; } while (0)
|
||||
#endif
|
||||
|
||||
#if STEPS_PER_M_Y >= 4096000
|
||||
#define um_to_steps_y(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Y / 10000L) + 50L) / 100L; } while (0)
|
||||
#elif STEPS_PER_M_Y >= 409600
|
||||
#define um_to_steps_y(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Y / 1000L) + 500L) / 1000L; } while (0)
|
||||
#elif STEPS_PER_M_Y >= 40960
|
||||
#define um_to_steps_y(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Y / 100L) + 5000L) / 10000L; } while (0)
|
||||
#elif STEPS_PER_M_Y >= 4096
|
||||
#define um_to_steps_y(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Y / 10L) + 50000L) / 100000L; } while (0)
|
||||
#else
|
||||
#define um_to_steps_y(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Y / 1L) + 500000L) / 1000000L; } while (0)
|
||||
#endif
|
||||
|
||||
#if STEPS_PER_M_Z >= 4096000
|
||||
#define um_to_steps_z(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Z / 10000L) + 50L) / 100L; } while (0)
|
||||
#elif STEPS_PER_M_Z >= 409600
|
||||
#define um_to_steps_z(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Z / 1000L) + 500L) / 1000L; } while (0)
|
||||
#elif STEPS_PER_M_Z >= 40960
|
||||
#define um_to_steps_z(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Z / 100L) + 5000L) / 10000L; } while (0)
|
||||
#elif STEPS_PER_M_Z >= 4096
|
||||
#define um_to_steps_z(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Z / 10L) + 50000L) / 100000L; } while (0)
|
||||
#else
|
||||
#define um_to_steps_z(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_Z / 1L) + 500000L) / 1000000L; } while (0)
|
||||
#endif
|
||||
|
||||
#if STEPS_PER_M_E >= 4096000
|
||||
#define um_to_steps_e(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_E / 10000L) + 50L) / 100L; } while (0)
|
||||
#elif STEPS_PER_M_E >= 409600
|
||||
#define um_to_steps_e(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_E / 1000L) + 500L) / 1000L; } while (0)
|
||||
#elif STEPS_PER_M_E >= 40960
|
||||
#define um_to_steps_e(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_E / 100L) + 5000L) / 10000L; } while (0)
|
||||
#elif STEPS_PER_M_E >= 4096
|
||||
#define um_to_steps_e(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_E / 10L) + 50000L) / 100000L; } while (0)
|
||||
#else
|
||||
#define um_to_steps_e(dest, src) \
|
||||
do { dest = (src * (STEPS_PER_M_E / 1L) + 500000L) / 1000000L; } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ACCELERATION_REPRAP
|
||||
#ifdef ACCELERATION_RAMPING
|
||||
#error Cant use ACCELERATION_REPRAP and ACCELERATION_RAMPING together.
|
||||
|
|
|
|||
|
|
@ -3,9 +3,16 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
// return rounded result of multiplicand * multiplier / divisor
|
||||
const int32_t muldiv(int32_t multiplicand, uint32_t multiplier,
|
||||
uint32_t divisor);
|
||||
|
||||
// convert micrometer distances to motor step distances
|
||||
#define um_to_steps_x(distance) muldiv(distance, STEPS_PER_M_X, 1000000UL);
|
||||
#define um_to_steps_y(distance) muldiv(distance, STEPS_PER_M_Y, 1000000UL);
|
||||
#define um_to_steps_z(distance) muldiv(distance, STEPS_PER_M_Z, 1000000UL);
|
||||
#define um_to_steps_e(distance) muldiv(distance, STEPS_PER_M_E, 1000000UL);
|
||||
|
||||
#endif /* _DDA_MATHS_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue