diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index f9ece0240..109ad6cc5 100755 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -388,7 +388,7 @@ int feedrate_percentage = 100, saved_feedrate_percentage, flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); bool axis_relative_modes[] = AXIS_RELATIVE_MODES, - volumetric_enabled = + volumetric_enabled = #if ENABLED(VOLUMETRIC_DEFAULT_ON) true #else @@ -1987,8 +1987,13 @@ static void clean_up_after_endstop_or_probe_move() { #define STOW_PROBE() set_probe_deployed(false) #if ENABLED(BLTOUCH) + void bltouch_command(int angle) { + servo[Z_ENDSTOP_SERVO_NR].move(angle); // Give the BL-Touch the command and wait + safe_delay(375); + } + FORCE_INLINE void set_bltouch_deployed(const bool &deploy) { - servo[Z_ENDSTOP_SERVO_NR].move(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW); + bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW); #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { SERIAL_ECHOPAIR("set_bltouch_deployed(", deploy); @@ -2016,7 +2021,15 @@ static void clean_up_after_endstop_or_probe_move() { // When deploying make sure BLTOUCH is not already triggered #if ENABLED(BLTOUCH) - if (deploy && TEST_BLTOUCH()) { stop(); return true; } + if (deploy && TEST_BLTOUCH()) { // If BL-Touch says it's triggered + bltouch_command(BLTOUCH_RESET); // try to reset it. + set_bltouch_deployed(true); // Also needs to deploy and stow to + set_bltouch_deployed(false); // clear the triggered condition. + if (TEST_BLTOUCH()) { // If it still claims to be triggered... + stop(); // punt! + return true; + } + } #elif ENABLED(Z_PROBE_SLED) if (axis_unhomed_error(true, false, false)) { stop(); return true; } #elif ENABLED(Z_PROBE_ALLEN_KEY) @@ -3902,7 +3915,7 @@ inline void gcode_G28() { * R Set the Right limit of the probing grid * * Parameters with BILINEAR only: - * + * * Z Supply an additional Z probe offset * * Global Parameters: @@ -10435,6 +10448,12 @@ void setup() { mixing_virtual_tool_mix[t][i] = mixing_factor[i]; #endif + #if ENABLED(BLTOUCH) + bltouch_command(BLTOUCH_RESET); // Just in case the BLTouch is in the error state, try to + set_bltouch_deployed(true); // reset it. Also needs to deploy and stow to clear the + set_bltouch_deployed(false); // error condition. + #endif + #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 i2c.onReceive(i2c_on_receive); i2c.onRequest(i2c_on_request); diff --git a/Marlin/endstops.h b/Marlin/endstops.h index 4f2ce9e5d..2788fb64e 100644 --- a/Marlin/endstops.h +++ b/Marlin/endstops.h @@ -92,4 +92,11 @@ class Endstops { extern Endstops endstops; +#if HAS_BED_PROBE + #define ENDSTOPS_ENABLED (endstops.enabled || endstops.z_probe_enabled) +#else + #define ENDSTOPS_ENABLED endstops.enabled +#endif + + #endif // ENDSTOPS_H diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index 932b1e9ca..ddab5416e 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -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); diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 9eb68f7f1..0dda55d37 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -33,6 +33,10 @@ #include "stepper.h" #endif +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #include "endstops.h" +#endif + #if ENABLED(USE_WATCHDOG) #include "watchdog.h" #endif @@ -1944,5 +1948,15 @@ void Temperature::isr() { } #endif + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + + extern volatile uint8_t e_hit; + + if (e_hit && ENDSTOPS_ENABLED) { + endstops.update(); // call endstop update routine + e_hit--; + } + #endif + SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR }