use TC1 for servo, TC0 for tone for samd51
- make Tone_Handler() a strong symbol
This commit is contained in:
parent
1e92424a50
commit
aa5fa81bb7
2 changed files with 80 additions and 67 deletions
|
|
@ -20,12 +20,6 @@
|
||||||
#include "Tone.h"
|
#include "Tone.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE);
|
|
||||||
#else
|
|
||||||
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t toneMaxFrequency = F_CPU / 2;
|
uint32_t toneMaxFrequency = F_CPU / 2;
|
||||||
uint32_t lastOutputPin = 0xFFFFFFFF;
|
uint32_t lastOutputPin = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
@ -37,22 +31,24 @@ volatile bool toneIsActive = false;
|
||||||
volatile bool firstTimeRunning = false;
|
volatile bool firstTimeRunning = false;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
#define TONE_TC TC0
|
#define TONE_TC TC0
|
||||||
#define TONE_TC_IRQn TC0_IRQn
|
#define TONE_TC_IRQn TC0_IRQn
|
||||||
#define TONE_TC_GCLK_ID TC0_GCLK_ID
|
#define TONE_TC_GCLK_ID TC0_GCLK_ID
|
||||||
|
#define Tone_Handler TC0_Handler
|
||||||
|
|
||||||
|
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define TONE_TC TC5
|
#define TONE_TC TC5
|
||||||
#define TONE_TC_IRQn TC5_IRQn
|
#define TONE_TC_IRQn TC5_IRQn
|
||||||
|
#define Tone_Handler TC5_Handler
|
||||||
|
|
||||||
|
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TONE_TC_TOP 0xFFFF
|
#define TONE_TC_TOP 0xFFFF
|
||||||
#define TONE_TC_CHANNEL 0
|
#define TONE_TC_CHANNEL 0
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
void TC0_Handler (void) __attribute__ ((weak, alias("Tone_Handler")));
|
|
||||||
#else
|
|
||||||
void TC5_Handler (void) __attribute__ ((weak, alias("Tone_Handler")));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void resetTC (Tc* TCx)
|
static inline void resetTC (Tc* TCx)
|
||||||
{
|
{
|
||||||
// Disable TCx
|
// Disable TCx
|
||||||
|
|
@ -72,6 +68,14 @@ void toneAccurateClock (uint32_t accurateSystemCoreClockFrequency)
|
||||||
|
|
||||||
void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Avoid divide by zero error by calling 'noTone' instead
|
||||||
|
if (frequency == 0)
|
||||||
|
{
|
||||||
|
noTone(outputPin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Configure interrupt request
|
// Configure interrupt request
|
||||||
NVIC_DisableIRQ(TONE_TC_IRQn);
|
NVIC_DisableIRQ(TONE_TC_IRQn);
|
||||||
NVIC_ClearPendingIRQ(TONE_TC_IRQn);
|
NVIC_ClearPendingIRQ(TONE_TC_IRQn);
|
||||||
|
|
@ -91,9 +95,6 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's a rest, set to 1Hz (below audio range)
|
|
||||||
frequency = (frequency > 0 ? frequency : 1);
|
|
||||||
|
|
||||||
if (toneIsActive && (outputPin != lastOutputPin))
|
if (toneIsActive && (outputPin != lastOutputPin))
|
||||||
noTone(lastOutputPin);
|
noTone(lastOutputPin);
|
||||||
|
|
||||||
|
|
@ -167,8 +168,8 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
lastOutputPin = outputPin;
|
lastOutputPin = outputPin;
|
||||||
digitalWrite(outputPin, LOW);
|
digitalWrite(outputPin, LOW);
|
||||||
pinMode(outputPin, OUTPUT);
|
pinMode(outputPin, OUTPUT);
|
||||||
}
|
|
||||||
toneIsActive = true;
|
toneIsActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Enable TONE_TC
|
// Enable TONE_TC
|
||||||
TONE_TC->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
|
TONE_TC->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
|
||||||
|
|
@ -179,9 +180,19 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
|
|
||||||
void noTone (uint32_t outputPin)
|
void noTone (uint32_t outputPin)
|
||||||
{
|
{
|
||||||
|
/* 'tone' need to run at least once in order to enable GCLK for
|
||||||
|
* the timers used for the tone-functionality. If 'noTone' is called
|
||||||
|
* without ever calling 'tone' before then 'WAIT_TC16_REGS_SYNC(TCx)'
|
||||||
|
* will wait infinitely. The variable 'firstTimeRunning' is set the
|
||||||
|
* 1st time 'tone' is set so it can be used to detect wether or not
|
||||||
|
* 'tone' has been called before.
|
||||||
|
*/
|
||||||
|
if(firstTimeRunning)
|
||||||
|
{
|
||||||
resetTC(TONE_TC);
|
resetTC(TONE_TC);
|
||||||
digitalWrite(outputPin, LOW);
|
digitalWrite(outputPin, LOW);
|
||||||
toneIsActive = false;
|
toneIsActive = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -39,26 +39,27 @@
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
#if defined (_useTimer1)
|
#if defined (_useTimer1)
|
||||||
#define TC_FOR_TIMER1 TC0
|
#define TC_FOR_TIMER1 TC1
|
||||||
#define CHANNEL_FOR_TIMER1 0
|
#define CHANNEL_FOR_TIMER1 0
|
||||||
#define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0
|
#define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0
|
||||||
#define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0
|
#define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0
|
||||||
#define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0
|
#define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0
|
||||||
#define ID_TC_FOR_TIMER1 ID_TC0
|
#define ID_TC_FOR_TIMER1 ID_TC1
|
||||||
#define IRQn_FOR_TIMER1 TC0_IRQn
|
#define IRQn_FOR_TIMER1 TC1_IRQn
|
||||||
#define HANDLER_FOR_TIMER1 TC0_Handler
|
#define HANDLER_FOR_TIMER1 TC1_Handler
|
||||||
#define GCM_FOR_TIMER_1 9 // GCLK_TC0
|
#define GCM_FOR_TIMER_1 TC1_GCLK_ID
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_useTimer2)
|
#if defined (_useTimer2)
|
||||||
#define TC_FOR_TIMER2 TC0
|
#define TC_FOR_TIMER2 TC1
|
||||||
#define CHANNEL_FOR_TIMER2 1
|
#define CHANNEL_FOR_TIMER2 1
|
||||||
#define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1
|
#define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1
|
||||||
#define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1
|
#define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1
|
||||||
#define INTFLAG_BIT_FOR_TIMER_2 TC_INTFLAG_MC1
|
#define INTFLAG_BIT_FOR_TIMER_2 TC_INTFLAG_MC1
|
||||||
#define ID_TC_FOR_TIMER2 ID_TC0
|
#define ID_TC_FOR_TIMER2 ID_TC1
|
||||||
#define IRQn_FOR_TIMER2 TC0_IRQn
|
#define IRQn_FOR_TIMER2 TC1_IRQn
|
||||||
#define HANDLER_FOR_TIMER2 TC0_Handler
|
#define HANDLER_FOR_TIMER2 TC1_Handler
|
||||||
#define GCM_FOR_TIMER_2 9 // GCLK_TC0
|
#define GCM_FOR_TIMER_2 TC1_GCLK_ID
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if defined (_useTimer1)
|
#if defined (_useTimer1)
|
||||||
|
|
@ -72,6 +73,7 @@
|
||||||
#define HANDLER_FOR_TIMER1 TC4_Handler
|
#define HANDLER_FOR_TIMER1 TC4_Handler
|
||||||
#define GCM_FOR_TIMER_1 GCM_TC4_TC5
|
#define GCM_FOR_TIMER_1 GCM_TC4_TC5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_useTimer2)
|
#if defined (_useTimer2)
|
||||||
#define TC_FOR_TIMER2 TC4
|
#define TC_FOR_TIMER2 TC4
|
||||||
#define CHANNEL_FOR_TIMER2 1
|
#define CHANNEL_FOR_TIMER2 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue