From 50059690e0192be879bcd7c48c45b790d41a53a4 Mon Sep 17 00:00:00 2001 From: Sebastianv650 Date: Sun, 20 Nov 2016 13:09:12 +0100 Subject: [PATCH 1/2] Allow UART ISRs inside the stepper ISR If the stepper ISR takes too long, chars are lost which leads to serial communication errors like "Line number not +1" or "Wrong checksum". In worst case, the printer can even do crazy moves. With this changes, UART interrupts are handled inside the stepper ISR. This way, no chars should be lost. --- Marlin/stepper.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index 974dbad0e..95208d6f8 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -331,6 +331,14 @@ void Stepper::set_directions() { ISR(TIMER1_COMPA_vect) { Stepper::isr(); } void Stepper::isr() { + //Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + CBI(TIMSK0, OCIE0A); //estepper ISR + #endif + CBI(TIMSK0, OCIE0B); //Temperature ISR + DISABLE_STEPPER_DRIVER_INTERRUPT(); + sei(); + if (cleaning_buffer_counter) { current_block = NULL; planner.discard_current_block(); @@ -339,6 +347,12 @@ void Stepper::isr() { #endif cleaning_buffer_counter--; OCR1A = 200; // Run at max speed - 10 KHz + //re-enable ISRs + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + SBI(TIMSK0, OCIE0A); + #endif + SBI(TIMSK0, OCIE0B); + ENABLE_STEPPER_DRIVER_INTERRUPT(); return; } @@ -368,6 +382,11 @@ void Stepper::isr() { if (current_block->steps[Z_AXIS] > 0) { enable_z(); OCR1A = 2000; // Run at slow speed - 1 KHz + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + SBI(TIMSK0, OCIE0A); + #endif + SBI(TIMSK0, OCIE0B); + ENABLE_STEPPER_DRIVER_INTERRUPT(); return; } #endif @@ -378,6 +397,11 @@ void Stepper::isr() { } else { OCR1A = 2000; // Run at slow speed - 1 KHz + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + SBI(TIMSK0, OCIE0A); + #endif + SBI(TIMSK0, OCIE0B); + ENABLE_STEPPER_DRIVER_INTERRUPT(); return; } } @@ -402,10 +426,6 @@ void Stepper::isr() { // Take multiple steps per interrupt (For high speed moves) bool all_steps_done = false; for (int8_t i = 0; i < step_loops; i++) { - #ifndef USBCON - customizedSerial.checkRx(); // Check for serial chars. - #endif - #if ENABLED(LIN_ADVANCE) counter_E += current_block->steps[E_AXIS]; @@ -694,6 +714,11 @@ void Stepper::isr() { current_block = NULL; planner.discard_current_block(); } + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + SBI(TIMSK0, OCIE0A); + #endif + SBI(TIMSK0, OCIE0B); + ENABLE_STEPPER_DRIVER_INTERRUPT(); } #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) From 912704a0d85fdcdbe4f9783a9e007f6e83c11dab Mon Sep 17 00:00:00 2001 From: Sebastianv650 Date: Sun, 20 Nov 2016 18:17:42 +0100 Subject: [PATCH 2/2] Enable ISRs inside temperature ISR to capture chars at UART at 250000 baud. --- Marlin/temperature.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index f01c0862b..4895d1da9 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -1489,6 +1489,9 @@ void Temperature::set_current_temp_raw() { ISR(TIMER0_COMPB_vect) { Temperature::isr(); } void Temperature::isr() { + //Allow UART and stepper ISRs + CBI(TIMSK0, OCIE0B); //Disable Temperature ISR + sei(); static uint8_t temp_count = 0; static TempState temp_state = StartupDelay; @@ -1940,4 +1943,6 @@ void Temperature::isr() { if (!endstop_monitor_count) endstop_monitor(); // report changes in endstop status } #endif + + SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR }