diff --git a/src/application.cpp b/src/application.cpp index 6285917..128b1df 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -77,6 +77,13 @@ void Application::CheckManualOperation() { } mp::ResponseCommandStatus Application::RunningCommandStatus() const { + if (mui::userInput.PrinterInCharge()) { + mui::Event event = mui::userInput.ConsumeEventForPrinter(); + if (event != mui::Event::NoEvent) { + return mp::ResponseCommandStatus(mp::ResponseMsgParamCodes::Button, (uint8_t)event); + } + } + switch (currentCommand->Error()) { case ErrorCode::RUNNING: return mp::ResponseCommandStatus(mp::ResponseMsgParamCodes::Processing, (uint16_t)currentCommand->State()); diff --git a/src/logic/tool_change.cpp b/src/logic/tool_change.cpp index df21ba4..a236224 100644 --- a/src/logic/tool_change.cpp +++ b/src/logic/tool_change.cpp @@ -28,6 +28,10 @@ bool ToolChange::Reset(uint8_t param) { return true; } + // @@TODO establish printer in charge of UI processing for the ToolChange command only. + // We'll see how that works and then probably we'll introduce some kind of protocol settings to switch UI handling. + mui::userInput.SetPrinterInCharge(true); + // we are either already at the correct slot, just the filament is not loaded - load the filament directly // or we are standing at another slot ... plannedSlot = param; @@ -55,6 +59,7 @@ void logic::ToolChange::GoToFeedingToBondtech() { void logic::ToolChange::ToolChangeFinishedCorrectly() { ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::on, ml::off); + mui::userInput.SetPrinterInCharge(false); FinishedOK(); } diff --git a/src/modules/protocol.h b/src/modules/protocol.h index ed4143a..d8a36a9 100644 --- a/src/modules/protocol.h +++ b/src/modules/protocol.h @@ -37,7 +37,8 @@ enum class ResponseMsgParamCodes : uint8_t { Error = 'E', Finished = 'F', Accepted = 'A', - Rejected = 'R' + Rejected = 'R', + Button = 'B' // the MMU registered a button press and is sending it to the printer for processing }; /// A request message - requests are being sent by the printer into the MMU. diff --git a/src/modules/user_input.cpp b/src/modules/user_input.cpp index a178f2c..e2a22f2 100644 --- a/src/modules/user_input.cpp +++ b/src/modules/user_input.cpp @@ -21,6 +21,14 @@ void UserInput::ProcessMessage(uint8_t ev) { } Event UserInput::ConsumeEvent() { + if (printerInCharge) { + return Event::NoEvent; + } else { + return ConsumeEventForPrinter(); + } +} + +Event UserInput::ConsumeEventForPrinter() { if (eventQueue.empty()) return Event::NoEvent; Event rv; diff --git a/src/modules/user_input.h b/src/modules/user_input.h index 8adc953..6c3115e 100644 --- a/src/modules/user_input.h +++ b/src/modules/user_input.h @@ -8,6 +8,7 @@ namespace modules { /// User input module collects input from buttons and from communication for the logic layer namespace user_input { +/// Beware - button codes intentionally match the protocol button encoding for optimization purposes enum class Event : int8_t { NoEvent = -1, Left = 0, @@ -26,17 +27,37 @@ public: /// enqueues a user event coming from a communication void ProcessMessage(uint8_t ev); - /// dequeues the most recent event from the queue for processing + /// Dequeues the most recent event from the queue for processing. + /// This is what all the state machines shall call as is encapsulates + /// the logic of not providing the buttons for the MMU FW in case the printer + /// is in charge of UI processing. Event ConsumeEvent(); + /// Dequeues the most recent event from the queue for sending to the printer. + /// Beware - use this call wisely, it is intended only for extraction of events to be sent to the printer. + Event ConsumeEventForPrinter(); + /// @returns true if there is at least one event in the event queue bool AnyEvent() const { return !eventQueue.empty(); } /// Remove all buffered events from the event queue void Clear(); + /// Sets the UI module into a mode when the printer is in charge of processing the buttons (from all sources). + /// That means the MMU will detect its buttons but it will not react upon them. + /// This mode is important for error recovery when the printer needs to do some stuff before the MMU (like preheating the nozzle). + inline void SetPrinterInCharge(bool pc) { + printerInCharge = pc; + } + + /// @returns true if the printer is in charge of the buttons + inline bool PrinterInCharge() const { + return printerInCharge; + } + private: CircularBuffer eventQueue; + bool printerInCharge = false; }; extern UserInput userInput;