mmu2.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /// @file
  2. #pragma once
  3. #include "mmu2_protocol_logic.h"
  4. struct E_Step;
  5. namespace MMU2 {
  6. /// @@TODO hmmm, 12 bytes... may be we can reduce that
  7. struct xyz_pos_t {
  8. float xyz[3];
  9. xyz_pos_t()=default;
  10. };
  11. // general MMU setup for MK3
  12. enum : uint8_t {
  13. FILAMENT_UNKNOWN = 0xffU
  14. };
  15. /// Top-level interface between Logic and Marlin.
  16. /// Intentionally named MMU2 to be (almost) a drop-in replacement for the previous implementation.
  17. /// Most of the public methods share the original naming convention as well.
  18. class MMU2 {
  19. public:
  20. MMU2();
  21. /// Powers ON the MMU, then initializes the UART and protocol logic
  22. void Start();
  23. /// Stops the protocol logic, closes the UART, powers OFF the MMU
  24. void Stop();
  25. /// States of a printer with the MMU:
  26. /// - Active
  27. /// - Connecting
  28. /// - Stopped
  29. ///
  30. /// When the printer's FW starts, the MMU2 mode is either Stopped or NotResponding (based on user's preference).
  31. /// When the MMU successfully establishes communication, the state changes to Active.
  32. enum class xState : uint_fast8_t {
  33. Active, ///< MMU has been detected, connected, communicates and is ready to be worked with.
  34. Connecting, ///< MMU is connected but it doesn't communicate (yet). The user wants the MMU, but it is not ready to be worked with.
  35. Stopped ///< The user doesn't want the printer to work with the MMU. The MMU itself is not powered and does not work at all.
  36. };
  37. inline xState State() const { return state; }
  38. // @@TODO temporary wrappers to make old gcc survive the code
  39. inline bool Enabled()const { return State() == xState::Active; }
  40. /// Different levels of resetting the MMU
  41. enum ResetForm : uint8_t {
  42. Software = 0, ///< sends a X0 command into the MMU, the MMU will watchdog-reset itself
  43. ResetPin = 1, ///< trigger the reset pin of the MMU
  44. CutThePower = 2 ///< power off and power on (that includes +5V and +24V power lines)
  45. };
  46. /// Perform a reset of the MMU
  47. /// @param level physical form of the reset
  48. void Reset(ResetForm level);
  49. /// Power off the MMU (cut the power)
  50. void PowerOff();
  51. /// Power on the MMU
  52. void PowerOn();
  53. /// The main loop of MMU processing.
  54. /// Doesn't loop (block) inside, performs just one step of logic state machines.
  55. /// Also, internally it prevents recursive entries.
  56. void mmu_loop();
  57. /// The main MMU command - select a different slot
  58. /// @param index of the slot to be selected
  59. /// @returns false if the operation cannot be performed (Stopped)
  60. bool tool_change(uint8_t index);
  61. /// Handling of special Tx, Tc, T? commands
  62. bool tool_change(const char *special);
  63. /// Unload of filament in collaboration with the MMU.
  64. /// That includes rotating the printer's extruder in order to release filament.
  65. /// @returns false if the operation cannot be performed (Stopped or cold extruder)
  66. bool unload();
  67. /// Load (insert) filament just into the MMU (not into printer's nozzle)
  68. /// @returns false if the operation cannot be performed (Stopped)
  69. bool load_filament(uint8_t index);
  70. /// Load (push) filament from the MMU into the printer's nozzle
  71. /// @returns false if the operation cannot be performed (Stopped or cold extruder)
  72. bool load_filament_to_nozzle(uint8_t index);
  73. /// Move MMU's selector aside and push the selected filament forward.
  74. /// Usable for improving filament's tip or pulling the remaining piece of filament out completely.
  75. bool eject_filament(uint8_t index, bool recover);
  76. /// Issue a Cut command into the MMU
  77. /// Requires unloaded filament from the printer (obviously)
  78. /// @returns false if the operation cannot be performed (Stopped)
  79. bool cut_filament(uint8_t index);
  80. /// @returns the active filament slot index (0-4) or 0xff in case of no active tool
  81. uint8_t get_current_tool() const;
  82. bool set_filament_type(uint8_t index, uint8_t type);
  83. /// Issue a "button" click into the MMU - to be used from Error screens of the MMU
  84. /// to select one of the 3 possible options to resolve the issue
  85. void Button(uint8_t index);
  86. /// Issue an explicit "homing" command into the MMU
  87. void Home(uint8_t mode);
  88. /// @returns current state of FINDA (true=filament present, false=filament not present)
  89. inline bool FindaDetectsFilament()const { return logic.FindaPressed(); }
  90. private:
  91. /// Perform software self-reset of the MMU (sends an X0 command)
  92. void ResetX0();
  93. /// Trigger reset pin of the MMU
  94. void TriggerResetPin();
  95. /// Perform power cycle of the MMU (cold boot)
  96. /// Please note this is a blocking operation (sleeps for some time inside while doing the power cycle)
  97. void PowerCycle();
  98. /// Stop the communication, but keep the MMU powered on (for scenarios with incorrect FW version)
  99. void StopKeepPowered();
  100. /// Along with the mmu_loop method, this loops until a response from the MMU is received and acts upon.
  101. /// In case of an error, it parks the print head and turns off nozzle heating
  102. void manage_response(const bool move_axes, const bool turn_off_nozzle);
  103. /// Performs one step of the protocol logic state machine
  104. /// and reports progress and errors if needed to attached ExtUIs.
  105. /// Updates the global state of MMU (Active/Connecting/Stopped) at runtime, see @ref State
  106. StepStatus LogicStep();
  107. void filament_ramming();
  108. void execute_extruder_sequence(const E_Step *sequence, uint8_t steps);
  109. void SetActiveExtruder(uint8_t ex);
  110. /// Reports an error into attached ExtUIs
  111. /// @param ec error code, see ErrorCode
  112. void ReportError(ErrorCode ec);
  113. /// Reports progress of operations into attached ExtUIs
  114. /// @param pc progress code, see ProgressCode
  115. void ReportProgress(ProgressCode pc);
  116. /// Responds to a change of MMU's progress
  117. /// - plans additional steps, e.g. starts the E-motor after fsensor trigger
  118. void OnMMUProgressMsg(ProgressCode pc);
  119. /// Report the msg into the general logging subsystem (through Marlin's SERIAL_ECHO stuff)
  120. void LogErrorEvent(const char *msg);
  121. /// Report the msg into the general logging subsystem (through Marlin's SERIAL_ECHO stuff)
  122. void LogEchoEvent(const char *msg);
  123. /// Save print and park the print head
  124. void SaveAndPark(bool move_axes, bool turn_off_nozzle);
  125. /// Resume print (unpark, turn on heating etc.)
  126. void ResumeAndUnPark(bool move_axes, bool turn_off_nozzle);
  127. /// Check for any button/user input coming from the printer's UI
  128. void CheckUserInput();
  129. /// Entry check of all external commands.
  130. /// It can wait until the MMU becomes ready.
  131. /// Optionally, it can also emit/display an error screen and the user can decide what to do next.
  132. /// @returns false if the MMU is not ready to perform the command (for whatever reason)
  133. bool WaitForMMUReady();
  134. ProtocolLogic logic; ///< implementation of the protocol logic layer
  135. int extruder; ///< currently active slot in the MMU ... somewhat... not sure where to get it from yet
  136. xyz_pos_t resume_position;
  137. int16_t resume_hotend_temp;
  138. ProgressCode lastProgressCode = ProgressCode::OK;
  139. ErrorCode lastErrorCode = ErrorCode::MMU_NOT_RESPONDING;
  140. StepStatus logicStepLastStatus;
  141. enum xState state;
  142. bool mmu_print_saved;
  143. bool loadFilamentStarted;
  144. friend struct LoadingToNozzleRAII;
  145. /// true in case we are doing the LoadToNozzle operation - that means the filament shall be loaded all the way down to the nozzle
  146. /// unlike the mid-print ToolChange commands, which only load the first ~30mm and then the G-code takes over.
  147. bool loadingToNozzle;
  148. };
  149. /// following Marlin's way of doing stuff - one and only instance of MMU implementation in the code base
  150. /// + avoiding buggy singletons on the AVR platform
  151. extern MMU2 mmu2;
  152. } // namespace MMU2