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.
These were commits 9dbfa7217e0de8b140846ab480d6b4a7fc9b6791 and
2b596cb05e621ed822071486f812eb334328267a.
There are several reasons why this new approach didn't work out well:
- The machine coordinate system is lost on relative movements.
OK, we could keep tracking it, but this would mean even more
code, so even more chances for bugs.
- With the lost coordinate system, no software endstops are possible.
- Neither of X, Y, Z will ever overflow.
- If a movement planner would appear one day, he'd have to handle
relative movements as well. Even more code duplication.
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 makes the code cleaner and the reduction of code
probably easily compensates for keeping global interrupts
enabled for a bit longer. Talked to macscifi about this.
Saves about 300 bytes of binary size.
We want to stop stepping as there are no steps left, not one step later.
Accordingly, we get rid of a small pause between two movements and
also have to decelerate one step earlier.
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.
This is an intermediate step where both, the old and the new
ramping calculation methods are used and compared. The commit
is done for the case the new method needs debugging in other setups.
This fix is really a hack to protect from overflow/underflows
in the acceleration code due to the limited precision of the
fixed point calculations. It does, however, protect the code
from accidently turning off the step timer or setting the
timer interval value outside of the range defined by the current
interval and the ultimate endpoint interval.
This is a cleanup replacement for the code posted on the reprap forum:
http://forums.reprap.org/read.php?147,33082,83467#msg-83467
Specifically, disable interrupts just before returning and then enable
the timer interrupt if appropriate. This means that the timer interrupt
cannot actually fire until after the RETI, so the function cannot be
entered recursively.
& tests of the debug_flags. Currently the compiler is able to eliminate
the block and the & operation when the constant is zero, but since
the debug_flags variable is a volatile the compiler does not eliminate
the load of the variable. By pretesting and shortcutting the load is
eliminated. Saves a small number of bytes when the debug build is
disabled and costs nothing when it is enabled.
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).
Which includes a seperate file (graycode.c) with the defines and additional variable declaration.
I went with the "graycode" spelling, as there's about ten times as many hits for that as for "greycode" on google. I've read that both spellings are acceptable, but whatever.
Signed-off-by: Michael Moon <triffid.hunter@gmail.com>