Browse Source

Added Y_DUAL_STEPPER_DRIVERS

Enables two stepper drivers to be used for the Y axis (useful for
Shapeoko style machines)
Each Y driver can be stepped either the same way or in opposite
directions, accounting for different hardware setups (leadscrew vs. belt
driven)
Richard Miles 10 years ago
parent
commit
7ee275b620
3 changed files with 325 additions and 144 deletions
  1. 67
    6
      Marlin/Configuration_adv.h
  2. 20
    10
      Marlin/Marlin.h
  3. 238
    128
      Marlin/stepper.cpp

+ 67
- 6
Marlin/Configuration_adv.h View File

18
 //#define WATCH_TEMP_PERIOD 40000 //40 seconds
18
 //#define WATCH_TEMP_PERIOD 40000 //40 seconds
19
 //#define WATCH_TEMP_INCREASE 10  //Heat up at least 10 degree in 20 seconds
19
 //#define WATCH_TEMP_INCREASE 10  //Heat up at least 10 degree in 20 seconds
20
 
20
 
21
-// Wait for Cooldown
22
-// This defines if the M109 call should not block if it is cooling down.
23
-// example: From a current temp of 220, you set M109 S200. 
24
-// if CooldownNoWait is defined M109 will not wait for the cooldown to finish
25
-#define CooldownNoWait true
26
-
27
 #ifdef PIDTEMP
21
 #ifdef PIDTEMP
28
   // this adds an experimental additional term to the heatingpower, proportional to the extrusion speed.
22
   // this adds an experimental additional term to the heatingpower, proportional to the extrusion speed.
29
   // if Kc is choosen well, the additional required power due to increased melting should be compensated.
23
   // if Kc is choosen well, the additional required power due to increased melting should be compensated.
152
   #define EXTRUDERS 1
146
   #define EXTRUDERS 1
153
 #endif
147
 #endif
154
 
148
 
149
+// Same again but for Y Axis.
150
+#define Y_DUAL_STEPPER_DRIVERS
151
+
152
+// Define if the two Y drives need to rotate in opposite directions
153
+#define INVERT_Y2_VS_Y_DIR true
154
+
155
+#ifdef Y_DUAL_STEPPER_DRIVERS
156
+  #undef EXTRUDERS
157
+  #define EXTRUDERS 1
158
+#endif
159
+
160
+#ifdef Z_DUAL_STEPPER_DRIVERS && Y_DUAL_STEPPER_DRIVERS
161
+  #error "You cannot have dual drivers for both Y and Z"
162
+#endif 
163
+
164
+// Enable this for dual x-carriage printers. 
165
+// A dual x-carriage design has the advantage that the inactive extruder can be parked which
166
+// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage
167
+// allowing faster printing speeds.
168
+//#define DUAL_X_CARRIAGE
169
+#ifdef DUAL_X_CARRIAGE
170
+// Configuration for second X-carriage
171
+// Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop;
172
+// the second x-carriage always homes to the maximum endstop.
173
+#define X2_MIN_POS 80     // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage
174
+#define X2_MAX_POS 353    // set maximum to the distance between toolheads when both heads are homed 
175
+#define X2_HOME_DIR 1     // the second X-carriage always homes to the maximum endstop position
176
+#define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position 
177
+    // However: In this mode the EXTRUDER_OFFSET_X value for the second extruder provides a software 
178
+    // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops
179
+    // without modifying the firmware (through the "M218 T1 X???" command).
180
+    // Remember: you should set the second extruder x-offset to 0 in your slicer.
181
+
182
+// Pins for second x-carriage stepper driver (defined here to avoid further complicating pins.h)
183
+#define X2_ENABLE_PIN 29
184
+#define X2_STEP_PIN 25
185
+#define X2_DIR_PIN 23
186
+
187
+// There are a few selectable movement modes for dual x-carriages using M605 S<mode>
188
+//    Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results
189
+//                           as long as it supports dual x-carriages. (M605 S0)
190
+//    Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so
191
+//                           that additional slicer support is not required. (M605 S1)
192
+//    Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all  
193
+//                           actions of the first x-carriage. This allows the printer to print 2 arbitrary items at
194
+//                           once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm])
195
+
196
+// This is the default power-up mode which can be later using M605. 
197
+#define DEFAULT_DUAL_X_CARRIAGE_MODE 0 
198
+
199
+// As the x-carriages are independent we can now account for any relative Z offset
200
+#define EXTRUDER1_Z_OFFSET 0.0           // z offset relative to extruder 0
201
+
202
+// Default settings in "Auto-park Mode" 
203
+#define TOOLCHANGE_PARK_ZLIFT   0.2      // the distance to raise Z axis when parking an extruder
204
+#define TOOLCHANGE_UNPARK_ZLIFT 1        // the distance to raise Z axis when unparking an extruder
205
+
206
+// Default x offset in duplication mode (typically set to half print bed width)
207
+#define DEFAULT_DUPLICATION_X_OFFSET 100
208
+
209
+#endif //DUAL_X_CARRIAGE
210
+    
155
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
211
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
156
 #define X_HOME_RETRACT_MM 5 
212
 #define X_HOME_RETRACT_MM 5 
157
 #define Y_HOME_RETRACT_MM 5 
213
 #define Y_HOME_RETRACT_MM 5 
174
 #define DEFAULT_MINIMUMFEEDRATE       0.0     // minimum feedrate
230
 #define DEFAULT_MINIMUMFEEDRATE       0.0     // minimum feedrate
175
 #define DEFAULT_MINTRAVELFEEDRATE     0.0
231
 #define DEFAULT_MINTRAVELFEEDRATE     0.0
176
 
232
 
233
+// Feedrates for manual moves along X, Y, Z, E from panel
234
+#ifdef ULTIPANEL
235
+#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60}  // set the speeds for manual moves (mm/min)
236
+#endif
237
+
177
 // minimum time in microseconds that a movement needs to take if the buffer is emptied.
238
 // minimum time in microseconds that a movement needs to take if the buffer is emptied.
178
 #define DEFAULT_MINSEGMENTTIME        20000
239
 #define DEFAULT_MINSEGMENTTIME        20000
179
 
240
 

+ 20
- 10
Marlin/Marlin.h View File

51
   #define MYSERIAL MSerial
51
   #define MYSERIAL MSerial
52
 #endif
52
 #endif
53
 
53
 
