#pragma once #include "../../../../src/logic/command_base.h" #include "../../../../src/modules/globals.h" #include "../../../../src/modules/idler.h" extern void main_loop(); extern void ForceReinitAllAutomata(); template bool WhileCondition(SM &sm, COND cond, uint32_t maxLoops = 5000) { uint32_t step = 0; while (cond(step) && --maxLoops) { main_loop(); sm.Step(); ++step; } return maxLoops > 0; } template bool WhileTopState(SM &sm, ProgressCode state, uint32_t maxLoops = 5000) { return WhileCondition( sm, [&](uint32_t) { return sm.TopLevelState() == state; }, maxLoops); } bool EnsureActiveSlotIndex(uint8_t slot, modules::globals::FilamentLoadState loadState); void SetFINDAStateAndDebounce(bool press); bool SimulateUnloadToFINDA(uint32_t step, uint32_t fsOff, uint32_t findaOff); bool SimulateFeedToFINDA(uint32_t step, uint32_t findaOn); bool SimulateRetractFromFINDA(uint32_t step, uint32_t findaOff); void PressButtonAndDebounce(logic::CommandBase &cb, uint8_t btnIndex, bool fromPrinter); void ClearButtons(logic::CommandBase &cb); void SetMinimalBowdenLength(); void SetFSensorStateAndDebounce(bool press); // these are recommended max steps for simulated movement of the idler and selector // - roughly the amount of motion steps from one end to the other + some margin // ... could be computed in the future from the pre-set number of microsteps and real positions static constexpr uint32_t idlerEngageDisengageMaxSteps = 40000UL; static constexpr uint32_t selectorMoveMaxSteps = 40000UL; void HomeIdlerAndSelector(); void SimulateErrDisengagingIdler(logic::CommandBase &cb, ErrorCode deferredEC); template bool SimulateEngageIdlerFully(T &cb) { return WhileCondition( cb, [&](uint32_t) { return !mi::idler.Engaged(); }, 5000); } template bool SimulateEngageIdlerPartially(T &cb) { return WhileCondition( cb, [&](uint32_t) { return !mi::idler.PartiallyDisengaged(); }, 5000); } void HomeIdler();