Prusa3d Marlin fork
mmu2.h
Go to the documentation of this file.
1 #pragma once
3 
4 #include "mmu2_state.h"
5 #include "mmu2_marlin.h"
6 
7 #ifdef __AVR__
8  #include "mmu2_protocol_logic.h"
9 typedef float feedRate_t;
10 
11 #else
12  #include "protocol_logic.h"
13  #include <atomic>
14 #endif
15 
16 struct E_Step;
17 
18 namespace MMU2 {
19 
20 // general MMU setup for MK3
21 enum : uint8_t {
22  FILAMENT_UNKNOWN = 0xffU
23 };
24 
25 struct Version {
26  uint8_t major, minor, build;
27 };
28 
32 class MMU2 {
33 public:
34  MMU2();
35 
37  void Start();
38 
40  void Stop();
41 
43  void Status();
44 
45  inline xState State() const { return state; }
46 
47  inline bool Enabled() const { return State() == xState::Active; }
48 
50  enum ResetForm : uint8_t {
51  Software = 0,
52  ResetPin = 1,
53  CutThePower = 2,
54  EraseEEPROM = 42,
55  };
56 
58  enum SavedState : uint8_t {
59  None = 0, // No state saved.
60  ParkExtruder = 1, // The extruder was parked.
61  Cooldown = 2, // The extruder was allowed to cool.
62  CooldownPending = 4,
63  };
64 
66  enum ErrorSource : uint8_t {
67  ErrorSourcePrinter = 0,
68  ErrorSourceMMU = 1,
69  ErrorSourceNone = 0xFF,
70  };
71 
74  void Tune();
75 
78  void Reset(ResetForm level);
79 
81  void PowerOff();
82 
84  void PowerOn();
85 
89  bool ReadRegister(uint8_t address);
90 
95  bool WriteRegister(uint8_t address, uint16_t data);
96 
100  void mmu_loop();
101 
105  bool tool_change(uint8_t slot);
106 
108  bool tool_change(char code, uint8_t slot);
109 
113  bool unload();
114 
117  bool load_filament(uint8_t slot);
118 
121  bool load_filament_to_nozzle(uint8_t slot);
122 
125  bool eject_filament(uint8_t slot, bool enableFullScreenMsg = true);
126 
130  bool cut_filament(uint8_t slot, bool enableFullScreenMsg = true);
131 
133  void get_statistics();
134 
141  bool loading_test(uint8_t slot);
142 
144  uint8_t get_current_tool() const;
145 
147  uint8_t get_tool_change_tool() const;
148 
149  bool set_filament_type(uint8_t slot, uint8_t type);
150 
153  void Button(uint8_t index);
154 
156  void Home(uint8_t mode);
157 
159  inline bool FindaDetectsFilament() const { return logic.FindaPressed(); }
160 
161  inline uint16_t TotalFailStatistics() const { return logic.FailStatistics(); }
162 
164  inline ErrorCode MMUCurrentErrorCode() const { return logic.Error(); }
165 
167  inline uint8_t GetCommandInProgress() const { return logic.CommandInProgress(); }
168 
170  inline ErrorSource MMULastErrorSource() const { return lastErrorSource; }
171 
173  inline ErrorCode GetLastErrorCode() const { return lastErrorCode; }
174 
178  if (State() == xState::Active) {
179  return { logic.MmuFwVersionMajor(), logic.MmuFwVersionMinor(), logic.MmuFwVersionRevision() };
180  } else {
181  return { 0, 0, 0 };
182  }
183  }
184 
186  inline bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; }
187 
191  bool RetryIfPossible(ErrorCode ec);
192 
194  inline uint16_t ToolChangeCounter() const { return toolchange_counter; };
195 
197  inline void ClearToolChangeCounter() { toolchange_counter = 0; };
198 
199  inline uint16_t TMCFailures() const { return tmcFailures; }
200  inline void IncrementTMCFailures() { ++tmcFailures; }
201  inline void ClearTMCFailures() { tmcFailures = 0; }
202 
205  inline uint16_t GetLastReadRegisterValue() const {
206  return lastReadRegisterValue;
207  };
208  inline void InvokeErrorScreen(ErrorCode ec) {
209  // The printer may not raise an error when the MMU is busy
210  if (!logic.CommandInProgress() // MMU must not be busy
211  && MMUCurrentErrorCode() == ErrorCode::OK // The protocol must not be in error state
212  && lastErrorCode != ec) // The error code is not a duplicate
213  {
214  ReportError(ec, ErrorSource::ErrorSourcePrinter);
215  }
216  }
217 
218  void ClearPrinterError() {
219  logic.ClearPrinterError();
220  lastErrorCode = ErrorCode::OK;
221  lastErrorSource = ErrorSource::ErrorSourceNone;
222  }
223 
226  inline void SetPrinterButtonOperation(Buttons btn) {
227  printerButtonOperation = btn;
228  }
229 
232  inline Buttons GetPrinterButtonOperation() {
233  return printerButtonOperation;
234  }
235 
236  inline void ClearPrinterButtonOperation() {
237  printerButtonOperation = Buttons::NoButton;
238  }
239 
240 #ifndef UNITTEST
241 private:
242 #endif
244  void ResetX0();
245 
247  void ResetX42();
248 
250  void TriggerResetPin();
251 
254  void PowerCycle();
255 
257  void StopKeepPowered();
258 
262  [[nodiscard]] bool manage_response(const bool move_axes, const bool turn_off_nozzle);
263 
267  void mmu_loop_inner(bool reportErrors);
268 
273  StepStatus LogicStep(bool reportErrors);
274 
275  void filament_ramming();
276  void execute_extruder_sequence(const E_Step *sequence, uint8_t steps);
277  void execute_load_to_nozzle_sequence();
278 
282  void ReportError(ErrorCode ec, ErrorSource res);
283 
286  void ReportProgress(ProgressCode pc);
287 
295  void OnMMUProgressMsg(ProgressCode pc);
297  void OnMMUProgressMsgChanged(ProgressCode pc);
299  void OnMMUProgressMsgSame(ProgressCode pc);
300 
303  void SaveHotendTemp(bool turn_off_nozzle);
304 
306  void SaveAndPark(bool move_axes);
307 
309  void ResumeHotendTemp();
310 
312  void ResumeUnpark();
313 
315  void CheckUserInput();
316 
320  void CheckFINDARunout();
321 
326  bool WaitForMMUReady();
327 
333  bool VerifyFilamentEnteredPTFE();
334 
336  void ToolChangeCommon(uint8_t slot);
337  bool ToolChangeCommonOnce(uint8_t slot);
338 
339  void HelpUnloadToFinda();
340  void UnloadInner();
341  void CutFilamentInner(uint8_t slot);
342 
343  void SetCurrentTool(uint8_t ex);
344 
345  ProtocolLogic logic;
346  uint8_t extruder;
347  uint8_t tool_change_extruder;
348 
349  pos3d resume_position;
350  int16_t resume_hotend_temp;
351 
352  ProgressCode lastProgressCode = ProgressCode::OK;
353  ErrorCode lastErrorCode = ErrorCode::MMU_NOT_RESPONDING;
354  ErrorSource lastErrorSource = ErrorSource::ErrorSourceNone;
355  Buttons lastButton = Buttons::NoButton;
356  uint16_t lastReadRegisterValue = 0;
357  Buttons printerButtonOperation = Buttons::NoButton;
358 
359  StepStatus logicStepLastStatus;
360 
361  enum xState state;
362 
363  uint8_t mmu_print_saved;
364  bool loadFilamentStarted;
365  bool unloadFilamentStarted;
366 
367  uint16_t toolchange_counter;
368  uint16_t tmcFailures;
369 };
370 
373 extern MMU2 mmu2;
374 
375 } // namespace MMU2
ResetForm
Different levels of resetting the MMU.
Definition: mmu2.h:50
void SetPrinterButtonOperation(Buttons btn)
Queue a button operation which the printer can act upon.
Definition: mmu2.h:226
ErrorSource
Source of operation error.
Definition: mmu2.h:66
uint16_t ToolChangeCounter() const
Definition: mmu2.h:194
bool WriteRegister(uint8_t address, uint16_t data)
ErrorSource MMULastErrorSource() const
Definition: mmu2.h:170
bool FindaDetectsFilament() const
Definition: mmu2.h:159
ErrorCode GetLastErrorCode() const
Definition: mmu2.h:173
void ClearToolChangeCounter()
Set toolchange counter to zero.
Definition: mmu2.h:197
SavedState
Saved print state on error.
Definition: mmu2.h:58
uint16_t GetLastReadRegisterValue() const
Definition: mmu2.h:205
uint8_t GetCommandInProgress() const
Definition: mmu2.h:167
uint8_t get_tool_change_tool() const
bool MMU_PRINT_SAVED() const
Method to read-only mmu_print_saved.
Definition: mmu2.h:186
Buttons GetPrinterButtonOperation()
Get the printer button operation.
Definition: mmu2.h:232
Version GetMMUFWVersion() const
Definition: mmu2.h:177
uint8_t get_current_tool() const
ErrorCode MMUCurrentErrorCode() const
Definition: mmu2.h:164
New MMU2 protocol logic.
Definition: mmu2.cpp:26
xState
Definition: mmu2_state.h:15
@ Active
MMU has been detected, connected, communicates and is ready to be worked with.
MMU2 mmu2
Definition: mmu2.cpp:41
StepStatus
ProtocolLogic stepping statuses.
Definition: mmu2_protocol_logic.h:53
Definition: mmu2.h:25