Avoid the stepper interrupt being missed by extending the tick time

beyond the current time. This is a trick borrwed from upstream Marlin.

In debug mode, watch for the missed stepper interrupt ticks where the interrupts
are missed by more than 20% of the 10kHz stepper interrupt repeat rate,
and show the statistics (number of missed ticks and by how many micro
seconds was the interrupt missed, and what was the maximum missed
interrupt delay) on the display and send it to the serial line.
This commit is contained in:
bubnikv 2018-02-15 11:44:19 +01:00
parent 2babbb3b11
commit dd2468d306
2 changed files with 31 additions and 20 deletions

View file

@ -131,6 +131,7 @@ uint8_t LastStepMask = 0;
#ifdef DEBUG_STEPPER_TIMER_MISSED
extern bool stepper_timer_overflow_state;
extern uint16_t stepper_timer_overflow_last;
#endif /* DEBUG_STEPPER_TIMER_MISSED */
//===========================================================================
@ -381,22 +382,25 @@ ISR(TIMER1_COMPA_vect) {
isr();
// Don't run the ISR faster than possible
// if (OCR1A < TCNT1 + 16) OCR1A = TCNT1 + 16;
// Is there a 8us time left before the next interrupt triggers?
if (OCR1A < TCNT1 + 16) {
#ifdef DEBUG_STEPPER_TIMER_MISSED
// Verify whether the next planned timer interrupt has not been missed already.
// This debugging test takes < 1.125us
// This skews the profiling slightly as the fastest stepper timer
// interrupt repeats at a 100us rate (10kHz).
if (OCR1A < TCNT1) {
if (OCR1A + 40 < TCNT1) {
// The interrupt was delayed by more than 20us (which is 1/5th of the 10kHz ISR repeat rate).
// Give a warning.
stepper_timer_overflow_state = true;
WRITE_NC(BEEPER, HIGH);
SERIAL_PROTOCOLPGM("Stepper timer overflow ");
SERIAL_PROTOCOL(OCR1A);
SERIAL_PROTOCOLPGM("<");
SERIAL_PROTOCOL(TCNT1);
SERIAL_PROTOCOLLN("!");
stepper_timer_overflow_last = TCNT1 - OCR1A;
// Beep, the beeper will be cleared at the stepper_timer_overflow() called from the main thread.
WRITE(BEEPER, HIGH);
}
#endif
// Fix the next interrupt to be executed after 8us from now.
OCR1A = TCNT1 + 16;
}
}
FORCE_INLINE void stepper_next_block()

View file

@ -5182,14 +5182,21 @@ void stack_error() {
#ifdef DEBUG_STEPPER_TIMER_MISSED
bool stepper_timer_overflow_state = false;
uint16_t stepper_timer_overflow_max = 0;
uint16_t stepper_timer_overflow_last = 0;
uint16_t stepper_timer_overflow_cnt = 0;
void stepper_timer_overflow() {
SET_OUTPUT(BEEPER);
WRITE(BEEPER, HIGH);
delay(1000);
char msg[28];
sprintf_P(msg, PSTR("#%d %d max %d"), ++ stepper_timer_overflow_cnt, stepper_timer_overflow_last >> 1, stepper_timer_overflow_max >> 1);
lcd_setstatus(msg);
stepper_timer_overflow_state = false;
if (stepper_timer_overflow_last > stepper_timer_overflow_max)
stepper_timer_overflow_max = stepper_timer_overflow_last;
SERIAL_ECHOPGM("Stepper timer overflow: ");
MYSERIAL.print(msg);
SERIAL_ECHOLNPGM("");
WRITE(BEEPER, LOW);
lcd_display_message_fullscreen_P(MSG_STEPPER_TIMER_OVERFLOW_ERROR);
//err_triggered = 1;
while (1) delay_keep_alive(1000);
}
#endif /* DEBUG_STEPPER_TIMER_MISSED */