Split the planner sync code out of planner_abort_hard() so that we can
independently resync the planner position from the counters.
This is needed in xyzcal as we directly modify the stepper counters
(bypassing both planner and stepper).
Call this new function instead of planner_abort_hard() when leaving, so
that motion can resume in the middle of the gcode_M45 instruction.
After calling planner_abort_hard() no motion command can be
scheduled until we return to the main loop since the call can
potentially be scheduled inside a nested process_command call.
Despite previous fixes, bugs keep creeping in due to nested calls not
being obvious to detect at all.
Stop allowing motion _completely_ for the entire processing loop by
default. That is, instead of aborting the current plan_buffer_line call,
abort the entire command until we can actually schedule motion safely
again.
This benefits handling of pretty much all g/m-codes, since this flag
(now "planner_aborted" for clarity) becomes a general "command aborted"
call.
This also now ensures that the flag prevents _any_ new block (including
blocks partially planned while servicing an interrupt) are scheduled
after planner_abort_hard is called.
There are only two exceptions where it's safe to resume in this context:
- Within uvlo_, where we never return to the main processing loop
- When we're intentionally scheduling a new process_command loop for a
MK3 filament recheck (which is *bad*)
Handle those two cases as exceptions.
Everywhere MINTEMP is checked, use the configurable value set by M302,
not an hardcoded value.
EXTRUDE_MINTEMP is now used only as the initial default value.
Reduce the precision of extrude_min_temp to an integer to reduce the
generated code size (constant folding did in fact do the same previously
anyway). Having tenths of degrees is not necessary for this feature.
Instead of using a mixture of int8_t, unsigned char and (incorrectly)
int, use uint8_t consistently for indexing the current block.
This improves the performance of the wait loop in plan_buffer_line,
which currently expands all comparisons to a word for no reason.
This also extends the theoretical limit to 128 entries.
Add some static assertions to ensure BLOCK_BUFFER_SIZE is correct.
* Combine repeated calls into functions with much less parameters -> 2KB
down.
* Save some bytes by removing unnecessary 1-character strings: "x" -> 'x'
used in SERIAL_xxx printing macros.
This is also saves some CPU cycles
* Fix compilation for MK25S and MK3
* Copy surrounding indentation
* Fix compilation for a rare HW setup
* rename mesh_planXX_buffer_line back to mesh_plan_buffer_line
* Remove active_extruder from remaining plan_buffer_line_destinationXYZE
calls and one more fix of indentation
To maintain an accurate step count (which is required for correct
position recovery), any call to plan_set_position&co needs to be done
synchronously and from a halted state.
However, G92 E* is currently special-cased to skip the sync (likely to
avoid the associated performance cost), causing an incorrect E step
count and position to be set. This breaks absolute position recovery,
miscalculation of the LA factor and possibly other weird issues.
We rewrite the handling of G92 to always sync but still special-case the
frequent "G92 E0" for performance by using a free bit in the block flags.
To avoid a sync, we relay the request for reset first to the planner
which clears its internal state and then relays the request to the final
stepper isr.
Since the global feedrate can be similarly modified for moves ahead of
time, save the original feedrate in the planner as we do for
gcode_target.
This avoids having to undo feedmultiply (and machine limits!) from
"nominal_speed" as previously done.
Thanks @leptun
When starting to replay existing USB/SD commands from a recovery state,
an immediate relative move needs to compensate for a previously
interrupted move. This is almost the norm for the E axis.
Instead of saving the relative status of the move (which needs to
account for the world2machine conversion and is not always available on
a chunked move split by MBL) save directly the calculated target
position for the move in the original plan, which is easy to replay.
While handling moves in a recursive plan, such a filament check,
ensure restore_print_from_ram_and_continue unwinds the stack by
aborting early from any call that waits on the planner.
This currently only handles G1 moves, but hard-coded behavior that can
trigger recursive behavior (such as filament change) will probably have
to be checked too.
Do not store the block e_D ratio, store directly the computed
compression factor so that we can recompute the advance steps
quickly and update them in sync with the acceleration rates.
access to the low / high words of the 32bit values.
This is a prerequisity for an optimized 16bit only DDA
in case the number of step is lower than 32767.
Improved accuracy of diagonal moves by oversampling the path discretization.
Accelerated the planner by rewriting time critical routines from floating
point to fixed point arithmetics.