diff --git a/tests/unit/logic/load_filament/test_load_filament.cpp b/tests/unit/logic/load_filament/test_load_filament.cpp index 1c7bc43..d9676de 100644 --- a/tests/unit/logic/load_filament/test_load_filament.cpp +++ b/tests/unit/logic/load_filament/test_load_filament.cpp @@ -131,6 +131,7 @@ void FailedLoadToFindaResolveHelp(uint8_t slot, logic::LoadFilament &lf) { // In this case we check the first option PressButtonAndDebounce(lf, mb::Left, false); + ClearButtons(lf); REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::blink0, ErrorCode::RUNNING, ProgressCode::ERREngagingIdler)); @@ -142,8 +143,6 @@ void FailedLoadToFindaResolveHelp(uint8_t slot, logic::LoadFilament &lf) { REQUIRE(WhileTopState(lf, ProgressCode::ERREngagingIdler, idlerEngageDisengageMaxSteps)); REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, slot, slot, false, true, ml::off, ml::blink0, ErrorCode::RUNNING, ProgressCode::ERRHelpingFilament)); - - ClearButtons(lf); } void FailedLoadToFindaResolveHelpFindaTriggered(uint8_t slot, logic::LoadFilament &lf) { @@ -171,8 +170,9 @@ void FailedLoadToFindaResolveManual(uint8_t slot, logic::LoadFilament &lf) { // simulate the user fixed the issue himself // Perform press on button 2 + debounce + switch on FINDA - hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::high); + SetFINDAStateAndDebounce(true); PressButtonAndDebounce(lf, mb::Right, false); + ClearButtons(lf); // the Idler also engages in this call as this is planned as the next step SimulateIdlerHoming(lf); @@ -180,8 +180,6 @@ void FailedLoadToFindaResolveManual(uint8_t slot, logic::LoadFilament &lf) { // pulling filament back REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, slot, slot, true, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda)); - ClearButtons(lf); - // Stage 3 - retracting from finda // we'll assume the finda is working correctly here REQUIRE(WhileCondition( @@ -216,24 +214,23 @@ void FailedLoadToFindaResolveManual(uint8_t slot, logic::LoadFilament &lf) { } void FailedLoadToFindaResolveManualNoFINDA(uint8_t slot, logic::LoadFilament &lf) { - // Perform press on button 2 + debounce + keep FINDA OFF (i.e. the user didn't solve anything) + // Perform press and release on button 2 + debounce + keep FINDA OFF (i.e. the user didn't solve anything) PressButtonAndDebounce(lf, mb::Right, false); + ClearButtons(lf); SimulateIdlerHoming(lf); - ClearButtons(lf); - // pulling filament back REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_SWITCH_ON, ProgressCode::ERRWaitingForUser)); } void FailedLoadToFindaResolveTryAgain(uint8_t slot, logic::LoadFilament &lf) { PressButtonAndDebounce(lf, mb::Middle, false); + ClearButtons(lf); // the state machine should have restarted // Idler's position needs to be ignored as it has started homing after the button press REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, config::toolCount, slot, false, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToFinda)); - ClearButtons(lf); SimulateIdlerHoming(lf); @@ -361,6 +358,7 @@ void LoadFilamentStopped(uint8_t slot, logic::LoadFilament &lf) { // now press a button PressButtonAndDebounce(lf, mb::Middle, false); + ClearButtons(lf); REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, slot, slot, false, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda)); diff --git a/tests/unit/logic/stubs/homing.cpp b/tests/unit/logic/stubs/homing.cpp index dad3f75..0d6583c 100644 --- a/tests/unit/logic/stubs/homing.cpp +++ b/tests/unit/logic/stubs/homing.cpp @@ -142,6 +142,18 @@ bool SimulateFailedHomeSelectorPostfix(logic::CommandBase &cb) { PressButtonAndDebounce(cb, mb::Middle, false); + // Holding down the button has no effect + if (cb.Error() == ErrorCode::RUNNING) + return false; + if (cb.State() == ProgressCode::Homing) + return false; + if (ms::selector.HomingValid()) + return false; + if (mm::motion.Enabled(mm::Selector)) + return false; + + ClearButtons(cb); + // it shall start homing again if (cb.Error() != ErrorCode::RUNNING) return false; @@ -152,8 +164,6 @@ bool SimulateFailedHomeSelectorPostfix(logic::CommandBase &cb) { if (!mm::motion.Enabled(mm::Selector)) return false; - ClearButtons(cb); - return true; } diff --git a/tests/unit/logic/unload_filament/test_unload_filament.cpp b/tests/unit/logic/unload_filament/test_unload_filament.cpp index a07773b..09a29a6 100644 --- a/tests/unit/logic/unload_filament/test_unload_filament.cpp +++ b/tests/unit/logic/unload_filament/test_unload_filament.cpp @@ -74,16 +74,19 @@ void RegularUnloadFromSlot04(uint8_t slot, logic::UnloadFilament &uf, uint8_t en REQUIRE(VerifyState(uf, mg::FilamentLoadState::InSelector, slot, slot, false, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda)); // Stage 2 - retracting from FINDA - REQUIRE(WhileTopState(uf, ProgressCode::RetractingFromFinda, idlerEngageDisengageMaxSteps)); + REQUIRE(WhileTopState(uf, ProgressCode::RetractingFromFinda)); - // Stage 3 - idler was engaged, disengage it - REQUIRE(WhileTopState(uf, ProgressCode::DisengagingIdler, idlerEngageDisengageMaxSteps)); + REQUIRE(VerifyState(uf, mg::FilamentLoadState::AtPulley, slot, slot, false, true, ml::off, ml::off, ErrorCode::RUNNING, ProgressCode::DisengagingIdler)); + // Stage 3 - If selector is not homed, we must home while the idler is disengaging before we can exit ProgressCode::DisengagingIdler state if (selectorShallHomeAtEnd) { REQUIRE(ms::selector.Slot() == 0xff); SimulateSelectorHoming(uf); } + // Stage 4 - Wait application to exit DisengagingIdler state + REQUIRE(WhileTopState(uf, ProgressCode::DisengagingIdler, idlerEngageDisengageMaxSteps)); + // filament unloaded // idler should have been disengaged // no change in selector's position @@ -177,6 +180,7 @@ void FindaDidntTriggerResolveHelp(uint8_t slot, logic::UnloadFilament &uf) { REQUIRE_FALSE(mui::userInput.AnyEvent()); // Perform press on button 0 + debounce PressButtonAndDebounce(uf, mb::Left, false); + ClearButtons(uf); REQUIRE_FALSE(mui::userInput.AnyEvent()); // button processed and nothing remains // we still think we have filament loaded at this stage @@ -260,6 +264,7 @@ void FindaDidntTriggerResolveTryAgain(uint8_t slot, logic::UnloadFilament &uf) { // In this case we check the second option PressButtonAndDebounce(uf, mb::Middle, false); + ClearButtons(uf); // we still think we have filament loaded at this stage // idler should have been disengaged @@ -305,8 +310,9 @@ void FailedUnloadResolveManual(uint8_t slot, logic::UnloadFilament &uf) { // simulate the user fixed the issue himself // Perform press on button 2 + debounce + switch off FINDA - hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low); + SetFINDAStateAndDebounce(false); PressButtonAndDebounce(uf, mb::Right, false); + ClearButtons(uf); REQUIRE(VerifyState(uf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, false, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToFinda)); @@ -331,6 +337,7 @@ void FailedUnloadResolveManualFINDAon(uint8_t slot, logic::UnloadFilament &uf) { // Perform press on button 2 + debounce + keep FINDA on PressButtonAndDebounce(uf, mb::Right, false); + ClearButtons(uf); REQUIRE(VerifyState(uf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, true, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_SWITCH_OFF, ProgressCode::ERRWaitingForUser)); } @@ -340,8 +347,9 @@ void FailedUnloadResolveManualFSensorOn(uint8_t slot, logic::UnloadFilament &uf) // Perform press on button 2 + debounce + keep FSensor on SetFSensorStateAndDebounce(true); - hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low); + SetFINDAStateAndDebounce(false); PressButtonAndDebounce(uf, mb::Right, false); + ClearButtons(uf); REQUIRE(VerifyState(uf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::blink0, ErrorCode::FSENSOR_DIDNT_SWITCH_OFF, ProgressCode::ERRWaitingForUser)); } @@ -376,8 +384,9 @@ TEST_CASE("unload_filament::unload_homing_retry", "[unload_filament][homing]") { FindaDidntTriggerCommonSetup(slot, uf); // simulate the user fixed the issue himself (not really important, we are after a failed homing of the selector) - hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low); + SetFINDAStateAndDebounce(false); PressButtonAndDebounce(uf, mb::Right, false); + ClearButtons(uf); SimulateIdlerHoming(uf); // make Idler happy REQUIRE(WhileCondition(uf, std::bind(SimulateFeedToFINDA, _1, 100), 5000)); diff --git a/tests/unit/modules/buttons/test_buttons.cpp b/tests/unit/modules/buttons/test_buttons.cpp index 1885755..a55fb16 100644 --- a/tests/unit/modules/buttons/test_buttons.cpp +++ b/tests/unit/modules/buttons/test_buttons.cpp @@ -4,6 +4,13 @@ #include "buttons.h" #include "../hal/adc.h" +enum : uint8_t { + Waiting = 0, + Detected = 1, + WaitForRelease = 2, + Update = 3, +}; + bool Step_Basic_One_Button_Test(mb::Buttons &b, uint8_t oversampleFactor, uint8_t testedButtonIndex, uint8_t otherButton1, uint8_t otherButton2) { for (uint8_t i = 0; i < oversampleFactor; ++i) { b.Step(); // should detect the press but remain in detected state - wait for debounce @@ -97,14 +104,20 @@ TEST_CASE("buttons::Step-basic-button-one-after-other", "[buttons]") { CHECK(Step_Basic_One_Button_Test(b, oversampleFactor, 2, 0, 1)); } -void StepAndCheck(mb::Buttons &b, uint8_t oversampleFactor, bool rightPressed, bool middlePressed, bool leftPressed) { +void StepAndCheck(mb::Buttons &b, uint8_t oversampleFactor, bool rightPressed, bool middlePressed, bool leftPressed, uint8_t state) { for (uint8_t i = 0; i < oversampleFactor; ++i) { b.Step(); // should detect the press but remain in detected state - wait for debounce mt::IncMillis(); } - CHECK(b.ButtonPressed(mb::Right) == rightPressed); - CHECK(b.ButtonPressed(mb::Middle) == middlePressed); - CHECK(b.ButtonPressed(mb::Left) == leftPressed); + if (state == Update) { + CHECK(b.ButtonReleased(mb::Right) == rightPressed); + CHECK(b.ButtonReleased(mb::Middle) == middlePressed); + CHECK(b.ButtonReleased(mb::Left) == leftPressed); + } else { + CHECK(b.ButtonPressed(mb::Right) == rightPressed); + CHECK(b.ButtonPressed(mb::Middle) == middlePressed); + CHECK(b.ButtonPressed(mb::Left) == leftPressed); + } } /// This test tries to simulate a bouncing effect on data from ADC on the first button @@ -120,31 +133,31 @@ TEST_CASE("buttons::Step-debounce-one-button", "[buttons]") { mb::Buttons b; // 5: should detect the press but remain in detected state - wait for debounce - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Detected); // 1023: reset to waiting - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Waiting); // 5: pressed again, still in debouncing state - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Detected); // 9: no change - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Detected); // 6: no change - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Detected); // 7: one step from "pressed" - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Detected); // 8: fifth set of samples - should report "pressed" finally - StepAndCheck(b, oversampleFactor, true, false, false); + StepAndCheck(b, oversampleFactor, true, false, false, WaitForRelease); // 1023: sixth set of samples - button released (no debouncing on release) - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, 1, true, false, false, Update); // 1023: seventh set of samples - still released - StepAndCheck(b, oversampleFactor, false, false, false); + StepAndCheck(b, oversampleFactor, false, false, false, Waiting); } TEST_CASE("buttons::verify_ADC_stub", "[buttons]") { diff --git a/tests/unit/modules/user_input/test_user_input.cpp b/tests/unit/modules/user_input/test_user_input.cpp index 6bcc3a1..925bd3c 100644 --- a/tests/unit/modules/user_input/test_user_input.cpp +++ b/tests/unit/modules/user_input/test_user_input.cpp @@ -22,6 +22,13 @@ void PressButtonAndDebounce(uint8_t btnIndex) { } } +void ReleaseButton(uint8_t btnIndex) { + hal::adc::SetADC(config::buttonsADCIndex, config::buttonADCMaxValue); + mb::buttons.Step(); + mui::userInput.Step(); + mt::IncMillis(); +} + TEST_CASE("user_input::printer_in_charge", "[user_input]") { uint8_t button; mui::Event event; @@ -54,6 +61,11 @@ TEST_CASE("user_input::printer_in_charge", "[user_input]") { REQUIRE(mb::buttons.ButtonPressed(button)); // we should NOT be able to extract the event with ConsumeEvent REQUIRE(mui::userInput.ConsumeEvent() == mui::NoEvent); + REQUIRE_FALSE(mui::userInput.AnyEvent()); + + ReleaseButton(button); + REQUIRE(mb::buttons.ButtonReleased(button)); + REQUIRE(mui::userInput.ConsumeEvent() == mui::NoEvent); REQUIRE(mui::userInput.AnyEvent()); // but we should be able to extract that message with ConsumeEventForPrinter REQUIRE(mui::userInput.ConsumeEventForPrinter() == event); @@ -78,7 +90,11 @@ TEST_CASE("user_input::button_pressed_MMU", "[user_input]") { PressButtonAndDebounce(button); REQUIRE(mb::buttons.ButtonPressed(button)); + REQUIRE(mui::userInput.ConsumeEvent() == mui::NoEvent); + REQUIRE_FALSE(mui::userInput.AnyEvent()); // we should be able to extract the event with ConsumeEvent + ReleaseButton(button); + REQUIRE(mb::buttons.ButtonReleased(button)); REQUIRE(mui::userInput.AnyEvent()); REQUIRE(mui::userInput.ConsumeEvent() == event); REQUIRE_FALSE(mui::userInput.AnyEvent());