Browse Source

Fix IDEX layer shift and DIR states (#19756)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
nb-rapidia 3 years ago
parent
commit
418b3e5ee2
No account linked to committer's email address

+ 6
- 15
Marlin/src/feature/pause.cpp View File

@@ -223,8 +223,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
223 223
   #if ENABLED(DUAL_X_CARRIAGE)
224 224
     const int8_t saved_ext        = active_extruder;
225 225
     const bool saved_ext_dup_mode = extruder_duplication_enabled;
226
-    active_extruder = DXC_ext;
227
-    extruder_duplication_enabled = false;
226
+    set_duplication_enabled(false, DXC_ext);
228 227
   #endif
229 228
 
230 229
   // Slow Load filament
@@ -245,9 +244,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
245 244
   }
246 245
 
247 246
   #if ENABLED(DUAL_X_CARRIAGE)      // Tie the two extruders movement back together.
248
-    active_extruder = saved_ext;
249
-    extruder_duplication_enabled = saved_ext_dup_mode;
250
-    stepper.set_directions();
247
+    set_duplication_enabled(saved_ext_dup_mode, saved_ext);
251 248
   #endif
252 249
 
253 250
   #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE)
@@ -439,17 +436,14 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
439 436
   #if ENABLED(DUAL_X_CARRIAGE)
440 437
     const int8_t saved_ext        = active_extruder;
441 438
     const bool saved_ext_dup_mode = extruder_duplication_enabled;
442
-    active_extruder = DXC_ext;
443
-    extruder_duplication_enabled = false;
439
+    set_duplication_enabled(false, DXC_ext);
444 440
   #endif
445 441
 
446 442
   if (unload_length)   // Unload the filament
447 443
     unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
448 444
 
449 445
   #if ENABLED(DUAL_X_CARRIAGE)
450
-    active_extruder = saved_ext;
451
-    extruder_duplication_enabled = saved_ext_dup_mode;
452
-    stepper.set_directions();
446
+    set_duplication_enabled(saved_ext_dup_mode, saved_ext);
453 447
   #endif
454 448
 
455 449
   return true;
@@ -495,8 +489,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
495 489
   #if ENABLED(DUAL_X_CARRIAGE)
496 490
     const int8_t saved_ext        = active_extruder;
497 491
     const bool saved_ext_dup_mode = extruder_duplication_enabled;
498
-    active_extruder = DXC_ext;
499
-    extruder_duplication_enabled = false;
492
+    set_duplication_enabled(false, DXC_ext);
500 493
   #endif
501 494
 
502 495
   // Wait for filament insert by user and press button
@@ -550,9 +543,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
550 543
     idle_no_sleep();
551 544
   }
552 545
   #if ENABLED(DUAL_X_CARRIAGE)
553
-    active_extruder = saved_ext;
554
-    extruder_duplication_enabled = saved_ext_dup_mode;
555
-    stepper.set_directions();
546
+    set_duplication_enabled(saved_ext_dup_mode, saved_ext);
556 547
   #endif
557 548
 }
558 549
 

+ 4
- 3
Marlin/src/feature/pause.h View File

@@ -89,10 +89,11 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
89 89
 
90 90
 void wait_for_confirmation(const bool is_reload=false, const int8_t max_beep_count=0 DXC_PARAMS);
91 91
 
92
-void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, const int8_t max_beep_count=0, int16_t targetTemp=0 DXC_PARAMS);
92
+void resume_print(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=ADVANCED_PAUSE_PURGE_LENGTH,
93
+                    const int8_t max_beep_count=0, int16_t targetTemp=0 DXC_PARAMS);
93 94
 
94
-bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0, const bool show_lcd=false,
95
-                          const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
95
+bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0,
96
+                    const bool show_lcd=false, const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
96 97
 
97 98
 bool unload_filament(const float &unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT
98 99
   #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)

+ 1
- 1
Marlin/src/feature/runout.h View File

@@ -237,7 +237,7 @@ class FilamentSensorBase {
237 237
         #if NUM_RUNOUT_SENSORS == 1
238 238
           UNUSED(extruder);
239 239
         #else
240
-          if ( !TERN0(DUAL_X_CARRIAGE, dxc_is_duplicating())
240
+          if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating())
241 241
             && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled)
242 242
           ) return TEST(runout_states, extruder); // A specific extruder ran out
243 243
         #endif

+ 2
- 3
Marlin/src/gcode/bedlevel/G35.cpp View File

