Instead of converting them to absolute first, then back to
relative and having all the fuzz with working on the queue's
start vs. working at the queue's end, mark a movement as relative
and use this directly.
The implementation is slightly different this time, as it's not
using these famous bresenham algorithms. The intention is to
allow axis-independent movements, as it's required for
EMC-quality look-ahead.
This is a intrusive patch and for now, it's done for the X axis only.
To make comparison with the former approach easier ...
The advantages of this change:
- Converting from mm to steps in gcode_parse.c and back in dda.c
wastes cycles and accuracy.
- In dda.c, UM_PER_STEP simply goes away, so distance calculations
work now with STEPS_PER_MM > 500 just fine. 1/16 microstepping
on threaded rods (Z axis) becomes possible.
- Distance calculations (feedrate, acceleration, ...) become much
simpler.
- A wide range of STEPS_PER_M can now be handled at reasonable
(4 decimal digit) accuracy with a simple macro. Formerly,
we were limited to 500 steps/mm, now we can do 4'096 steps/mm
and could easily raise this another digit.
Disadvantages:
- STEPS_PER_MM is gone in config.h, using STEPS_PER_M is required,
because the preprocessor refuses to compare numbers with decimal
points in them.
- The DDA has to store the position in steps anyways to avoid
rounding errors.
This required to also introduce dda_init() and re-adjust the
number of accelerating steps a bit.
Goal of this is to make look-ahead possible by just reducing
the number of deceleration steps and acceleration steps of
the next move. dda->c and dda->n no longer go down to their
initial values, then.
Also, quite a number of variables in the dda struct are used only when
the dda is live, so there is no need to store that for each
movement of the queue.
Steptimeout is used both inside and outside
of interrupts, and as such it needs special attention.
Specifically, the increment outside of the interrupt
context needs to occur when interrupts are disabled,
or a clear of the variable can be missed.
The variable was also made volatile. This is not strictly necessary
given the current code, but it is the more conservative approach
to dealing with the variable (and costs nothing in the current code).