[sky9x/Taranis] Audio mixer!
This commit is contained in:
@@ -36,33 +36,22 @@
|
||||
|
||||
#include "../../opentx.h"
|
||||
|
||||
uint32_t currentFrequency = 0;
|
||||
|
||||
uint32_t getFrequency()
|
||||
void setSampleRate(uint32_t frequency)
|
||||
{
|
||||
return currentFrequency;
|
||||
}
|
||||
register Tc *ptc ;
|
||||
register uint32_t timer ;
|
||||
|
||||
void setFrequency(uint32_t frequency)
|
||||
{
|
||||
if (currentFrequency != frequency) {
|
||||
currentFrequency = frequency;
|
||||
timer = Master_frequency / (8 * frequency) ; // MCK/8 and 100 000 Hz
|
||||
if (timer > 65535)
|
||||
timer = 65535 ;
|
||||
if (timer < 2)
|
||||
timer = 2 ;
|
||||
|
||||
register Tc *ptc ;
|
||||
register uint32_t timer ;
|
||||
|
||||
timer = Master_frequency / (8 * frequency) ; // MCK/8 and 100 000 Hz
|
||||
if (timer > 65535)
|
||||
timer = 65535 ;
|
||||
if (timer < 2)
|
||||
timer = 2 ;
|
||||
|
||||
ptc = TC0 ; // Tc block 0 (TC0-2)
|
||||
ptc->TC_CHANNEL[1].TC_CCR = TC_CCR0_CLKDIS ; // Stop clock
|
||||
ptc->TC_CHANNEL[1].TC_RC = timer ; // 100 000 Hz
|
||||
ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ;
|
||||
ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
}
|
||||
ptc = TC0 ; // Tc block 0 (TC0-2)
|
||||
ptc->TC_CHANNEL[1].TC_CCR = TC_CCR0_CLKDIS ; // Stop clock
|
||||
ptc->TC_CHANNEL[1].TC_RC = timer ; // 100 000 Hz
|
||||
ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ;
|
||||
ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
}
|
||||
|
||||
// Start TIMER1 at 100000Hz, used for DACC trigger
|
||||
@@ -108,29 +97,22 @@ void dacInit()
|
||||
|
||||
dacptr->DACC_CDR = 2048 ; // Half amplitude
|
||||
|
||||
// Data for PDC must NOT be in flash, PDC needs a RAM source.
|
||||
dacFill(Sine_values, 50/*100 samples*/);
|
||||
dacptr->DACC_PTCR = DACC_PTCR_TXTEN ;
|
||||
|
||||
NVIC_EnableIRQ(DACC_IRQn) ;
|
||||
}
|
||||
|
||||
bool dacQueue(AudioBuffer *buffer)
|
||||
{
|
||||
dacStart();
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void DAC_IRQHandler()
|
||||
{
|
||||
// Data for PDC must NOT be in flash, PDC needs a RAM source.
|
||||
if (audioQueue.state == AUDIO_PLAYING_WAV) {
|
||||
if (nextAudioData) {
|
||||
DACC->DACC_TNPR = CONVERT_PTR(nextAudioData);
|
||||
DACC->DACC_TNCR = nextAudioSize;
|
||||
nextAudioData = NULL;
|
||||
}
|
||||
else {
|
||||
dacStop();
|
||||
}
|
||||
}
|
||||
else if (audioQueue.state == AUDIO_PLAYING_TONE){
|
||||
DACC->DACC_TNPR = CONVERT_PTR(Sine_values);
|
||||
DACC->DACC_TNCR = 50 ; // words, 100 16 bit values
|
||||
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer();
|
||||
if (nextBuffer) {
|
||||
DACC->DACC_TNPR = CONVERT_PTR(nextBuffer->data);
|
||||
DACC->DACC_TNCR = nextBuffer->size/2;
|
||||
}
|
||||
else {
|
||||
dacStop();
|
||||
|
||||
@@ -40,11 +40,7 @@
|
||||
void audioInit( void ) ;
|
||||
void audioEnd( void ) ;
|
||||
|
||||
void setFrequency( uint32_t frequency ) ;
|
||||
uint32_t getFrequency();
|
||||
|
||||
extern uint16_t *nextAudioData;
|
||||
extern uint16_t nextAudioSize;
|
||||
void setSampleRate( uint32_t frequency ) ;
|
||||
|
||||
inline void dacStart()
|
||||
{
|
||||
@@ -61,31 +57,4 @@ inline void dacStop()
|
||||
#define VOLUME_LEVEL_DEF 12
|
||||
void setVolume(uint8_t volume);
|
||||
|
||||
inline void dacFill(uint16_t *data, uint16_t size)
|
||||
{
|
||||
register Dacc *dacptr = DACC;
|
||||
dacptr->DACC_TPR = CONVERT_PTR(data);
|
||||
dacptr->DACC_TNPR = CONVERT_PTR(data);
|
||||
dacptr->DACC_TCR = size; // words
|
||||
dacptr->DACC_TNCR = size; // words
|
||||
}
|
||||
|
||||
inline uint16_t dacQueue(uint16_t *data, uint16_t size)
|
||||
{
|
||||
register Dacc *dacptr = DACC;
|
||||
if (dacptr->DACC_ISR & DACC_ISR_TXBUFE) {
|
||||
dacptr->DACC_TPR = CONVERT_PTR(data);
|
||||
dacptr->DACC_TCR = size;
|
||||
return size;
|
||||
}
|
||||
else if (dacptr->DACC_TNCR == 0) {
|
||||
dacptr->DACC_TNPR = CONVERT_PTR(data);
|
||||
dacptr->DACC_TNCR = size;
|
||||
return size;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,8 +78,8 @@
|
||||
#define RESUME_PPMIN_INTERRUPT() TIMSK3 |= (1<<ICIE3)
|
||||
#define TIMER_AUDIO_VECT TIMER4_OVF_vect
|
||||
#define SET_TIMER_AUDIO_CTRL() TCCR4B = (0b111 << CS20)
|
||||
#define PAUSE_AUDIO_INTERRUPT() TIMSK4 &= ~(1<<OCIE4A)
|
||||
#define RESUME_AUDIO_INTERRUPT() TIMSK4 |= (1<<OCIE4A)
|
||||
#define PAUSE_AUDIO_INTERRUPT() TIMSK4 &= ~(1<<TOIE4)
|
||||
#define RESUME_AUDIO_INTERRUPT() TIMSK4 |= (1<<TOIE4)
|
||||
#else
|
||||
#define TIMER_16KHZ_VECT TIMER0_OVF_vect
|
||||
#define COUNTER_16KHZ TCNT0
|
||||
|
||||
@@ -37,25 +37,15 @@
|
||||
#include "../../opentx.h"
|
||||
|
||||
bool dacIdle = true;
|
||||
uint32_t currentFrequency = 0;
|
||||
|
||||
uint32_t getFrequency()
|
||||
void setSampleRate(uint32_t frequency)
|
||||
{
|
||||
return currentFrequency;
|
||||
}
|
||||
register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz
|
||||
|
||||
void setFrequency(uint32_t frequency)
|
||||
{
|
||||
if (currentFrequency != frequency) {
|
||||
currentFrequency = frequency;
|
||||
|
||||
register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz
|
||||
|
||||
TIM6->CR1 &= ~TIM_CR1_CEN ;
|
||||
TIM6->CNT = 0 ;
|
||||
TIM6->ARR = limit<uint32_t>(2, timer, 65535) ;
|
||||
TIM6->CR1 |= TIM_CR1_CEN ;
|
||||
}
|
||||
TIM6->CR1 &= ~TIM_CR1_CEN ;
|
||||
TIM6->CNT = 0 ;
|
||||
TIM6->ARR = limit<uint32_t>(2, timer, 65535) ;
|
||||
TIM6->CR1 |= TIM_CR1_CEN ;
|
||||
}
|
||||
|
||||
// Start TIMER6 at 100000Hz, used for DAC trigger
|
||||
@@ -87,24 +77,42 @@ void dacInit()
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 |
|
||||
DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ;
|
||||
DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ;
|
||||
DMA1_Stream5->PAR = CONVERT_PTR(&DAC->DHR12R1);
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(Sine_values);
|
||||
// DMA1_Stream5->M0AR = CONVERT_PTR(Sine_values);
|
||||
DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
|
||||
DMA1_Stream5->NDTR = 100 ;
|
||||
// DMA1_Stream5->NDTR = 100 ;
|
||||
|
||||
DAC->DHR12R1 = 2010 ;
|
||||
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
|
||||
DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 ; // Enable DAC
|
||||
NVIC_SetPriority( DMA1_Stream5_IRQn, 2 ) ; // High priority interrupt
|
||||
NVIC_EnableIRQ(TIM6_DAC_IRQn) ;
|
||||
NVIC_SetPriority(DMA1_Stream5_IRQn, 2) ; // High priority interrupt
|
||||
NVIC_EnableIRQ(TIM6_DAC_IRQn) ; // TODO needed?
|
||||
NVIC_EnableIRQ(DMA1_Stream5_IRQn) ;
|
||||
}
|
||||
|
||||
bool dacQueue(AudioBuffer *buffer)
|
||||
{
|
||||
if (dacIdle) {
|
||||
dacIdle = false;
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(buffer->data);
|
||||
DMA1_Stream5->NDTR = buffer->size;
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
|
||||
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
|
||||
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sound routines
|
||||
void audioInit()
|
||||
{
|
||||
dacInit() ;
|
||||
dacInit();
|
||||
}
|
||||
|
||||
void audioEnd()
|
||||
@@ -129,13 +137,14 @@ extern "C" void DMA1_Stream5_IRQHandler()
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
|
||||
if (nextAudioData) {
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(nextAudioData);
|
||||
DMA1_Stream5->NDTR = nextAudioSize*2;
|
||||
|
||||
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer();
|
||||
if (nextBuffer) {
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(nextBuffer->data);
|
||||
DMA1_Stream5->NDTR = nextBuffer->size;
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel
|
||||
DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag
|
||||
nextAudioData = NULL;
|
||||
}
|
||||
else {
|
||||
dacIdle = true;
|
||||
|
||||
@@ -40,12 +40,9 @@
|
||||
extern void audioInit( void ) ;
|
||||
extern void audioEnd( void ) ;
|
||||
|
||||
extern void setFrequency( uint32_t frequency ) ;
|
||||
extern uint32_t getFrequency();
|
||||
extern void setSampleRate(uint32_t frequency);
|
||||
|
||||
extern bool dacIdle;
|
||||
extern uint16_t *nextAudioData;
|
||||
extern uint16_t nextAudioSize;
|
||||
|
||||
inline void dacStart()
|
||||
{
|
||||
@@ -60,31 +57,6 @@ inline void dacStop()
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_CIRC ;
|
||||
}
|
||||
|
||||
inline void dacFill(uint16_t *data, uint16_t size)
|
||||
{
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN; // Disable DMA channel
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(data);
|
||||
DMA1_Stream5->NDTR = size*2;
|
||||
}
|
||||
|
||||
inline uint16_t dacQueue(uint16_t *data, uint16_t size)
|
||||
{
|
||||
if (dacIdle) {
|
||||
dacIdle = false;
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR(data);
|
||||
DMA1_Stream5->NDTR = size*2;
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
|
||||
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
|
||||
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
|
||||
return size;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define VOLUME_LEVEL_MAX 23
|
||||
#define VOLUME_LEVEL_DEF 12
|
||||
static const int8_t volumeScale[VOLUME_LEVEL_MAX+1] =
|
||||
|
||||
Reference in New Issue
Block a user