2 stepper.c - stepper motor driver: executes motion plans using stepper motors
5 Copyright (c) 2009-2011 Simen Svale Skogsrud
7 Grbl is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Grbl is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Grbl. If not, see <http://www.gnu.org/licenses/>.
21 /* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
22 and Philipp Tiefenbacher. */
27 #include "temperature.h"
30 #include "speed_lookuptable.h"
34 //===========================================================================
35 //=============================public variables ============================
36 //===========================================================================
37 block_t *current_block; // A pointer to the block currently being traced
40 //===========================================================================
41 //=============================private variables ============================
42 //===========================================================================
43 //static makes it inpossible to be called from outside of this file by extern.!
45 // Variables used by The Stepper Driver Interrupt
46 static unsigned char out_bits; // The next stepping-bits to be output
47 static long counter_x, // Counter variables for the bresenham line tracer
51 volatile static unsigned long step_events_completed; // The number of step events executed in the current block
53 static long advance_rate, advance, final_advance = 0;
54 static long old_advance = 0;
56 static long e_steps[3];
57 static long acceleration_time, deceleration_time;
58 //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
59 static unsigned short acc_step_rate; // needed for deccelaration start point
60 static char step_loops;
61 static unsigned short OCR1A_nominal;
63 volatile long endstops_trigsteps[3]={0,0,0};
64 volatile long endstops_stepsTotal,endstops_stepsDone;
65 static volatile bool endstop_x_hit=false;
66 static volatile bool endstop_y_hit=false;
67 static volatile bool endstop_z_hit=false;
69 static bool old_x_min_endstop=false;
70 static bool old_x_max_endstop=false;
71 static bool old_y_min_endstop=false;
72 static bool old_y_max_endstop=false;
73 static bool old_z_min_endstop=false;
74 static bool old_z_max_endstop=false;
76 static bool check_endstops = true;
78 volatile long count_position[NUM_AXIS] = { 0, 0, 0, 0};
79 volatile char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
81 //===========================================================================
82 //=============================functions ============================
83 //===========================================================================
85 #define CHECK_ENDSTOPS if(check_endstops)
87 // intRes = intIn1 * intIn2 >> 16
90 // r27 to store the byte 1 of the 24 bit result
91 #define MultiU16X8toH16(intRes, charIn1, intIn2) \
100 "adc %A0, r26 \n\t" \
101 "adc %B0, r26 \n\t" \
112 // intRes = longIn1 * longIn2 >> 24
115 // r27 to store the byte 1 of the 48bit result
116 #define MultiU24X24toH16(intRes, longIn1, longIn2) \
119 "mul %A1, %B2 \n\t" \
121 "mul %B1, %C2 \n\t" \
122 "movw %A0, r0 \n\t" \
123 "mul %C1, %C2 \n\t" \
125 "mul %C1, %B2 \n\t" \
128 "mul %A1, %C2 \n\t" \
131 "adc %B0, r26 \n\t" \
132 "mul %B1, %B2 \n\t" \
135 "adc %B0, r26 \n\t" \
136 "mul %C1, %A2 \n\t" \
139 "adc %B0, r26 \n\t" \
140 "mul %B1, %A2 \n\t" \
142 "adc %A0, r26 \n\t" \
143 "adc %B0, r26 \n\t" \
145 "adc %A0, r26 \n\t" \
146 "adc %B0, r26 \n\t" \
157 // Some useful constants
159 #define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= (1<<OCIE1A)
160 #define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~(1<<OCIE1A)
163 void checkHitEndstops()
165 if( endstop_x_hit || endstop_y_hit || endstop_z_hit) {
167 SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT);
169 SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/axis_steps_per_unit[X_AXIS]);
172 SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/axis_steps_per_unit[Y_AXIS]);
175 SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]);
184 void endstops_hit_on_purpose()
191 void enable_endstops(bool check)
193 check_endstops = check;
196 // __________________________
197 // /| |\ _________________ ^
202 // +-----+------------------------+---+--+---------------+----+ e
203 // | BLOCK 1 | BLOCK 2 | d
207 // The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
208 // first block->accelerate_until step_events_completed, then keeps going at constant speed until
209 // step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
210 // The slope of acceleration is calculated with the leib ramp alghorithm.
214 ENABLE_STEPPER_DRIVER_INTERRUPT();
218 for(int8_t i=0; i < 6; i++){
223 FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
224 unsigned short timer;
225 if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
227 if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
228 step_rate = (step_rate >> 2)&0x3fff;
231 else if(step_rate > 10000) { // If steprate > 10kHz >> step 2 times
232 step_rate = (step_rate >> 1)&0x7fff;
239 if(step_rate < (F_CPU/500000)) step_rate = (F_CPU/500000);
240 step_rate -= (F_CPU/500000); // Correct for minimal speed
241 if(step_rate >= (8*256)){ // higher step rate
242 unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
243 unsigned char tmp_step_rate = (step_rate & 0x00ff);
244 unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
245 MultiU16X8toH16(timer, tmp_step_rate, gain);
246 timer = (unsigned short)pgm_read_word_near(table_address) - timer;
248 else { // lower step rates
249 unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];
250 table_address += ((step_rate)>>1) & 0xfffc;
251 timer = (unsigned short)pgm_read_word_near(table_address);
252 timer -= (((unsigned short)pgm_read_word_near(table_address+2) * (unsigned char)(step_rate & 0x0007))>>3);
254 if(timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen)
258 // Initializes the trapezoid generator from the current block. Called whenever a new
260 FORCE_INLINE void trapezoid_generator_reset() {
262 advance = current_block->initial_advance;
263 final_advance = current_block->final_advance;
264 // Do E steps + advance steps
265 e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
266 old_advance = advance >>8;
268 deceleration_time = 0;
269 // step_rate to timer interval
270 OCR1A_nominal = calc_timer(current_block->nominal_rate);
271 acc_step_rate = current_block->initial_rate;
272 acceleration_time = calc_timer(acc_step_rate);
273 OCR1A = acceleration_time;
275 // SERIAL_ECHO_START;
276 // SERIAL_ECHOPGM("advance :");
277 // SERIAL_ECHO(current_block->advance/256.0);
278 // SERIAL_ECHOPGM("advance rate :");
279 // SERIAL_ECHO(current_block->advance_rate/256.0);
280 // SERIAL_ECHOPGM("initial advance :");
281 // SERIAL_ECHO(current_block->initial_advance/256.0);
282 // SERIAL_ECHOPGM("final advance :");
283 // SERIAL_ECHOLN(current_block->final_advance/256.0);
287 // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
288 // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
289 ISR(TIMER1_COMPA_vect)
291 // If there is no current block, attempt to pop one from the buffer
292 if (current_block == NULL) {
293 // Anything in the buffer?
294 current_block = plan_get_current_block();
295 if (current_block != NULL) {
296 current_block->busy = true;
297 trapezoid_generator_reset();
298 counter_x = -(current_block->step_event_count >> 1);
299 counter_y = counter_x;
300 counter_z = counter_x;
301 counter_e = counter_x;
302 step_events_completed = 0;
305 if(current_block->steps_z > 0) {
307 OCR1A = 2000; //1ms wait
313 // e_steps[current_block->active_extruder] = 0;
321 if (current_block != NULL) {
322 // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
323 out_bits = current_block->direction_bits;
325 // Set direction en check limit switches
326 if ((out_bits & (1<<X_AXIS)) != 0) { // stepping along -X axis
327 #if !defined COREXY //NOT COREXY
328 WRITE(X_DIR_PIN, INVERT_X_DIR);
330 count_direction[X_AXIS]=-1;
334 bool x_min_endstop=(READ(X_MIN_PIN) != X_ENDSTOPS_INVERTING);
335 if(x_min_endstop && old_x_min_endstop && (current_block->steps_x > 0)) {
336 endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
338 step_events_completed = current_block->step_event_count;
340 old_x_min_endstop = x_min_endstop;
345 #if !defined COREXY //NOT COREXY
346 WRITE(X_DIR_PIN,!INVERT_X_DIR);
349 count_direction[X_AXIS]=1;
353 bool x_max_endstop=(READ(X_MAX_PIN) != X_ENDSTOPS_INVERTING);
354 if(x_max_endstop && old_x_max_endstop && (current_block->steps_x > 0)){
355 endstops_trigsteps[X_AXIS] = count_position[X_AXIS];
357 step_events_completed = current_block->step_event_count;
359 old_x_max_endstop = x_max_endstop;
364 if ((out_bits & (1<<Y_AXIS)) != 0) { // -direction
365 #if !defined COREXY //NOT COREXY
366 WRITE(Y_DIR_PIN,INVERT_Y_DIR);
368 count_direction[Y_AXIS]=-1;
372 bool y_min_endstop=(READ(Y_MIN_PIN) != Y_ENDSTOPS_INVERTING);
373 if(y_min_endstop && old_y_min_endstop && (current_block->steps_y > 0)) {
374 endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
376 step_events_completed = current_block->step_event_count;
378 old_y_min_endstop = y_min_endstop;
383 #if !defined COREXY //NOT COREXY
384 WRITE(Y_DIR_PIN,!INVERT_Y_DIR);
386 count_direction[Y_AXIS]=1;
390 bool y_max_endstop=(READ(Y_MAX_PIN) != Y_ENDSTOPS_INVERTING);
391 if(y_max_endstop && old_y_max_endstop && (current_block->steps_y > 0)){
392 endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS];
394 step_events_completed = current_block->step_event_count;
396 old_y_max_endstop = y_max_endstop;
402 #ifdef COREXY //coreXY kinematics defined
403 if((current_block->steps_x >= current_block->steps_y)&&((out_bits & (1<<X_AXIS)) == 0)){ //+X is major axis
404 WRITE(X_DIR_PIN, !INVERT_X_DIR);
405 WRITE(Y_DIR_PIN, !INVERT_Y_DIR);
407 if((current_block->steps_x >= current_block->steps_y)&&((out_bits & (1<<X_AXIS)) != 0)){ //-X is major axis
408 WRITE(X_DIR_PIN, INVERT_X_DIR);
409 WRITE(Y_DIR_PIN, INVERT_Y_DIR);
411 if((current_block->steps_y > current_block->steps_x)&&((out_bits & (1<<Y_AXIS)) == 0)){ //+Y is major axis
412 WRITE(X_DIR_PIN, !INVERT_X_DIR);
413 WRITE(Y_DIR_PIN, INVERT_Y_DIR);
415 if((current_block->steps_y > current_block->steps_x)&&((out_bits & (1<<Y_AXIS)) != 0)){ //-Y is major axis
416 WRITE(X_DIR_PIN, INVERT_X_DIR);
417 WRITE(Y_DIR_PIN, !INVERT_Y_DIR);
422 if ((out_bits & (1<<Z_AXIS)) != 0) { // -direction
423 WRITE(Z_DIR_PIN,INVERT_Z_DIR);
424 count_direction[Z_AXIS]=-1;
428 bool z_min_endstop=(READ(Z_MIN_PIN) != Z_ENDSTOPS_INVERTING);
429 if(z_min_endstop && old_z_min_endstop && (current_block->steps_z > 0)) {
430 endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
432 step_events_completed = current_block->step_event_count;
434 old_z_min_endstop = z_min_endstop;
439 WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
440 count_direction[Z_AXIS]=1;
444 bool z_max_endstop=(READ(Z_MAX_PIN) != Z_ENDSTOPS_INVERTING);
445 if(z_max_endstop && old_z_max_endstop && (current_block->steps_z > 0)) {
446 endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
448 step_events_completed = current_block->step_event_count;
450 old_z_max_endstop = z_max_endstop;
456 if ((out_bits & (1<<E_AXIS)) != 0) { // -direction
458 count_direction[E_AXIS]=-1;
462 count_direction[E_AXIS]=1;
468 for(int8_t i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves)
469 #if MOTHERBOARD != 8 // !teensylu
470 MSerial.checkRx(); // Check for serial chars.
474 counter_e += current_block->steps_e;
476 counter_e -= current_block->step_event_count;
477 if ((out_bits & (1<<E_AXIS)) != 0) { // - direction
478 e_steps[current_block->active_extruder]--;
481 e_steps[current_block->active_extruder]++;
487 counter_x += current_block->steps_x;
489 WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
490 counter_x -= current_block->step_event_count;
491 count_position[X_AXIS]+=count_direction[X_AXIS];
492 WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
495 counter_y += current_block->steps_y;
497 WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
498 counter_y -= current_block->step_event_count;
499 count_position[Y_AXIS]+=count_direction[Y_AXIS];
500 WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
505 counter_x += current_block->steps_x;
506 counter_y += current_block->steps_y;
508 if ((counter_x > 0)&&!(counter_y>0)){ //X step only
509 WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
510 WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
511 counter_x -= current_block->step_event_count;
512 count_position[X_AXIS]+=count_direction[X_AXIS];
513 WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
514 WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
517 if (!(counter_x > 0)&&(counter_y>0)){ //Y step only
518 WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
519 WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
520 counter_y -= current_block->step_event_count;
521 count_position[Y_AXIS]+=count_direction[Y_AXIS];
522 WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
523 WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
526 if ((counter_x > 0)&&(counter_y>0)){ //step in both axes
527 if (((out_bits & (1<<X_AXIS)) == 0)^((out_bits & (1<<Y_AXIS)) == 0)){ //X and Y in different directions
528 WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
529 counter_x -= current_block->step_event_count;
530 WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
532 count_position[X_AXIS]+=count_direction[X_AXIS];
533 count_position[Y_AXIS]+=count_direction[Y_AXIS];
534 WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
535 counter_y -= current_block->step_event_count;
536 WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
538 else{ //X and Y in same direction
539 WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
540 counter_x -= current_block->step_event_count;
541 WRITE(X_STEP_PIN, INVERT_X_STEP_PIN) ;
543 count_position[X_AXIS]+=count_direction[X_AXIS];
544 count_position[Y_AXIS]+=count_direction[Y_AXIS];
545 WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
546 counter_y -= current_block->step_event_count;
547 WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
552 counter_z += current_block->steps_z;
554 WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);
555 counter_z -= current_block->step_event_count;
556 count_position[Z_AXIS]+=count_direction[Z_AXIS];
557 WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN);
561 counter_e += current_block->steps_e;
563 WRITE_E_STEP(!INVERT_E_STEP_PIN);
564 counter_e -= current_block->step_event_count;
565 count_position[E_AXIS]+=count_direction[E_AXIS];
566 WRITE_E_STEP(INVERT_E_STEP_PIN);
569 step_events_completed += 1;
570 if(step_events_completed >= current_block->step_event_count) break;
572 // Calculare new timer value
573 unsigned short timer;
574 unsigned short step_rate;
575 if (step_events_completed <= (unsigned long int)current_block->accelerate_until) {
577 MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
578 acc_step_rate += current_block->initial_rate;
581 if(acc_step_rate > current_block->nominal_rate)
582 acc_step_rate = current_block->nominal_rate;
584 // step_rate to timer interval
585 timer = calc_timer(acc_step_rate);
587 acceleration_time += timer;
589 for(int8_t i=0; i < step_loops; i++) {
590 advance += advance_rate;
592 //if(advance > current_block->advance) advance = current_block->advance;
593 // Do E steps + advance steps
594 e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
595 old_advance = advance >>8;
599 else if (step_events_completed > (unsigned long int)current_block->decelerate_after) {
600 MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
602 if(step_rate > acc_step_rate) { // Check step_rate stays positive
603 step_rate = current_block->final_rate;
606 step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point.
610 if(step_rate < current_block->final_rate)
611 step_rate = current_block->final_rate;
613 // step_rate to timer interval
614 timer = calc_timer(step_rate);
616 deceleration_time += timer;
618 for(int8_t i=0; i < step_loops; i++) {
619 advance -= advance_rate;
621 if(advance < final_advance) advance = final_advance;
622 // Do E steps + advance steps
623 e_steps[current_block->active_extruder] += ((advance >>8) - old_advance);
624 old_advance = advance >>8;
628 OCR1A = OCR1A_nominal;
631 // If current block is finished, reset pointer
632 if (step_events_completed >= current_block->step_event_count) {
633 current_block = NULL;
634 plan_discard_current_block();
640 unsigned char old_OCR0A;
641 // Timer interrupt for E. e_steps is set in the main routine;
642 // Timer 0 is shared with millies
643 ISR(TIMER0_COMPA_vect)
645 old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz)
647 // Set E direction (Depends on E direction + advance)
648 for(unsigned char i=0; i<4;i++) {
649 if (e_steps[0] != 0) {
650 WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN);
651 if (e_steps[0] < 0) {
652 WRITE(E0_DIR_PIN, INVERT_E0_DIR);
654 WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN);
656 else if (e_steps[0] > 0) {
657 WRITE(E0_DIR_PIN, !INVERT_E0_DIR);
659 WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN);
663 if (e_steps[1] != 0) {
664 WRITE(E1_STEP_PIN, INVERT_E_STEP_PIN);
665 if (e_steps[1] < 0) {
666 WRITE(E1_DIR_PIN, INVERT_E1_DIR);
668 WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN);
670 else if (e_steps[1] > 0) {
671 WRITE(E1_DIR_PIN, !INVERT_E1_DIR);
673 WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN);
678 if (e_steps[2] != 0) {
679 WRITE(E2_STEP_PIN, INVERT_E_STEP_PIN);
680 if (e_steps[2] < 0) {
681 WRITE(E2_DIR_PIN, INVERT_E2_DIR);
683 WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN);
685 else if (e_steps[2] > 0) {
686 WRITE(E2_DIR_PIN, !INVERT_E2_DIR);
688 WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN);
698 //Initialize Dir Pins
700 SET_OUTPUT(X_DIR_PIN);
703 SET_OUTPUT(Y_DIR_PIN);
706 SET_OUTPUT(Z_DIR_PIN);
709 SET_OUTPUT(E0_DIR_PIN);
711 #if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1)
712 SET_OUTPUT(E1_DIR_PIN);
714 #if defined(E2_DIR_PIN) && (E2_DIR_PIN > -1)
715 SET_OUTPUT(E2_DIR_PIN);
718 //Initialize Enable Pins - steppers default to disabled.
720 #if (X_ENABLE_PIN > -1)
721 SET_OUTPUT(X_ENABLE_PIN);
722 if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
724 #if (Y_ENABLE_PIN > -1)
725 SET_OUTPUT(Y_ENABLE_PIN);
726 if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
728 #if (Z_ENABLE_PIN > -1)
729 SET_OUTPUT(Z_ENABLE_PIN);
730 if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
732 #if (E0_ENABLE_PIN > -1)
733 SET_OUTPUT(E0_ENABLE_PIN);
734 if(!E_ENABLE_ON) WRITE(E0_ENABLE_PIN,HIGH);
736 #if defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
737 SET_OUTPUT(E1_ENABLE_PIN);
738 if(!E_ENABLE_ON) WRITE(E1_ENABLE_PIN,HIGH);
740 #if defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
741 SET_OUTPUT(E2_ENABLE_PIN);
742 if(!E_ENABLE_ON) WRITE(E2_ENABLE_PIN,HIGH);
745 //endstops and pullups
748 SET_INPUT(X_MIN_PIN);
749 #ifdef ENDSTOPPULLUP_XMIN
750 WRITE(X_MIN_PIN,HIGH);
755 SET_INPUT(Y_MIN_PIN);
756 #ifdef ENDSTOPPULLUP_YMIN
757 WRITE(Y_MIN_PIN,HIGH);
762 SET_INPUT(Z_MIN_PIN);
763 #ifdef ENDSTOPPULLUP_ZMIN
764 WRITE(Z_MIN_PIN,HIGH);
769 SET_INPUT(X_MAX_PIN);
770 #ifdef ENDSTOPPULLUP_XMAX
771 WRITE(X_MAX_PIN,HIGH);
776 SET_INPUT(Y_MAX_PIN);
777 #ifdef ENDSTOPPULLUP_YMAX
778 WRITE(Y_MAX_PIN,HIGH);
783 SET_INPUT(Z_MAX_PIN);
784 #ifdef ENDSTOPPULLUP_ZMAX
785 WRITE(Z_MAX_PIN,HIGH);
790 //Initialize Step Pins
791 #if (X_STEP_PIN > -1)
792 SET_OUTPUT(X_STEP_PIN);
793 WRITE(X_STEP_PIN,INVERT_X_STEP_PIN);
794 if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
796 #if (Y_STEP_PIN > -1)
797 SET_OUTPUT(Y_STEP_PIN);
798 WRITE(Y_STEP_PIN,INVERT_Y_STEP_PIN);
799 if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
801 #if (Z_STEP_PIN > -1)
802 SET_OUTPUT(Z_STEP_PIN);
803 WRITE(Z_STEP_PIN,INVERT_Z_STEP_PIN);
804 if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
806 #if (E0_STEP_PIN > -1)
807 SET_OUTPUT(E0_STEP_PIN);
808 WRITE(E0_STEP_PIN,INVERT_E_STEP_PIN);
809 if(!E_ENABLE_ON) WRITE(E0_ENABLE_PIN,HIGH);
811 #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1)
812 SET_OUTPUT(E1_STEP_PIN);
813 WRITE(E1_STEP_PIN,INVERT_E_STEP_PIN);
814 if(!E_ENABLE_ON) WRITE(E1_ENABLE_PIN,HIGH);
816 #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1)
817 SET_OUTPUT(E2_STEP_PIN);
818 WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN);
819 if(!E_ENABLE_ON) WRITE(E2_ENABLE_PIN,HIGH);
822 #ifdef CONTROLLERFAN_PIN
823 SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
826 // waveform generation = 0100 = CTC
827 TCCR1B &= ~(1<<WGM13);
828 TCCR1B |= (1<<WGM12);
829 TCCR1A &= ~(1<<WGM11);
830 TCCR1A &= ~(1<<WGM10);
832 // output mode = 00 (disconnected)
833 TCCR1A &= ~(3<<COM1A0);
834 TCCR1A &= ~(3<<COM1B0);
836 // Set the timer pre-scaler
837 // Generally we use a divider of 8, resulting in a 2MHz timer
838 // frequency on a 16MHz MCU. If you are going to change this, be
839 // sure to regenerate speed_lookuptable.h with
840 // create_speed_lookuptable.py
841 TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10);
845 ENABLE_STEPPER_DRIVER_INTERRUPT();
848 #if defined(TCCR0A) && defined(WGM01)
849 TCCR0A &= ~(1<<WGM01);
850 TCCR0A &= ~(1<<WGM00);
855 TIMSK0 |= (1<<OCIE0A);
858 enable_endstops(true); // Start with endstops active. After homing they can be disabled
863 // Block until all buffered steps are executed
864 void st_synchronize()
866 while( blocks_queued()) {
868 manage_inactivity(1);
873 void st_set_position(const long &x, const long &y, const long &z, const long &e)
875 CRITICAL_SECTION_START;
876 count_position[X_AXIS] = x;
877 count_position[Y_AXIS] = y;
878 count_position[Z_AXIS] = z;
879 count_position[E_AXIS] = e;
880 CRITICAL_SECTION_END;
883 void st_set_e_position(const long &e)
885 CRITICAL_SECTION_START;
886 count_position[E_AXIS] = e;
887 CRITICAL_SECTION_END;
890 long st_get_position(uint8_t axis)
893 CRITICAL_SECTION_START;
894 count_pos = count_position[axis];
895 CRITICAL_SECTION_END;
899 void finishAndDisableSteppers()
902 LCD_MESSAGEPGM(MSG_STEPPER_RELEASED);
913 DISABLE_STEPPER_DRIVER_INTERRUPT();
914 while(blocks_queued())
915 plan_discard_current_block();
916 current_block = NULL;
917 ENABLE_STEPPER_DRIVER_INTERRUPT();