|
|
|
@ -345,13 +345,50 @@ ISR(TIMER1_COMPA_vect) {
|
|
|
|
|
void Stepper::isr() {
|
|
|
|
|
#define _ENABLE_ISRs() cli(); SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT()
|
|
|
|
|
|
|
|
|
|
uint16_t timer, remainder, ocr_val;
|
|
|
|
|
|
|
|
|
|
static uint32_t step_remaining = 0;
|
|
|
|
|
|
|
|
|
|
#define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
|
|
|
|
|
#define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
|
|
|
|
|
|
|
|
|
|
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
|
|
|
|
|
//Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
|
|
|
|
|
CBI(TIMSK0, OCIE0B); //Temperature ISR
|
|
|
|
|
// Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
|
|
|
|
|
CBI(TIMSK0, OCIE0B); // Temperature ISR
|
|
|
|
|
DISABLE_STEPPER_DRIVER_INTERRUPT();
|
|
|
|
|
sei();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define _SPLIT(L) (ocr_val = (uint16_t)L)
|
|
|
|
|
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
|
|
|
|
#define SPLIT(L) _SPLIT(L)
|
|
|
|
|
#else // sample endstops in between step pulses
|
|
|
|
|
#define SPLIT(L) do { \
|
|
|
|
|
_SPLIT(L); \
|
|
|
|
|
if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \
|
|
|
|
|
remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
|
|
|
|
|
ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \
|
|
|
|
|
step_remaining = (uint16_t)L - ocr_val; \
|
|
|
|
|
} \
|
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
if (step_remaining && ENDSTOPS_ENABLED) { // Just check endstops - not yet time for a step
|
|
|
|
|
endstops.update();
|
|
|
|
|
ocr_val = step_remaining;
|
|
|
|
|
if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) {
|
|
|
|
|
step_remaining = step_remaining - ENDSTOP_NOMINAL_OCR_VAL;
|
|
|
|
|
ocr_val = ENDSTOP_NOMINAL_OCR_VAL;
|
|
|
|
|
}
|
|
|
|
|
else step_remaining = 0; // last one before the ISR that does the step
|
|
|
|
|
_NEXT_ISR(ocr_val); //
|
|
|
|
|
|
|
|
|
|
NOLESS(OCR1A, TCNT1 + 16);
|
|
|
|
|
|
|
|
|
|
_ENABLE_ISRs(); // re-enable ISRs
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
if (cleaning_buffer_counter) {
|
|
|
|
|
--cleaning_buffer_counter;
|
|
|
|
|
current_block = NULL;
|
|
|
|
@ -407,21 +444,16 @@ void Stepper::isr() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update endstops state, if enabled
|
|
|
|
|
if ((endstops.enabled
|
|
|
|
|
#if HAS_BED_PROBE
|
|
|
|
|
|| endstops.z_probe_enabled
|
|
|
|
|
#endif
|
|
|
|
|
)
|
|
|
|
|
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
|
|
|
|
&& e_hit
|
|
|
|
|
#endif
|
|
|
|
|
) {
|
|
|
|
|
endstops.update();
|
|
|
|
|
|
|
|
|
|
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
|
|
|
|
|
|
|
|
|
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
|
|
|
|
if (ENDSTOPS_ENABLED && e_hit) {
|
|
|
|
|
endstops.update();
|
|
|
|
|
e_hit--;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (ENDSTOPS_ENABLED) endstops.update();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Take multiple steps per interrupt (For high speed moves)
|
|
|
|
|
bool all_steps_done = false;
|
|
|
|
@ -600,7 +632,10 @@ void Stepper::isr() {
|
|
|
|
|
|
|
|
|
|
// step_rate to timer interval
|
|
|
|
|
uint16_t timer = calc_timer(acc_step_rate);
|
|
|
|
|
_NEXT_ISR(timer);
|
|
|
|
|
|
|
|
|
|
SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
|
|
|
|
|
_NEXT_ISR(ocr_val);
|
|
|
|
|
|
|
|
|
|
acceleration_time += timer;
|
|
|
|
|
|
|
|
|
|
#if ENABLED(LIN_ADVANCE)
|
|
|
|
@ -653,7 +688,10 @@ void Stepper::isr() {
|
|
|
|
|
|
|
|
|
|
// step_rate to timer interval
|
|
|
|
|
uint16_t timer = calc_timer(step_rate);
|
|
|
|
|
_NEXT_ISR(timer);
|
|
|
|
|
|
|
|
|
|
SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
|
|
|
|
|
_NEXT_ISR(ocr_val);
|
|
|
|
|
|
|
|
|
|
deceleration_time += timer;
|
|
|
|
|
|
|
|
|
|
#if ENABLED(LIN_ADVANCE)
|
|
|
|
@ -702,7 +740,9 @@ void Stepper::isr() {
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
_NEXT_ISR(OCR1A_nominal);
|
|
|
|
|
SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
|
|
|
|
|
_NEXT_ISR(ocr_val);
|
|
|
|
|
|
|
|
|
|
// ensure we're running at the correct step rate, even if we just came off an acceleration
|
|
|
|
|
step_loops = step_loops_nominal;
|
|
|
|
|
}
|
|
|
|
@ -726,9 +766,9 @@ void Stepper::isr() {
|
|
|
|
|
// Timer interrupt for E. e_steps is set in the main routine;
|
|
|
|
|
|
|
|
|
|
void Stepper::advance_isr() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nextAdvanceISR = eISR_Rate;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define SET_E_STEP_DIR(INDEX) \
|
|
|
|
|
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
|
|
|
|
|
|
|
|
|
@ -803,7 +843,7 @@ void Stepper::isr() {
|
|
|
|
|
|
|
|
|
|
// Run Advance stepping ISR if flagged
|
|
|
|
|
if (!nextAdvanceISR) advance_isr();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Is the next advance ISR scheduled before the next main ISR?
|
|
|
|
|
if (nextAdvanceISR <= nextMainISR) {
|
|
|
|
|
// Set up the next interrupt
|
|
|
|
@ -822,7 +862,7 @@ void Stepper::isr() {
|
|
|
|
|
// Will call Stepper::isr on the next interrupt
|
|
|
|
|
nextMainISR = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Don't run the ISR faster than possible
|
|
|
|
|
NOLESS(OCR1A, TCNT1 + 16);
|
|
|
|
|
|
|
|
|
|