Tone fixes/changes (#10151)

This commit is contained in:
Bob-the-Kuhn 2018-03-19 04:48:06 -05:00 committed by Scott Lahteine
parent 2f192dbcd6
commit 53362b81cc
4 changed files with 29 additions and 12 deletions

View File

@ -67,7 +67,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TC1, 0, TC3_IRQn, 2}, // 3 - stepper { TC1, 0, TC3_IRQn, 2}, // 3 - stepper
{ TC1, 1, TC4_IRQn, 15}, // 4 - temperature { TC1, 1, TC4_IRQn, 15}, // 4 - temperature
{ TC1, 2, TC5_IRQn, 0}, // 5 - [servo timer3] { TC1, 2, TC5_IRQn, 0}, // 5 - [servo timer3]
{ TC2, 0, TC6_IRQn, 0}, // 6 - tone { TC2, 0, TC6_IRQn, 15}, // 6 - tone
{ TC2, 1, TC7_IRQn, 0}, // 7 { TC2, 1, TC7_IRQn, 0}, // 7
{ TC2, 2, TC8_IRQn, 0}, // 8 { 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); pmc_enable_periph_clk((uint32_t)irq);
NVIC_SetPriority(irq, TimerConfig [timer_num].priority); 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_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency); TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency);

View File

@ -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; 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) { 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; 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 (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_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_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); bool HAL_timer_interrupt_enabled(const uint8_t timer_num);

View File

@ -34,13 +34,15 @@ static pin_t tone_pin;
volatile static int32_t toggles; volatile static int32_t toggles;
void toneInit() { 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) { void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
tone_pin = _pin; tone_pin = _pin;
toggles = 2 * frequency * duration / 1000; 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); HAL_timer_enable_interrupt(TONE_TIMER_NUM);
} }
@ -52,11 +54,13 @@ void noTone(const pin_t _pin) {
HAL_TONE_TIMER_ISR { HAL_TONE_TIMER_ISR {
static uint8_t pin_state = 0; static uint8_t pin_state = 0;
HAL_timer_isr_prologue(TONE_TIMER_NUM); HAL_timer_isr_prologue(TONE_TIMER_NUM);
if (toggles) { if (toggles) {
toggles--; toggles--;
digitalWrite(tone_pin, (pin_state ^= 1)); 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 #endif // ARDUINO_ARCH_SAM

View File

@ -648,7 +648,7 @@ void setup() {
#ifdef HAL_INIT #ifdef HAL_INIT
HAL_init(); HAL_init();
#if defined(ARDUINO_ARCH_SAM) && PIN_EXISTS(BEEPER) #if defined(ARDUINO_ARCH_SAM) && PIN_EXISTS(BEEPER) && ENABLED(SPEAKER)
toneInit(); toneInit();
#endif #endif
#endif #endif