diff --git a/tests/unit/logic/homing/test_homing.cpp b/tests/unit/logic/homing/test_homing.cpp index 0dd3b9f..a1c696e 100644 --- a/tests/unit/logic/homing/test_homing.cpp +++ b/tests/unit/logic/homing/test_homing.cpp @@ -11,6 +11,7 @@ #include "../../../../src/modules/selector.h" #include "../../../../src/logic/home.h" +#include "../../../../src/logic/move_selector.h" #include "../../../../src/logic/load_filament.h" #include "../../../../src/logic/unload_filament.h" @@ -95,3 +96,90 @@ bool SelectorFailedRetry() { TEST_CASE("homing::selector_failed_retry", "[homing]") { REQUIRE(SelectorFailedRetry()); } + +bool SimulateFailedMoveFirstTime(logic::CommandBase &cb) { + { + // do 5 steps until we trigger the simulated stallguard + for (uint8_t i = 0; i < 5; ++i) { + main_loop(); + cb.Step(); + } + + mm::TriggerStallGuard(mm::Selector); + main_loop(); + cb.Step(); + mm::motion.StallGuardReset(mm::Selector); + } + + while (ms::selector.State() != mm::MovableBase::MoveFailed) { + main_loop(); + cb.Step(); + } + + REQUIRE_FALSE(!WhileTopState(cb, ProgressCode::MovingSelector, 5)); + + REQUIRE(cb.Error() == ErrorCode::MOVE_SELECTOR_FAILED); + REQUIRE(cb.State() == ProgressCode::ERRWaitingForUser); + // REQUIRE_FALSE(mm::motion.Enabled(mm::Selector)); + + // do a few steps before pushing the button + WhileTopState(cb, ProgressCode::ERRWaitingForUser, 5); + + // REQUIRE_FALSE(mm::motion.Enabled(mm::Selector)); + + PressButtonAndDebounce(cb, mb::Middle); + + // it shall start homing again + REQUIRE(cb.Error() == ErrorCode::RUNNING); + REQUIRE(cb.State() == ProgressCode::Homing); + REQUIRE_FALSE(ms::selector.HomingValid()); + REQUIRE(mm::motion.Enabled(mm::Selector)); + + ClearButtons(cb); + + return true; +} + +bool SelectorMoveFailedRetry(uint8_t fromSlot, uint8_t toSlot) { + // prepare startup conditions + ForceReinitAllAutomata(); + + // change the startup to what we need here + EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::AtPulley); + + // set FINDA OFF + debounce + SetFINDAStateAndDebounce(false); + + logic::MoveSelector ms; + REQUIRE(VerifyState(ms, mg::FilamentLoadState::AtPulley, mi::Idler::IdleSlotIndex(), fromSlot, false, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK)); + + ms.Reset(toSlot); + REQUIRE(VerifyState(ms, mg::FilamentLoadState::AtPulley, mi::Idler::IdleSlotIndex(), fromSlot, false, false, ml::off, ml::off, ErrorCode::RUNNING, ProgressCode::MovingSelector)); + + REQUIRE(SimulateFailedMoveFirstTime(ms)); + + // for (uint8_t i = 0; i < 5; ++i) { + // REQUIRE(SimulateFailedHomeSelectorRepeated(h)); + // } + + // both selector and idler shall home + SimulateIdlerAndSelectorHoming(ms); + + REQUIRE(WhileTopState(ms, ProgressCode::Homing, 5000)); + + REQUIRE(VerifyState(ms, mg::FilamentLoadState::AtPulley, mi::Idler::IdleSlotIndex(), toSlot, false, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK)); + REQUIRE(mi::idler.HomingValid()); + REQUIRE(ms::selector.HomingValid()); + + return true; +} + +TEST_CASE("moving::selector_stallguard", "[moving]") { + for (uint8_t from = 0; from < config::toolCount; ++from) { + for (uint8_t to = 0; to < config::toolCount; ++to) { + if (from != to) { + REQUIRE(SelectorMoveFailedRetry(from, to)); + } + } + } +}