From a1a88ebabc57f40fdbfe6f4b77f62fe7a2dc8a5d Mon Sep 17 00:00:00 2001 From: Chris Pepper Date: Wed, 7 Mar 2018 23:53:25 +0000 Subject: [PATCH] HAL function to ensure min stepper interrupt interval (#9985) --- Marlin/src/HAL/HAL_AVR/HAL_AVR.h | 4 +++ Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp | 4 +-- Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h | 8 +++++- Marlin/src/HAL/HAL_LPC1768/HAL_timers.h | 9 ++++++- .../src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h | 11 ++++++-- .../HAL/HAL_STM32F7/HAL_timers_STM32F7.cpp | 5 ++++ .../src/HAL/HAL_STM32F7/HAL_timers_STM32F7.h | 5 +++- Marlin/src/HAL/HAL_STM32F7/TMC2660.h | 2 +- .../HAL/HAL_TEENSY35_36/HAL_timers_Teensy.h | 7 ++++++ Marlin/src/module/stepper.cpp | 25 +++---------------- 10 files changed, 51 insertions(+), 29 deletions(-) diff --git a/Marlin/src/HAL/HAL_AVR/HAL_AVR.h b/Marlin/src/HAL/HAL_AVR/HAL_AVR.h index 33143a7fa..7734e5030 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_AVR.h +++ b/Marlin/src/HAL/HAL_AVR/HAL_AVR.h @@ -126,6 +126,8 @@ extern "C" { #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE #define STEPPER_TIMER_PRESCALE 8 +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts + #define STEP_TIMER_NUM 1 #define TIMER_OCR_1 OCR1A #define TIMER_COUNTER_1 TCNT1 @@ -148,6 +150,8 @@ extern "C" { #define _CAT(a, ...) a ## __VA_ARGS__ #define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare) +#define HAL_timer_restrain(timer, interval_µs) NOLESS(_CAT(TIMER_OCR_, timer), _CAT(TIMER_COUNTER_, timer) + interval_µs * HAL_TICKS_PER_US) + #define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer) #define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer) diff --git a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp index 48236cf91..87323861a 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp +++ b/Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp @@ -221,7 +221,7 @@ void spiBegin (void) { /** Soft SPI receive byte */ uint8_t spiRec() { uint8_t data = 0; - // no interrupts during byte receive - about 8 us + // no interrupts during byte receive - about 8µs cli(); // output pin high - like sending 0xFF WRITE(MOSI_PIN, HIGH); @@ -252,7 +252,7 @@ void spiBegin (void) { //------------------------------------------------------------------------------ /** Soft SPI send byte */ void spiSend(uint8_t data) { - // no interrupts during byte send - about 8 us + // no interrupts during byte send - about 8µs cli(); for (uint8_t i = 0; i < 8; i++) { WRITE(SCK_PIN, LOW); diff --git a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h index b25ec1697..2ad740ae1 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h +++ b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h @@ -50,9 +50,10 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals #define STEPPER_TIMER_PRESCALE 1.0 // prescaler for setting stepper frequency #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per us +#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) @@ -108,6 +109,11 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV; } +FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_µs * HAL_TICKS_PER_US; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); +} + void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h index 5627a7d2d..1890a3001 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h @@ -49,10 +49,12 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals #define STEPPER_TIMER_PRESCALE 1.0 // prescaler for setting stepper frequency #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per us +#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define HAL_TEMP_TIMER_RATE 1000000 #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts + #define PULSE_TIMER_NUM STEP_TIMER_NUM #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE @@ -118,6 +120,11 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { return 0; } +FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_µs * HAL_TICKS_PER_US; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); +} + void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h index 271571bbc..6f23bf4a0 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h @@ -67,13 +67,15 @@ typedef uint16_t hal_timer_t; #define HAL_TIMER_RATE (F_CPU) // frequency of timers peripherals #define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz #define HAL_STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per us +#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define PULSE_TIMER_NUM STEP_TIMER_NUM #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 100 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 100 // temperature interrupt frequency + +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts #define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) #define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) @@ -152,6 +154,11 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { } } +FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_µs * HAL_TICKS_PER_US; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); +} + FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { switch (timer_num) { case STEP_TIMER_NUM: diff --git a/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.cpp b/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.cpp index d239e49dd..a50c5c7f9 100644 --- a/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.cpp +++ b/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.cpp @@ -137,6 +137,11 @@ uint32_t HAL_timer_get_count(const uint8_t timer_num) { return __HAL_TIM_GetCounter(&timerConfig[timer_num].timerdef); } +void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_µs * HAL_TICKS_PER_US; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); +} + void HAL_timer_isr_prologue(const uint8_t timer_num) { if (__HAL_TIM_GET_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE) == SET) { __HAL_TIM_CLEAR_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE); diff --git a/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.h b/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.h index 059fc2258..7dff146f4 100644 --- a/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.h +++ b/Marlin/src/HAL/HAL_STM32F7/HAL_timers_STM32F7.h @@ -44,7 +44,7 @@ #define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals #define STEPPER_TIMER_PRESCALE 54 // was 40,prescaler for setting stepper timer, 2Mhz #define HAL_STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per us +#define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs #define PULSE_TIMER_NUM STEP_TIMER_NUM #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE @@ -52,6 +52,8 @@ #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz #define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts + #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) @@ -94,6 +96,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num); void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare); hal_timer_t HAL_timer_get_compare(const uint8_t timer_num); uint32_t HAL_timer_get_count(const uint8_t timer_num); +void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs); void HAL_timer_isr_prologue(const uint8_t timer_num); diff --git a/Marlin/src/HAL/HAL_STM32F7/TMC2660.h b/Marlin/src/HAL/HAL_STM32F7/TMC2660.h index 44d6b103f..9b0f50e40 100644 --- a/Marlin/src/HAL/HAL_STM32F7/TMC2660.h +++ b/Marlin/src/HAL/HAL_STM32F7/TMC2660.h @@ -315,7 +315,7 @@ class TMC26XStepper { /*! * \brief readout the motor maximum current in mA (1000 is an Amp) * This is the maximum current. to get the current current - which may be affected by CoolStep us getCurrentCurrent() - *\return the maximum motor current in milli amps + * \return the maximum motor current in milli amps * \sa getCurrentCurrent() */ unsigned int getCurrent(void); diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.h b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.h index 94878ce04..0075a6b2c 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.h +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_timers_Teensy.h @@ -66,6 +66,8 @@ typedef uint32_t hal_timer_t; #define TEMP_TIMER_FREQUENCY 1000 +#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts + #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM) @@ -103,6 +105,11 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { return 0; } +FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_µs) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_µs * HAL_TICKS_PER_US; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); +} + void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num); bool HAL_timer_interrupt_enabled(const uint8_t timer_num); diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 1efa5ef89..9da2c036c 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -365,11 +365,7 @@ void Stepper::isr() { _NEXT_ISR(ocr_val); #if DISABLED(LIN_ADVANCE) - #ifdef CPU_32_BIT - HAL_timer_set_compare(STEP_TIMER_NUM, ocr_val); - #else - NOLESS(OCR1A, TCNT1 + 16); - #endif + HAL_timer_restrain(STEP_TIMER_NUM, STEP_TIMER_MIN_INTERVAL); HAL_ENABLE_ISRs(); // re-enable ISRs #endif @@ -731,14 +727,7 @@ void Stepper::isr() { } #if DISABLED(LIN_ADVANCE) - #ifdef CPU_32_BIT - // Make sure stepper interrupt does not monopolise CPU by adjusting count to give about 8 us room - hal_timer_t stepper_timer_count = HAL_timer_get_compare(STEP_TIMER_NUM), - stepper_timer_current_count = HAL_timer_get_count(STEP_TIMER_NUM) + 8 * HAL_TICKS_PER_US; - HAL_timer_set_compare(STEP_TIMER_NUM, max(stepper_timer_count, stepper_timer_current_count)); - #else - NOLESS(OCR1A, TCNT1 + 16); - #endif + HAL_timer_restrain(STEP_TIMER_NUM, STEP_TIMER_MIN_INTERVAL); #endif // If current block is finished, reset pointer @@ -901,14 +890,8 @@ void Stepper::isr() { } // Don't run the ISR faster than possible - #ifdef CPU_32_BIT - // Make sure stepper interrupt does not monopolise CPU by adjusting count to give about 8 us room - uint32_t stepper_timer_count = HAL_timer_get_compare(STEP_TIMER_NUM), - stepper_timer_current_count = HAL_timer_get_count(STEP_TIMER_NUM) + 8 * HAL_TICKS_PER_US; - HAL_timer_set_compare(STEP_TIMER_NUM, max(stepper_timer_count, stepper_timer_current_count)); - #else - NOLESS(OCR1A, TCNT1 + 16); - #endif + // Make sure stepper interrupt does not monopolise CPU by adjusting compare to give about 8µs room + HAL_timer_restrain(STEP_TIMER_NUM, STEP_TIMER_MIN_INTERVAL); // Restore original ISR settings HAL_ENABLE_ISRs();