Hello,
we're implementing an Audio application running at 48kHz, 96kHz and 192kHz.
SAI source clock is generated with the internal Audio PLL. (49.152 MHz)
We configured the SAI1 with Tx0 (asyn / leader) and Rx0 (syn).
SAI FIFO is activated with 16 words (default middle value)
SAI Tx and Rx are driven by DMA channel. The DMA is used with 2 chained TCDs (to create a double buffer mechanism).
SAI works with 2 channels / 24 bits (32-bit aligned word).
Here an example of the conf on Sample rate change
// SubDivSamples is 4/8/16 respectively for 48/96/192 kHz
uint32_t singleBufferSize = 2 * sizeof(int32_t) * getSubDivSamples();
uint32_t minorLoopSize = 8 * sizeof(int32_t);
EDMA_PrepareTransfer(
&transferConfig,
txBuffer0,
sizeof(int32_t),
(void *)sai1TxRegAddr,
sizeof(int32_t),
minorLoopSize,
singleBufferSize,
kEDMA_MemoryToPeripheral);
EDMA_TcdSetTransferConfig(TxTcd0, &transferConfig, TxTcd1);
EDMA_TcdEnableInterrupts(TxTcd0, kEDMA_MajorInterruptEnable);
EDMA_PrepareTransfer(
&transferConfig,
txBuffer1,
sizeof(int32_t),
(void *)sai1TxRegAddr,
sizeof(int32_t),
minorLoopSize,
singleBufferSize,
kEDMA_MemoryToPeripheral);
EDMA_TcdSetTransferConfig(TxTcd1, &transferConfig, TxTcd0);
EDMA_TcdEnableInterrupts(TxTcd1, kEDMA_MajorInterruptEnable);
EDMA_InstallTCD(DMA0, mTxDmaHandle.channel, TxTcd0);
EDMA_StartTransfer(&mTxDmaHandle);
SAI_TxEnableDMA(SAI1, kSAI_FIFORequestDMAEnable, true);
SAI_TxSetChannelFIFOMask(SAI1, 1U << kSaiTxChannelId);
SAI_TxEnable(SAI1, true);
Then the Tx interrupt occurs with a frequency of 12kHz. (each 4 samples at 48kHz, each 8 samples at 96kHz, ...)
I monitor Tx and Rx interrupt callbacks (with GPIOs) and I2S signal (BCLK, SYNC, TX, Rx)
Everything works well at 48kHz and 96kHz.
But the system stops when I change the Sample Rate to 192kHz.
I can see that I2S BCLK and SYNC are correct.
I can see the first interrupts at 192kHz (about 14 DMA cycles) and then it stops.
I can change the Sample rate back to 48kHz but the interrupt never recovers.
If someone has an idea.
解決済! 解決策の投稿を見る。
I finally found the solution. My issue was due to an overflow of a buffer located just before the TCDs in memory, that altered the content of the TCDs.
The code is now working perfectly.
Hello @ju_fz,
Sorry for the late response.
The issue might be related to a FIFO overrun. To help narrow it down, could you try increasing the FIFO size to its maximum value of 32 words, as specified in Chapter 37.3.4 "Data FIFO" of the Reference Manual?
Additionally, please check the error status flags in the Transmit Control Register (TCSR), detailed in section 37.5.1.4, to see if any error conditions are being reported.
BR
Habib
hello,
thanks for the reply.
SAI FIFO Size is always 32 words.
I have set up the FIFO watermark to 16.
I checked TCSR in several contexts:
I tried to detect the SAI FIFO Error Flag in the DMA Interrupt. I tested it at the entry and output of the interrupt. And no error is detected during the interrupt but the DMA stopped.
I tried to disable Rx SAI/DMA. Tx still stops at 192kHz.
I currently have no more clue.
Julien
Hello @ju_fz,
According to the TCSR value (0x90170001), three flags are detected:
These flags indicate that the DMA is unable to transmit data quickly enough to prevent them from being triggered. This could be due to several factors, such as other interrupts or a slow CPU. It also explains why the issue does not occur at lower sample rates. Please ensure that interrupts are handled in a timely manner so the DMA can transmit data smoothly.
BR
Habib
I finally found the solution. My issue was due to an overflow of a buffer located just before the TCDs in memory, that altered the content of the TCDs.
The code is now working perfectly.