54
-#define SERIAL_PROTOCOL(x) MYSERIAL.print(x);
55
-#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y);
56
-#define SERIAL_PROTOCOLPGM(x) serialprintPGM(PSTR(x));
57
-#define SERIAL_PROTOCOLLN(x) {MYSERIAL.print(x);MYSERIAL.write('\n');}
58
-#define SERIAL_PROTOCOLLNPGM(x) {serialprintPGM(PSTR(x));MYSERIAL.write('\n');}
54
+#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
55
+#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
56
+#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
57
+#define SERIAL_PROTOCOLLN(x) (MYSERIAL.print(x),MYSERIAL.write('\n'))
58
+#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x)),MYSERIAL.write('\n'))
59
 
59
 
60
 
60
 
61
 const char errormagic[] PROGMEM ="Error:";
61
 const char errormagic[] PROGMEM ="Error:";
62
 const char echomagic[] PROGMEM ="echo:";
62
 const char echomagic[] PROGMEM ="echo:";
63
-#define SERIAL_ERROR_START serialprintPGM(errormagic);
63
+#define SERIAL_ERROR_START (serialprintPGM(errormagic))
64
 #define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
64
 #define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
65
 #define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
65
 #define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
66
 #define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
66
 #define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
67
 #define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
67
 #define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
68
 
68
 
69
-#define SERIAL_ECHO_START serialprintPGM(echomagic);
69
+#define SERIAL_ECHO_START (serialprintPGM(echomagic))
70
 #define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
70
 #define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
71
 #define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
71
 #define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
72
 #define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
72
 #define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
96
 
96
 
97
 void manage_inactivity();
97
 void manage_inactivity();
98
 
98
 
99
-#if defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1
99
+#if defined(DUAL_X_CARRIAGE) && defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 \
100
+    && defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1
101
+  #define  enable_x() do { WRITE(X_ENABLE_PIN, X_ENABLE_ON); WRITE(X2_ENABLE_PIN, X_ENABLE_ON); } while (0)
102
+  #define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); } while (0)
103
+#elif defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1
100
   #define  enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON)
104
   #define  enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON)
101
   #define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON)
105
   #define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON)
102
 #else
106
 #else
105
 #endif
109
 #endif
106
 
110
 
107
 #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
111
 #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
108
-  #define  enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
109
-  #define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON)
112
+  #ifdef Y_DUAL_STEPPER_DRIVERS
113
+    #define  enable_y() { WRITE(Y_ENABLE_PIN, Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN,  Y_ENABLE_ON); }
114
+    #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); }
115
+  #else
116
+    #define  enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
117
+    #define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON)
118
+  #endif
110
 #else
119
 #else
111
   #define enable_y() ;
120
   #define enable_y() ;
112
   #define disable_y() ;
121
   #define disable_y() ;
159
 void get_coordinates();
168
 void get_coordinates();
160
 #ifdef DELTA
169
 #ifdef DELTA
161
 void calculate_delta(float cartesian[3]);
170
 void calculate_delta(float cartesian[3]);
171
+extern float delta[3];
162
 #endif
172
 #endif
163
 void prepare_move();
173
 void prepare_move();
164
 void kill();
174
 void kill();

+ 238
- 128
Marlin/stepper.cpp View File

48
 // Variables used by The Stepper Driver Interrupt
48
 // Variables used by The Stepper Driver Interrupt
49
 static unsigned char out_bits;        // The next stepping-bits to be output
49
 static unsigned char out_bits;        // The next stepping-bits to be output
50
 static long counter_x,       // Counter variables for the bresenham line tracer
50
 static long counter_x,       // Counter variables for the bresenham line tracer
51
-            counter_y, 
52
-            counter_z,       
51
+            counter_y,
52
+            counter_z,
53
             counter_e;
53
             counter_e;
54
 volatile static unsigned long step_events_completed; // The number of step events executed in the current block
54
 volatile static unsigned long step_events_completed; // The number of step events executed in the current block
55
 #ifdef ADVANCE
55
 #ifdef ADVANCE
224
 //   |               BLOCK 1            |      BLOCK 2          |    d
224
 //   |               BLOCK 1            |      BLOCK 2          |    d
225
 //
225
 //
226
 //                           time ----->
226
 //                           time ----->
227
-// 
228
-//  The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates 
229
-//  first block->accelerate_until step_events_completed, then keeps going at constant speed until 
227
+//
228
+//  The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
229
+//  first block->accelerate_until step_events_completed, then keeps going at constant speed until
230
 //  step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
230
 //  step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
231
 //  The slope of acceleration is calculated with the leib ramp alghorithm.
231
 //  The slope of acceleration is calculated with the leib ramp alghorithm.
232
 
232
 
233
 void st_wake_up() {
233
 void st_wake_up() {
234
   //  TCNT1 = 0;
234
   //  TCNT1 = 0;
235
-  ENABLE_STEPPER_DRIVER_INTERRUPT();  
235
+  ENABLE_STEPPER_DRIVER_INTERRUPT();
236
 }
236
 }
237
 
237
 
238
 void step_wait(){
238
 void step_wait(){
239
     for(int8_t i=0; i < 6; i++){
239
     for(int8_t i=0; i < 6; i++){
240
     }
240
     }
241
 }
241
 }
242
-  
242
+
243
 
243
 
244
 FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
244
 FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
245
   unsigned short timer;
245
   unsigned short timer;
246
   if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
246
   if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
247
-  
247
+
248
   if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
248
   if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
249
     step_rate = (step_rate >> 2)&0x3fff;
249
     step_rate = (step_rate >> 2)&0x3fff;
250
     step_loops = 4;
250
     step_loops = 4;
255
   }
255
   }
256
   else {
256
   else {
257
     step_loops = 1;
257
     step_loops = 1;
258
-  } 
259
-  
258
+  }
259
+
260
   if(step_rate < (F_CPU/500000)) step_rate = (F_CPU/500000);
260
   if(step_rate < (F_CPU/500000)) step_rate = (F_CPU/500000);
261
   step_rate -= (F_CPU/500000); // Correct for minimal speed
261
   step_rate -= (F_CPU/500000); // Correct for minimal speed
262
-  if(step_rate >= (8*256)){ // higher step rate 
262
+  if(step_rate >= (8*256)){ // higher step rate
263
     unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
263
     unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
264
     unsigned char tmp_step_rate = (step_rate & 0x00ff);
264
     unsigned char tmp_step_rate = (step_rate & 0x00ff);
265
     unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
265
     unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
276
   return timer;
276
   return timer;
277
 }
277
 }
278
 
278
 
