diff --git a/Firmware/MarlinSerial.cpp b/Firmware/MarlinSerial.cpp index 357de7c60..0464fe41f 100644 --- a/Firmware/MarlinSerial.cpp +++ b/Firmware/MarlinSerial.cpp @@ -49,11 +49,13 @@ FORCE_INLINE void store_char(unsigned char c) } -//#elif defined(SIG_USART_RECV) #if defined(M_USARTx_RX_vect) - // fixed by Mark Sproul this is on the 644/644p - //SIGNAL(SIG_USART_RECV) -SIGNAL(M_USARTx_RX_vect) +// The serial line receive interrupt routine for a baud rate 115200 +// ticks at maximum 11.76 kHz and blocks for 2.688 us at each tick. +// If the serial line is fully utilized, this corresponds to 3.16% +// loading of the CPU (the interrupt invocation overhead not taken into account). +// As the serial line is not fully utilized, the CPU load is likely around 1%. +ISR(M_USARTx_RX_vect) { // Test for a framing error. if (M_UCSRxA & (1< 18 (approximately), which is sufficient because MIN_PRINT_FAN_SPEED is higher @@ -7912,6 +7937,8 @@ void stop_and_save_print_to_ram(float z_move, float e_move) card.sdprinting = false; // card.closefile(); saved_printing = true; + // We may have missed a stepper timer interrupt. Be safe than sorry, reset the stepper timer before re-enabling interrupts. + st_reset_timer(); sei(); if ((z_move != 0) || (e_move != 0)) { // extruder or z move #if 1 diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index 771daafec..bdf4c3abf 100644 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -627,6 +627,10 @@ void get_command() sd_count.value = 0; cli(); + // This block locks the interrupts globally for 3.56 us, + // which corresponds to a maximum repeat frequency of 280.70 kHz. + // This blocking is safe in the context of a 10kHz stepper driver interrupt + // or a 115200 Bd serial line receive interrupt, which will not trigger faster than 12kHz. ++ buflen; bufindw += len; sdpos_atomic = card.get_sdpos()+1; diff --git a/Firmware/cmdqueue.h b/Firmware/cmdqueue.h index 2c6f93b75..dad81c94c 100644 --- a/Firmware/cmdqueue.h +++ b/Firmware/cmdqueue.h @@ -18,6 +18,10 @@ #define CMDBUFFER_CURRENT_TYPE_UI 3 // Command in cmdbuffer was generated by another G-code. #define CMDBUFFER_CURRENT_TYPE_CHAINED 4 +// Command has been processed and its SD card length has been possibly pushed +// to the planner queue, but not yet removed from the cmdqueue. +// This is a temporary state to reduce stepper interrupt locking time. +#define CMDBUFFER_CURRENT_TYPE_TO_BE_REMOVED 5 // How much space to reserve for the chained commands // of type CMDBUFFER_CURRENT_TYPE_CHAINED, diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 999e7b18d..a08aacc05 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -264,6 +264,10 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit } CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section + // This block locks the interrupts globally for 4.38 us, + // which corresponds to a maximum repeat frequency of 228.57 kHz. + // This blocking is safe in the context of a 10kHz stepper driver interrupt + // or a 115200 Bd serial line receive interrupt, which will not trigger faster than 12kHz. if (! block->busy) { // Don't update variables if block is busy. block->accelerate_until = accelerate_steps; block->decelerate_after = accelerate_steps+plateau_steps; @@ -561,8 +565,7 @@ extern volatile uint32_t step_events_completed; // The number of step events exe void planner_abort_hard() { // Abort the stepper routine and flush the planner queue. - // DISABLE_STEPPER_DRIVER_INTERRUPT - TIMSK1 &= ~(1<decelerate_after after which it decelerates until the trapezoid generator is reset. // The slope of acceleration is calculated with the leib ramp alghorithm. -void st_wake_up() { - // TCNT1 = 0; - ENABLE_STEPPER_DRIVER_INTERRUPT(); -} - -void step_wait(){ - for(int8_t i=0; i < 6; i++){ - } -} - - FORCE_INLINE unsigned short calc_timer(uint16_t step_rate) { unsigned short timer; if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY; @@ -858,6 +843,11 @@ void isr() { if (OCR1A < TCNT1) { stepper_timer_overflow_state = true; WRITE_NC(BEEPER, HIGH); + SERIAL_PROTOCOLPGM("Stepper timer overflow "); + SERIAL_PROTOCOL(OCR1A); + SERIAL_PROTOCOLPGM("<"); + SERIAL_PROTOCOL(TCNT1); + SERIAL_PROTOCOLLN("!"); } #endif } @@ -1141,6 +1131,7 @@ void st_init() // create_speed_lookuptable.py TCCR1B = (TCCR1B & ~(0x07<