Browse Source

Convert AudioOutputAnalog to use DMAChannel.h

dds
PaulStoffregen 10 years ago
parent
commit
e613025bc3
2 changed files with 27 additions and 23 deletions
  1. +22
    -22
      output_dac.cpp
  2. +5
    -1
      output_dac.h

+ 22
- 22
output_dac.cpp View File



void AudioOutputAnalog::begin(void) void AudioOutputAnalog::begin(void)
{ {
dma(); // Allocate the DMA channel first

SIM_SCGC2 |= SIM_SCGC2_DAC0; SIM_SCGC2 |= SIM_SCGC2_DAC0;
DAC0_C0 = DAC_C0_DACEN; // 1.2V VDDA is DACREF_2 DAC0_C0 = DAC_C0_DACEN; // 1.2V VDDA is DACREF_2
//DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
// slowly ramp up to DC voltage, approx 1/4 second // slowly ramp up to DC voltage, approx 1/4 second
for (int16_t i=0; i<2048; i+=8) { for (int16_t i=0; i<2048; i+=8) {
*(int16_t *)&(DAC0_DAT0L) = i; *(int16_t *)&(DAC0_DAT0L) = i;
PDB0_MOD = PDB_PERIOD; PDB0_MOD = PDB_PERIOD;
PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG | PDB_SC_PDBIE | PDB_SC_DMAEN; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG | PDB_SC_PDBIE | PDB_SC_DMAEN;
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
DMA_CR = 0;
DMA_TCD4_SADDR = dac_buffer;
DMA_TCD4_SOFF = 2;
DMA_TCD4_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
DMA_TCD4_NBYTES_MLNO = 2;
DMA_TCD4_SLAST = -sizeof(dac_buffer);
DMA_TCD4_DADDR = &DAC0_DAT0L;
DMA_TCD4_DOFF = 0;
DMA_TCD4_CITER_ELINKNO = sizeof(dac_buffer) / 2;
DMA_TCD4_DLASTSGA = 0;
DMA_TCD4_BITER_ELINKNO = sizeof(dac_buffer) / 2;
DMA_TCD4_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
DMAMUX0_CHCFG4 = DMAMUX_DISABLE;
DMAMUX0_CHCFG4 = DMAMUX_SOURCE_PDB | DMAMUX_ENABLE;

dma().TCD->SADDR = dac_buffer;
dma().TCD->SOFF = 2;
dma().TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma().TCD->NBYTES_MLNO = 2;
dma().TCD->SLAST = -sizeof(dac_buffer);
dma().TCD->DADDR = &DAC0_DAT0L;
dma().TCD->DOFF = 0;
dma().TCD->CITER_ELINKNO = sizeof(dac_buffer) / 2;
dma().TCD->DLASTSGA = 0;
dma().TCD->BITER_ELINKNO = sizeof(dac_buffer) / 2;
dma().TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma().triggerAtHardwareEvent(DMAMUX_SOURCE_PDB);
update_responsibility = update_setup(); update_responsibility = update_setup();
DMA_SERQ = 4;
NVIC_ENABLE_IRQ(IRQ_DMA_CH4);
dma().enable();
dma().attachInterrupt(isr);
} }


void AudioOutputAnalog::analogReference(int ref) void AudioOutputAnalog::analogReference(int ref)
// TODO: the DAC has much higher bandwidth than the datasheet says // TODO: the DAC has much higher bandwidth than the datasheet says
// can we output a 2X oversampled output, for easier filtering? // can we output a 2X oversampled output, for easier filtering?


void dma_ch4_isr(void)
void AudioOutputAnalog::isr(void)
{ {
const int16_t *src, *end; const int16_t *src, *end;
int16_t *dest; int16_t *dest;
audio_block_t *block; audio_block_t *block;
uint32_t saddr; uint32_t saddr;


saddr = (uint32_t)DMA_TCD4_SADDR;
DMA_CINT = 4;
//saddr = (uint32_t)DMA_TCD4_SADDR;
//DMA_CINT = 4;
saddr = (uint32_t)(dma().TCD->SADDR);
dma().clearInterrupt();
if (saddr < (uint32_t)dac_buffer + sizeof(dac_buffer) / 2) { if (saddr < (uint32_t)dac_buffer + sizeof(dac_buffer) / 2) {
// DMA is transmitting the first half of the buffer // DMA is transmitting the first half of the buffer
// so we must fill the second half // so we must fill the second half

+ 5
- 1
output_dac.h View File

virtual void update(void); virtual void update(void);
void begin(void); void begin(void);
void analogReference(int ref); void analogReference(int ref);
friend void dma_ch4_isr(void);
private: private:
static audio_block_t *block_left_1st; static audio_block_t *block_left_1st;
static audio_block_t *block_left_2nd; static audio_block_t *block_left_2nd;
static bool update_responsibility; static bool update_responsibility;
audio_block_t *inputQueueArray[1]; audio_block_t *inputQueueArray[1];
static inline DMAChannel &dma() __attribute__((always_inline)) {
static DMAChannel mydma;
return mydma;
}
static void isr(void);
}; };


#endif #endif

Loading…
Cancel
Save