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>
After lots of try and error the conclusion was, disabling this
interrupt makes the timer vulnerable to be messed up by
characters incoming over the serial line. So, now the
interrupt is enabled as a move starts and not disabled before
the move, and all subsequent moves are done.
Problem was: For short moves, you have to ramp down before
reaching target speed. The point of return was set to half
of the number of total steps.
Now, what happens is there's an uneven number of steps? In
integer math, 3 / 2 = 1, so the move would ramp one step up,
one step down and ... well, one step even further down, resulting
in a really sloooow step. Slow, like a full second or so.
Adding one to the first half, the movement ramps two steps up,
one down and would do another step at minimum speed, if it wasn't
already at target position. This is about as accurate as we
can get it without introducing more code at interrupt time.
each axis individually, as the combined speed of two or more
axes can be higher than the limit of a single one.
While this is tested to work well for all three acceleration
types, I'm not enthusiastic about the code, as it adds almost
500 bytes. Perhaps an efficient-coding-geek can help :-)