@@ -110,9 +110,8 @@ void GcodeSuite::G35() {
110 110
     tool_change(0, true);
111 111
   #endif
112 112
 
113
-  #if HAS_DUPLICATION_MODE
114
-    extruder_duplication_enabled = false;
115
-  #endif
113
+  // Disable duplication mode on homing
114
+  TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
116 115
 
117 116
   // Home all before this procedure
118 117
   home_all_axes();

+ 12
- 16
Marlin/src/gcode/calibrate/G28.cpp View File

@@ -134,8 +134,8 @@
134 134
 
135 135
       if (DEBUGGING(LEVELING)) DEBUG_POS("home_z_safely", destination);
136 136
 
137
-      // This causes the carriage on Dual X to unpark
138
-      TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false);
137
+      // Free the active extruder for movement
138
+      TERN_(DUAL_X_CARRIAGE, idex_set_parked(false));
139 139
 
140 140
       TERN_(SENSORLESS_HOMING, safe_delay(500)); // Short delay needed to settle
141 141
 
@@ -282,7 +282,7 @@ void GcodeSuite::G28() {
282 282
     tool_change(0, true);
283 283
   #endif
284 284
 
285
-  TERN_(HAS_DUPLICATION_MODE, extruder_duplication_enabled = false);
285
+  TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
286 286
 
287 287
   remember_feedrate_scaling_off();
288 288
 
@@ -342,16 +342,14 @@ void GcodeSuite::G28() {
342 342
         homeaxis(X_AXIS);
343 343
 
344 344
         // Remember this extruder's position for later tool change
345
-        inactive_extruder_x_pos = current_position.x;
345
+        inactive_extruder_x = current_position.x;
346 346
 
347 347
         // Home the 1st (left) extruder
348 348
         active_extruder = 0;
349 349
         homeaxis(X_AXIS);
350 350
 
351
-        // Consider the active extruder to be parked
352
-        raised_parked_position = current_position;
353
-        delayed_move_time = 0;
354
-        active_extruder_parked = true;
351
+        // Consider the active extruder to be in its "parked" position
352
+        idex_set_parked();
355 353
 
356 354
       #else
357 355
 
@@ -392,7 +390,7 @@ void GcodeSuite::G28() {
392 390
    */
393 391
   #if ENABLED(DUAL_X_CARRIAGE)
394 392
 
395
-    if (dxc_is_duplicating()) {
393
+    if (idex_is_duplicating()) {
396 394
 
397 395
       TERN_(IMPROVE_HOMING_RELIABILITY, slow_homing = begin_slow_homing());
398 396
 
@@ -401,19 +399,17 @@ void GcodeSuite::G28() {
401 399
       homeaxis(X_AXIS);
402 400
 
403 401
       // Remember this extruder's position for later tool change
404
-      inactive_extruder_x_pos = current_position.x;
402
+      inactive_extruder_x = current_position.x;
405 403
 
406 404
       // Home the 1st (left) extruder
407 405
       active_extruder = 0;
408 406
       homeaxis(X_AXIS);
409 407
 
410 408
       // Consider the active extruder to be parked
411
-      raised_parked_position = current_position;
412
-      delayed_move_time = 0;
413
-      active_extruder_parked = true;
414
-      extruder_duplication_enabled = IDEX_saved_duplication_state;
415
-      dual_x_carriage_mode         = IDEX_saved_mode;
416
-      stepper.set_directions();
409
+      idex_set_parked();
410
+
411
+      dual_x_carriage_mode = IDEX_saved_mode;
412
+      set_duplication_enabled(IDEX_saved_duplication_state);
417 413
 
418 414
       TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing));
419 415
     }

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

@@ -113,7 +113,7 @@ void GcodeSuite::G34() {
113 113
       tool_change(0, true);
114 114
     #endif
115 115
 
116
-    TERN_(HAS_DUPLICATION_MODE, extruder_duplication_enabled = false);
116
+    TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
117 117
 
118 118
     // In BLTOUCH HS mode, the probe travels in a deployed state.
119 119
     // Users of G34 might have a badly misaligned bed, so raise Z by the

+ 6
- 9
Marlin/src/gcode/control/M605.cpp View File

@@ -68,7 +68,7 @@
68 68
       const DualXMode previous_mode = dual_x_carriage_mode;
69 69
 
70 70
       dual_x_carriage_mode = (DualXMode)parser.value_byte();
71
-      mirrored_duplication_mode = false;
71
+      idex_set_mirrored_mode(false);
72 72
 
73 73
       if (dual_x_carriage_mode == DXC_MIRRORED_MODE) {
74 74
         if (previous_mode != DXC_DUPLICATION_MODE) {
@@ -77,8 +77,7 @@
77 77
           dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
78 78
           return;
79 79
         }
80
-        mirrored_duplication_mode = true;
81
-        stepper.set_directions();
80
+        idex_set_mirrored_mode(true);
82 81
         float x_jog = current_position.x - .1;
83 82
         for (uint8_t i = 2; --i;) {
84 83
           planner.buffer_line(x_jog, current_position.y, current_position.z, current_position.e, feedrate_mm_s, 0);
@@ -102,10 +101,8 @@
102 101
           dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
103 102
           break;
104 103
       }
105
-      active_extruder_parked = false;
106
-      extruder_duplication_enabled = false;
107
-      stepper.set_directions();
108
-      delayed_move_time = 0;
104
+      idex_set_parked(false);
105
+      set_duplication_enabled(false);
109 106
     }
110 107
     else if (!parser.seen('W'))  // if no S or W parameter, the DXC mode gets reset to the user's default
111 108
       dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
@@ -125,7 +122,7 @@
125 122
         if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ");
126 123
         DEBUG_ECHOPGM(" parked.");
127 124
         DEBUG_ECHOPAIR("\nactive_extruder_x_pos: ", current_position.x);
128
-        DEBUG_ECHOPAIR("\ninactive_extruder_x_pos: ", inactive_extruder_x_pos);
125
+        DEBUG_ECHOPAIR("\ninactive_extruder_x: ", inactive_extruder_x);
129 126
         DEBUG_ECHOPAIR("\nextruder_duplication_enabled: ", int(extruder_duplication_enabled));
130 127
         DEBUG_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
131 128
         DEBUG_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
@@ -166,7 +163,7 @@
166 163
       if (parser.seenval('P')) duplication_e_mask = parser.value_int();   // Set the mask directly
167 164
       else if (parser.seenval('E')) duplication_e_mask = pow(2, parser.value_int() + 1) - 1; // Set the mask by E index
168 165
       ena = (2 == parser.intval('S', extruder_duplication_enabled ? 2 : 0));
169
-      extruder_duplication_enabled = ena && (duplication_e_mask >= 3);
166
+      set_duplication_enabled(ena && (duplication_e_mask >= 3));
170 167
     }
171 168
     SERIAL_ECHO_START();
172 169
     SERIAL_ECHOPGM(STR_DUPLICATION_MODE);

+ 2
- 2
Marlin/src/gcode/feature/pause/M600.cpp View File

@@ -87,7 +87,7 @@ void GcodeSuite::M600() {
87 87
     if (!parser.seen('T')) {  // If no tool index is specified, M600 was (probably) sent in response to filament runout.
88 88
                               // In this case, for duplicating modes set DXC_ext to the extruder that ran out.
89 89
       #if HAS_FILAMENT_SENSOR && NUM_RUNOUT_SENSORS > 1
90
-        if (dxc_is_duplicating())
90
+        if (idex_is_duplicating())
91 91
           DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_STATE) ? 1 : 0;
92 92
       #else
93 93
         DXC_ext = active_extruder;
@@ -108,7 +108,7 @@ void GcodeSuite::M600() {
108 108
   #if HAS_MULTI_EXTRUDER
109 109
     // Change toolhead if specified
110 110
     const uint8_t active_extruder_before_filament_change = active_extruder;
111
-    if (active_extruder != target_extruder && TERN1(DUAL_X_CARRIAGE, !dxc_is_duplicating()))
111
+    if (active_extruder != target_extruder && TERN1(DUAL_X_CARRIAGE, !idex_is_duplicating()))
112 112
       tool_change(target_extruder, false);
113 113
   #endif
114 114
 

+ 2
- 2
Marlin/src/gcode/temp/M104_M109.cpp View File

@@ -94,7 +94,7 @@ void GcodeSuite::M104() {
94 94
     thermalManager.setTargetHotend(temp, target_extruder);
95 95
 
96 96
     #if ENABLED(DUAL_X_CARRIAGE)
97
-      if (dxc_is_duplicating() && target_extruder == 0)
97
+      if (idex_is_duplicating() && target_extruder == 0)
98 98
         thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
99 99
     #endif
100 100
 
@@ -172,7 +172,7 @@ void GcodeSuite::M109() {
172 172
     thermalManager.setTargetHotend(temp, target_extruder);
173 173
 
174 174
     #if ENABLED(DUAL_X_CARRIAGE)
175
-      if (dxc_is_duplicating() && target_extruder == 0)
175
+      if (idex_is_duplicating() && target_extruder == 0)
176 176
         thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1);
177 177
     #endif
178 178
 

+ 2
- 2
Marlin/src/libs/L64XX/L64XX_Marlin.cpp View File

@@ -62,11 +62,11 @@ const uint8_t L64XX_Marlin::index_to_dir[MAX_L64XX] = {
62 62
   INVERT_X_DIR, INVERT_Y_DIR, INVERT_Z_DIR
63 63
   , (INVERT_X_DIR)                            // X2
64 64
     #if ENABLED(X_DUAL_STEPPER_DRIVERS)
65
-      ^ (INVERT_X2_VS_X_DIR)
65
+      ^ ENABLED(INVERT_X2_VS_X_DIR)
66 66
     #endif
67 67
   , (INVERT_Y_DIR)                            // Y2
68 68
     #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
69
-      ^ (INVERT_Y2_VS_Y_DIR)
69
+      ^ ENABLED(INVERT_Y2_VS_Y_DIR)
70 70
     #endif
71 71
   , INVERT_Z_DIR, INVERT_Z_DIR, INVERT_Z_DIR  // Z2,Z3,Z4
72 72
 

+ 60
- 37
Marlin/src/module/motion.cpp View File

@@ -569,7 +569,7 @@ void restore_feedrate_and_scaling() {
569 569
           soft_endstop.min.x = X2_MIN_POS;
570 570
           soft_endstop.max.x = dual_max_x;
571 571
         }
572
-        else if (dxc_is_duplicating()) {
572
+        else if (idex_is_duplicating()) {
573 573
           // In Duplication Mode, T0 can move as far left as X1_MIN_POS
574 574
           // but not so far to the right that T1 would move past the end
575 575
           soft_endstop.min.x = X1_MIN_POS;
@@ -932,8 +932,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
932 932
 #endif // !UBL_SEGMENTED
933 933
 
934 934
 #if HAS_DUPLICATION_MODE
935
-  bool extruder_duplication_enabled,
936
-       mirrored_duplication_mode;
935
+  bool extruder_duplication_enabled;
937 936
   #if ENABLED(MULTI_NOZZLE_DUPLICATION)
938 937
     uint8_t duplication_e_mask; // = 0
939 938
   #endif
@@ -942,12 +941,13 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
942 941
 #if ENABLED(DUAL_X_CARRIAGE)
943 942
 
944 943
   DualXMode dual_x_carriage_mode         = DEFAULT_DUAL_X_CARRIAGE_MODE;
945
-  float inactive_extruder_x_pos          = X2_MAX_POS,                    // used in mode 0 & 1
946
-        duplicate_extruder_x_offset      = DEFAULT_DUPLICATION_X_OFFSET;  // used in mode 2
947
-  xyz_pos_t raised_parked_position;                                       // used in mode 1
948
-  bool active_extruder_parked            = false;                         // used in mode 1 & 2
949
-  millis_t delayed_move_time             = 0;                             // used in mode 1
950
-  int16_t duplicate_extruder_temp_offset = 0;                             // used in mode 2
944
+  float inactive_extruder_x              = X2_MAX_POS,                    // Used in mode 0 & 1
945
+        duplicate_extruder_x_offset      = DEFAULT_DUPLICATION_X_OFFSET;  // Used in mode 2
946
+  xyz_pos_t raised_parked_position;                                       // Used in mode 1
947
+  bool active_extruder_parked            = false;                         // Used in mode 1 & 2
948
+  millis_t delayed_move_time             = 0;                             // Used in mode 1
949
+  int16_t duplicate_extruder_temp_offset = 0;                             // Used in mode 2
950
+  bool idex_mirrored_mode                = false;                         // Used in mode 3
951 951
 
952 952
   float x_home_pos(const uint8_t extruder) {
953 953
     if (extruder == 0)
@@ -962,6 +962,23 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
962 962
       return hotend_offset[1].x > 0 ? hotend_offset[1].x : X2_HOME_POS;
963 963
   }
964 964
 
965
+  void idex_set_mirrored_mode(const bool mirr) {
966
+    idex_mirrored_mode = mirr;
967
+    stepper.set_directions();
968
+  }
969
+
970
+  void set_duplication_enabled(const bool dupe, const int8_t tool_index/*=-1*/) {
971
+    extruder_duplication_enabled = dupe;
972
+    if (tool_index >= 0) active_extruder = tool_index;
973
+    stepper.set_directions();
974
+  }
975
+
976
+  void idex_set_parked(const bool park/*=true*/) {
977
+    delayed_move_time = 0;
978
+    active_extruder_parked = park;
979
+    if (park) raised_parked_position = current_position;  // Remember current raised toolhead position for use by unpark
980
+  }
981
+
965 982
   /**
966 983
    * Prepare a linear move in a dual X axis setup
967 984
    *
@@ -970,9 +987,10 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
970 987
   inline bool dual_x_carriage_unpark() {
971 988
     if (active_extruder_parked) {
972 989
       switch (dual_x_carriage_mode) {
973
-        case DXC_FULL_CONTROL_MODE:
974
-          break;
975
-        case DXC_AUTO_PARK_MODE:
990
+
991
+        case DXC_FULL_CONTROL_MODE: break;
992
+
993
+        case DXC_AUTO_PARK_MODE: {
976 994
           if (current_position.e == destination.e) {
977 995
             // This is a travel move (with no extrusion)
978 996
             // Skip it, but keep track of the current position
@@ -984,23 +1002,27 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
984 1002
               return true;
985 1003
             }
986 1004
           }
987
-          // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
988
-
989
-            #define CUR_X    current_position.x
990
-            #define CUR_Y    current_position.y
991
-            #define CUR_Z    current_position.z
992
-            #define CUR_E    current_position.e
993
-            #define RAISED_X raised_parked_position.x
994
-            #define RAISED_Y raised_parked_position.y
995
-            #define RAISED_Z raised_parked_position.z
996
-
997
-            if (  planner.buffer_line(RAISED_X, RAISED_Y, RAISED_Z, CUR_E, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder))
998
-              if (planner.buffer_line(   CUR_X,    CUR_Y, RAISED_Z, CUR_E, PLANNER_XY_FEEDRATE(),             active_extruder))
999
-                  line_to_current_position(planner.settings.max_feedrate_mm_s[Z_AXIS]);
1000
-          delayed_move_time = 0;
1001
-          active_extruder_parked = false;
1002
-          if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Clear active_extruder_parked");
1003
-          break;
1005
+          //
1006
+          // Un-park the active extruder
1007
+          //
1008
+          const feedRate_t fr_zfast = planner.settings.max_feedrate_mm_s[Z_AXIS];
1009
+          #define CURPOS current_position
1010
+          #define RAISED raised_parked_position
1011
+          //  1. Move to the raised parked XYZ. Presumably the tool is already at XY.
1012
+          if (planner.buffer_line(RAISED.x, RAISED.y, RAISED.z, CURPOS.e, fr_zfast, active_extruder)) {
1013
+            //  2. Move to the current native XY and raised Z. Presumably this is a null move.
1014
+            if (planner.buffer_line(CURPOS.x, CURPOS.y, RAISED.z, CURPOS.e, PLANNER_XY_FEEDRATE(), active_extruder)) {
1015
+              //  3. Lower Z back down
1016
+              line_to_current_position(fr_zfast);
1017
+            }
1018
+          }
1019
+          planner.synchronize(); // paranoia
1020
+          stepper.set_directions();
1021
+
1022
+          idex_set_parked(false);
1023
+          if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("idex_set_parked(false)");
1024
+        } break;
1025
+
1004 1026
         case DXC_MIRRORED_MODE:
1005 1027
         case DXC_DUPLICATION_MODE:
1006 1028
           if (active_extruder == 0) {
@@ -1008,22 +1030,23 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
1008 1030
             if (dual_x_carriage_mode == DXC_DUPLICATION_MODE)
1009 1031
               new_pos.x += duplicate_extruder_x_offset;
1010 1032
             else
1011
-              new_pos.x = inactive_extruder_x_pos;
1012
-            // move duplicate extruder into correct duplication position.
1013
-            if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Set planner X", inactive_extruder_x_pos, " ... Line to X", new_pos.x);
1014
-            planner.set_position_mm(inactive_extruder_x_pos, current_position.y, current_position.z, current_position.e);
1033
+              new_pos.x = inactive_extruder_x;
1034
+            // Move duplicate extruder into correct duplication position.
1035
+            if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Set planner X", inactive_extruder_x, " ... Line to X", new_pos.x);
1036
+            planner.set_position_mm(inactive_extruder_x, current_position.y, current_position.z, current_position.e);
1015 1037
             if (!planner.buffer_line(new_pos, planner.settings.max_feedrate_mm_s[X_AXIS], 1)) break;
1038
+
1016 1039
             planner.synchronize();
1017 1040
             sync_plan_position();
1018
-            extruder_duplication_enabled = true;
1019
-            active_extruder_parked = false;
1020
-            if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Set extruder_duplication_enabled\nClear active_extruder_parked");
1041
+
1042
+            set_duplication_enabled(true);
1043
+            idex_set_parked(false);
1044
+            if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("set_duplication_enabled(true)\nidex_set_parked(false)");
1021 1045
           }
1022 1046
           else if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Active extruder not 0");
1023 1047
           break;
1024 1048
       }
1025 1049
     }
1026
-    stepper.set_directions();
1027 1050
     return false;
1028 1051
   }
1029 1052
 

+ 9
- 4
Marlin/src/module/motion.h View File

@@ -384,8 +384,7 @@ bool homing_needed_error(uint8_t axis_bits=0x07);
384 384
  * Duplication mode
385 385
  */
386 386
 #if HAS_DUPLICATION_MODE
387
-  extern bool extruder_duplication_enabled,       // Used in Dual X mode 2
388
-              mirrored_duplication_mode;          // Used in Dual X mode 3
387
+  extern bool extruder_duplication_enabled;       // Used in Dual X mode 2
389 388
   #if ENABLED(MULTI_NOZZLE_DUPLICATION)
390 389
     extern uint8_t duplication_e_mask;
391 390
   #endif
@@ -404,23 +403,29 @@ bool homing_needed_error(uint8_t axis_bits=0x07);
404 403
   };
405 404
 
406 405
   extern DualXMode dual_x_carriage_mode;
407
-  extern float inactive_extruder_x_pos,           // Used in mode 0 & 1
406
+  extern float inactive_extruder_x,               // Used in mode 0 & 1
408 407
                duplicate_extruder_x_offset;       // Used in mode 2 & 3
409 408
   extern xyz_pos_t raised_parked_position;        // Used in mode 1
410 409
   extern bool active_extruder_parked;             // Used in mode 1, 2 & 3
411 410
   extern millis_t delayed_move_time;              // Used in mode 1
412 411
   extern int16_t duplicate_extruder_temp_offset;  // Used in mode 2 & 3
412
+  extern bool idex_mirrored_mode;                 // Used in mode 3
413 413
 
414
-  FORCE_INLINE bool dxc_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; }
414
+  FORCE_INLINE bool idex_is_duplicating() { return dual_x_carriage_mode >= DXC_DUPLICATION_MODE; }
415 415
 
416 416
   float x_home_pos(const uint8_t extruder);
417 417
 
418 418
   FORCE_INLINE int x_home_dir(const uint8_t extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; }
419 419
 
420
+  void set_duplication_enabled(const bool dupe, const int8_t tool_index=-1);
421
+  void idex_set_mirrored_mode(const bool mirr);
422
+  void idex_set_parked(const bool park=true);
423
+
420 424
 #else
421 425
 
422 426
   #if ENABLED(MULTI_NOZZLE_DUPLICATION)
423 427
     enum DualXMode : char { DXC_DUPLICATION_MODE = 2 };
428
+    FORCE_INLINE void set_duplication_enabled(const bool dupe) { extruder_duplication_enabled = dupe; }
424 429
   #endif
425 430
 
426 431
   FORCE_INLINE int x_home_dir(const uint8_t) { return home_dir(X_AXIS); }

+ 14
- 23
Marlin/src/module/stepper.cpp View File

@@ -348,7 +348,7 @@ xyze_int8_t Stepper::count_direction{0};
348 348
   }
349 349
 
350 350
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
351
-  #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)
351
+  #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) ^ ENABLED(INVERT_X2_VS_X_DIR)); }while(0)
352 352
   #if ENABLED(X_DUAL_ENDSTOPS)
353 353
     #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v)
354 354
   #else
@@ -356,7 +356,7 @@ xyze_int8_t Stepper::count_direction{0};
356 356
   #endif
357 357
 #elif ENABLED(DUAL_X_CARRIAGE)
358 358
   #define X_APPLY_DIR(v,ALWAYS) do{ \
359
-    if (extruder_duplication_enabled || ALWAYS) { X_DIR_WRITE(v); X2_DIR_WRITE(mirrored_duplication_mode ? !(v) : v); } \
359
+    if (extruder_duplication_enabled || ALWAYS) { X_DIR_WRITE(v); X2_DIR_WRITE((v) ^ idex_mirrored_mode); } \
360 360
     else if (last_moved_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
361 361
   }while(0)
362 362
   #define X_APPLY_STEP(v,ALWAYS) do{ \
@@ -369,7 +369,7 @@ xyze_int8_t Stepper::count_direction{0};
369 369
 #endif
370 370
 
371 371
 #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
372
-  #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0)
372
+  #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) ^ ENABLED(INVERT_Y2_VS_Y_DIR)); }while(0)
373 373
   #if ENABLED(Y_DUAL_ENDSTOPS)
374 374
     #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v)
375 375
   #else
@@ -1605,10 +1605,9 @@ void Stepper::pulse_phase_isr() {
1605 1605
               PAGE_SEGMENT_UPDATE(Z, high >> 4);
1606 1606
               PAGE_SEGMENT_UPDATE(E, high & 0xF);
1607 1607
 
1608
-              if (dm != last_direction_bits) {
1609
-                last_direction_bits = dm;
1610
-                set_directions();
1611
-              }
1608
+              if (dm != last_direction_bits)
1609
+                set_directions(dm);
1610
+
1612 1611
             } break;
1613 1612
 
1614 1613
             default: break;
@@ -2131,9 +2130,7 @@ uint32_t Stepper::block_phase_isr() {
2131 2130
         MIXER_STEPPER_SETUP();
2132 2131
       #endif
2133 2132
 
2134
-      #if HAS_MULTI_EXTRUDER
2135
-        stepper_extruder = current_block->extruder;
2136
-      #endif
2133
+      TERN_(HAS_MULTI_EXTRUDER, stepper_extruder = current_block->extruder);
2137 2134
 
2138 2135
       // Initialize the trapezoid generator from the current block.
2139 2136
       #if ENABLED(LIN_ADVANCE)
@@ -2151,17 +2148,14 @@ uint32_t Stepper::block_phase_isr() {
2151 2148
         else LA_isr_rate = LA_ADV_NEVER;
2152 2149
       #endif
2153 2150
 
2154
-      if ( ENABLED(HAS_L64XX)  // Always set direction for L64xx (Also enables the chips)
2151
+      if ( ENABLED(HAS_L64XX)       // Always set direction for L64xx (Also enables the chips)
2152
+        || ENABLED(DUAL_X_CARRIAGE) // TODO: Find out why this fixes "jittery" small circles
2155 2153
         || current_block->direction_bits != last_direction_bits
2156 2154
         || TERN(MIXING_EXTRUDER, false, stepper_extruder != last_moved_extruder)
2157 2155
       ) {
2158
-        last_direction_bits = current_block->direction_bits;
2159
-        #if HAS_MULTI_EXTRUDER
2160
-          last_moved_extruder = stepper_extruder;
2161
-        #endif
2162
-
2156
+        TERN_(HAS_MULTI_EXTRUDER, last_moved_extruder = stepper_extruder);
2163 2157
         TERN_(HAS_L64XX, L64XX_OK_to_power_up = true);
2164
-        set_directions();
2158
+        set_directions(current_block->direction_bits);
2165 2159
       }
2166 2160
 
2167 2161
       #if ENABLED(LASER_POWER_INLINE)
@@ -2583,12 +2577,9 @@ void Stepper::init() {
2583 2577
   #endif
2584 2578
 
2585 2579
   // Init direction bits for first moves
2586
-  last_direction_bits = 0
2587
-    | (INVERT_X_DIR ? _BV(X_AXIS) : 0)
2588
-    | (INVERT_Y_DIR ? _BV(Y_AXIS) : 0)
2589
-    | (INVERT_Z_DIR ? _BV(Z_AXIS) : 0);
2590
-
2591
-  set_directions();
2580
+  set_directions((INVERT_X_DIR ? _BV(X_AXIS) : 0)
2581
+               | (INVERT_Y_DIR ? _BV(Y_AXIS) : 0)
2582
+               | (INVERT_Z_DIR ? _BV(Z_AXIS) : 0));
2592 2583
 
2593 2584
   #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
2594 2585
     initialized = true;

+ 7
- 1
Marlin/src/module/stepper.h View File

@@ -514,9 +514,15 @@ class Stepper {
514 514
       static void refresh_motor_power();
515 515
     #endif
516 516
 
517
-    // Set direction bits for all steppers
517
+    // Update direction states for all steppers
518 518
     static void set_directions();
519 519
 
520
+    // Set direction bits and update all stepper DIR states
521
+    static void set_directions(const uint8_t bits) {
522
+      last_direction_bits = bits;
523
+      set_directions();
524
+    }
525
+
520 526
   private:
521 527
 
522 528
     // Set the current position in steps

+ 26
- 15
Marlin/src/module/tool_change.cpp View File

@@ -61,6 +61,10 @@
61 61
   #include "../gcode/gcode.h"
62 62
 #endif
63 63
 
64
+#if ENABLED(DUAL_X_CARRIAGE)
65
+  #include "stepper.h"
66
+#endif
67
+
64 68
 #if ANY(SWITCHING_EXTRUDER, SWITCHING_NOZZLE, SWITCHING_TOOLHEAD)
65 69
   #include "servo.h"
66 70
 #endif
@@ -701,6 +705,13 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
701 705
 
702 706
 #if ENABLED(DUAL_X_CARRIAGE)
703 707
 
708
+  /**
709
+   * @brief Dual X Tool Change
710
+   * @details Change tools, with extra behavior based on current mode
711
+   *
712
+   * @param new_tool Tool index to activate
713
+   * @param no_move Flag indicating no moves should take place
714
+   */
704 715
   inline void dualx_tool_change(const uint8_t new_tool, bool &no_move) {
705 716
 
706 717
     DEBUG_ECHOPGM("Dual X Carriage Mode ");
@@ -711,17 +722,16 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
711 722
       case DXC_MIRRORED_MODE:     DEBUG_ECHOLNPGM("MIRRORED");     break;
712 723
     }
713 724
 
725
+    // Get the home position of the currently-active tool
714 726
     const float xhome = x_home_pos(active_extruder);
715
-    if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE
716
-        && IsRunning() && !no_move
717
-        && (delayed_move_time || current_position.x != xhome)
718
-    ) {
719 727
 
728
+    if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE                  // If Auto-Park mode is enabled
729
+        && IsRunning() && !no_move                                  // ...and movement is permitted
730
+        && (delayed_move_time || current_position.x != xhome)       // ...and delayed_move_time is set OR not "already parked"...
731
+    ) {
720 732
       DEBUG_ECHOLNPAIR("MoveX to ", xhome);
721
-
722
-      // Park old head
723 733
       current_position.x = xhome;
724
-      line_to_current_position(planner.settings.max_feedrate_mm_s[X_AXIS]);
734
+      line_to_current_position(planner.settings.max_feedrate_mm_s[X_AXIS]);   // Park the current head
725 735
       planner.synchronize();
726 736
     }
727 737
 
@@ -736,20 +746,21 @@ inline void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_a
736 746
     switch (dual_x_carriage_mode) {
737 747
       case DXC_FULL_CONTROL_MODE:
738 748
         // New current position is the position of the activated extruder
739
-        current_position.x = inactive_extruder_x_pos;
749
+        current_position.x = inactive_extruder_x;
740 750
         // Save the inactive extruder's position (from the old current_position)
741
-        inactive_extruder_x_pos = destination.x;
751
+        inactive_extruder_x = destination.x;
752
+        DEBUG_ECHOLNPAIR("DXC Full Control curr.x=", current_position.x, " dest.x=", destination.x);
742 753
         break;
743 754
       case DXC_AUTO_PARK_MODE:
744
-        // record current raised toolhead position for use by unpark
745
-        raised_parked_position = current_position;
746
-        active_extruder_parked = true;
747
-        delayed_move_time = 0;
755
+        idex_set_parked();
748 756
         break;
749 757
       default:
750 758
         break;
751 759
     }
752 760
 
761
+    // Ensure X axis DIR pertains to the correct carriage
762
+    stepper.set_directions();
763
+
753 764
     DEBUG_ECHOLNPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no");
754 765
     DEBUG_POS("New extruder (parked)", current_position);
755 766
   }
@@ -875,7 +886,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
875 886
     planner.synchronize();
876 887
 
877 888
     #if ENABLED(DUAL_X_CARRIAGE)  // Only T0 allowed if the Printer is in DXC_DUPLICATION_MODE or DXC_MIRRORED_MODE
878
-      if (new_tool != 0 && dxc_is_duplicating())
889
+      if (new_tool != 0 && idex_is_duplicating())
879 890
          return invalid_extruder_error(new_tool);
880 891
     #endif
881 892
 
@@ -1151,7 +1162,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
1151 1162
           }
1152 1163
         #endif
1153 1164
 
1154
-        TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false);
1165
+        TERN_(DUAL_X_CARRIAGE, idex_set_parked(false));
1155 1166
       }
1156 1167
 
1157 1168
       #if ENABLED(SWITCHING_NOZZLE)

Loading…
Cancel
Save