I am working with a Teensy 4.1 and the Audio Adapter. I extracted some code from the Audio Library output_i2s to do some direct writing to the sgtl5000 DAC. Here is the begin function I am using:
void CodecDAC_begin(void)
{
CodecDAC_dma.begin(true); // Allocate the DMA channel first
CodecDAC_config_i2s();
CORE_PIN7_CONFIG = 3; //1:TX_DATA0 pin 7 on uP
CodecDAC_dma.TCD->SADDR = myi2s_tx_buffer; //source address
CodecDAC_dma.TCD->SOFF = 2; // source buffer address increment per transfer in bytes
CodecDAC_dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); // specifies 16 bit source and destination
CodecDAC_dma.TCD->NBYTES_MLNO = 2; // bytes to transfer for each service request///////////////////////////////////////////////////////////////////
CodecDAC_dma.TCD->SLAST = -sizeof(myi2s_tx_buffer); // last source address adjustment
CodecDAC_dma.TCD->DOFF = 0; // increments at destination
CodecDAC_dma.TCD->CITER_ELINKNO = sizeof(myi2s_tx_buffer) / 2;
CodecDAC_dma.TCD->DLASTSGA = 0; // destination address offset
CodecDAC_dma.TCD->BITER_ELINKNO = sizeof(myi2s_tx_buffer) / 2;
CodecDAC_dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; // enables interrupt when transfers half and full complete
CodecDAC_dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0 + 2); // I2S1 register DMA writes to
CodecDAC_dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ SAI1_TX); // i2s channel that will trigger the DMA transfer when ready for data
CodecDAC_dma.enable();
I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE;
CodecDAC_dma.attachInterrupt(CodecDAC_isr);
}
This may be a naïve question, but because I am not double buffering the output myi2s_tx_buffer, I was wondering if is it possible to corrupt the DMA transfer if I write to the myi2s_tx_buffer while the DMA transfer is in progress?? I am getting some sporadic results and think that might be the cause.
Thanks for any help.
Neal
void CodecDAC_begin(void)
{
CodecDAC_dma.begin(true); // Allocate the DMA channel first
CodecDAC_config_i2s();
CORE_PIN7_CONFIG = 3; //1:TX_DATA0 pin 7 on uP
CodecDAC_dma.TCD->SADDR = myi2s_tx_buffer; //source address
CodecDAC_dma.TCD->SOFF = 2; // source buffer address increment per transfer in bytes
CodecDAC_dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); // specifies 16 bit source and destination
CodecDAC_dma.TCD->NBYTES_MLNO = 2; // bytes to transfer for each service request///////////////////////////////////////////////////////////////////
CodecDAC_dma.TCD->SLAST = -sizeof(myi2s_tx_buffer); // last source address adjustment
CodecDAC_dma.TCD->DOFF = 0; // increments at destination
CodecDAC_dma.TCD->CITER_ELINKNO = sizeof(myi2s_tx_buffer) / 2;
CodecDAC_dma.TCD->DLASTSGA = 0; // destination address offset
CodecDAC_dma.TCD->BITER_ELINKNO = sizeof(myi2s_tx_buffer) / 2;
CodecDAC_dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; // enables interrupt when transfers half and full complete
CodecDAC_dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0 + 2); // I2S1 register DMA writes to
CodecDAC_dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ SAI1_TX); // i2s channel that will trigger the DMA transfer when ready for data
CodecDAC_dma.enable();
I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE;
CodecDAC_dma.attachInterrupt(CodecDAC_isr);
}
This may be a naïve question, but because I am not double buffering the output myi2s_tx_buffer, I was wondering if is it possible to corrupt the DMA transfer if I write to the myi2s_tx_buffer while the DMA transfer is in progress?? I am getting some sporadic results and think that might be the cause.
Thanks for any help.
Neal