279
-// Initializes the trapezoid generator from the current block. Called whenever a new 
279
+// Initializes the trapezoid generator from the current block. Called whenever a new
280
 // block begins.
280
 // block begins.
281
 FORCE_INLINE void trapezoid_generator_reset() {
281
 FORCE_INLINE void trapezoid_generator_reset() {
282
   #ifdef ADVANCE
282
   #ifdef ADVANCE
284
     final_advance = current_block->final_advance;
284
     final_advance = current_block->final_advance;
285
     // Do E steps + advance steps
285
     // Do E steps + advance steps
286
     e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
286
     e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
287
-    old_advance = advance >>8;  
287
+    old_advance = advance >>8;
288
   #endif
288
   #endif
289
   deceleration_time = 0;
289
   deceleration_time = 0;
290
   // step_rate to timer interval
290
   // step_rate to timer interval
294
   acc_step_rate = current_block->initial_rate;
294
   acc_step_rate = current_block->initial_rate;
295
   acceleration_time = calc_timer(acc_step_rate);
295
   acceleration_time = calc_timer(acc_step_rate);
296
   OCR1A = acceleration_time;
296
   OCR1A = acceleration_time;
297
-  
297
+
298
 //    SERIAL_ECHO_START;
298
 //    SERIAL_ECHO_START;
299
 //    SERIAL_ECHOPGM("advance :");
299
 //    SERIAL_ECHOPGM("advance :");
300
 //    SERIAL_ECHO(current_block->advance/256.0);
300
 //    SERIAL_ECHO(current_block->advance/256.0);
304
 //  SERIAL_ECHO(current_block->initial_advance/256.0);
304
 //  SERIAL_ECHO(current_block->initial_advance/256.0);
305
 //    SERIAL_ECHOPGM("final advance :");
305
 //    SERIAL_ECHOPGM("final advance :");
306
 //    SERIAL_ECHOLN(current_block->final_advance/256.0);
306
 //    SERIAL_ECHOLN(current_block->final_advance/256.0);
307
-    
307
+
308
 }
308
 }
309
 
309
 
310
-// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.  
311
-// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. 
310
+// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
311
+// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
312
 ISR(TIMER1_COMPA_vect)
312
 ISR(TIMER1_COMPA_vect)
313
-{    
313
+{
314
   // If there is no current block, attempt to pop one from the buffer
314
   // If there is no current block, attempt to pop one from the buffer
315
   if (current_block == NULL) {
315
   if (current_block == NULL) {
316
     // Anything in the buffer?
316
     // Anything in the buffer?
322
       counter_y = counter_x;
322
       counter_y = counter_x;
323
       counter_z = counter_x;
323
       counter_z = counter_x;
324
       counter_e = counter_x;
324
       counter_e = counter_x;
325
-      step_events_completed = 0; 
326
-      
327
-      #ifdef Z_LATE_ENABLE 
325
+      step_events_completed = 0;
326
+
327
+      #ifdef Z_LATE_ENABLE
328
         if(current_block->steps_z > 0) {
328
         if(current_block->steps_z > 0) {
329
           enable_z();
329
           enable_z();
330
           OCR1A = 2000; //1ms wait
330
           OCR1A = 2000; //1ms wait
331
           return;
331
           return;
332
         }
332
         }
333
       #endif
333
       #endif
334
-      
334
+
335
 //      #ifdef ADVANCE
335
 //      #ifdef ADVANCE
336
 //      e_steps[current_block->active_extruder] = 0;
336
 //      e_steps[current_block->active_extruder] = 0;
337
 //      #endif
337
 //      #endif
338
-    } 
338
+    }
339
     else {
339
     else {
340
         OCR1A=2000; // 1kHz.
340
         OCR1A=2000; // 1kHz.
341
-    }    
342
-  } 
341
+    }
342
+  }
343
 
343
 
