|
@@ -91,8 +91,9 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even
|
91
|
91
|
|
92
|
92
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
93
|
93
|
|
94
|
|
- uint8_t Stepper::old_OCR0A = 0;
|
95
|
|
- volatile uint8_t Stepper::eISR_Rate = 200; // Keep the ISR at a low rate until needed
|
|
94
|
+ uint16_t Stepper::nextMainISR = 0,
|
|
95
|
+ Stepper::nextAdvanceISR = 65535,
|
|
96
|
+ Stepper::eISR_Rate = 65535;
|
96
|
97
|
|
97
|
98
|
#if ENABLED(LIN_ADVANCE)
|
98
|
99
|
volatile int Stepper::e_steps[E_STEPPERS];
|
|
@@ -328,16 +329,23 @@ void Stepper::set_directions() {
|
328
|
329
|
* 2000 1 KHz - sleep rate
|
329
|
330
|
* 4000 500 Hz - init rate
|
330
|
331
|
*/
|
331
|
|
-ISR(TIMER1_COMPA_vect) { Stepper::isr(); }
|
|
332
|
+ISR(TIMER1_COMPA_vect) {
|
|
333
|
+ #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
|
334
|
+ Stepper::advance_isr_scheduler();
|
|
335
|
+ #else
|
|
336
|
+ Stepper::isr();
|
|
337
|
+ #endif
|
|
338
|
+}
|
332
|
339
|
|
333
|
340
|
void Stepper::isr() {
|
334
|
|
- //Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
|
335
|
|
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
336
|
|
- CBI(TIMSK0, OCIE0A); //estepper ISR
|
|
341
|
+ #define _ENABLE_ISRs() cli(); SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT()
|
|
342
|
+
|
|
343
|
+ #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
|
|
344
|
+ //Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
|
|
345
|
+ CBI(TIMSK0, OCIE0B); //Temperature ISR
|
|
346
|
+ DISABLE_STEPPER_DRIVER_INTERRUPT();
|
|
347
|
+ sei();
|
337
|
348
|
#endif
|
338
|
|
- CBI(TIMSK0, OCIE0B); //Temperature ISR
|
339
|
|
- DISABLE_STEPPER_DRIVER_INTERRUPT();
|
340
|
|
- sei();
|
341
|
349
|
|
342
|
350
|
if (cleaning_buffer_counter) {
|
343
|
351
|
--cleaning_buffer_counter;
|
|
@@ -346,13 +354,8 @@ void Stepper::isr() {
|
346
|
354
|
#ifdef SD_FINISHED_RELEASECOMMAND
|
347
|
355
|
if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
348
|
356
|
#endif
|
349
|
|
- OCR1A = 200; // Run at max speed - 10 KHz
|
350
|
|
- //re-enable ISRs
|
351
|
|
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
352
|
|
- SBI(TIMSK0, OCIE0A);
|
353
|
|
- #endif
|
354
|
|
- SBI(TIMSK0, OCIE0B);
|
355
|
|
- ENABLE_STEPPER_DRIVER_INTERRUPT();
|
|
357
|
+ _NEXT_ISR(200); // Run at max speed - 10 KHz
|
|
358
|
+ _ENABLE_ISRs(); // re-enable ISRs
|
356
|
359
|
return;
|
357
|
360
|
}
|
358
|
361
|
|
|
@@ -381,12 +384,8 @@ void Stepper::isr() {
|
381
|
384
|
#if ENABLED(Z_LATE_ENABLE)
|
382
|
385
|
if (current_block->steps[Z_AXIS] > 0) {
|
383
|
386
|
enable_z();
|
384
|
|
- OCR1A = 2000; // Run at slow speed - 1 KHz
|
385
|
|
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
386
|
|
- SBI(TIMSK0, OCIE0A);
|
387
|
|
- #endif
|
388
|
|
- SBI(TIMSK0, OCIE0B);
|
389
|
|
- ENABLE_STEPPER_DRIVER_INTERRUPT();
|
|
387
|
+ _NEXT_ISR(2000); // Run at slow speed - 1 KHz
|
|
388
|
+ _ENABLE_ISRs(); // re-enable ISRs
|
390
|
389
|
return;
|
391
|
390
|
}
|
392
|
391
|
#endif
|
|
@@ -396,12 +395,8 @@ void Stepper::isr() {
|
396
|
395
|
// #endif
|
397
|
396
|
}
|
398
|
397
|
else {
|
399
|
|
- OCR1A = 2000; // Run at slow speed - 1 KHz
|
400
|
|
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
401
|
|
- SBI(TIMSK0, OCIE0A);
|
402
|
|
- #endif
|
403
|
|
- SBI(TIMSK0, OCIE0B);
|
404
|
|
- ENABLE_STEPPER_DRIVER_INTERRUPT();
|
|
398
|
+ _NEXT_ISR(2000); // Run at slow speed - 1 KHz
|
|
399
|
+ _ENABLE_ISRs(); // re-enable ISRs
|
405
|
400
|
return;
|
406
|
401
|
}
|
407
|
402
|
}
|
|
@@ -586,7 +581,7 @@ void Stepper::isr() {
|
586
|
581
|
|
587
|
582
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
588
|
583
|
// If we have esteps to execute, fire the next advance_isr "now"
|
589
|
|
- if (e_steps[TOOL_E_INDEX]) OCR0A = TCNT0 + 2;
|
|
584
|
+ if (e_steps[TOOL_E_INDEX]) nextAdvanceISR = 0;
|
590
|
585
|
#endif
|
591
|
586
|
|
592
|
587
|
// Calculate new timer value
|
|
@@ -600,7 +595,7 @@ void Stepper::isr() {
|
600
|
595
|
|
601
|
596
|
// step_rate to timer interval
|
602
|
597
|
uint16_t timer = calc_timer(acc_step_rate);
|
603
|
|
- OCR1A = timer;
|
|
598
|
+ _NEXT_ISR(timer);
|
604
|
599
|
acceleration_time += timer;
|
605
|
600
|
|
606
|
601
|
#if ENABLED(LIN_ADVANCE)
|
|
@@ -637,7 +632,7 @@ void Stepper::isr() {
|
637
|
632
|
#endif // ADVANCE or LIN_ADVANCE
|
638
|
633
|
|
639
|
634
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
640
|
|
- eISR_Rate = (timer >> 3) * step_loops / abs(e_steps[TOOL_E_INDEX]); //>> 3 is divide by 8. Reason: Timer 1 runs at 16/8=2MHz, Timer 0 at 16/64=0.25MHz. ==> 2/0.25=8.
|
|
635
|
+ eISR_Rate = !e_steps[TOOL_E_INDEX] ? 65535 : timer * step_loops / abs(e_steps[TOOL_E_INDEX]);
|
641
|
636
|
#endif
|
642
|
637
|
}
|
643
|
638
|
else if (step_events_completed > (uint32_t)current_block->decelerate_after) {
|
|
@@ -653,7 +648,7 @@ void Stepper::isr() {
|
653
|
648
|
|
654
|
649
|
// step_rate to timer interval
|
655
|
650
|
uint16_t timer = calc_timer(step_rate);
|
656
|
|
- OCR1A = timer;
|
|
651
|
+ _NEXT_ISR(timer);
|
657
|
652
|
deceleration_time += timer;
|
658
|
653
|
|
659
|
654
|
#if ENABLED(LIN_ADVANCE)
|
|
@@ -688,7 +683,7 @@ void Stepper::isr() {
|
688
|
683
|
#endif // ADVANCE or LIN_ADVANCE
|
689
|
684
|
|
690
|
685
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
691
|
|
- eISR_Rate = (timer >> 3) * step_loops / abs(e_steps[TOOL_E_INDEX]);
|
|
686
|
+ eISR_Rate = !e_steps[TOOL_E_INDEX] ? 65535 : timer * step_loops / abs(e_steps[TOOL_E_INDEX]);
|
692
|
687
|
#endif
|
693
|
688
|
}
|
694
|
689
|
else {
|
|
@@ -698,40 +693,37 @@ void Stepper::isr() {
|
698
|
693
|
if (current_block->use_advance_lead)
|
699
|
694
|
current_estep_rate[TOOL_E_INDEX] = final_estep_rate;
|
700
|
695
|
|
701
|
|
- eISR_Rate = (OCR1A_nominal >> 3) * step_loops_nominal / abs(e_steps[TOOL_E_INDEX]);
|
|
696
|
+ eISR_Rate = !e_steps[TOOL_E_INDEX] ? 65535 : OCR1A_nominal * step_loops_nominal / abs(e_steps[TOOL_E_INDEX]);
|
702
|
697
|
|
703
|
698
|
#endif
|
704
|
699
|
|
705
|
|
- OCR1A = OCR1A_nominal;
|
|
700
|
+ _NEXT_ISR(OCR1A_nominal);
|
706
|
701
|
// ensure we're running at the correct step rate, even if we just came off an acceleration
|
707
|
702
|
step_loops = step_loops_nominal;
|
708
|
703
|
}
|
709
|
704
|
|
710
|
|
- NOLESS(OCR1A, TCNT1 + 16);
|
|
705
|
+ #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
|
|
706
|
+ NOLESS(OCR1A, TCNT1 + 16);
|
|
707
|
+ #endif
|
711
|
708
|
|
712
|
709
|
// If current block is finished, reset pointer
|
713
|
710
|
if (all_steps_done) {
|
714
|
711
|
current_block = NULL;
|
715
|
712
|
planner.discard_current_block();
|
716
|
713
|
}
|
717
|
|
- #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
718
|
|
- SBI(TIMSK0, OCIE0A);
|
|
714
|
+ #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
|
|
715
|
+ _ENABLE_ISRs(); // re-enable ISRs
|
719
|
716
|
#endif
|
720
|
|
- SBI(TIMSK0, OCIE0B);
|
721
|
|
- ENABLE_STEPPER_DRIVER_INTERRUPT();
|
722
|
717
|
}
|
723
|
718
|
|
724
|
719
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
|
725
|
720
|
|
726
|
721
|
// Timer interrupt for E. e_steps is set in the main routine;
|
727
|
|
- // Timer 0 is shared with millies
|
728
|
|
- ISR(TIMER0_COMPA_vect) { Stepper::advance_isr(); }
|
729
|
722
|
|
730
|
723
|
void Stepper::advance_isr() {
|
731
|
|
-
|
732
|
|
- old_OCR0A += eISR_Rate;
|
733
|
|
- OCR0A = old_OCR0A;
|
734
|
|
-
|
|
724
|
+
|
|
725
|
+ nextAdvanceISR = eISR_Rate;
|
|
726
|
+
|
735
|
727
|
#define SET_E_STEP_DIR(INDEX) \
|
736
|
728
|
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
|
737
|
729
|
|
|
@@ -795,6 +787,46 @@ void Stepper::isr() {
|
795
|
787
|
|
796
|
788
|
}
|
797
|
789
|
|
|
790
|
+ void Stepper::advance_isr_scheduler() {
|
|
791
|
+ // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
|
|
792
|
+ CBI(TIMSK0, OCIE0B); // Temperature ISR
|
|
793
|
+ DISABLE_STEPPER_DRIVER_INTERRUPT();
|
|
794
|
+ sei();
|
|
795
|
+
|
|
796
|
+ // Run main stepping ISR if flagged
|
|
797
|
+ if (!nextMainISR) isr();
|
|
798
|
+
|
|
799
|
+ // Run Advance stepping ISR if flagged
|
|
800
|
+ if (!nextAdvanceISR) advance_isr();
|
|
801
|
+
|
|
802
|
+ // Is the next advance ISR scheduled before the next main ISR?
|
|
803
|
+ if (nextAdvanceISR <= nextMainISR) {
|
|
804
|
+ // Set up the next interrupt
|
|
805
|
+ OCR1A = nextAdvanceISR;
|
|
806
|
+ // New interval for the next main ISR
|
|
807
|
+ if (nextMainISR) nextMainISR -= nextAdvanceISR;
|
|
808
|
+ // Will call Stepper::advance_isr on the next interrupt
|
|
809
|
+ nextAdvanceISR = 0;
|
|
810
|
+ }
|
|
811
|
+ else {
|
|
812
|
+ // The next main ISR comes first
|
|
813
|
+ OCR1A = nextMainISR;
|
|
814
|
+ // New interval for the next advance ISR, if any
|
|
815
|
+ if (nextAdvanceISR && nextAdvanceISR != 65535)
|
|
816
|
+ nextAdvanceISR -= nextMainISR;
|
|
817
|
+ // Will call Stepper::isr on the next interrupt
|
|
818
|
+ nextMainISR = 0;
|
|
819
|
+ }
|
|
820
|
+
|
|
821
|
+ // Don't run the ISR faster than possible
|
|
822
|
+ NOLESS(OCR1A, TCNT1 + 16);
|
|
823
|
+
|
|
824
|
+ // Restore original ISR settings
|
|
825
|
+ cli();
|
|
826
|
+ SBI(TIMSK0, OCIE0B);
|
|
827
|
+ ENABLE_STEPPER_DRIVER_INTERRUPT();
|
|
828
|
+ }
|
|
829
|
+
|
798
|
830
|
#endif // ADVANCE or LIN_ADVANCE
|
799
|
831
|
|
800
|
832
|
void Stepper::init() {
|
|
@@ -981,12 +1013,6 @@ void Stepper::init() {
|
981
|
1013
|
#endif
|
982
|
1014
|
}
|
983
|
1015
|
|
984
|
|
- #if defined(TCCR0A) && defined(WGM01)
|
985
|
|
- CBI(TCCR0A, WGM01);
|
986
|
|
- CBI(TCCR0A, WGM00);
|
987
|
|
- #endif
|
988
|
|
- SBI(TIMSK0, OCIE0A);
|
989
|
|
-
|
990
|
1016
|
#endif // ADVANCE or LIN_ADVANCE
|
991
|
1017
|
|
992
|
1018
|
endstops.enable(true); // Start with endstops active. After homing they can be disabled
|