Browse Source

SMUFF (MMU2 clone) support (#19912)

Giuliano Zaro 4 years ago
parent
commit
41529b6598
No account linked to committer's email address

+ 10
- 24
Marlin/Configuration.h View File

@@ -158,33 +158,19 @@
158 158
 #endif
159 159
 
160 160
 /**
161
- * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants.
162
- *
163
- * This device allows one stepper driver on a control board to drive
164
- * two to eight stepper motors, one at a time, in a manner suitable
165
- * for extruders.
166
- *
167
- * This option only allows the multiplexer to switch on tool-change.
168
- * Additional options to configure custom E moves are pending.
169
- */
170
-//#define MK2_MULTIPLEXER
171
-#if ENABLED(MK2_MULTIPLEXER)
172
-  // Override the default DIO selector pins here, if needed.
173
-  // Some pins files may provide defaults for these pins.
174
-  //#define E_MUX0_PIN 40  // Always Required
175
-  //#define E_MUX1_PIN 42  // Needed for 3 to 8 inputs
176
-  //#define E_MUX2_PIN 44  // Needed for 5 to 8 inputs
177
-#endif
178
-
179
-/**
180
- * Průša Multi-Material Unit v2
161
+ * Multi-Material Unit
162
+ * Set to one of these predefined models:
181 163
  *
182
- * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
183
- * Requires EXTRUDERS = 5
164
+ *   PRUSA_MMU1      : Průša MMU1 (The "multiplexer" version)
165
+ *   PRUSA_MMU2      : Průša MMU2
166
+ *   PRUSA_MMU2S     : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
167
+ *   SMUFF_EMU_MMU2  : Technik Gegg SMUFF (Průša MMU2 emulation mode)
168
+ *   SMUFF_EMU_MMU2S : Technik Gegg SMUFF (Průša MMU2S emulation mode)
184 169
  *
185
- * For additional configuration see Configuration_adv.h
170
+ * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
171
+ * See additional options in Configuration_adv.h.
186 172
  */
187
-//#define PRUSA_MMU2
173
+//#define MMU_MODEL PRUSA_MMU2
188 174
 
189 175
 // A dual extruder that uses a single stepper motor
190 176
 //#define SWITCHING_EXTRUDER

+ 37
- 23
Marlin/Configuration_adv.h View File

@@ -3532,11 +3532,24 @@
3532 3532
 #endif
3533 3533
 
3534 3534
 /**
3535
- * Průša Multi-Material Unit v2
3535
+ * Průša Multi-Material Unit (MMU)
3536 3536
  * Enable in Configuration.h
3537
+ *
3538
+ * These devices allow a single stepper driver on the board to drive
3539
+ * multi-material feeders with any number of stepper motors.
3537 3540
  */
3538
-#if ENABLED(PRUSA_MMU2)
3539
-
3541
+#if HAS_PRUSA_MMU1
3542
+  /**
3543
+   * This option only allows the multiplexer to switch on tool-change.
3544
+   * Additional options to configure custom E moves are pending.
3545
+   *
3546
+   * Override the default DIO selector pins here, if needed.
3547
+   * Some pins files may provide defaults for these pins.
3548
+   */
3549
+  //#define E_MUX0_PIN 40  // Always Required
3550
+  //#define E_MUX1_PIN 42  // Needed for 3 to 8 inputs
3551
+  //#define E_MUX2_PIN 44  // Needed for 5 to 8 inputs
3552
+#elif HAS_PRUSA_MMU2
3540 3553
   // Serial port used for communication with MMU2.
3541 3554
   // For AVR enable the UART port used for the MMU. (e.g., mmuSerial)
3542 3555
   // For 32-bit boards check your HAL for available serial ports. (e.g., Serial2)
@@ -3554,7 +3567,7 @@
3554 3567
 
3555 3568
   // Add an LCD menu for MMU2
3556 3569
   //#define MMU2_MENUS
3557
-  #if ENABLED(MMU2_MENUS)
3570
+  #if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S)
3558 3571
     // Settings for filament load / unload from the LCD menu.
3559 3572
     // This is for Průša MK3-style extruders. Customize for your hardware.
3560 3573
     #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
@@ -3580,28 +3593,11 @@
3580 3593
   #endif
3581 3594
 
3582 3595
   /**
3583
-   * MMU Extruder Sensor
3584
-   *
3585
-   * Support for a Průša (or other) IR Sensor to detect filament near the extruder
3586
-   * and make loading more reliable. Suitable for an extruder equipped with a filament
3587
-   * sensor less than 38mm from the gears.
3588
-   *
3589
-   * During loading the extruder will stop when the sensor is triggered, then do a last
3590
-   * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
3591
-   * If all attempts fail, a filament runout will be triggered.
3592
-   */
3593
-  //#define MMU_EXTRUDER_SENSOR
3594
-  #if ENABLED(MMU_EXTRUDER_SENSOR)
3595
-    #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
3596
-  #endif
3597
-
3598
-  /**
3599 3596
    * Using a sensor like the MMU2S
3600 3597
    * This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S.
3601 3598
    * See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11
3602 3599
    */
3603
-  //#define PRUSA_MMU2_S_MODE
3604
-  #if ENABLED(PRUSA_MMU2_S_MODE)
3600
+  #if HAS_PRUSA_MMU2S
3605 3601
     #define MMU2_C0_RETRY   5             // Number of retries (total time = timeout*retries)
3606 3602
 
3607 3603
     #define MMU2_CAN_LOAD_FEEDRATE 800    // (mm/min)
@@ -3617,11 +3613,29 @@
3617 3613
     #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \
3618 3614
       { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE }
3619 3615
 
3616
+  #else
3617
+
3618
+    /**
3619
+     * MMU1 Extruder Sensor
3620
+     *
3621
+     * Support for a Průša (or other) IR Sensor to detect filament near the extruder
3622
+     * and make loading more reliable. Suitable for an extruder equipped with a filament
3623
+     * sensor less than 38mm from the gears.
3624
+     *
3625
+     * During loading the extruder will stop when the sensor is triggered, then do a last
3626
+     * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
3627
+     * If all attempts fail, a filament runout will be triggered.
3628
+     */
3629
+    //#define MMU_EXTRUDER_SENSOR
3630
+    #if ENABLED(MMU_EXTRUDER_SENSOR)
3631
+      #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
3632
+    #endif
3633
+
3620 3634
   #endif
3621 3635
 
3622 3636
   //#define MMU2_DEBUG  // Write debug info to serial output
3623 3637
 
3624
-#endif // PRUSA_MMU2
3638
+#endif // HAS_PRUSA_MMU2
3625 3639
 
3626 3640
 /**
3627 3641
  * Advanced Print Counter settings

+ 2
- 2
Marlin/src/HAL/LPC1768/inc/SanityCheck.h View File

@@ -97,8 +97,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
97 97
   #define IS_RX0(P) (P == P0_03)
98 98
   #if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
99 99
     #error "Serial port pins (0) conflict with Trinamic SPI pins!"
100
-  #elif ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
101
-    #error "Serial port pins (0) conflict with MK2 multiplexer pins!"
100
+  #elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
101
+    #error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!"
102 102
   #elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN))
103 103
     #error "Serial port pins (0) conflict with X/Y axis SPI pins!"
104 104
   #endif

+ 9
- 12
Marlin/src/MarlinCore.cpp View File

@@ -213,8 +213,8 @@
213 213
   #include "feature/controllerfan.h"
214 214
 #endif
215 215
 
216
-#if ENABLED(PRUSA_MMU2)
217
-  #include "feature/mmu2/mmu2.h"
216
+#if HAS_PRUSA_MMU2
217
+  #include "feature/mmu/mmu2.h"
218 218
 #endif
219 219
 
220 220
 #if HAS_L64XX
@@ -713,9 +713,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
713 713
   TERN_(HAS_FILAMENT_SENSOR, runout.run());
714 714
 
715 715
   // Run HAL idle tasks
716
-  #ifdef HAL_IDLETASK
717
-    HAL_idletask();
718
-  #endif
716
+  TERN_(HAL_IDLETASK, HAL_idletask());
719 717
 
720 718
   // Check network connection
721 719
   TERN_(HAS_ETHERNET, ethernet.check());
@@ -772,7 +770,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
772 770
   #endif
773 771
 
774 772
   // Update the Průša MMU2
775
-  TERN_(PRUSA_MMU2, mmu2.mmu_loop());
773
+  TERN_(HAS_PRUSA_MMU2, mmu2.mmu_loop());
776 774
 
777 775
   // Handle Joystick jogging
778 776
   TERN_(POLL_JOG, joystick.inject_jog_moves());
@@ -780,9 +778,8 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
780 778
   // Direct Stepping
781 779
   TERN_(DIRECT_STEPPING, page_manager.write_responses());
782 780
 
783
-  #if HAS_TFT_LVGL_UI
784
-    LV_TASK_HANDLER();
785
-  #endif
781
+  // Update the LVGL interface
782
+  TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER());
786 783
 }
787 784
 
788 785
 /**
@@ -1187,8 +1184,8 @@ void setup() {
1187 1184
     SETUP_RUN(caselight.update_brightness());
1188 1185
   #endif
1189 1186
 
1190
-  #if ENABLED(MK2_MULTIPLEXER)
1191
-    SETUP_LOG("MK2_MULTIPLEXER");
1187
+  #if HAS_PRUSA_MMU1
1188
+    SETUP_LOG("Prusa MMU1");
1192 1189
     SET_OUTPUT(E_MUX0_PIN);
1193 1190
     SET_OUTPUT(E_MUX1_PIN);
1194 1191
     SET_OUTPUT(E_MUX2_PIN);
@@ -1268,7 +1265,7 @@ void setup() {
1268 1265
     SETUP_RUN(test_tmc_connection(true, true, true, true));
1269 1266
   #endif
1270 1267
 
1271
-  #if ENABLED(PRUSA_MMU2)
1268
+  #if HAS_PRUSA_MMU2
1272 1269
     SETUP_RUN(mmu2.init());
1273 1270
   #endif
1274 1271
 

Marlin/src/feature/snmm.cpp → Marlin/src/feature/mmu/mmu.cpp View File

@@ -22,7 +22,7 @@
22 22
 
23 23
 #include "../inc/MarlinConfig.h"
24 24
 
25
-#if ENABLED(MK2_MULTIPLEXER)
25
+#if HAS_PRUSA_MMU1
26 26
 
27 27
 #include "../module/stepper.h"
28 28
 
@@ -35,4 +35,4 @@ void select_multiplexed_stepper(const uint8_t e) {
35 35
   safe_delay(100);
36 36
 }
37 37
 
38
-#endif // MK2_MULTIPLEXER
38
+#endif // HAS_PRUSA_MMU1

Marlin/src/feature/snmm.h → Marlin/src/feature/mmu/mmu.h View File


Marlin/src/feature/mmu2/serial-protocol.md → Marlin/src/feature/mmu/mmu2-serial-protocol.md View File


Marlin/src/feature/mmu2/mmu2.cpp → Marlin/src/feature/mmu/mmu2.cpp View File

@@ -22,7 +22,7 @@
22 22
 
23 23
 #include "../../inc/MarlinConfig.h"
24 24
 
25
-#if ENABLED(PRUSA_MMU2)
25
+#if HAS_PRUSA_MMU2
26 26
 
27 27
 #include "mmu2.h"
28 28
 #include "../../lcd/menu/menu_mmu2.h"
@@ -94,7 +94,7 @@ MMU2 mmu2;
94 94
 #define mmuSerial   MMU2_SERIAL
95 95
 
96 96
 bool MMU2::enabled, MMU2::ready, MMU2::mmu_print_saved;
97
-#if ENABLED(PRUSA_MMU2_S_MODE)
97
+#if HAS_PRUSA_MMU2S
98 98
   bool MMU2::mmu2s_triggered;
99 99
 #endif
100 100
 uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder;
@@ -105,23 +105,19 @@ int16_t MMU2::version = -1, MMU2::buildnr = -1;
105 105
 millis_t MMU2::prev_request, MMU2::prev_P0_request;
106 106
 char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
107 107
 
108
-#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
109
-
110
-  struct E_Step {
111
-    float extrude;        //!< extrude distance in mm
112
-    feedRate_t feedRate;  //!< feed rate in mm/s
113
-  };
114
-
115
-  static constexpr E_Step
116
-      ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
117
-    , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
118
-    #if ENABLED(PRUSA_MMU2_S_MODE)
119
-      , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
120
-      , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
121
-    #endif
122
-  ;
123
-
124
-#endif // MMU2_MENUS
108
+struct E_Step {
109
+  float extrude;        //!< extrude distance in mm
110
+  feedRate_t feedRate;  //!< feed rate in mm/s
111
+};
112
+
113
+static constexpr E_Step
114
+    ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
115
+  , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
116
+  #if HAS_PRUSA_MMU2S
117
+    , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
118
+    , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
119
+  #endif
120
+;
125 121
 
126 122
 MMU2::MMU2() {
127 123
   rx_buffer[0] = '\0';
@@ -162,7 +158,7 @@ uint8_t MMU2::get_current_tool() {
162 158
   return extruder == MMU2_NO_TOOL ? -1 : extruder;
163 159
 }
164 160
 
165
-#if EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR)
161
+#if EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR)
166 162
   #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE)
167 163
 #endif
168 164
 
@@ -188,7 +184,7 @@ void MMU2::mmu_loop() {
188 184
 
189 185
     case -2:
190 186
       if (rx_ok()) {
191
-        sscanf(rx_buffer, "%uok\n", &version);
187
+        sscanf(rx_buffer, "%huok\n", &version);
192 188
 
193 189
         DEBUG_ECHOLNPAIR("MMU => ", version, "\nMMU <= 'S2'");
194 190
 
@@ -199,7 +195,7 @@ void MMU2::mmu_loop() {
199 195
 
200 196
     case -3:
201 197
       if (rx_ok()) {
202
-        sscanf(rx_buffer, "%uok\n", &buildnr);
198
+        sscanf(rx_buffer, "%huok\n", &buildnr);
203 199
 
204 200
         DEBUG_ECHOLNPAIR("MMU => ", buildnr);
205 201
 
@@ -242,7 +238,7 @@ void MMU2::mmu_loop() {
242 238
 
243 239
         enabled = true;
244 240
         state = 1;
245
-        TERN_(PRUSA_MMU2_S_MODE, mmu2s_triggered = false);
241
+        TERN_(HAS_PRUSA_MMU2S, mmu2s_triggered = false);
246 242
       }
247 243
       break;
248 244
 
@@ -307,7 +303,7 @@ void MMU2::mmu_loop() {
307 303
         state = 2; // wait for response
308 304
       }
309 305
 
310
-      TERN_(PRUSA_MMU2_S_MODE, check_filament());
306
+      TERN_(HAS_PRUSA_MMU2S, check_filament());
311 307
       break;
312 308
 
313 309
     case 2:   // response to command P0
@@ -324,7 +320,7 @@ void MMU2::mmu_loop() {
324 320
       else if (ELAPSED(millis(), prev_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
325 321
         state = 1;
326 322
 
327
-      TERN_(PRUSA_MMU2_S_MODE, check_filament());
323
+      TERN_(HAS_PRUSA_MMU2S, check_filament());
328 324
       break;
329 325
 
330 326
     case 3:   // response to mmu commands
@@ -340,9 +336,9 @@ void MMU2::mmu_loop() {
340 336
       #endif
341 337
 
342 338
       if (rx_ok()) {
343
-        // Response to C0 mmu command in PRUSA_MMU2_S_MODE
339
+        // Response to C0 mmu command in MMU2S model
344 340
         bool can_reset = true;
345
-        #if ENABLED(PRUSA_MMU2_S_MODE)
341
+        #if HAS_PRUSA_MMU2S
346 342
           if (!mmu2s_triggered && last_cmd == MMU_CMD_C0) {
347 343
             can_reset = false;
348 344
             // MMU ok received but filament sensor not triggered, retrying...
@@ -367,7 +363,7 @@ void MMU2::mmu_loop() {
367 363
         }
368 364
         state = 1;
369 365
       }
370
-      TERN_(PRUSA_MMU2_S_MODE, check_filament());
366
+      TERN_(HAS_PRUSA_MMU2S, check_filament());
371 367
       break;
372 368
   }
373 369
 }
@@ -487,7 +483,7 @@ static void mmu2_not_responding() {
487 483
   BUZZ(100, 659);
488 484
 }
489 485
 
490
-#if ENABLED(PRUSA_MMU2_S_MODE)
486
+#if HAS_PRUSA_MMU2S
491 487
 
492 488
   bool MMU2::load_to_gears() {
493 489
     command(MMU_CMD_C0);
@@ -541,33 +537,38 @@ static void mmu2_not_responding() {
541 537
    * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
542 538
    */
543 539
   void MMU2::tool_change(const char* special) {
544
-
545
-    if (!enabled) return;
546
-
547
-    #if ENABLED(MMU2_MENUS)
540
+      if (!enabled) return;
548 541
 
549 542
       set_runout_valid(false);
550 543
 
551 544
       switch (*special) {
552 545
         case '?': {
553
-          uint8_t index = mmu2_choose_filament();
554
-          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
555
-          load_filament_to_nozzle(index);
546
+          #if ENABLED(MMU2_MENUS)
547
+            const uint8_t index = mmu2_choose_filament();
548
+            while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
549
+            load_filament_to_nozzle(index);
550
+          #else
551
+            BUZZ(400, 40);
552
+          #endif
556 553
         } break;
557 554
 
558 555
         case 'x': {
559
-          planner.synchronize();
560
-          uint8_t index = mmu2_choose_filament();
561
-          DISABLE_AXIS_E0();
562
-          command(MMU_CMD_T0 + index);
563
-          manage_response(true, true);
564
-
565
-          if (load_to_gears()) {
566
-            mmu_loop();
567
-            ENABLE_AXIS_E0();
568
-            extruder = index;
569
-            active_extruder = 0;
570
-          }
556
+          #if ENABLED(MMU2_MENUS)
557
+            planner.synchronize();
558
+            const uint8_t index = mmu2_choose_filament();
559
+            DISABLE_AXIS_E0();
560
+            command(MMU_CMD_T0 + index);
561
+            manage_response(true, true);
562
+
563
+            if (load_to_gears()) {
564
+              mmu_loop();
565
+              ENABLE_AXIS_E0();
566
+              extruder = index;
567
+              active_extruder = 0;
568
+            }
569
+          #else
570
+            BUZZ(400, 40);
571
+          #endif
571 572
         } break;
572 573
 
573 574
         case 'c': {
@@ -577,8 +578,6 @@ static void mmu2_not_responding() {
577 578
       }
578 579
 
579 580
       set_runout_valid(true);
580
-
581
-    #endif // MMU2_MENUS
582 581
   }
583 582
 
584 583
 #elif ENABLED(MMU_EXTRUDER_SENSOR)
@@ -628,20 +627,23 @@ static void mmu2_not_responding() {
628 627
   void MMU2::tool_change(const char* special) {
629 628
     if (!enabled) return;
630 629
 
631
-    #if ENABLED(MMU2_MENUS)
632
-
633
-      set_runout_valid(false);
630
+    set_runout_valid(false);
634 631
 
635
-      switch (*special) {
636
-        case '?': {
637
-          DEBUG_ECHOLNPGM("case ?\n");
632
+    switch (*special) {
633
+      case '?': {
634
+        DEBUG_ECHOLNPGM("case ?\n");
635
+        #if ENABLED(MMU2_MENUS)
638 636
           uint8_t index = mmu2_choose_filament();
639 637
           while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
640 638
           load_filament_to_nozzle(index);
641
-        } break;
639
+        #else
640
+          BUZZ(400, 40);
641
+        #endif
642
+      } break;
642 643
 
643
-        case 'x': {
644
-          DEBUG_ECHOLNPGM("case x\n");
644
+      case 'x': {
645
+        DEBUG_ECHOLNPGM("case x\n");
646
+        #if ENABLED(MMU2_MENUS)
645 647
           planner.synchronize();
646 648
           uint8_t index = mmu2_choose_filament();
647 649
           DISABLE_AXIS_E0();
@@ -654,18 +656,19 @@ static void mmu2_not_responding() {
654 656
           ENABLE_AXIS_E0();
655 657
           extruder = index;
656 658
           active_extruder = 0;
657
-        } break;
658
-
659
-        case 'c': {
660
-          DEBUG_ECHOLNPGM("case c\n");
661
-          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
662
-          execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
663
-        } break;
664
-      }
659
+        #else
660
+          BUZZ(400, 40);
661
+        #endif
662
+      } break;
665 663
 
666
-      set_runout_valid(true);
664
+      case 'c': {
665
+        DEBUG_ECHOLNPGM("case c\n");
666
+        while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
667
+        execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
668
+      } break;
669
+    }
667 670
 
668
-    #endif // MMU2_MENUS
671
+    set_runout_valid(true);
669 672
   }
670 673
 
671 674
   void MMU2::mmu_continue_loading() {
@@ -682,68 +685,74 @@ static void mmu2_not_responding() {
682 685
     mmu_idl_sens = 0;
683 686
   }
684 687
 
685
-#elif DISABLED(MMU_EXTRUDER_SENSOR) && DISABLED(PRUSA_MMU2_S_MODE)
688
+#else // !HAS_PRUSA_MMU2S && !MMU_EXTRUDER_SENSOR
686 689
 
687
-/**
688
- * Handle tool change
689
- */
690
-void MMU2::tool_change(const uint8_t index) {
691
-  if (!enabled) return;
692
-
693
-  set_runout_valid(false);
690
+  /**
691
+   * Handle tool change
692
+   */
693
+  void MMU2::tool_change(const uint8_t index) {
694
+    if (!enabled) return;
694 695
 
695
-  if (index != extruder) {
696
-    DISABLE_AXIS_E0();
697
-    ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
698
-    command(MMU_CMD_T0 + index);
699
-    manage_response(true, true);
700
-    command(MMU_CMD_C0);
701
-    extruder = index; //filament change is finished
702
-    active_extruder = 0;
703
-    ENABLE_AXIS_E0();
704
-    SERIAL_ECHO_START();
705
-    SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
706
-    ui.reset_status();
707
-  }
696
+    set_runout_valid(false);
708 697
 
709
-  set_runout_valid(true);
710
-}
698
+    if (index != extruder) {
699
+      DISABLE_AXIS_E0();
700
+      ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
701
+      command(MMU_CMD_T0 + index);
702
+      manage_response(true, true);
703
+      command(MMU_CMD_C0);
704
+      extruder = index; //filament change is finished
705
+      active_extruder = 0;
706
+      ENABLE_AXIS_E0();
707
+      SERIAL_ECHO_START();
708
+      SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
709
+      ui.reset_status();
710
+    }
711 711
 
712
-/**
713
- * Handle special T?/Tx/Tc commands
714
- *
715
- * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically
716
- * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
717
- * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
718
- */
719
-void MMU2::tool_change(const char* special) {
720
-  if (!enabled) return;
712
+    set_runout_valid(true);
713
+  }
721 714
 
722
-  #if ENABLED(MMU2_MENUS)
715
+  /**
716
+   * Handle special T?/Tx/Tc commands
717
+   *
718
+   * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically
719
+   * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
720
+   * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
721
+   */
722
+  void MMU2::tool_change(const char* special) {
723
+    if (!enabled) return;
723 724
 
724 725
     set_runout_valid(false);
725 726
 
726 727
     switch (*special) {
727 728
       case '?': {
728 729
         DEBUG_ECHOLNPGM("case ?\n");
729
-        uint8_t index = mmu2_choose_filament();
730
-        while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
731
-        load_filament_to_nozzle(index);
730
+        #if ENABLED(MMU2_MENUS)
731
+          uint8_t index = mmu2_choose_filament();
732
+          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
733
+          load_filament_to_nozzle(index);
734
+        #else
735
+          BUZZ(400, 40);
736
+        #endif
732 737
       } break;
733 738
 
734 739
       case 'x': {
735 740
         DEBUG_ECHOLNPGM("case x\n");
736
-        planner.synchronize();
737
-        uint8_t index = mmu2_choose_filament();
738
-        DISABLE_AXIS_E0();
739
-        command(MMU_CMD_T0 + index);
740
-        manage_response(true, true);
741
-        command(MMU_CMD_C0);
742
-        mmu_loop();
741
+        #if ENABLED(MMU2_MENUS)
742
+          planner.synchronize();
743
+          uint8_t index = mmu2_choose_filament();
744
+          DISABLE_AXIS_E0();
745
+          command(MMU_CMD_T0 + index);
746
+          manage_response(true, true);
747
+          command(MMU_CMD_C0);
748
+          mmu_loop();
743 749
 
744
-        ENABLE_AXIS_E0();
745
-        extruder = index;
746
-        active_extruder = 0;
750
+          ENABLE_AXIS_E0();
751
+          extruder = index;
752
+          active_extruder = 0;
753
+        #else
754
+          BUZZ(400, 40);
755
+        #endif
747 756
       } break;
748 757
 
749 758
       case 'c': {
@@ -754,11 +763,9 @@ void MMU2::tool_change(const char* special) {
754 763
     }
755 764
 
756 765
     set_runout_valid(true);
757
-
758
-  #endif
759 766
   }
760 767
 
761
-#endif // MMU_EXTRUDER_SENSOR
768
+#endif // HAS_PRUSA_MMU2S
762 769
 
763 770
 /**
764 771
  * Set next command
@@ -866,7 +873,7 @@ void MMU2::filament_runout() {
866 873
   planner.synchronize();
867 874
 }
868 875
 
869
-#if ENABLED(PRUSA_MMU2_S_MODE)
876
+#if HAS_PRUSA_MMU2S
870 877
 
871 878
   void MMU2::check_filament() {
872 879
     const bool present = FILAMENT_PRESENT();
@@ -907,162 +914,159 @@ void MMU2::filament_runout() {
907 914
     DEBUG_ECHOLNPGM(" succeeded.");
908 915
     return true;
909 916
   }
917
+
910 918
 #endif
911 919
 
912
-#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
920
+// Load filament into MMU2
921
+void MMU2::load_filament(const uint8_t index) {
922
+  if (!enabled) return;
923
+  command(MMU_CMD_L0 + index);
924
+  manage_response(false, false);
925
+  BUZZ(200, 404);
926
+}
913 927
 
914
-  // Load filament into MMU2
915
-  void MMU2::load_filament(const uint8_t index) {
916
-    if (!enabled) return;
917
-    command(MMU_CMD_L0 + index);
918
-    manage_response(false, false);
928
+/**
929
+ * Switch material and load to nozzle
930
+ */
931
+bool MMU2::load_filament_to_nozzle(const uint8_t index) {
932
+
933
+  if (!enabled) return false;
934
+
935
+  if (thermalManager.tooColdToExtrude(active_extruder)) {
919 936
     BUZZ(200, 404);
937
+    LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
938
+    return false;
920 939
   }
921 940
 
922
-  /**
923
-   * Switch material and load to nozzle
924
-   */
925
-  bool MMU2::load_filament_to_nozzle(const uint8_t index) {
941
+  command(MMU_CMD_T0 + index);
942
+  manage_response(true, true);
926 943
 
927
-    if (!enabled) return false;
944
+  const bool success = load_to_gears();
945
+  if (success) {
946
+    mmu_loop();
947
+    extruder = index;
948
+    active_extruder = 0;
949
+    load_to_nozzle();
950
+    BUZZ(200, 404);
951
+  }
952
+  return success;
953
+}
928 954
 
929
-    if (thermalManager.tooColdToExtrude(active_extruder)) {
930
-      BUZZ(200, 404);
931
-      LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
932
-      return false;
933
-    }
955
+/**
956
+ * Load filament to nozzle of multimaterial printer
957
+ *
958
+ * This function is used only only after T? (user select filament) and M600 (change filament).
959
+ * It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
960
+ * filament to nozzle.
961
+ */
962
+void MMU2::load_to_nozzle() {
963
+  if (!enabled) return;
964
+  execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
965
+}
934 966
 
935
-    command(MMU_CMD_T0 + index);
936
-    manage_response(true, true);
967
+bool MMU2::eject_filament(const uint8_t index, const bool recover) {
937 968
 
938
-    const bool success = load_to_gears();
939
-    if (success) {
940
-      mmu_loop();
941
-      extruder = index;
942
-      active_extruder = 0;
943
-      load_to_nozzle();
944
-      BUZZ(200, 404);
945
-    }
946
-    return success;
947
-  }
969
+  if (!enabled) return false;
948 970
 
949
-  /**
950
-   * Load filament to nozzle of multimaterial printer
951
-   *
952
-   * This function is used only only after T? (user select filament) and M600 (change filament).
953
-   * It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
954
-   * filament to nozzle.
955
-   */
956
-  void MMU2::load_to_nozzle() {
957
-    if (!enabled) return;
958
-    execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
971
+  if (thermalManager.tooColdToExtrude(active_extruder)) {
972
+    BUZZ(200, 404);
973
+    LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
974
+    return false;
959 975
   }
960 976
 
961
-  bool MMU2::eject_filament(const uint8_t index, const bool recover) {
977
+  LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
962 978
 
963
-    if (!enabled) return false;
964
-
965
-    if (thermalManager.tooColdToExtrude(active_extruder)) {
966
-      BUZZ(200, 404);
967
-      LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
968
-      return false;
969
-    }
979
+  ENABLE_AXIS_E0();
980
+  current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
981
+  line_to_current_position(MMM_TO_MMS(2500));
982
+  planner.synchronize();
983
+  command(MMU_CMD_E0 + index);
984
+  manage_response(false, false);
970 985
 
971
-    LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
986
+  if (recover)  {
987
+    LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
988
+    BUZZ(200, 404);
989
+    TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR));
990
+    TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")));
991
+    wait_for_user_response();
992
+    BUZZ(200, 404);
993
+    BUZZ(200, 404);
972 994
 
973
-    ENABLE_AXIS_E0();
974
-    current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
975
-    line_to_current_position(2500 / 60);
976
-    planner.synchronize();
977
-    command(MMU_CMD_E0 + index);
995
+    command(MMU_CMD_R0);
978 996
     manage_response(false, false);
997
+  }
979 998
 
980
-    if (recover)  {
981
-      LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
982
-      BUZZ(200, 404);
983
-      TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR));
984
-      TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")));
985
-      wait_for_user_response();
986
-      BUZZ(200, 404);
987
-      BUZZ(200, 404);
988
-
989
-      command(MMU_CMD_R0);
990
-      manage_response(false, false);
991
-    }
992
-
993
-    ui.reset_status();
999
+  ui.reset_status();
994 1000
 
995
-    // no active tool
996
-    extruder = MMU2_NO_TOOL;
1001
+  // no active tool
1002
+  extruder = MMU2_NO_TOOL;
997 1003
 
998
-    set_runout_valid(false);
1004
+  set_runout_valid(false);
999 1005
 
1000
-    BUZZ(200, 404);
1006
+  BUZZ(200, 404);
1001 1007
 
1002
-    DISABLE_AXIS_E0();
1008
+  DISABLE_AXIS_E0();
1003 1009
 
1004
-    return true;
1005
-  }
1010
+  return true;
1011
+}
1006 1012
 
1007
-  /**
1008
-   * Unload from hotend and retract to MMU
1009
-   */
1010
-  bool MMU2::unload() {
1013
+/**
1014
+ * Unload from hotend and retract to MMU
1015
+ */
1016
+bool MMU2::unload() {
1011 1017
 
1012
-    if (!enabled) return false;
1018
+  if (!enabled) return false;
1013 1019
 
1014
-    if (thermalManager.tooColdToExtrude(active_extruder)) {
1015
-      BUZZ(200, 404);
1016
-      LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
1017
-      return false;
1018
-    }
1019
-
1020
-    filament_ramming();
1020
+  if (thermalManager.tooColdToExtrude(active_extruder)) {
1021
+    BUZZ(200, 404);
1022
+    LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
1023
+    return false;
1024
+  }
1021 1025
 
1022
-    command(MMU_CMD_U0);
1023
-    manage_response(false, true);
1026
+  filament_ramming();
1024 1027
 
1025
-    BUZZ(200, 404);
1028
+  command(MMU_CMD_U0);
1029
+  manage_response(false, true);
1026 1030
 
1027
-    // no active tool
1028
-    extruder = MMU2_NO_TOOL;
1031
+  BUZZ(200, 404);
1029 1032
 
1030
-    set_runout_valid(false);
1033
+  // no active tool
1034
+  extruder = MMU2_NO_TOOL;
1031 1035
 
1032
-    return true;
1033
-  }
1036
+  set_runout_valid(false);
1034 1037
 
1035
-  /**
1036
-   * Unload sequence to optimize shape of the tip of the unloaded filament
1037
-   */
1038
-  void MMU2::filament_ramming() {
1039
-    execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step));
1040
-  }
1038
+  return true;
1039
+}
1041 1040
 
1042
-  void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
1041
+/**
1042
+ * Unload sequence to optimize shape of the tip of the unloaded filament
1043
+ */
1044
+void MMU2::filament_ramming() {
1045
+  execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step));
1046
+}
1043 1047
 
1044
-    planner.synchronize();
1045
-    ENABLE_AXIS_E0();
1048
+void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
1046 1049
 
1047
-    const E_Step* step = sequence;
1050
+  planner.synchronize();
1051
+  ENABLE_AXIS_E0();
1048 1052
 
1049
-    LOOP_L_N(i, steps) {
1050
-      const float es = pgm_read_float(&(step->extrude));
1051
-      const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
1053
+  const E_Step* step = sequence;
1052 1054
 
1053
-      DEBUG_ECHO_START();
1054
-      DEBUG_ECHOLNPAIR("E step ", es, "/", fr_mm_m);
1055
+  LOOP_L_N(i, steps) {
1056
+    const float es = pgm_read_float(&(step->extrude));
1057
+    const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
1055 1058
 
1056
-      current_position.e += es;
1057
-      line_to_current_position(MMM_TO_MMS(fr_mm_m));
1058
-      planner.synchronize();
1059
+    DEBUG_ECHO_START();
1060
+    DEBUG_ECHOLNPAIR("E step ", es, "/", fr_mm_m);
1059 1061
 
1060
-      step++;
1061
-    }
1062
+    current_position.e += es;
1063
+    line_to_current_position(MMM_TO_MMS(fr_mm_m));
1064
+    planner.synchronize();
1062 1065
 
1063
-    DISABLE_AXIS_E0();
1066
+    step++;
1064 1067
   }
1065 1068
 
1066
-#endif // HAS_LCD_MENU && MMU2_MENUS
1069
+  DISABLE_AXIS_E0();
1070
+}
1067 1071
 
1068
-#endif // PRUSA_MMU2
1072
+#endif // HAS_PRUSA_MMU2

Marlin/src/feature/mmu2/mmu2.h → Marlin/src/feature/mmu/mmu2.h View File

@@ -49,13 +49,11 @@ public:
49 49
   static uint8_t get_current_tool();
50 50
   static void set_filament_type(const uint8_t index, const uint8_t type);
51 51
 
52
-  #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
53
-    static bool unload();
54
-    static void load_filament(uint8_t);
55
-    static void load_all();
56
-    static bool load_filament_to_nozzle(const uint8_t index);
57
-    static bool eject_filament(const uint8_t index, const bool recover);
58
-  #endif
52
+  static bool unload();
53
+  static void load_filament(uint8_t);
54
+  static void load_all();
55
+  static bool load_filament_to_nozzle(const uint8_t index);
56
+  static bool eject_filament(const uint8_t index, const bool recover);
59 57
 
60 58
 private:
61 59
   static bool rx_str_P(const char* str);
@@ -72,15 +70,13 @@ private:
72 70
   static bool get_response();
73 71
   static void manage_response(const bool move_axes, const bool turn_off_nozzle);
74 72
 
75
-  #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
76
-    static void load_to_nozzle();
77
-    static void filament_ramming();
78
-    static void execute_extruder_sequence(const E_Step * sequence, int steps);
79
-  #endif
73
+  static void load_to_nozzle();
74
+  static void filament_ramming();
75
+  static void execute_extruder_sequence(const E_Step * sequence, int steps);
80 76
 
81 77
   static void filament_runout();
82 78
 
83
-  #if ENABLED(PRUSA_MMU2_S_MODE)
79
+  #if HAS_PRUSA_MMU2S
84 80
     static bool mmu2s_triggered;
85 81
     static void check_filament();
86 82
     static bool can_load();

+ 2
- 2
Marlin/src/gcode/config/M220.cpp View File

@@ -31,13 +31,13 @@
31 31
  *
32 32
  * Report the current speed percentage factor if no parameter is specified
33 33
  *
34
- * With PRUSA_MMU2...
34
+ * For MMU2 and MMU2S devices...
35 35
  *   B : Flag to back up the current factor
36 36
  *   R : Flag to restore the last-saved factor
37 37
  */
38 38
 void GcodeSuite::M220() {
39 39
 
40
-  #if ENABLED(PRUSA_MMU2)
40
+  #if HAS_PRUSA_MMU2
41 41
     static int16_t backup_feedrate_percentage = 100;
42 42
     if (parser.seen('B')) backup_feedrate_percentage = feedrate_percentage;
43 43
     if (parser.seen('R')) feedrate_percentage = backup_feedrate_percentage;

+ 4
- 4
Marlin/src/gcode/control/T.cpp View File

@@ -27,8 +27,8 @@
27 27
   #include "../../module/motion.h"
28 28
 #endif
29 29
 
30
-#if ENABLED(PRUSA_MMU2)
31
-  #include "../../feature/mmu2/mmu2.h"
30
+#if HAS_PRUSA_MMU2
31
+  #include "../../feature/mmu/mmu2.h"
32 32
 #endif
33 33
 
34 34
 #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
@@ -40,7 +40,7 @@
40 40
  *   F[units/min] Set the movement feedrate
41 41
  *   S1           Don't move the tool in XY after change
42 42
  *
43
- * For PRUSA_MMU2:
43
+ * For PRUSA_MMU2(S) and SMUFF_EMU_MMU2(S)
44 44
  *   T[n] Gcode to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
45 45
  *   T?   Gcode to extrude shouldn't have to follow. Load to extruder wheels is done automatically.
46 46
  *   Tx   Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load.
@@ -54,7 +54,7 @@ void GcodeSuite::T(const int8_t tool_index) {
54 54
   // Count this command as movement / activity
55 55
   reset_stepper_timeout();
56 56
 
57
-  #if ENABLED(PRUSA_MMU2)
57
+  #if HAS_PRUSA_MMU2
58 58
     if (parser.string_arg) {
59 59
       mmu2.tool_change(parser.string_arg);   // Special commands T?/Tx/Tc
60 60
       return;

+ 8
- 8
Marlin/src/gcode/feature/pause/M701_M702.cpp View File

@@ -38,8 +38,8 @@
38 38
   #include "../../../lcd/marlinui.h"
39 39
 #endif
40 40
 
41
-#if ENABLED(PRUSA_MMU2)
42
-  #include "../../../feature/mmu2/mmu2.h"
41
+#if HAS_PRUSA_MMU2
42
+  #include "../../../feature/mmu/mmu2.h"
43 43
 #endif
44 44
 
45 45
 #if ENABLED(MIXING_EXTRUDER)
@@ -86,7 +86,7 @@ void GcodeSuite::M701() {
86 86
   // Show initial "wait for load" message
87 87
   TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_LOAD, PAUSE_MODE_LOAD_FILAMENT, target_extruder));
88 88
 
89
-  #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2)
89
+  #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
90 90
     // Change toolhead if specified
91 91
     uint8_t active_extruder_before_filament_change = active_extruder;
92 92
     if (active_extruder != target_extruder)
@@ -98,7 +98,7 @@ void GcodeSuite::M701() {
98 98
     do_blocking_move_to_z(_MIN(current_position.z + park_point.z, Z_MAX_POS), feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
99 99
 
100 100
   // Load filament
101
-  #if ENABLED(PRUSA_MMU2)
101
+  #if HAS_PRUSA_MMU2
102 102
     mmu2.load_filament_to_nozzle(target_extruder);
103 103
   #else
104 104
     constexpr float     purge_length = ADVANCED_PAUSE_PURGE_LENGTH,
@@ -121,7 +121,7 @@ void GcodeSuite::M701() {
121 121
   if (park_point.z > 0)
122 122
     do_blocking_move_to_z(_MAX(current_position.z - park_point.z, 0), feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
123 123
 
124
-  #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2)
124
+  #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
125 125
     // Restore toolhead if it was changed
126 126
     if (active_extruder_before_filament_change != active_extruder)
127 127
       tool_change(active_extruder_before_filament_change, false);
@@ -186,7 +186,7 @@ void GcodeSuite::M702() {
186 186
   // Show initial "wait for unload" message
187 187
   TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_UNLOAD, PAUSE_MODE_UNLOAD_FILAMENT, target_extruder));
188 188
 
189
-  #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2)
189
+  #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
190 190
     // Change toolhead if specified
191 191
     uint8_t active_extruder_before_filament_change = active_extruder;
192 192
     if (active_extruder != target_extruder)
@@ -198,7 +198,7 @@ void GcodeSuite::M702() {
198 198
     do_blocking_move_to_z(_MIN(current_position.z + park_point.z, Z_MAX_POS), feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
199 199
 
200 200
   // Unload filament
201
-  #if ENABLED(PRUSA_MMU2)
201
+  #if HAS_PRUSA_MMU2
202 202
     mmu2.unload();
203 203
   #else
204 204
     #if BOTH(HAS_MULTI_EXTRUDER, FILAMENT_UNLOAD_ALL_EXTRUDERS)
@@ -227,7 +227,7 @@ void GcodeSuite::M702() {
227 227
   if (park_point.z > 0)
228 228
     do_blocking_move_to_z(_MAX(current_position.z - park_point.z, 0), feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
229 229
 
230
-  #if HAS_MULTI_EXTRUDER && DISABLED(PRUSA_MMU2)
230
+  #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
231 231
     // Restore toolhead if it was changed
232 232
     if (active_extruder_before_filament_change != active_extruder)
233 233
       tool_change(active_extruder_before_filament_change, false);

+ 3
- 3
Marlin/src/gcode/feature/prusa_MMU2/M403.cpp View File

@@ -22,10 +22,10 @@
22 22
 
23 23
 #include "../../../inc/MarlinConfigPre.h"
24 24
 
25
-#if ENABLED(PRUSA_MMU2)
25
+#if HAS_PRUSA_MMU2
26 26
 
27 27
 #include "../../gcode.h"
28
-#include "../../../feature/mmu2/mmu2.h"
28
+#include "../../../feature/mmu/mmu2.h"
29 29
 
30 30
 /**
31 31
  * M403: Set filament type for MMU2
@@ -46,4 +46,4 @@ void GcodeSuite::M403() {
46 46
     SERIAL_ECHO_MSG("M403 - bad arguments.");
47 47
 }
48 48
 
49
-#endif // PRUSA_MMU2
49
+#endif // HAS_PRUSA_MMU2

+ 1
- 1
Marlin/src/gcode/gcode.cpp View File

@@ -702,7 +702,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
702 702
         case 402: M402(); break;                                  // M402: Stow probe
703 703
       #endif
704 704
 
705
-      #if ENABLED(PRUSA_MMU2)
705
+      #if HAS_PRUSA_MMU2
706 706
         case 403: M403(); break;
707 707
       #endif
708 708
 

+ 2
- 2
Marlin/src/gcode/gcode.h View File

@@ -181,7 +181,7 @@
181 181
  * M217 - Set filament swap parameters: "M217 S<length> P<feedrate> R<feedrate>". (Requires SINGLENOZZLE)
182 182
  * M218 - Set/get a tool offset: "M218 T<index> X<offset> Y<offset>". (Requires 2 or more extruders)
183 183
  * M220 - Set Feedrate Percentage: "M220 S<percent>" (i.e., "FR" on the LCD)
184
- *        Use "M220 B" to back up the Feedrate Percentage and "M220 R" to restore it. (Requires PRUSA_MMU2)
184
+ *        Use "M220 B" to back up the Feedrate Percentage and "M220 R" to restore it. (Requires an MMU_MODEL version 2 or 2S)
185 185
  * M221 - Set Flow Percentage: "M221 S<percent>"
186 186
  * M226 - Wait until a pin is in a given state: "M226 P<pin> S<state>" (Requires DIRECT_PIN_CONTROL)
187 187
  * M240 - Trigger a camera to take a photograph. (Requires PHOTO_GCODE)
@@ -735,7 +735,7 @@ private:
735 735
     static void M402();
736 736
   #endif
737 737
 
738
-  TERN_(PRUSA_MMU2, static void M403());
738
+  TERN_(HAS_PRUSA_MMU2, static void M403());
739 739
 
740 740
   #if ENABLED(FILAMENT_WIDTH_SENSOR)
741 741
     static void M404();

+ 1
- 1
Marlin/src/gcode/parser.cpp View File

@@ -155,7 +155,7 @@ void GCodeParser::parse(char *p) {
155 155
       // Skip spaces to get the numeric part
156 156
       while (*p == ' ') p++;
157 157
 
158
-      #if ENABLED(PRUSA_MMU2)
158
+      #if HAS_PRUSA_MMU2
159 159
         if (letter == 'T') {
160 160
           // check for special MMU2 T?/Tx/Tc commands
161 161
           if (*p == '?' || *p == 'x' || *p == 'c') {

+ 35
- 7
Marlin/src/inc/Conditionals_LCD.h View File

@@ -496,6 +496,36 @@
496 496
 #endif
497 497
 
498 498
 /**
499
+ *  Multi-Material-Unit supported models
500
+ */
501
+#define PRUSA_MMU1      1
502
+#define PRUSA_MMU2      2
503
+#define PRUSA_MMU2S     3
504
+#define SMUFF_EMU_MMU2  12
505
+#define SMUFF_EMU_MMU2S 13
506
+
507
+#ifdef MMU_MODEL
508
+  #define HAS_MMU 1
509
+  #if MMU_MODEL == PRUSA_MMU1
510
+    #define HAS_PRUSA_MMU1 1
511
+  #elif MMU_MODEL % 10 == PRUSA_MMU2
512
+    #define HAS_PRUSA_MMU2 1
513
+  #elif MMU_MODEL % 10 == PRUSA_MMU2S
514
+    #define HAS_PRUSA_MMU2 1
515
+    #define HAS_PRUSA_MMU2S 1
516
+  #endif
517
+  #if MMU_MODEL >= SMUFF_EMU_MMU2
518
+    #define HAS_SMUFF 1
519
+  #endif
520
+#endif
521
+
522
+#undef PRUSA_MMU1
523
+#undef PRUSA_MMU2
524
+#undef PRUSA_MMU2S
525
+#undef SMUFF_EMU_MMU2
526
+#undef SMUFF_EMU_MMU2S
527
+
528
+/**
499 529
  * Extruders have some combination of stepper motors and hotends
500 530
  * so we separate these concepts into the defines:
501 531
  *
@@ -512,8 +542,6 @@
512 542
   #undef SWITCHING_EXTRUDER
513 543
   #undef SWITCHING_NOZZLE
514 544
   #undef MIXING_EXTRUDER
515
-  #undef MK2_MULTIPLEXER
516
-  #undef PRUSA_MMU2
517 545
   #undef HOTEND_IDLE_TIMEOUT
518 546
 #elif EXTRUDERS > 1
519 547
   #define HAS_MULTI_EXTRUDER 1
@@ -539,17 +567,17 @@
539 567
 #elif ENABLED(SWITCHING_TOOLHEAD)
540 568
   #define E_STEPPERS      EXTRUDERS
541 569
   #define E_MANUAL        EXTRUDERS
542
-#elif ENABLED(PRUSA_MMU2)
570
+#elif HAS_PRUSA_MMU2
543 571
   #define E_STEPPERS 1
544 572
 #endif
545 573
 
546
-// No inactive extruders with MK2_MULTIPLEXER or SWITCHING_NOZZLE
547
-#if EITHER(MK2_MULTIPLEXER, SWITCHING_NOZZLE)
574
+// No inactive extruders with SWITCHING_NOZZLE or Průša MMU1
575
+#if ENABLED(SWITCHING_NOZZLE) || HAS_PRUSA_MMU1
548 576
   #undef DISABLE_INACTIVE_EXTRUDER
549 577
 #endif
550 578
 
551
-// Průša MK2 Multiplexer and MMU 2.0 force SINGLENOZZLE
552
-#if EITHER(MK2_MULTIPLEXER, PRUSA_MMU2)
579
+// Průša MMU1, MMU 2.0, MMUS 2.0 and SMUFF force SINGLENOZZLE
580
+#if HAS_MMU
553 581
   #define SINGLENOZZLE
554 582
 #endif
555 583
 

+ 79
- 61
Marlin/src/inc/SanityCheck.h View File

@@ -804,7 +804,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
804 804
   #if !PIN_EXISTS(FIL_RUNOUT)
805 805
     #error "FILAMENT_RUNOUT_SENSOR requires FIL_RUNOUT_PIN."
806 806
   #elif NUM_RUNOUT_SENSORS > E_STEPPERS
807
-    #error "NUM_RUNOUT_SENSORS cannot exceed the number of E steppers."
807
+    #if HAS_PRUSA_MMU2
808
+      #error "NUM_RUNOUT_SENSORS must be 1 with MMU2 / MMU2S."
809
+    #else
810
+      #error "NUM_RUNOUT_SENSORS cannot exceed the number of E steppers."
811
+    #endif
808 812
   #elif NUM_RUNOUT_SENSORS >= 2 && !PIN_EXISTS(FIL_RUNOUT2)
809 813
     #error "FIL_RUNOUT2_PIN is required with NUM_RUNOUT_SENSORS >= 2."
810 814
   #elif NUM_RUNOUT_SENSORS >= 3 && !PIN_EXISTS(FIL_RUNOUT3)
@@ -868,6 +872,42 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
868 872
 #endif
869 873
 
870 874
 /**
875
+ * Sanity checking for all Průša MMU
876
+ */
877
+#ifdef SNMM
878
+  #error "SNMM is obsolete. Define MMU_MODEL as PRUSA_MMU1 instead."
879
+#elif ENABLED(MK2_MULTIPLEXER)
880
+  #error "MK2_MULTIPLEXER is obsolete. Define MMU_MODEL as PRUSA_MMU1 instead."
881
+#elif ENABLED(PRUSA_MMU2)
882
+  #error "PRUSA_MMU2 is obsolete. Define MMU_MODEL as PRUSA_MMU2 instead."
883
+#elif ENABLED(PRUSA_MMU2_S_MODE)
884
+  #error "PRUSA_MMU2_S_MODE is obsolete. Define MMU_MODEL as PRUSA_MMU2S instead."
885
+#endif
886
+
887
+/**
888
+ * Multi-Material-Unit 2 / SMUFF requirements
889
+ */
890
+#if HAS_PRUSA_MMU2
891
+  #if EXTRUDERS != 5
892
+    #undef SINGLENOZZLE
893
+    #error "PRUSA_MMU2(S) requires exactly 5 EXTRUDERS. Please update your Configuration."
894
+  #elif DISABLED(NOZZLE_PARK_FEATURE)
895
+    #error "PRUSA_MMU2(S) requires NOZZLE_PARK_FEATURE. Enable it to continue."
896
+  #elif HAS_PRUSA_MMU2S && DISABLED(FILAMENT_RUNOUT_SENSOR)
897
+    #error "PRUSA_MMU2S requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
898
+  #elif ENABLED(MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR)
899
+    #error "MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
900
+  #elif ENABLED(MMU_EXTRUDER_SENSOR) && !HAS_LCD_MENU
901
+    #error "MMU_EXTRUDER_SENSOR requires an LCD supporting MarlinUI to be enabled."
902
+  #elif DISABLED(ADVANCED_PAUSE_FEATURE)
903
+    static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2(S) / SMUFF_EMU_MMU2(S).");
904
+  #endif
905
+#endif
906
+#if HAS_SMUFF && EXTRUDERS > 12
907
+  #error "Too many extruders for SMUFF_EMU_MMU2(S). (12 maximum)."
908
+#endif
909
+
910
+/**
871 911
  * Options only for EXTRUDERS > 1
872 912
  */
873 913
 #if HAS_MULTI_EXTRUDER
@@ -902,17 +942,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
902 942
     #error "TOOLCHANGE_ZRAISE required for EXTRUDERS > 1."
903 943
   #endif
904 944
 
905
-#elif ENABLED(MK2_MULTIPLEXER)
906
-  #error "MK2_MULTIPLEXER requires 2 or more EXTRUDERS."
945
+#elif HAS_PRUSA_MMU1 || HAS_SMUFF
946
+
947
+  #error "Multi-Material-Unit requires 2 or more EXTRUDERS."
948
+
907 949
 #elif ENABLED(SINGLENOZZLE)
950
+
908 951
   #error "SINGLENOZZLE requires 2 or more EXTRUDERS."
909
-#endif
910 952
 
911
-/**
912
- * Sanity checking for the Průša MK2 Multiplexer
913
- */
914
-#ifdef SNMM
915
-  #error "SNMM is now MK2_MULTIPLEXER."
916 953
 #endif
917 954
 
918 955
 /**
@@ -1870,48 +1907,46 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
1870 1907
 /**
1871 1908
  * Test Extruder Stepper Pins
1872 1909
  */
1873
-#if DISABLED(MK2_MULTIPLEXER) // MK2_MULTIPLEXER uses E0 stepper only
1874
-  #if E_STEPPERS
1875
-    #if !(PINS_EXIST(E0_STEP, E0_DIR) && HAS_E0_ENABLE)
1876
-      #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board."
1910
+#if E_STEPPERS
1911
+  #if !(PINS_EXIST(E0_STEP, E0_DIR) && HAS_E0_ENABLE)
1912
+    #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board."
1913
+  #endif
1914
+  #if E_STEPPERS > 1
1915
+    #if !(PINS_EXIST(E1_STEP, E1_DIR) && HAS_E1_ENABLE)
1916
+      #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board."
1877 1917
     #endif
1878
-    #if E_STEPPERS > 1
1879
-      #if !(PINS_EXIST(E1_STEP, E1_DIR) && HAS_E1_ENABLE)
1880
-        #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board."
1918
+    #if E_STEPPERS > 2
1919
+      #if !(PINS_EXIST(E2_STEP, E2_DIR) && HAS_E2_ENABLE)
1920
+        #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board."
1881 1921
       #endif
1882
-      #if E_STEPPERS > 2
1883
-        #if !(PINS_EXIST(E2_STEP, E2_DIR) && HAS_E2_ENABLE)
1884
-          #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board."
1922
+      #if E_STEPPERS > 3
1923
+        #if !(PINS_EXIST(E3_STEP, E3_DIR) && HAS_E3_ENABLE)
1924
+          #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board."
1885 1925
         #endif
1886
-        #if E_STEPPERS > 3
1887
-          #if !(PINS_EXIST(E3_STEP, E3_DIR) && HAS_E3_ENABLE)
1888
-            #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board."
1926
+        #if E_STEPPERS > 4
1927
+          #if !(PINS_EXIST(E4_STEP, E4_DIR) && HAS_E4_ENABLE)
1928
+            #error "E4_STEP_PIN, E4_DIR_PIN, or E4_ENABLE_PIN not defined for this board."
1889 1929
           #endif
1890
-          #if E_STEPPERS > 4
1891
-            #if !(PINS_EXIST(E4_STEP, E4_DIR) && HAS_E4_ENABLE)
1892
-              #error "E4_STEP_PIN, E4_DIR_PIN, or E4_ENABLE_PIN not defined for this board."
1930
+          #if E_STEPPERS > 5
1931
+            #if !(PINS_EXIST(E5_STEP, E5_DIR) && HAS_E5_ENABLE)
1932
+              #error "E5_STEP_PIN, E5_DIR_PIN, or E5_ENABLE_PIN not defined for this board."
1893 1933
             #endif
1894
-            #if E_STEPPERS > 5
1895
-              #if !(PINS_EXIST(E5_STEP, E5_DIR) && HAS_E5_ENABLE)
1896
-                #error "E5_STEP_PIN, E5_DIR_PIN, or E5_ENABLE_PIN not defined for this board."
1934
+            #if E_STEPPERS > 6
1935
+              #if !(PINS_EXIST(E6_STEP, E6_DIR) && HAS_E6_ENABLE)
1936
+                #error "E6_STEP_PIN, E6_DIR_PIN, or E6_ENABLE_PIN not defined for this board."
1897 1937
               #endif
1898
-              #if E_STEPPERS > 6
1899
-                #if !(PINS_EXIST(E6_STEP, E6_DIR) && HAS_E6_ENABLE)
1900
-                  #error "E6_STEP_PIN, E6_DIR_PIN, or E6_ENABLE_PIN not defined for this board."
1938
+              #if E_STEPPERS > 7
1939
+                #if !(PINS_EXIST(E7_STEP, E7_DIR) && HAS_E7_ENABLE)
1940
+                  #error "E7_STEP_PIN, E7_DIR_PIN, or E7_ENABLE_PIN not defined for this board."
1901 1941
                 #endif
1902
-                #if E_STEPPERS > 7
1903
-                  #if !(PINS_EXIST(E7_STEP, E7_DIR) && HAS_E7_ENABLE)
1904
-                    #error "E7_STEP_PIN, E7_DIR_PIN, or E7_ENABLE_PIN not defined for this board."
1905
-                  #endif
1906
-                #endif // E_STEPPERS > 7
1907
-              #endif // E_STEPPERS > 6
1908
-            #endif // E_STEPPERS > 5
1909
-          #endif // E_STEPPERS > 4
1910
-        #endif // E_STEPPERS > 3
1911
-      #endif // E_STEPPERS > 2
1912
-    #endif // E_STEPPERS > 1
1913
-  #endif // E_STEPPERS
1914
-#endif
1942
+              #endif // E_STEPPERS > 7
1943
+            #endif // E_STEPPERS > 6
1944
+          #endif // E_STEPPERS > 5
1945
+        #endif // E_STEPPERS > 4
1946
+      #endif // E_STEPPERS > 3
1947
+    #endif // E_STEPPERS > 2
1948
+  #endif // E_STEPPERS > 1
1949
+#endif // E_STEPPERS
1915 1950
 
1916 1951
 /**
1917 1952
  * Endstop Tests
@@ -2978,23 +3013,6 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
2978 3013
 #endif
2979 3014
 
2980 3015
 /**
2981
- * Průša MMU2 requirements
2982
- */
2983
-#if ENABLED(PRUSA_MMU2)
2984
-  #if EXTRUDERS != 5
2985
-    #error "PRUSA_MMU2 requires EXTRUDERS = 5."
2986
-  #elif DISABLED(NOZZLE_PARK_FEATURE)
2987
-    #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE. Enable it to continue."
2988
-  #elif EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR)
2989
-    #error "PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
2990
-  #elif BOTH(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR)
2991
-    #error "Enable only one of PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR."
2992
-  #elif DISABLED(ADVANCED_PAUSE_FEATURE)
2993
-    static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2.");
2994
-  #endif
2995
-#endif
2996
-
2997
-/**
2998 3016
  * Advanced PRINTCOUNTER settings
2999 3017
  */
3000 3018
 #if ENABLED(PRINTCOUNTER)

+ 1
- 1
Marlin/src/lcd/menu/menu_main.cpp View File

@@ -46,7 +46,7 @@
46 46
   #define MACHINE_CAN_PAUSE 1
47 47
 #endif
48 48
 
49
-#if ENABLED(PRUSA_MMU2)
49
+#if ENABLED(MMU2_MENUS)
50 50
   #include "../../lcd/menu/menu_mmu2.h"
51 51
 #endif
52 52
 

+ 17
- 17
Marlin/src/lcd/menu/menu_mmu2.cpp View File

@@ -24,13 +24,10 @@
24 24
 
25 25
 #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
26 26
 
27
-#include "../../feature/mmu2/mmu2.h"
27
+#include "../../feature/mmu/mmu2.h"
28 28
 #include "menu_mmu2.h"
29 29
 #include "menu_item.h"
30 30
 
31
-uint8_t currentTool;
32
-bool mmuMenuWait;
33
-
34 31
 //
35 32
 // Load Filament
36 33
 //
@@ -123,9 +120,12 @@ void menu_mmu2() {
123 120
 // T* Choose Filament
124 121
 //
125 122
 
126
-inline void action_mmu2_choose(const uint8_t tool) {
127
-  currentTool = tool;
128
-  mmuMenuWait = false;
123
+uint8_t feeder_index;
124
+bool wait_for_mmu_menu;
125
+
126
+inline void action_mmu2_chosen(const uint8_t index) {
127
+  feeder_index = index;
128
+  wait_for_mmu_menu = false;
129 129
 }
130 130
 
131 131
 void menu_mmu2_choose_filament() {
@@ -133,7 +133,7 @@ void menu_mmu2_choose_filament() {
133 133
   #if LCD_HEIGHT > 2
134 134
     STATIC_ITEM(MSG_MMU2_CHOOSE_FILAMENT_HEADER, SS_DEFAULT|SS_INVERT);
135 135
   #endif
136
-  LOOP_L_N(i, 5) ACTION_ITEM_N(i, MSG_MMU2_FILAMENT_N, []{ action_mmu2_choose(MenuItemBase::itemIndex); });
136
+  LOOP_L_N(i, 5) ACTION_ITEM_N(i, MSG_MMU2_FILAMENT_N, []{ action_mmu2_chosen(MenuItemBase::itemIndex); });
137 137
   END_MENU();
138 138
 }
139 139
 
@@ -142,32 +142,32 @@ void menu_mmu2_choose_filament() {
142 142
 //
143 143
 
144 144
 void menu_mmu2_pause() {
145
-  currentTool = mmu2.get_current_tool();
145
+  feeder_index = mmu2.get_current_tool();
146 146
   START_MENU();
147 147
   #if LCD_HEIGHT > 2
148 148
     STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, SS_DEFAULT|SS_INVERT);
149 149
   #endif
150
-  ACTION_ITEM(MSG_MMU2_RESUME, []{ mmuMenuWait = false; });
150
+  ACTION_ITEM(MSG_MMU2_RESUME, []{ wait_for_mmu_menu = false; });
151 151
   ACTION_ITEM(MSG_MMU2_UNLOAD_FILAMENT, []{ mmu2.unload(); });
152
-  ACTION_ITEM(MSG_MMU2_LOAD_FILAMENT, []{ mmu2.load_filament(currentTool); });
153
-  ACTION_ITEM(MSG_MMU2_LOAD_TO_NOZZLE, []{ mmu2.load_filament_to_nozzle(currentTool); });
152
+  ACTION_ITEM(MSG_MMU2_LOAD_FILAMENT, []{ mmu2.load_filament(feeder_index); });
153
+  ACTION_ITEM(MSG_MMU2_LOAD_TO_NOZZLE, []{ mmu2.load_filament_to_nozzle(feeder_index); });
154 154
   END_MENU();
155 155
 }
156 156
 
157 157
 void mmu2_M600() {
158 158
   ui.defer_status_screen();
159 159
   ui.goto_screen(menu_mmu2_pause);
160
-  mmuMenuWait = true;
161
-  while (mmuMenuWait) idle();
160
+  wait_for_mmu_menu = true;
161
+  while (wait_for_mmu_menu) idle();
162 162
 }
163 163
 
164 164
 uint8_t mmu2_choose_filament() {
165 165
   ui.defer_status_screen();
166 166
   ui.goto_screen(menu_mmu2_choose_filament);
167
-  mmuMenuWait = true;
168
-  while (mmuMenuWait) idle();
167
+  wait_for_mmu_menu = true;
168
+  while (wait_for_mmu_menu) idle();
169 169
   ui.return_to_status();
170
-  return currentTool;
170
+  return feeder_index;
171 171
 }
172 172
 
173 173
 #endif // HAS_LCD_MENU && MMU2_MENUS

+ 96
- 147
Marlin/src/module/settings.cpp View File

@@ -1068,46 +1068,30 @@ void MarlinSettings::postprocess() {
1068 1068
         #if AXIS_IS_TMC(Z4)
1069 1069
           tmc_stepper_current.Z4 = stepperZ4.getMilliamps();
1070 1070
         #endif
1071
-        #if MAX_EXTRUDERS
1072
-          #if AXIS_IS_TMC(E0)
1073
-            tmc_stepper_current.E0 = stepperE0.getMilliamps();
1074
-          #endif
1075
-          #if MAX_EXTRUDERS > 1
1076
-            #if AXIS_IS_TMC(E1)
1077
-              tmc_stepper_current.E1 = stepperE1.getMilliamps();
1078
-            #endif
1079
-            #if MAX_EXTRUDERS > 2
1080
-              #if AXIS_IS_TMC(E2)
1081
-                tmc_stepper_current.E2 = stepperE2.getMilliamps();
1082
-              #endif
1083
-              #if MAX_EXTRUDERS > 3
1084
-                #if AXIS_IS_TMC(E3)
1085
-                  tmc_stepper_current.E3 = stepperE3.getMilliamps();
1086
-                #endif
1087
-                #if MAX_EXTRUDERS > 4
1088
-                  #if AXIS_IS_TMC(E4)
1089
-                    tmc_stepper_current.E4 = stepperE4.getMilliamps();
1090
-                  #endif
1091
-                  #if MAX_EXTRUDERS > 5
1092
-                    #if AXIS_IS_TMC(E5)
1093
-                      tmc_stepper_current.E5 = stepperE5.getMilliamps();
1094
-                    #endif
1095
-                    #if MAX_EXTRUDERS > 6
1096
-                      #if AXIS_IS_TMC(E6)
1097
-                        tmc_stepper_current.E6 = stepperE6.getMilliamps();
1098
-                      #endif
1099
-                      #if MAX_EXTRUDERS > 7
1100
-                        #if AXIS_IS_TMC(E7)
1101
-                          tmc_stepper_current.E7 = stepperE7.getMilliamps();
1102
-                        #endif
1103
-                      #endif // MAX_EXTRUDERS > 7
1104
-                    #endif // MAX_EXTRUDERS > 6
1105
-                  #endif // MAX_EXTRUDERS > 5
1106
-                #endif // MAX_EXTRUDERS > 4
1107
-              #endif // MAX_EXTRUDERS > 3
1108
-            #endif // MAX_EXTRUDERS > 2
1109
-          #endif // MAX_EXTRUDERS > 1
1110
-        #endif // MAX_EXTRUDERS
1071
+        #if AXIS_IS_TMC(E0)
1072
+          tmc_stepper_current.E0 = stepperE0.getMilliamps();
1073
+        #endif
1074
+        #if AXIS_IS_TMC(E1)
1075
+          tmc_stepper_current.E1 = stepperE1.getMilliamps();
1076
+        #endif
1077
+        #if AXIS_IS_TMC(E2)
1078
+          tmc_stepper_current.E2 = stepperE2.getMilliamps();
1079
+        #endif
1080
+        #if AXIS_IS_TMC(E3)
1081
+          tmc_stepper_current.E3 = stepperE3.getMilliamps();
1082
+        #endif
1083
+        #if AXIS_IS_TMC(E4)
1084
+          tmc_stepper_current.E4 = stepperE4.getMilliamps();
1085
+        #endif
1086
+        #if AXIS_IS_TMC(E5)
1087
+          tmc_stepper_current.E5 = stepperE5.getMilliamps();
1088
+        #endif
1089
+        #if AXIS_IS_TMC(E6)
1090
+          tmc_stepper_current.E6 = stepperE6.getMilliamps();
1091
+        #endif
1092
+        #if AXIS_IS_TMC(E7)
1093
+          tmc_stepper_current.E7 = stepperE7.getMilliamps();
1094
+        #endif
1111 1095
       #endif
1112 1096
       EEPROM_WRITE(tmc_stepper_current);
1113 1097
     }
@@ -1144,46 +1128,30 @@ void MarlinSettings::postprocess() {
1144 1128
         #if AXIS_HAS_STEALTHCHOP(Z4)
1145 1129
           tmc_hybrid_threshold.Z4 = stepperZ4.get_pwm_thrs();
1146 1130
         #endif
1147
-        #if MAX_EXTRUDERS
1148
-          #if AXIS_HAS_STEALTHCHOP(E0)
1149
-            tmc_hybrid_threshold.E0 = stepperE0.get_pwm_thrs();
1150
-          #endif
1151
-          #if MAX_EXTRUDERS > 1
1152
-            #if AXIS_HAS_STEALTHCHOP(E1)
1153
-              tmc_hybrid_threshold.E1 = stepperE1.get_pwm_thrs();
1154
-            #endif
1155
-            #if MAX_EXTRUDERS > 2
1156
-              #if AXIS_HAS_STEALTHCHOP(E2)
1157
-                tmc_hybrid_threshold.E2 = stepperE2.get_pwm_thrs();
1158
-              #endif
1159
-              #if MAX_EXTRUDERS > 3
1160
-                #if AXIS_HAS_STEALTHCHOP(E3)
1161
-                  tmc_hybrid_threshold.E3 = stepperE3.get_pwm_thrs();
1162
-                #endif
1163
-                #if MAX_EXTRUDERS > 4
1164
-                  #if AXIS_HAS_STEALTHCHOP(E4)
1165
-                    tmc_hybrid_threshold.E4 = stepperE4.get_pwm_thrs();
1166
-                  #endif
1167
-                  #if MAX_EXTRUDERS > 5
1168
-                    #if AXIS_HAS_STEALTHCHOP(E5)
1169
-                      tmc_hybrid_threshold.E5 = stepperE5.get_pwm_thrs();
1170
-                    #endif
1171
-                    #if MAX_EXTRUDERS > 6
1172
-                      #if AXIS_HAS_STEALTHCHOP(E6)
1173
-                        tmc_hybrid_threshold.E6 = stepperE6.get_pwm_thrs();
1174
-                      #endif
1175
-                      #if MAX_EXTRUDERS > 7
1176
-                        #if AXIS_HAS_STEALTHCHOP(E7)
1177
-                          tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs();
1178
-                        #endif
1179
-                      #endif // MAX_EXTRUDERS > 7
1180
-                    #endif // MAX_EXTRUDERS > 6
1181
-                  #endif // MAX_EXTRUDERS > 5
1182
-                #endif // MAX_EXTRUDERS > 4
1183
-              #endif // MAX_EXTRUDERS > 3
1184
-            #endif // MAX_EXTRUDERS > 2
1185
-          #endif // MAX_EXTRUDERS > 1
1186
-        #endif // MAX_EXTRUDERS
1131
+        #if AXIS_HAS_STEALTHCHOP(E0)
1132
+          tmc_hybrid_threshold.E0 = stepperE0.get_pwm_thrs();
1133
+        #endif
1134
+        #if AXIS_HAS_STEALTHCHOP(E1)
1135
+          tmc_hybrid_threshold.E1 = stepperE1.get_pwm_thrs();
1136
+        #endif
1137
+        #if AXIS_HAS_STEALTHCHOP(E2)
1138
+          tmc_hybrid_threshold.E2 = stepperE2.get_pwm_thrs();
1139
+        #endif
1140
+        #if AXIS_HAS_STEALTHCHOP(E3)
1141
+          tmc_hybrid_threshold.E3 = stepperE3.get_pwm_thrs();
1142
+        #endif
1143
+        #if AXIS_HAS_STEALTHCHOP(E4)
1144
+          tmc_hybrid_threshold.E4 = stepperE4.get_pwm_thrs();
1145
+        #endif
1146
+        #if AXIS_HAS_STEALTHCHOP(E5)
1147
+          tmc_hybrid_threshold.E5 = stepperE5.get_pwm_thrs();
1148
+        #endif
1149
+        #if AXIS_HAS_STEALTHCHOP(E6)
1150
+          tmc_hybrid_threshold.E6 = stepperE6.get_pwm_thrs();
1151
+        #endif
1152
+        #if AXIS_HAS_STEALTHCHOP(E7)
1153
+          tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs();
1154
+        #endif
1187 1155
       #else
1188 1156
         const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
1189 1157
           .X  = 100, .Y  = 100, .Z  =   3,
@@ -1219,73 +1187,54 @@ void MarlinSettings::postprocess() {
1219 1187
     {
1220 1188
       _FIELD_TEST(tmc_stealth_enabled);
1221 1189
 
1222
-      tmc_stealth_enabled_t tmc_stealth_enabled = { false, false, false, false, false, false, false, false, false, false, false, false, false };
1223
-
1224
-      #if HAS_STEALTHCHOP
1225
-        #if AXIS_HAS_STEALTHCHOP(X)
1226
-          tmc_stealth_enabled.X = stepperX.get_stored_stealthChop();
1227
-        #endif
1228
-        #if AXIS_HAS_STEALTHCHOP(Y)
1229
-          tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop();
1230
-        #endif
1231
-        #if AXIS_HAS_STEALTHCHOP(Z)
1232
-          tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop();
1233
-        #endif
1234
-        #if AXIS_HAS_STEALTHCHOP(X2)
1235
-          tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop();
1236
-        #endif
1237
-        #if AXIS_HAS_STEALTHCHOP(Y2)
1238
-          tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop();
1239
-        #endif
1240
-        #if AXIS_HAS_STEALTHCHOP(Z2)
1241
-          tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop();
1242
-        #endif
1243
-        #if AXIS_HAS_STEALTHCHOP(Z3)
1244
-          tmc_stealth_enabled.Z3 = stepperZ3.get_stored_stealthChop();
1245
-        #endif
1246
-        #if AXIS_HAS_STEALTHCHOP(Z4)
1247
-          tmc_stealth_enabled.Z4 = stepperZ4.get_stored_stealthChop();
1248
-        #endif
1249
-        #if MAX_EXTRUDERS
1250
-          #if AXIS_HAS_STEALTHCHOP(E0)
1251
-            tmc_stealth_enabled.E0 = stepperE0.get_stored_stealthChop();
1252
-          #endif
1253
-          #if MAX_EXTRUDERS > 1
1254
-            #if AXIS_HAS_STEALTHCHOP(E1)
1255
-              tmc_stealth_enabled.E1 = stepperE1.get_stored_stealthChop();
1256
-            #endif
1257
-            #if MAX_EXTRUDERS > 2
1258
-              #if AXIS_HAS_STEALTHCHOP(E2)
1259
-                tmc_stealth_enabled.E2 = stepperE2.get_stored_stealthChop();
1260
-              #endif
1261
-              #if MAX_EXTRUDERS > 3
1262
-                #if AXIS_HAS_STEALTHCHOP(E3)
1263
-                  tmc_stealth_enabled.E3 = stepperE3.get_stored_stealthChop();
1264
-                #endif
1265
-                #if MAX_EXTRUDERS > 4
1266
-                  #if AXIS_HAS_STEALTHCHOP(E4)
1267
-                    tmc_stealth_enabled.E4 = stepperE4.get_stored_stealthChop();
1268
-                  #endif
1269
-                  #if MAX_EXTRUDERS > 5
1270
-                    #if AXIS_HAS_STEALTHCHOP(E5)
1271
-                      tmc_stealth_enabled.E5 = stepperE5.get_stored_stealthChop();
1272
-                    #endif
1273
-                    #if MAX_EXTRUDERS > 6
1274
-                      #if AXIS_HAS_STEALTHCHOP(E6)
1275
-                        tmc_stealth_enabled.E6 = stepperE6.get_stored_stealthChop();
1276
-                      #endif
1277
-                      #if MAX_EXTRUDERS > 7
1278
-                        #if AXIS_HAS_STEALTHCHOP(E7)
1279
-                          tmc_stealth_enabled.E7 = stepperE7.get_stored_stealthChop();
1280
-                        #endif
1281
-                      #endif // MAX_EXTRUDERS > 7
1282
-                    #endif // MAX_EXTRUDERS > 6
1283
-                  #endif // MAX_EXTRUDERS > 5
1284
-                #endif // MAX_EXTRUDERS > 4
1285
-              #endif // MAX_EXTRUDERS > 3
1286
-            #endif // MAX_EXTRUDERS > 2
1287
-          #endif // MAX_EXTRUDERS > 1
1288
-        #endif // MAX_EXTRUDERS
1190
+      tmc_stealth_enabled_t tmc_stealth_enabled = { false };
1191
+      #if AXIS_HAS_STEALTHCHOP(X)
1192
+        tmc_stealth_enabled.X = stepperX.get_stored_stealthChop();
1193
+      #endif
1194
+      #if AXIS_HAS_STEALTHCHOP(Y)
1195
+        tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop();
1196
+      #endif
1197
+      #if AXIS_HAS_STEALTHCHOP(Z)
1198
+        tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop();
1199
+      #endif
1200
+      #if AXIS_HAS_STEALTHCHOP(X2)
1201
+        tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop();
1202
+      #endif
1203
+      #if AXIS_HAS_STEALTHCHOP(Y2)
1204
+        tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop();
1205
+      #endif
1206
+      #if AXIS_HAS_STEALTHCHOP(Z2)
1207
+        tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop();
1208
+      #endif
1209
+      #if AXIS_HAS_STEALTHCHOP(Z3)
1210
+        tmc_stealth_enabled.Z3 = stepperZ3.get_stored_stealthChop();
1211
+      #endif
1212
+      #if AXIS_HAS_STEALTHCHOP(Z4)
1213
+        tmc_stealth_enabled.Z4 = stepperZ4.get_stored_stealthChop();
1214
+      #endif
1215
+      #if AXIS_HAS_STEALTHCHOP(E0)
1216
+        tmc_stealth_enabled.E0 = stepperE0.get_stored_stealthChop();
1217
+      #endif
1218
+      #if AXIS_HAS_STEALTHCHOP(E1)
1219
+        tmc_stealth_enabled.E1 = stepperE1.get_stored_stealthChop();
1220
+      #endif
1221
+      #if AXIS_HAS_STEALTHCHOP(E2)
1222
+        tmc_stealth_enabled.E2 = stepperE2.get_stored_stealthChop();
1223
+      #endif
1224
+      #if AXIS_HAS_STEALTHCHOP(E3)
1225
+        tmc_stealth_enabled.E3 = stepperE3.get_stored_stealthChop();
1226
+      #endif
1227
+      #if AXIS_HAS_STEALTHCHOP(E4)
1228
+        tmc_stealth_enabled.E4 = stepperE4.get_stored_stealthChop();
1229
+      #endif
1230
+      #if AXIS_HAS_STEALTHCHOP(E5)
1231
+        tmc_stealth_enabled.E5 = stepperE5.get_stored_stealthChop();
1232
+      #endif
1233
+      #if AXIS_HAS_STEALTHCHOP(E6)
1234
+        tmc_stealth_enabled.E6 = stepperE6.get_stored_stealthChop();
1235
+      #endif
1236
+      #if AXIS_HAS_STEALTHCHOP(E7)
1237
+        tmc_stealth_enabled.E7 = stepperE7.get_stored_stealthChop();
1289 1238
       #endif
1290 1239
       EEPROM_WRITE(tmc_stealth_enabled);
1291 1240
     }

+ 5
- 2
Marlin/src/module/stepper/indirection.h View File

@@ -417,12 +417,15 @@ void reset_stepper_drivers();    // Called by settings.load / settings.reset
417 417
     #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(E ?  INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
418 418
     #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(E ? !INVERT_E0_DIR :  INVERT_E0_DIR); }while(0)
419 419
   #endif
420
-#elif ENABLED(PRUSA_MMU2)
420
+
421
+#elif HAS_PRUSA_MMU2
422
+
421 423
   #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
422 424
   #define   NORM_E_DIR(E)   E0_DIR_WRITE(!INVERT_E0_DIR)
423 425
   #define    REV_E_DIR(E)   E0_DIR_WRITE( INVERT_E0_DIR)
424 426
 
425
-#elif ENABLED(MK2_MULTIPLEXER) // One multiplexed stepper driver, reversed on odd index
427
+#elif HAS_PRUSA_MMU1  // One multiplexed stepper driver, reversed on odd index
428
+
426 429
   #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
427 430
   #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ? !INVERT_E0_DIR:  INVERT_E0_DIR); }while(0)
428 431
   #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ?  INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)

+ 6
- 10
Marlin/src/module/tool_change.cpp View File

@@ -73,10 +73,6 @@
73 73
   #include "../feature/solenoid.h"
74 74
 #endif
75 75
 
76
-#if ENABLED(MK2_MULTIPLEXER)
77
-  #include "../feature/snmm.h"
78
-#endif
79
-
80 76
 #if ENABLED(MIXING_EXTRUDER)
81 77
   #include "../feature/mixing.h"
82 78
 #endif
@@ -89,8 +85,10 @@
89 85
   #include "../feature/fanmux.h"
90 86
 #endif
91 87
 
92
-#if ENABLED(PRUSA_MMU2)
93
-  #include "../feature/mmu2/mmu2.h"
88
+#if HAS_PRUSA_MMU1
89
+  #include "../feature/mmu/mmu.h"
90
+#elif HAS_PRUSA_MMU2
91
+  #include "../feature/mmu/mmu2.h"
94 92
 #endif
95 93
 
96 94
 #if HAS_LCD_MENU
@@ -863,7 +861,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
863 861
       mixer.T(new_tool);
864 862
     #endif
865 863
 
866
-  #elif ENABLED(PRUSA_MMU2)
864
+  #elif HAS_PRUSA_MMU2
867 865
 
868 866
     UNUSED(no_move);
869 867
 
@@ -1171,8 +1169,6 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
1171 1169
           do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]);
1172 1170
       #endif
1173 1171
 
1174
-      TERN_(PRUSA_MMU2, mmu2.tool_change(new_tool));
1175
-
1176 1172
       TERN_(SWITCHING_NOZZLE_TWO_SERVOS, lower_nozzle(new_tool));
1177 1173
 
1178 1174
     } // (new_tool != old_tool)
@@ -1184,7 +1180,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
1184 1180
       enable_solenoid_on_active_extruder();
1185 1181
     #endif
1186 1182
 
1187
-    #if ENABLED(MK2_MULTIPLEXER)
1183
+    #if HAS_PRUSA_MMU1
1188 1184
       if (new_tool >= E_STEPPERS) return invalid_extruder_error(new_tool);
1189 1185
       select_multiplexed_stepper(new_tool);
1190 1186
     #endif

+ 2
- 2
Marlin/src/pins/lpc1768/pins_MKS_SBASE.h View File

@@ -131,9 +131,9 @@
131 131
 #define PIN_P2_11                          P2_11  // Interrupt Capable
132 132
 
133 133
 //
134
-// Průša i3 MK2 Multi Material Multiplexer Support
134
+// Průša i3 MMU1 (Multi Material Multiplexer) Support
135 135
 //
136
-#if ENABLED(MK2_MULTIPLEXER)
136
+#if HAS_PRUSA_MMU1
137 137
   #define E_MUX0_PIN                       P1_23  // J8-3
138 138
   #define E_MUX1_PIN                       P2_12  // J8-4
139 139
   #define E_MUX2_PIN                       P2_11  // J8-5

+ 6
- 1
Marlin/src/pins/pins.h View File

@@ -35,7 +35,12 @@
35 35
  *    These numbers are the same in any pin mapping.
36 36
  */
37 37
 
38
-#define MAX_EXTRUDERS 8
38
+#if HAS_SMUFF
39
+  #define MAX_EXTRUDERS 12
40
+#else
41
+  #define MAX_EXTRUDERS 8
42
+#endif
43
+#define MAX_E_STEPPERS 8
39 44
 
40 45
 #if   MB(RAMPS_13_EFB, RAMPS_14_EFB, RAMPS_PLUS_EFB, RAMPS_14_RE_ARM_EFB, RAMPS_SMART_EFB, RAMPS_DUO_EFB, RAMPS4DUE_EFB)
41 46
   #define IS_RAMPS_EFB

+ 5
- 5
Marlin/src/pins/pins_postprocess.h View File

@@ -521,7 +521,7 @@
521 521
     #define X2_STEP_PIN   _EPIN(X2_E_INDEX, STEP)
522 522
     #define X2_DIR_PIN    _EPIN(X2_E_INDEX, DIR)
523 523
     #define X2_ENABLE_PIN _EPIN(X2_E_INDEX, ENABLE)
524
-    #if X2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(X2_STEP)
524
+    #if X2_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(X2_STEP)
525 525
       #error "No E stepper plug left for X2!"
526 526
     #endif
527 527
   #endif
@@ -594,7 +594,7 @@
594 594
     #define Y2_STEP_PIN   _EPIN(Y2_E_INDEX, STEP)
595 595
     #define Y2_DIR_PIN    _EPIN(Y2_E_INDEX, DIR)
596 596
     #define Y2_ENABLE_PIN _EPIN(Y2_E_INDEX, ENABLE)
597
-    #if Y2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Y2_STEP)
597
+    #if Y2_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(Y2_STEP)
598 598
       #error "No E stepper plug left for Y2!"
599 599
     #endif
600 600
   #endif
@@ -662,7 +662,7 @@
662 662
     #define Z2_STEP_PIN   _EPIN(Z2_E_INDEX, STEP)
663 663
     #define Z2_DIR_PIN    _EPIN(Z2_E_INDEX, DIR)
664 664
     #define Z2_ENABLE_PIN _EPIN(Z2_E_INDEX, ENABLE)
665
-    #if Z2_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Z2_STEP)
665
+    #if Z2_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(Z2_STEP)
666 666
       #error "No E stepper plug left for Z2!"
667 667
     #endif
668 668
   #endif
@@ -729,7 +729,7 @@
729 729
     #define Z3_STEP_PIN   _EPIN(Z3_E_INDEX, STEP)
730 730
     #define Z3_DIR_PIN    _EPIN(Z3_E_INDEX, DIR)
731 731
     #define Z3_ENABLE_PIN _EPIN(Z3_E_INDEX, ENABLE)
732
-    #if Z3_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Z3_STEP)
732
+    #if Z3_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(Z3_STEP)
733 733
       #error "No E stepper plug left for Z3!"
734 734
     #endif
735 735
   #endif
@@ -796,7 +796,7 @@
796 796
     #define Z4_STEP_PIN   _EPIN(Z4_E_INDEX, STEP)
797 797
     #define Z4_DIR_PIN    _EPIN(Z4_E_INDEX, DIR)
798 798
     #define Z4_ENABLE_PIN _EPIN(Z4_E_INDEX, ENABLE)
799
-    #if Z4_E_INDEX >= MAX_EXTRUDERS || !PIN_EXISTS(Z4_STEP)
799
+    #if Z4_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(Z4_STEP)
800 800
       #error "No E stepper plug left for Z4!"
801 801
     #endif
802 802
   #endif

+ 2
- 2
Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h View File

@@ -25,8 +25,8 @@
25 25
   #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
26 26
 #elif HOTENDS > 8 || E_STEPPERS > 8
27 27
   #error "BIGTREE GTR V1.0 supports up to 8 hotends / E-steppers."
28
-#elif HOTENDS > MAX_EXTRUDERS || E_STEPPERS > MAX_EXTRUDERS
29
-  #error "Marlin extruder/hotends limit! Increase MAX_EXTRUDERS to continue."
28
+#elif HOTENDS > MAX_E_STEPPERS || E_STEPPERS > MAX_E_STEPPERS
29
+  #error "Marlin extruder/hotends limit! Increase MAX_E_STEPPERS to continue."
30 30
 #endif
31 31
 
32 32
 #define BOARD_INFO_NAME "BTT GTR V1.0"

+ 14
- 4
buildroot/tests/mega2560-tests View File

@@ -66,28 +66,38 @@ exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE | Sle
66 66
 #
67 67
 restore_configs
68 68
 opt_set LCD_LANGUAGE zh_CN
69
+opt_set MMU_MODEL PRUSA_MMU2S
69 70
 opt_set EXTRUDERS 5
70 71
 opt_set NUM_SERVOS 1
71 72
 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \
72 73
            AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \
73 74
            NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
74
-           PRUSA_MMU2 MMU2_MENUS PRUSA_MMU2_S_MODE DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
75
+           MMU2_MENUS DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
75 76
            FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING
76
-exec_test $1 $2 "RAMPS | ZONESTAR + Chinese | MMU2 | Servo | 3-Point + Debug | G38 ..." "$3"
77
+exec_test $1 $2 "RAMPS | ZONESTAR + Chinese | MMU2S | Servo | 3-Point + Debug | G38 ..." "$3"
77 78
 
78 79
 #
79 80
 # 5 runout sensors with distinct states
80 81
 #
81 82
 restore_configs
83
+opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO
82 84
 opt_set EXTRUDERS 5
83 85
 opt_set NUM_SERVOS 1
86
+opt_set TEMP_SENSOR_1 1
87
+opt_set TEMP_SENSOR_2 1
88
+opt_set TEMP_SENSOR_3 1
89
+opt_set TEMP_SENSOR_4 1
84 90
 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \
85 91
            AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \
86 92
            NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
87
-           PRUSA_MMU2 MMU2_MENUS PRUSA_MMU2_S_MODE DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
93
+           DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
88 94
            FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING FIL_RUNOUT3_PULL
89
-opt_set MIXING_STEPPERS 5
95
+opt_set NUM_RUNOUT_SENSORS 5
96
+opt_set FIL_RUNOUT2_PIN 44
97
+opt_set FIL_RUNOUT3_PIN 45
90 98
 opt_set FIL_RUNOUT3_STATE HIGH
99
+opt_set FIL_RUNOUT4_PIN 46
100
+opt_set FIL_RUNOUT5_PIN 47
91 101
 exec_test $1 $2 "Multiple runout sensors (x5) | Distinct runout states"
92 102
 
93 103
 #

+ 5
- 5
platformio.ini View File

@@ -93,7 +93,8 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
93 93
   -<src/feature/leds/tempstat.cpp>
94 94
   -<src/feature/max7219.cpp>
95 95
   -<src/feature/mixing.cpp>
96
-  -<src/feature/mmu2> -<src/gcode/feature/prusa_MMU2>
96
+  -<src/feature/mmu/mmu.cpp>
97
+  -<src/feature/mmu/mmu2.cpp> -<src/gcode/feature/prusa_MMU2>
97 98
   -<src/feature/password> -<src/gcode/feature/password>
98 99
   -<src/feature/pause.cpp>
99 100
   -<src/feature/power.cpp>
@@ -101,7 +102,6 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
101 102
   -<src/feature/powerloss.cpp> -<src/gcode/feature/powerloss>
102 103
   -<src/feature/probe_temp_comp.cpp>
103 104
   -<src/feature/runout.cpp> -<src/gcode/feature/runout>
104
-  -<src/feature/snmm.cpp>
105 105
   -<src/feature/solenoid.cpp> -<src/gcode/control/M380_M381.cpp>
106 106
   -<src/feature/spindle_laser.cpp> -<src/gcode/control/M3-M5.cpp>
107 107
   -<src/feature/tmc_util.cpp> -<src/module/stepper/trinamic.cpp>
@@ -304,7 +304,8 @@ PRINTER_EVENT_LEDS      = src_filter=+<src/feature/leds/printer_event_leds.cpp>
304 304
 TEMP_STAT_LEDS          = src_filter=+<src/feature/leds/tempstat.cpp>
305 305
 MAX7219_DEBUG           = src_filter=+<src/feature/max7219.cpp> +<src/gcode/feature/leds/M7219.cpp>
306 306
 MIXING_EXTRUDER         = src_filter=+<src/feature/mixing.cpp> +<src/gcode/feature/mixing/M163-M165.cpp>
307
-PRUSA_MMU2              = src_filter=+<src/feature/mmu2> +<src/gcode/feature/prusa_MMU2>
307
+HAS_PRUSA_MMU1          = src_filter=+<src/feature/mmu/mmu.cpp>
308
+HAS_PRUSA_MMU2          = src_filter=+<src/feature/mmu/mmu2.cpp> +<src/gcode/feature/prusa_MMU2>
308 309
 PASSWORD_FEATURE        = src_filter=+<src/feature/password> +<src/gcode/feature/password>
309 310
 ADVANCED_PAUSE_FEATURE  = src_filter=+<src/feature/pause.cpp> +<src/gcode/feature/pause/M600.cpp> +<src/gcode/feature/pause/M603.cpp>
310 311
 AUTO_POWER_CONTROL      = src_filter=+<src/feature/power.cpp>
@@ -312,8 +313,7 @@ HAS_POWER_MONITOR       = src_filter=+<src/feature/power_monitor.cpp> +<src/gcod
312 313
 POWER_LOSS_RECOVERY     = src_filter=+<src/feature/powerloss.cpp> +<src/gcode/feature/powerloss>
313 314
 PROBE_TEMP_COMPENSATION = src_filter=+<src/feature/probe_temp_comp.cpp> +<src/gcode/calibrate/G76_M192_M871.cpp>
314 315
 HAS_FILAMENT_SENSOR     = src_filter=+<src/feature/runout.cpp> +<src/gcode/feature/runout>
315
-MK2_MULTIPLEXER         = src_filter=+<src/feature/snmm.cpp>
316
-EXT_SOLENOID|MANUAL_SOLENOID_CONTROL = src_filter=+<src/feature/solenoid.cpp> +<src/gcode/control/M380_M381.cpp>
316
+(EXT|MANUAL)_SOLENOID.* = src_filter=+<src/feature/solenoid.cpp> +<src/gcode/control/M380_M381.cpp>
317 317
 HAS_CUTTER              = src_filter=+<src/feature/spindle_laser.cpp> +<src/gcode/control/M3-M5.cpp>
318 318
 EXPERIMENTAL_I2CBUS     = src_filter=+<src/feature/twibus.cpp> +<src/gcode/feature/i2c>
319 319
 MECHANICAL_GANTRY_CAL.+ = src_filter=+<src/gcode/calibrate/G34.cpp>

Loading…
Cancel
Save