344
   if (current_block != NULL) {
344
   if (current_block != NULL) {
345
     // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
345
     // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
348
 
348
 
349
     // Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY)
349
     // Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY)
350
     if((out_bits & (1<<X_AXIS))!=0){
350
     if((out_bits & (1<<X_AXIS))!=0){
351
-      WRITE(X_DIR_PIN, INVERT_X_DIR);
351
+      #ifdef DUAL_X_CARRIAGE
352
+        if (extruder_duplication_enabled){
353
+          WRITE(X_DIR_PIN, INVERT_X_DIR);
354
+          WRITE(X2_DIR_PIN, INVERT_X_DIR);
355
+        }
356
+        else{
357
+          if (current_block->active_extruder != 0)
358
+            WRITE(X2_DIR_PIN, INVERT_X_DIR);
359
+          else
360
+            WRITE(X_DIR_PIN, INVERT_X_DIR);
361
+        }
362
+      #else
363
+        WRITE(X_DIR_PIN, INVERT_X_DIR);
364
+      #endif        
352
       count_direction[X_AXIS]=-1;
365
       count_direction[X_AXIS]=-1;
353
     }
366
     }
354
     else{
367
     else{
355
-      WRITE(X_DIR_PIN, !INVERT_X_DIR);
368
+      #ifdef DUAL_X_CARRIAGE
369
+        if (extruder_duplication_enabled){
370
+          WRITE(X_DIR_PIN, !INVERT_X_DIR);
371
+          WRITE(X2_DIR_PIN, !INVERT_X_DIR);
372
+        }
373
+        else{
374
+          if (current_block->active_extruder != 0)
375
+            WRITE(X2_DIR_PIN, !INVERT_X_DIR);
376
+          else
377
+            WRITE(X_DIR_PIN, !INVERT_X_DIR);
378
+        }
379
+      #else
380
+        WRITE(X_DIR_PIN, !INVERT_X_DIR);
381
+      #endif        
356
       count_direction[X_AXIS]=1;
382
       count_direction[X_AXIS]=1;
357
     }
383
     }
358
     if((out_bits & (1<<Y_AXIS))!=0){
384
     if((out_bits & (1<<Y_AXIS))!=0){
359
       WRITE(Y_DIR_PIN, INVERT_Y_DIR);
385
       WRITE(Y_DIR_PIN, INVERT_Y_DIR);
386
+	  
387
+	  #ifdef Y_DUAL_STEPPER_DRIVERS
388
+	    WRITE(Y2_DIR_PIN, !(INVERT_Y_DIR == INVERT_Y2_VS_Y_DIR));
389
+	  #endif
390
+	  
360
       count_direction[Y_AXIS]=-1;
391
       count_direction[Y_AXIS]=-1;
361
     }
392
     }
362
     else{
393
     else{
363
       WRITE(Y_DIR_PIN, !INVERT_Y_DIR);
394
       WRITE(Y_DIR_PIN, !INVERT_Y_DIR);
395
+	  
396
+	  #ifdef Y_DUAL_STEPPER_DRIVERS
397
+	    WRITE(Y2_DIR_PIN, (INVERT_Y_DIR == INVERT_Y2_VS_Y_DIR));
398
+	  #endif
399
+	  
364
       count_direction[Y_AXIS]=1;
400
       count_direction[Y_AXIS]=1;
365
     }
401
     }
366
-    
402
+
367
     // Set direction en check limit switches
403
     // Set direction en check limit switches
368
     #ifndef COREXY
404
     #ifndef COREXY
369
     if ((out_bits & (1<<X_AXIS)) != 0) {   // stepping along -X axis
405
     if ((out_bits & (1<<X_AXIS)) != 0) {   // stepping along -X axis
372
     #endif
408
     #endif
373
       CHECK_ENDSTOPS
409
       CHECK_ENDSTOPS
374
       {
410
       {
375
-        #if defined(X_MIN_PIN) && X_MIN_PIN > -1
376
-          bool x_min_endstop=(READ(X_MIN_PIN) != X_ENDSTOPS_INVERTING);
377
-          if(x_min_endstop && old_x_min_endstop && (current_block->steps_x > 0)) {
378
-            endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
379
-            endstop_x_hit=true;
380
-            step_events_completed = current_block->step_event_count;
381
-          }
382
-          old_x_min_endstop = x_min_endstop;
383
-        #endif
411
+        #ifdef DUAL_X_CARRIAGE
412
+        // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
413
+        if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) 
414
+            || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
415
+        #endif          
416
+        {
417
+          #if defined(X_MIN_PIN) && X_MIN_PIN > -1
418
+            bool x_min_endstop=(READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING);
419
+            if(x_min_endstop && old_x_min_endstop && (current_block->steps_x > 0)) {
420
+              endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
421
+              endstop_x_hit=true;
422
+              step_events_completed = current_block->step_event_count;
423
+            }
424
+            old_x_min_endstop = x_min_endstop;
425
+          #endif
426
+        }
384
       }
427
       }
385
     }
428
     }
386
     else { // +direction
429
     else { // +direction
387
-      CHECK_ENDSTOPS 
430
+      CHECK_ENDSTOPS
388
       {
431
       {
389
-        #if defined(X_MAX_PIN) && X_MAX_PIN > -1
390
-          bool x_max_endstop=(READ(X_MAX_PIN) != X_ENDSTOPS_INVERTING);
391
-          if(x_max_endstop && old_x_max_endstop && (current_block->steps_x > 0)){
392
-            endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
393
-            endstop_x_hit=true;
394
-            step_events_completed = current_block->step_event_count;
395
-          }
396
-          old_x_max_endstop = x_max_endstop;
397
-        #endif
432
+        #ifdef DUAL_X_CARRIAGE
433
+        // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
434
+        if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) 
435
+            || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
436
+        #endif          
437
+        {
438
+          #if defined(X_MAX_PIN) && X_MAX_PIN > -1
439
+            bool x_max_endstop=(READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING);
440
+            if(x_max_endstop && old_x_max_endstop && (current_block->steps_x > 0)){
441
+              endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
442
+              endstop_x_hit=true;
443
+              step_events_completed = current_block->step_event_count;
444
+            }
445
+            old_x_max_endstop = x_max_endstop;
446
+          #endif
447
+        }
398
       }
448
       }
399
     }
449
     }
400
 
450
 
406
       CHECK_ENDSTOPS
456
       CHECK_ENDSTOPS
