Browse Source

Use DMAChannel begin()

dds
PaulStoffregen 10 years ago
parent
commit
cb5c9e9729
7 changed files with 97 additions and 98 deletions
  1. +7
    -0
      Audio.h
  2. +35
    -34
      input_i2s.cpp
  3. +1
    -4
      input_i2s.h
  4. +18
    -19
      output_dac.cpp
  5. +1
    -4
      output_dac.h
  6. +34
    -33
      output_i2s.cpp
  7. +1
    -4
      output_i2s.h

+ 7
- 0
Audio.h View File

@@ -34,6 +34,13 @@
#error "The Audio Library only works with Teensy 3.X. Teensy 2.0 is unsupported."
#endif

#include "DMAChannel.h"
#ifndef DMACHANNEL_HAS_BEGIN
#error "You need to update DMAChannel.h & DMAChannel.cpp"
#error "https://github.com/PaulStoffregen/cores/blob/master/teensy3/DMAChannel.h"
#error "https://github.com/PaulStoffregen/cores/blob/master/teensy3/DMAChannel.cpp"
#endif

// When changing multiple audio object settings that must update at
// the same time, these functions allow the audio library interrupt
// to be disabled. For example, you may wish to begin playing a note

+ 35
- 34
input_i2s.cpp View File

@@ -32,11 +32,12 @@ audio_block_t * AudioInputI2S::block_left = NULL;
audio_block_t * AudioInputI2S::block_right = NULL;
uint16_t AudioInputI2S::block_offset = 0;
bool AudioInputI2S::update_responsibility = false;
DMAChannel AudioInputI2S::dma;


void AudioInputI2S::begin(void)
{
dma(); // Allocate the DMA channel first
dma.begin(true); // Allocate the DMA channel first

//block_left_1st = NULL;
//block_right_1st = NULL;
@@ -46,25 +47,25 @@ void AudioInputI2S::begin(void)

CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0

dma().TCD->SADDR = &I2S0_RDR0;
dma().TCD->SOFF = 0;
dma().TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma().TCD->NBYTES_MLNO = 2;
dma().TCD->SLAST = 0;
dma().TCD->DADDR = i2s_rx_buffer;
dma().TCD->DOFF = 2;
dma().TCD->CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma().TCD->DLASTSGA = -sizeof(i2s_rx_buffer);
dma().TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma().TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma().triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX);
dma.TCD->SADDR = &I2S0_RDR0;
dma.TCD->SOFF = 0;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma.TCD->NBYTES_MLNO = 2;
dma.TCD->SLAST = 0;
dma.TCD->DADDR = i2s_rx_buffer;
dma.TCD->DOFF = 2;
dma.TCD->CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer);
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX);
update_responsibility = update_setup();
dma().enable();
dma.enable();

I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR;
I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX
dma().attachInterrupt(isr);
dma.attachInterrupt(isr);
}

void AudioInputI2S::isr(void)
@@ -75,8 +76,8 @@ void AudioInputI2S::isr(void)
audio_block_t *left, *right;

//digitalWriteFast(3, HIGH);
daddr = (uint32_t)(dma().TCD->DADDR);
dma().clearInterrupt();
daddr = (uint32_t)(dma.TCD->DADDR);
dma.clearInterrupt();

if (daddr < (uint32_t)i2s_rx_buffer + sizeof(i2s_rx_buffer) / 2) {
// DMA is receiving to the first half of the buffer
@@ -170,7 +171,7 @@ void AudioInputI2S::update(void)

void AudioInputI2Sslave::begin(void)
{
dma(); // Allocate the DMA channel first
dma.begin(true); // Allocate the DMA channel first

//block_left_1st = NULL;
//block_right_1st = NULL;
@@ -179,25 +180,25 @@ void AudioInputI2Sslave::begin(void)

CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0

dma().TCD->SADDR = &I2S0_RDR0;
dma().TCD->SOFF = 0;
dma().TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma().TCD->NBYTES_MLNO = 2;
dma().TCD->SLAST = 0;
dma().TCD->DADDR = i2s_rx_buffer;
dma().TCD->DOFF = 2;
dma().TCD->CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma().TCD->DLASTSGA = -sizeof(i2s_rx_buffer);
dma().TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma().TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma().triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX);
dma.TCD->SADDR = &I2S0_RDR0;
dma.TCD->SOFF = 0;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma.TCD->NBYTES_MLNO = 2;
dma.TCD->SLAST = 0;
dma.TCD->DADDR = i2s_rx_buffer;
dma.TCD->DOFF = 2;
dma.TCD->CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer);
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX);
update_responsibility = update_setup();
dma().enable();
dma.enable();

I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR;
I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX
dma().attachInterrupt(isr);
dma.attachInterrupt(isr);
}



+ 1
- 4
input_i2s.h View File

