diff --git a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp index 43e8a0691..06b6d25b8 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.cpp @@ -61,15 +61,15 @@ // -------------------------------------------------------------------------- const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = { - { TC0, 0, TC0_IRQn, 0}, // 0 - [servo timer5] - { TC0, 1, TC1_IRQn, 0}, // 1 - { TC0, 2, TC2_IRQn, 0}, // 2 - { TC1, 0, TC3_IRQn, 2}, // 3 - stepper + { TC0, 0, TC0_IRQn, 0}, // 0 - [servo timer5] + { TC0, 1, TC1_IRQn, 0}, // 1 + { TC0, 2, TC2_IRQn, 0}, // 2 + { TC1, 0, TC3_IRQn, 2}, // 3 - stepper { TC1, 1, TC4_IRQn, 15}, // 4 - temperature - { TC1, 2, TC5_IRQn, 0}, // 5 - [servo timer3] - { TC2, 0, TC6_IRQn, 0}, // 6 - tone - { TC2, 1, TC7_IRQn, 0}, // 7 - { TC2, 2, TC8_IRQn, 0}, // 8 + { TC1, 2, TC5_IRQn, 0}, // 5 - [servo timer3] + { TC2, 0, TC6_IRQn, 15}, // 6 - tone + { TC2, 1, TC7_IRQn, 0}, // 7 + { TC2, 2, TC8_IRQn, 0}, // 8 }; // -------------------------------------------------------------------------- @@ -100,6 +100,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { pmc_enable_periph_clk((uint32_t)irq); NVIC_SetPriority(irq, TimerConfig [timer_num].priority); + // wave mode, reset counter on match with RC, TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency); diff --git a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h index a38bc6978..0429746e6 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h +++ b/Marlin/src/HAL/HAL_DUE/HAL_timers_Due.h @@ -109,11 +109,23 @@ 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_set_count(const uint8_t timer_num, const hal_timer_t counter) { + const tTimerConfig * const pConfig = &TimerConfig[timer_num]; + pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV = counter; +} + +// if counter too high then bump up compare FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks) { const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks; if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); } +// if counter too high then clear it +FORCE_INLINE static void HAL_timer_restrain_count(const uint8_t timer_num, const uint16_t interval_ticks) { + const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks; + if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_count(timer_num, 0); +} + 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_DUE/Tone.cpp b/Marlin/src/HAL/HAL_DUE/Tone.cpp index 88f92243e..1b8a3122b 100644 --- a/Marlin/src/HAL/HAL_DUE/Tone.cpp +++ b/Marlin/src/HAL/HAL_DUE/Tone.cpp @@ -34,13 +34,15 @@ static pin_t tone_pin; volatile static int32_t toggles; void toneInit() { - HAL_timer_start(TONE_TIMER_NUM, 1); // Lowest frequency possible + HAL_timer_start(TONE_TIMER_NUM, 100000); + HAL_timer_disable_interrupt(TONE_TIMER_NUM); } void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) { tone_pin = _pin; toggles = 2 * frequency * duration / 1000; - HAL_timer_set_compare(TONE_TIMER_NUM, VARIANT_MCK / 2 / frequency); // 84MHz / 2 prescaler / Hz + HAL_timer_set_count(TONE_TIMER_NUM, 0); // ensure first beep is correct (make sure counter is less than the compare value) + HAL_timer_set_compare(TONE_TIMER_NUM, VARIANT_MCK / 2 / 2 / frequency); // 84MHz / 2 prescaler / 2 interrupts per cycle /Hz HAL_timer_enable_interrupt(TONE_TIMER_NUM); } @@ -52,11 +54,13 @@ void noTone(const pin_t _pin) { HAL_TONE_TIMER_ISR { static uint8_t pin_state = 0; HAL_timer_isr_prologue(TONE_TIMER_NUM); + if (toggles) { toggles--; digitalWrite(tone_pin, (pin_state ^= 1)); } - else noTone(tone_pin); // seems superfluous ? + else noTone(tone_pin); // turn off interrupt + HAL_timer_restrain_count(TONE_TIMER_NUM, 10); // make sure next ISR isn't delayed by up to 2 minutes } #endif // ARDUINO_ARCH_SAM diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index c70988fad..5ffd30f53 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -648,7 +648,7 @@ void setup() { #ifdef HAL_INIT HAL_init(); - #if defined(ARDUINO_ARCH_SAM) && PIN_EXISTS(BEEPER) + #if defined(ARDUINO_ARCH_SAM) && PIN_EXISTS(BEEPER) && ENABLED(SPEAKER) toneInit(); #endif #endif