407
       {
457
       {
408
         #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1
458
         #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1
409
-          bool y_min_endstop=(READ(Y_MIN_PIN) != Y_ENDSTOPS_INVERTING);
459
+          bool y_min_endstop=(READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING);
410
           if(y_min_endstop && old_y_min_endstop && (current_block->steps_y > 0)) {
460
           if(y_min_endstop && old_y_min_endstop && (current_block->steps_y > 0)) {
411
             endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
461
             endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
412
             endstop_y_hit=true;
462
             endstop_y_hit=true;
420
       CHECK_ENDSTOPS
470
       CHECK_ENDSTOPS
421
       {
471
       {
422
         #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1
472
         #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1
423
-          bool y_max_endstop=(READ(Y_MAX_PIN) != Y_ENDSTOPS_INVERTING);
473
+          bool y_max_endstop=(READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING);
424
           if(y_max_endstop && old_y_max_endstop && (current_block->steps_y > 0)){
474
           if(y_max_endstop && old_y_max_endstop && (current_block->steps_y > 0)){
425
             endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
475
             endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
426
             endstop_y_hit=true;
476
             endstop_y_hit=true;
434
     if ((out_bits & (1<<Z_AXIS)) != 0) {   // -direction
484
     if ((out_bits & (1<<Z_AXIS)) != 0) {   // -direction
435
       WRITE(Z_DIR_PIN,INVERT_Z_DIR);
485
       WRITE(Z_DIR_PIN,INVERT_Z_DIR);
436
       
486
       
437
-	  #ifdef Z_DUAL_STEPPER_DRIVERS
487
+      #ifdef Z_DUAL_STEPPER_DRIVERS
438
         WRITE(Z2_DIR_PIN,INVERT_Z_DIR);
488
         WRITE(Z2_DIR_PIN,INVERT_Z_DIR);
439
       #endif
489
       #endif
440
-      
490
+
441
       count_direction[Z_AXIS]=-1;
491
       count_direction[Z_AXIS]=-1;
442
       CHECK_ENDSTOPS
492
       CHECK_ENDSTOPS
443
       {
493
       {
444
         #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
494
         #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
445
-          bool z_min_endstop=(READ(Z_MIN_PIN) != Z_ENDSTOPS_INVERTING);
495
+          bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
446
           if(z_min_endstop && old_z_min_endstop && (current_block->steps_z > 0)) {
496
           if(z_min_endstop && old_z_min_endstop && (current_block->steps_z > 0)) {
447
             endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
497
             endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
448
             endstop_z_hit=true;
498
             endstop_z_hit=true;
455
     else { // +direction
505
     else { // +direction
456
       WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
506
       WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
457
 
507
 
458
-	  #ifdef Z_DUAL_STEPPER_DRIVERS
508
+      #ifdef Z_DUAL_STEPPER_DRIVERS
459
         WRITE(Z2_DIR_PIN,!INVERT_Z_DIR);
509
         WRITE(Z2_DIR_PIN,!INVERT_Z_DIR);
460
       #endif
510
       #endif
461
 
511
 
463
       CHECK_ENDSTOPS
513
       CHECK_ENDSTOPS
464
       {
514
       {
465
         #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1
515
         #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1
466
-          bool z_max_endstop=(READ(Z_MAX_PIN) != Z_ENDSTOPS_INVERTING);
516
+          bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
467
           if(z_max_endstop && old_z_max_endstop && (current_block->steps_z > 0)) {
517
           if(z_max_endstop && old_z_max_endstop && (current_block->steps_z > 0)) {
468
             endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
518
             endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
469
             endstop_z_hit=true;
519
             endstop_z_hit=true;
484
         count_direction[E_AXIS]=1;
534
         count_direction[E_AXIS]=1;
485
       }
535
       }
486
     #endif //!ADVANCE
536
     #endif //!ADVANCE
487
-    
488
 
537
 
489
-    
490
-    for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves) 
538
+
539
+
540
+    for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves)
491
       #ifndef AT90USB
541
       #ifndef AT90USB
492
       MSerial.checkRx(); // Check for serial chars.
542
       MSerial.checkRx(); // Check for serial chars.
493
       #endif
543
       #endif
502
         else {
552
         else {
503
           e_steps[current_block->active_extruder]++;
553
           e_steps[current_block->active_extruder]++;
504
         }
554
         }
505
-      }    
555
+      }
506
       #endif //ADVANCE
556
       #endif //ADVANCE
507
 
557
 
508
         counter_x += current_block->steps_x;
558
         counter_x += current_block->steps_x;
509
         if (counter_x > 0) {
559
         if (counter_x > 0) {
560
+        #ifdef DUAL_X_CARRIAGE
561
+          if (extruder_duplication_enabled){
562
+            WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
563
+            WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN);
564
+          }
565
+          else {
566
+            if (current_block->active_extruder != 0)
567
+              WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN);
568
+            else
569
+              WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
570
+          }
571
+        #else
510
           WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
572
           WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
573
+        #endif        
511
           counter_x -= current_block->step_event_count;
574
           counter_x -= current_block->step_event_count;
512
           count_position[X_AXIS]+=count_direction[X_AXIS];   
575
           count_position[X_AXIS]+=count_direction[X_AXIS];   
576
+        #ifdef DUAL_X_CARRIAGE
577
+          if (extruder_duplication_enabled){
578
+            WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
579
+            WRITE(X2_STEP_PIN, INVERT_X_STEP_PIN);
580
+          }
581
+          else {
582
+            if (current_block->active_extruder != 0)
583
+              WRITE(X2_STEP_PIN, INVERT_X_STEP_PIN);
584
+            else
585
+              WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
586
+          }
587
+        #else
513
           WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
588
           WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
589
+        #endif
514
         }
590
         }
515
-  
591
+
516
         counter_y += current_block->steps_y;
592
         counter_y += current_block->steps_y;
517
         if (counter_y > 0) {
593
         if (counter_y > 0) {
518
           WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
594
           WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
519
-          counter_y -= current_block->step_event_count; 
520
-          count_position[Y_AXIS]+=count_direction[Y_AXIS]; 
595
+		  
596
+		  #ifdef Y_DUAL_STEPPER_DRIVERS
597
+			WRITE(Y2_STEP_PIN, !INVERT_Y_STEP_PIN);
598
+		  #endif
599
+		  
600
+          counter_y -= current_block->step_event_count;
601
+          count_position[Y_AXIS]+=count_direction[Y_AXIS];
521
           WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
602
           WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
603
+		  
604
+		  #ifdef Y_DUAL_STEPPER_DRIVERS
605
+			WRITE(Y2_STEP_PIN, INVERT_Y_STEP_PIN);
606
+		  #endif
522
         }
607
         }
523
-  
608
+
524
       counter_z += current_block->steps_z;
609
       counter_z += current_block->steps_z;
525
       if (counter_z > 0) {
610
       if (counter_z > 0) {
526
         WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);
611
         WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);
527
         
612
         
528
-		#ifdef Z_DUAL_STEPPER_DRIVERS
613
+        #ifdef Z_DUAL_STEPPER_DRIVERS
529
           WRITE(Z2_STEP_PIN, !INVERT_Z_STEP_PIN);
614
           WRITE(Z2_STEP_PIN, !INVERT_Z_STEP_PIN);
530
         #endif
615
         #endif
531
-        
616
+
532
         counter_z -= current_block->step_event_count;
617
         counter_z -= current_block->step_event_count;
533
         count_position[Z_AXIS]+=count_direction[Z_AXIS];
618
         count_position[Z_AXIS]+=count_direction[Z_AXIS];
534
         WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN);
619
         WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN);
535
         
620
         
536
-		#ifdef Z_DUAL_STEPPER_DRIVERS
621
+        #ifdef Z_DUAL_STEPPER_DRIVERS
537
           WRITE(Z2_STEP_PIN, INVERT_Z_STEP_PIN);
622
           WRITE(Z2_STEP_PIN, INVERT_Z_STEP_PIN);
538
         #endif
623
         #endif
539
       }
624
       }
547
           WRITE_E_STEP(INVERT_E_STEP_PIN);
632
           WRITE_E_STEP(INVERT_E_STEP_PIN);
548
         }
633
         }
549
       #endif //!ADVANCE
634
       #endif //!ADVANCE
550
-      step_events_completed += 1;  
635
+      step_events_completed += 1;
551
       if(step_events_completed >= current_block->step_event_count) break;
636
       if(step_events_completed >= current_block->step_event_count) break;
552
     }
637
     }
553
     // Calculare new timer value
638
     // Calculare new timer value
554
     unsigned short timer;
639
     unsigned short timer;
555
     unsigned short step_rate;
640
     unsigned short step_rate;
556
     if (step_events_completed <= (unsigned long int)current_block->accelerate_until) {
641
     if (step_events_completed <= (unsigned long int)current_block->accelerate_until) {
557
-      
642
+
558
       MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
643
       MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
559
       acc_step_rate += current_block->initial_rate;
644
       acc_step_rate += current_block->initial_rate;
560
-      
645
+
561
       // upper limit
646
       // upper limit
562
       if(acc_step_rate > current_block->nominal_rate)
647
       if(acc_step_rate > current_block->nominal_rate)
563
         acc_step_rate = current_block->nominal_rate;
648
         acc_step_rate = current_block->nominal_rate;
573
         //if(advance > current_block->advance) advance = current_block->advance;
658
         //if(advance > current_block->advance) advance = current_block->advance;
574
         // Do E steps + advance steps
659
         // Do E steps + advance steps
575
         e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
660
         e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
576
-        old_advance = advance >>8;  
577
-        
661
+        old_advance = advance >>8;
662
+
578
       #endif
663
       #endif
579
-    } 
580
-    else if (step_events_completed > (unsigned long int)current_block->decelerate_after) {   
664
+    }
665
+    else if (step_events_completed > (unsigned long int)current_block->decelerate_after) {
581
       MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
666
       MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
582
-      
667
+
583
       if(step_rate > acc_step_rate) { // Check step_rate stays positive
668
       if(step_rate > acc_step_rate) { // Check step_rate stays positive
584
         step_rate = current_block->final_rate;
669
         step_rate = current_block->final_rate;
585
       }
670
       }
602
         if(advance < final_advance) advance = final_advance;
687
         if(advance < final_advance) advance = final_advance;
603
         // Do E steps + advance steps
688
         // Do E steps + advance steps
604
         e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
689
         e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
605
-        old_advance = advance >>8;  
690
+        old_advance = advance >>8;
606
       #endif //ADVANCE
691
       #endif //ADVANCE
607
     }
692
     }
608
     else {
693
     else {
611
       step_loops = step_loops_nominal;
696
       step_loops = step_loops_nominal;
612
     }
697
     }
613
 
698
 
614
-    // If current block is finished, reset pointer 
699
+    // If current block is finished, reset pointer
615
     if (step_events_completed >= current_block->step_event_count) {
700
     if (step_events_completed >= current_block->step_event_count) {
616
       current_block = NULL;
701
       current_block = NULL;
617
       plan_discard_current_block();
702
       plan_discard_current_block();
618
-    }   
619
-  } 
703
+    }
704
+  }
620
 }
705
 }
