Dear,
In my development, the I2S underrun occured, and I haven't found the way to resolve it.
it will be appreciated with your help.
I have two questions about this:
1. It is described in "KL26P121M48SF4RM.PDF", as highlighted below. It provides the method to resolve.
But I am confused by the words "at least three bit clocks". I can't understand it clearly, furtherly I don't know how to writte the TDR to avoid FIFO underrun.
2. I found that if a delay is added at the end of the transmit loop, the underloop will not occur. The code is as below:
while(1){
for( i = 0; i < sizeof(g_AudioPcmData); i += 4 ){
Board_I2sSendData( I2S0, 0, 32, &g_AudioPcmData[i], 4 );
}
Board_Delay_us( 100*1000 );
}
The code of Board_I2sSendData() is as below:
status_t Board_I2sSendData(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size){
uint32_t i = 0;
uint32_t j = 0;
uint8_t bytesPerWord = bitWidth / 8U;
uint32_t data = 0;
uint32_t temp = 0;
status_t retValue = kSAI_SendSuccess;
while (i < size)
{
// Wait until FIFO is empty
while (!(base->TCSR & I2S_TCSR_FWF_MASK))
{
}
i += bytesPerWord;
for (j = bytesPerWord; j > 0; j--)
{
temp = (uint32_t)(*buffer);
data |= (temp << (8U * (j-1)));
buffer++;
}
base->TDR[channel] = data; //Load the word into data register
data = 0;
//Enable interrupt
SAI_TxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable);
//Enbale sending
SAI_TxEnable(base, true);
}
// Wait until the last data is sent, and the data register is empty, and can be written
while (!(base->TCSR & I2S_TCSR_FWF_MASK))
{
}
SAI_TxEnable(base, false);
return retValue;
}
I think I have found the reason.
It maybe caused by the GPIO interrupt. The GPIO interrupt handle program takes too long time. and causes the I2S underrun.
I will try the I2S interrupt or DMA transmit. That would resolve this question.