AnsweredAssumed Answered

How to avoid I2S underrun?

Question asked by Max pi on Jan 24, 2019
Latest reply on Jan 31, 2019 by Fang Li

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;
}

Outcomes