621
 
706
 
622
 #ifdef ADVANCE
707
 #ifdef ADVANCE
635
           WRITE(E0_DIR_PIN, INVERT_E0_DIR);
720
           WRITE(E0_DIR_PIN, INVERT_E0_DIR);
636
           e_steps[0]++;
721
           e_steps[0]++;
637
           WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN);
722
           WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN);
638
-        } 
723
+        }
639
         else if (e_steps[0] > 0) {
724
         else if (e_steps[0] > 0) {
640
           WRITE(E0_DIR_PIN, !INVERT_E0_DIR);
725
           WRITE(E0_DIR_PIN, !INVERT_E0_DIR);
641
           e_steps[0]--;
726
           e_steps[0]--;
649
           WRITE(E1_DIR_PIN, INVERT_E1_DIR);
734
           WRITE(E1_DIR_PIN, INVERT_E1_DIR);
650
           e_steps[1]++;
735
           e_steps[1]++;
651
           WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN);
736
           WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN);
652
-        } 
737
+        }
653
         else if (e_steps[1] > 0) {
738
         else if (e_steps[1] > 0) {
654
           WRITE(E1_DIR_PIN, !INVERT_E1_DIR);
739
           WRITE(E1_DIR_PIN, !INVERT_E1_DIR);
655
           e_steps[1]--;
740
           e_steps[1]--;
664
           WRITE(E2_DIR_PIN, INVERT_E2_DIR);
749
           WRITE(E2_DIR_PIN, INVERT_E2_DIR);
665
           e_steps[2]++;
750
           e_steps[2]++;
666
           WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN);
751
           WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN);
