In the entire code base, we basically use 4 LED scenarios:
- all off
- active slot green on
- active slot green blinking
- active slot red blinking
Compacting this behaviour into 4 functions saves in total ~140B - which is huge.
It's not an entirely clean solution, LEDs should not know anything about globals::ActiveSlot, but the savings are more important.
Ideally, such an optimization could have been done by the compiler.
Needs to be tweaked further to make it a production code.
But my primary concern now is the fact that it doesn't seem to help too much while homing over the too-tightened Idler cover.
This PR is a different solution to what @gudnimg found in PR#233 / PFW-1404.
The benefit of this approach is the fact, that the button press event is generated when the button is pressed and not after it has been released.
The downside is obvious:
CPUFLASH: +28B
RAM: +1B
- rename stall*guard to StallGuard (match name with the vendor)
- separate TMC2130 module from EEPROM (they do not need to know about each other at all)
- separate SGTHRS settings from motion - moved to globals like all other "global" parameters
- improved EEPROM storage for SGTHRS
It turned out FINDA needs running timer to perform BlockingInit() correctly.
Therefore setup() was split into setup() (no IRQ) and setup2() (IRQ enabled).
Then, finally, the check for FINDA state became reliable upon start of the FW.
- Check rates using the reported acceleration instead of deriving the
value from the slope.
- Simplify the tolerances when checking (use 10% for single-axis,
20% with multiple due to quantization)
- Check a broader range of values
Correctly compute both the number of steps and direction when
under/overflowing the current position by performing a relative move.
This makes a repeated PlanMove() _always_ perform the move correcly,
even when the upper-level code might require to handle the overflow
itself for measurement.
Add tests for this condition by exposing the internal CurBlockShift() to
the motion unit tests.
Do not assume any step can be merged while moving three axes at the same
time.
Use the worst case scenario involving indepedent parameters for each
axis.
This commit looks horribly complex, but the main idea is to have each of the logic::commands
report their terminal OK state in the same way. That allow for leveraging this very moment
to initiate the idle timeout.
Additionally, I wanted to hide the logic of idle mode detection, which resulted in moving the
top level logic from main.cpp into logic/idle_mode.cpp and a set of additional files to compile
in unit tests.
- fix homing procedure for Idler and Selector
(homing now ends with a move to the Parking position)
- fix unit tests' startup conditions with regard to necessary
homing of Idler and Selector
TODO: still test_cut_filament fails for minor reasons
This introduces a new #define UNITTEST_MOTION which is used to control
the testing scenario:
- Normal tests, we allow the stub to override the built-in definition.
- For motion tests, we stub the lower-level classes and test the
effective implementation
We also repeat the prototype of the function, which IMHO is more
readable and more flexible: we need to use inline for the real
definition, which would require even more macros otherwise.
If the queue is full and a new move is queued, panic!
Introduce a new error code QUEUE_FULL to help diagnose situations where
the queue is handled improperly: likely one of the state machines not
waiting for the previous actions to finish.
PulseGen::PlanMove returns a boolean if the queue cannot be moved.
We could extend this to Motion::PlanMove, however all moves would then
have to check for this. Having a global check such as this ensures
we never ignore such situation.