@@ -39,10 +39,7 @@ public:
protected:
AudioInputI2S(int dummy): AudioStream(0, NULL) {} // to be used only inside AudioInputI2Sslave !!
static bool update_responsibility;
static inline DMAChannel &dma() __attribute__((always_inline)) {
static DMAChannel mydma;
return mydma;
}
static DMAChannel dma;
static void isr(void);
private:
static audio_block_t *block_left;

+ 18
- 19
output_dac.cpp View File

@@ -33,10 +33,11 @@ DMAMEM static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
audio_block_t * AudioOutputAnalog::block_left_1st = NULL;
audio_block_t * AudioOutputAnalog::block_left_2nd = NULL;
bool AudioOutputAnalog::update_responsibility = false;
DMAChannel AudioOutputAnalog::dma;

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

SIM_SCGC2 |= SIM_SCGC2_DAC0;
DAC0_C0 = DAC_C0_DACEN; // 1.2V VDDA is DACREF_2
@@ -53,21 +54,21 @@ void AudioOutputAnalog::begin(void)
PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG | PDB_SC_PDBIE | PDB_SC_DMAEN;

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);
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();
dma().enable();
dma().attachInterrupt(isr);
dma.enable();
dma.attachInterrupt(isr);
}

void AudioOutputAnalog::analogReference(int ref)
@@ -113,10 +114,8 @@ void AudioOutputAnalog::isr(void)
audio_block_t *block;
uint32_t saddr;

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

+ 1
- 4
output_dac.h View File

@@ -42,10 +42,7 @@ private:
static audio_block_t *block_left_2nd;
static bool update_responsibility;
audio_block_t *inputQueueArray[1];
static inline DMAChannel &dma() __attribute__((always_inline)) {
static DMAChannel mydma;
return mydma;
}
static DMAChannel dma;
static void isr(void);
};


+ 34
- 33
output_i2s.cpp View File

@@ -34,10 +34,11 @@ uint16_t AudioOutputI2S::block_left_offset = 0;
uint16_t AudioOutputI2S::block_right_offset = 0;
bool AudioOutputI2S::update_responsibility = false;
DMAMEM static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
DMAChannel AudioOutputI2S::dma;

void AudioOutputI2S::begin(void)
{
dma(); // Allocate the DMA channel first
dma.begin(true); // Allocate the DMA channel first

block_left_1st = NULL;
block_right_1st = NULL;
@@ -46,23 +47,23 @@ void AudioOutputI2S::begin(void)
config_i2s();
CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0

dma().TCD->SADDR = i2s_tx_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(i2s_tx_buffer);
dma().TCD->DADDR = &I2S0_TDR0;
dma().TCD->DOFF = 0;
dma().TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma().TCD->DLASTSGA = 0;
dma().TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma().TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma().triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
dma.TCD->SADDR = i2s_tx_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(i2s_tx_buffer);
dma.TCD->DADDR = &I2S0_TDR0;
dma.TCD->DOFF = 0;
dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
update_responsibility = update_setup();
dma().enable();
dma.enable();

I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE | I2S_TCSR_FR;
dma().attachInterrupt(isr);
dma.attachInterrupt(isr);
}


@@ -73,8 +74,8 @@ void AudioOutputI2S::isr(void)
audio_block_t *block;
uint32_t saddr, offset;

saddr = (uint32_t)(dma().TCD->SADDR);
dma().clearInterrupt();
saddr = (uint32_t)(dma.TCD->SADDR);
dma.clearInterrupt();
if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) {
// DMA is transmitting the first half of the buffer
// so we must fill the second half
@@ -267,7 +268,7 @@ void AudioOutputI2S::config_i2s(void)

void AudioOutputI2Sslave::begin(void)
{
dma(); // Allocate the DMA channel first
dma.begin(true); // Allocate the DMA channel first

//pinMode(2, OUTPUT);
block_left_1st = NULL;
@@ -276,24 +277,24 @@ void AudioOutputI2Sslave::begin(void)
AudioOutputI2Sslave::config_i2s();
CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0

dma().TCD->SADDR = i2s_tx_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(i2s_tx_buffer);
dma().TCD->DADDR = &I2S0_TDR0;
dma().TCD->DOFF = 0;
dma().TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma().TCD->DLASTSGA = 0;
dma().TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma().TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma().triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
dma.TCD->SADDR = i2s_tx_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(i2s_tx_buffer);
dma.TCD->DADDR = &I2S0_TDR0;
dma.TCD->DOFF = 0;
dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
update_responsibility = update_setup();
dma().enable();
dma.enable();

I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE | I2S_TCSR_FR;
dma().attachInterrupt(isr);
dma.attachInterrupt(isr);
}

void AudioOutputI2Sslave::config_i2s(void)

+ 1
- 4
output_i2s.h View File

@@ -43,10 +43,7 @@ protected:
static audio_block_t *block_left_1st;
static audio_block_t *block_right_1st;
static bool update_responsibility;
static inline DMAChannel &dma() __attribute__((always_inline)) {
static DMAChannel mydma;
return mydma;
}
static DMAChannel dma;
static void isr(void);
private:
static audio_block_t *block_left_2nd;

Loading…
Cancel
Save