667
-        } 
752
+        }
668
         else if (e_steps[2] > 0) {
753
         else if (e_steps[2] > 0) {
669
           WRITE(E2_DIR_PIN, !INVERT_E2_DIR);
754
           WRITE(E2_DIR_PIN, !INVERT_E2_DIR);
670
           e_steps[2]--;
755
           e_steps[2]--;
680
 {
765
 {
681
   digipot_init(); //Initialize Digipot Motor Current
766
   digipot_init(); //Initialize Digipot Motor Current
682
   microstep_init(); //Initialize Microstepping Pins
767
   microstep_init(); //Initialize Microstepping Pins
683
-  
768
+
684
   //Initialize Dir Pins
769
   //Initialize Dir Pins
685
   #if defined(X_DIR_PIN) && X_DIR_PIN > -1
770
   #if defined(X_DIR_PIN) && X_DIR_PIN > -1
686
     SET_OUTPUT(X_DIR_PIN);
771
     SET_OUTPUT(X_DIR_PIN);
687
   #endif
772
   #endif
688
-  #if defined(Y_DIR_PIN) && Y_DIR_PIN > -1 
773
+  #if defined(X2_DIR_PIN) && X2_DIR_PIN > -1
774
+    SET_OUTPUT(X2_DIR_PIN);
775
+  #endif
776
+  #if defined(Y_DIR_PIN) && Y_DIR_PIN > -1
689
     SET_OUTPUT(Y_DIR_PIN);
777
     SET_OUTPUT(Y_DIR_PIN);
778
+	
779
+	#if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_DIR_PIN) && (Y2_DIR_PIN > -1)
780
+	  SET_OUTPUT(Y2_DIR_PIN);
781
+	#endif
690
   #endif
782
   #endif
691
-  #if defined(Z_DIR_PIN) && Z_DIR_PIN > -1 
783
+  #if defined(Z_DIR_PIN) && Z_DIR_PIN > -1
692
     SET_OUTPUT(Z_DIR_PIN);
784
     SET_OUTPUT(Z_DIR_PIN);
693
 
785
 
694
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && (Z2_DIR_PIN > -1)
786
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && (Z2_DIR_PIN > -1)
695
       SET_OUTPUT(Z2_DIR_PIN);
787
       SET_OUTPUT(Z2_DIR_PIN);
696
     #endif
788
     #endif
697
   #endif
789
   #endif
698
-  #if defined(E0_DIR_PIN) && E0_DIR_PIN > -1 
790
+  #if defined(E0_DIR_PIN) && E0_DIR_PIN > -1
699
     SET_OUTPUT(E0_DIR_PIN);
791
     SET_OUTPUT(E0_DIR_PIN);
700
   #endif
792
   #endif
701
   #if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1)
793
   #if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1)
711
     SET_OUTPUT(X_ENABLE_PIN);
803
     SET_OUTPUT(X_ENABLE_PIN);
712
     if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
804
     if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
713
   #endif
805
   #endif
806
+  #if defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1
807
+    SET_OUTPUT(X2_ENABLE_PIN);
808
+    if(!X_ENABLE_ON) WRITE(X2_ENABLE_PIN,HIGH);
809
+  #endif
714
   #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
810
   #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
715
     SET_OUTPUT(Y_ENABLE_PIN);
811
     SET_OUTPUT(Y_ENABLE_PIN);
716
     if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
812
     if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
813
+	
814
+	#if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_ENABLE_PIN) && (Y2_ENABLE_PIN > -1)
815
+	  SET_OUTPUT(Y2_ENABLE_PIN);
816
+	  if(!Y_ENABLE_ON) WRITE(Y2_ENABLE_PIN,HIGH);
817
+	#endif
717
   #endif
818
   #endif
718
   #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
819
   #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
719
     SET_OUTPUT(Z_ENABLE_PIN);
820
     SET_OUTPUT(Z_ENABLE_PIN);
720
     if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
821
     if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
721
-    
822
+
722
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && (Z2_ENABLE_PIN > -1)
823
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && (Z2_ENABLE_PIN > -1)
723
       SET_OUTPUT(Z2_ENABLE_PIN);
824
       SET_OUTPUT(Z2_ENABLE_PIN);
724
       if(!Z_ENABLE_ON) WRITE(Z2_ENABLE_PIN,HIGH);
825
       if(!Z_ENABLE_ON) WRITE(Z2_ENABLE_PIN,HIGH);
738
   #endif
839
   #endif
739
 
840
 
740
   //endstops and pullups
841
   //endstops and pullups
741
-  
842
+
742
   #if defined(X_MIN_PIN) && X_MIN_PIN > -1
843
   #if defined(X_MIN_PIN) && X_MIN_PIN > -1
743
-    SET_INPUT(X_MIN_PIN); 
844
+    SET_INPUT(X_MIN_PIN);
744
     #ifdef ENDSTOPPULLUP_XMIN
845
     #ifdef ENDSTOPPULLUP_XMIN
745
       WRITE(X_MIN_PIN,HIGH);
846
       WRITE(X_MIN_PIN,HIGH);
746
     #endif
847
     #endif
747
   #endif
848
   #endif
748
-      
849
+
749
   #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1
850
   #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1
750
-    SET_INPUT(Y_MIN_PIN); 
851
+    SET_INPUT(Y_MIN_PIN);
751
     #ifdef ENDSTOPPULLUP_YMIN
852
     #ifdef ENDSTOPPULLUP_YMIN
752
       WRITE(Y_MIN_PIN,HIGH);
853
       WRITE(Y_MIN_PIN,HIGH);
753
     #endif
854
     #endif
754
   #endif
855
   #endif
755
-  
856
+
756
   #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
857
   #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
757
-    SET_INPUT(Z_MIN_PIN); 
858
+    SET_INPUT(Z_MIN_PIN);
758
     #ifdef ENDSTOPPULLUP_ZMIN
859
     #ifdef ENDSTOPPULLUP_ZMIN
759
       WRITE(Z_MIN_PIN,HIGH);
860
       WRITE(Z_MIN_PIN,HIGH);
760
     #endif
861
     #endif
761
   #endif
862
   #endif
762
-      
863
+
763
   #if defined(X_MAX_PIN) && X_MAX_PIN > -1
864
   #if defined(X_MAX_PIN) && X_MAX_PIN > -1
764
-    SET_INPUT(X_MAX_PIN); 
865
+    SET_INPUT(X_MAX_PIN);
765
     #ifdef ENDSTOPPULLUP_XMAX
866
     #ifdef ENDSTOPPULLUP_XMAX
766
       WRITE(X_MAX_PIN,HIGH);
867
       WRITE(X_MAX_PIN,HIGH);
767
     #endif
868
     #endif
768
   #endif
869
   #endif
769
-      
870
+
770
   #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1
871
   #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1
771
-    SET_INPUT(Y_MAX_PIN); 
872
+    SET_INPUT(Y_MAX_PIN);
772
     #ifdef ENDSTOPPULLUP_YMAX
873
     #ifdef ENDSTOPPULLUP_YMAX
773
       WRITE(Y_MAX_PIN,HIGH);
874
       WRITE(Y_MAX_PIN,HIGH);
774
     #endif
875
     #endif
775
   #endif
876
   #endif
776
-  
877
+
777
   #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1
878
   #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1
778
-    SET_INPUT(Z_MAX_PIN); 
879
+    SET_INPUT(Z_MAX_PIN);
779
     #ifdef ENDSTOPPULLUP_ZMAX
880
     #ifdef ENDSTOPPULLUP_ZMAX
780
       WRITE(Z_MAX_PIN,HIGH);
881
       WRITE(Z_MAX_PIN,HIGH);
781
     #endif
882
     #endif
782
   #endif
883
   #endif
783
- 
884
+
784
 
885
 
785
   //Initialize Step Pins
886
   //Initialize Step Pins
786
-  #if defined(X_STEP_PIN) && (X_STEP_PIN > -1) 
887
+  #if defined(X_STEP_PIN) && (X_STEP_PIN > -1)
787
     SET_OUTPUT(X_STEP_PIN);
888
     SET_OUTPUT(X_STEP_PIN);
788
     WRITE(X_STEP_PIN,INVERT_X_STEP_PIN);
889
     WRITE(X_STEP_PIN,INVERT_X_STEP_PIN);
789
     disable_x();
890
     disable_x();
790
-  #endif  
791
-  #if defined(Y_STEP_PIN) && (Y_STEP_PIN > -1) 
891
+  #endif
892
+  #if defined(X2_STEP_PIN) && (X2_STEP_PIN > -1)
893
+    SET_OUTPUT(X2_STEP_PIN);
894
+    WRITE(X2_STEP_PIN,INVERT_X_STEP_PIN);
895
+    disable_x();
896
+  #endif
897
+  #if defined(Y_STEP_PIN) && (Y_STEP_PIN > -1)
792
     SET_OUTPUT(Y_STEP_PIN);
898
     SET_OUTPUT(Y_STEP_PIN);
793
     WRITE(Y_STEP_PIN,INVERT_Y_STEP_PIN);
899
     WRITE(Y_STEP_PIN,INVERT_Y_STEP_PIN);
900
+    #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_STEP_PIN) && (Y2_STEP_PIN > -1)
901
+      SET_OUTPUT(Y2_STEP_PIN);
902
+      WRITE(Y2_STEP_PIN,INVERT_Y_STEP_PIN);
903
+    #endif
794
     disable_y();
904
     disable_y();
795
-  #endif  
796
-  #if defined(Z_STEP_PIN) && (Z_STEP_PIN > -1) 
905
+  #endif
906
+  #if defined(Z_STEP_PIN) && (Z_STEP_PIN > -1)
797
     SET_OUTPUT(Z_STEP_PIN);
907
     SET_OUTPUT(Z_STEP_PIN);
798
     WRITE(Z_STEP_PIN,INVERT_Z_STEP_PIN);
908
     WRITE(Z_STEP_PIN,INVERT_Z_STEP_PIN);
799
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && (Z2_STEP_PIN > -1)
909
     #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && (Z2_STEP_PIN > -1)
801
       WRITE(Z2_STEP_PIN,INVERT_Z_STEP_PIN);
911
       WRITE(Z2_STEP_PIN,INVERT_Z_STEP_PIN);
802
     #endif
912
     #endif
803
     disable_z();
913
     disable_z();
804
-  #endif  
805
-  #if defined(E0_STEP_PIN) && (E0_STEP_PIN > -1) 
914
+  #endif
915
+  #if defined(E0_STEP_PIN) && (E0_STEP_PIN > -1)
806
     SET_OUTPUT(E0_STEP_PIN);
916
     SET_OUTPUT(E0_STEP_PIN);
807
     WRITE(E0_STEP_PIN,INVERT_E_STEP_PIN);
917
     WRITE(E0_STEP_PIN,INVERT_E_STEP_PIN);
808
     disable_e0();
918
     disable_e0();
809
-  #endif  
810
-  #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1) 
919
+  #endif
920
+  #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1)
811
     SET_OUTPUT(E1_STEP_PIN);
921
     SET_OUTPUT(E1_STEP_PIN);
812
     WRITE(E1_STEP_PIN,INVERT_E_STEP_PIN);
922
     WRITE(E1_STEP_PIN,INVERT_E_STEP_PIN);
813
     disable_e1();
923
     disable_e1();
814
-  #endif  
815
-  #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1) 
924
+  #endif
925
+  #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1)
816
     SET_OUTPUT(E2_STEP_PIN);
926
     SET_OUTPUT(E2_STEP_PIN);
817
     WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN);
927
     WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN);
818
     disable_e2();
928
     disable_e2();
819
-  #endif  
929
+  #endif
820
 
930
 
821
   // waveform generation = 0100 = CTC
931
   // waveform generation = 0100 = CTC
822
   TCCR1B &= ~(1<<WGM13);
932
   TCCR1B &= ~(1<<WGM13);
823
   TCCR1B |=  (1<<WGM12);
933
   TCCR1B |=  (1<<WGM12);
824
-  TCCR1A &= ~(1<<WGM11); 
934
+  TCCR1A &= ~(1<<WGM11);
825
   TCCR1A &= ~(1<<WGM10);
935
   TCCR1A &= ~(1<<WGM10);
826
 
936
 
827
   // output mode = 00 (disconnected)
937
   // output mode = 00 (disconnected)
828
-  TCCR1A &= ~(3<<COM1A0); 
829
-  TCCR1A &= ~(3<<COM1B0); 
830
-  
938
+  TCCR1A &= ~(3<<COM1A0);
939
+  TCCR1A &= ~(3<<COM1B0);
940
+
831
   // Set the timer pre-scaler
941
   // Set the timer pre-scaler
832
   // Generally we use a divider of 8, resulting in a 2MHz timer
942
   // Generally we use a divider of 8, resulting in a 2MHz timer
833
   // frequency on a 16MHz MCU. If you are going to change this, be
943
   // frequency on a 16MHz MCU. If you are going to change this, be
837
 
947
 
838
   OCR1A = 0x4000;
948
   OCR1A = 0x4000;
839
   TCNT1 = 0;
949
   TCNT1 = 0;
840
-  ENABLE_STEPPER_DRIVER_INTERRUPT();  
950
+  ENABLE_STEPPER_DRIVER_INTERRUPT();
841
 
951
 
842
   #ifdef ADVANCE
952
   #ifdef ADVANCE
843
   #if defined(TCCR0A) && defined(WGM01)
953
   #if defined(TCCR0A) && defined(WGM01)
844
     TCCR0A &= ~(1<<WGM01);
954
     TCCR0A &= ~(1<<WGM01);
845
     TCCR0A &= ~(1<<WGM00);
955
     TCCR0A &= ~(1<<WGM00);
846
-  #endif  
956
+  #endif
847
     e_steps[0] = 0;
957
     e_steps[0] = 0;
848
     e_steps[1] = 0;
958
     e_steps[1] = 0;
849
     e_steps[2] = 0;
959
     e_steps[2] = 0;
850
     TIMSK0 |= (1<<OCIE0A);
960
     TIMSK0 |= (1<<OCIE0A);
851
   #endif //ADVANCE
961
   #endif //ADVANCE
852
-  
962
+
853
   enable_endstops(true); // Start with endstops active. After homing they can be disabled
963
   enable_endstops(true); // Start with endstops active. After homing they can be disabled
854
   sei();
964
   sei();
855
 }
965
 }
893
 
1003
 
894
 void finishAndDisableSteppers()
1004
 void finishAndDisableSteppers()
895
 {
1005
 {
896
-  st_synchronize(); 
897
-  disable_x(); 
898
-  disable_y(); 
899
-  disable_z(); 
900
-  disable_e0(); 
901
-  disable_e1(); 
902
-  disable_e2(); 
1006
+  st_synchronize();
1007
+  disable_x();
1008
+  disable_y();
1009
+  disable_z();
1010
+  disable_e0();
1011
+  disable_e1();
1012
+  disable_e2();
903
 }
1013
 }
904
 
1014
 
905
 void quickStop()
1015
 void quickStop()
926
 {
1036
 {
927
   #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1
1037
   #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1
928
     const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT;
1038
     const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT;
929
-    
930
-    SPI.begin(); 
931
-    pinMode(DIGIPOTSS_PIN, OUTPUT);    
932
-    for(int i=0;i<=4;i++) 
1039
+
1040
+    SPI.begin();
1041
+    pinMode(DIGIPOTSS_PIN, OUTPUT);
1042
+    for(int i=0;i<=4;i++)
933
       //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
1043
       //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
934
       digipot_current(i,digipot_motor_current[i]);
1044
       digipot_current(i,digipot_motor_current[i]);
935
   #endif
1045
   #endif

Loading…
Cancel
Save