I'm trying to output sound using a K22F microcontroller connected to an SGTL5000 audio codec. I have been able to configure all the required clocks (TX_FS, TX_BCLK and MCLK) but am unable to produce any data on the I2S0_TXD0 pin of the K22F. I'm using version 2.0 of the Kinetis SDK.
Here's my setup code for the I2S/SAI controller:
// Initialise the SAI/I2S module
g_sai_tx_config.protocol = kSAI_BusI2S;
g_sai_tx_config.syncMode = kSAI_ModeAsync; // Since the MCU is providing MCLK
g_sai_tx_config.mclkOutputEnable = true;
g_sai_tx_config.mclkSource = kSAI_MclkSourceSysclk;
g_sai_tx_config.bclkSource = kSAI_BclkSourceMclkDiv;
g_sai_tx_config.masterSlave = kSAI_Master;
SAI_TxInit(I2S0, &g_sai_tx_config);
// Set the format of the data
g_sai_tx_format.bitWidth = kSAI_WordWidth16bits;
g_sai_tx_format.channel = 0; // Taken from Kinetis Serial Audio Training P17
g_sai_tx_format.sampleRate_Hz = kSAI_SampleRate48KHz;
g_sai_tx_format.masterClockHz = 256 * kSAI_SampleRate48KHz; //12.288MHz
g_sai_tx_format.stereo = kSAI_Stereo;
g_sai_tx_format.protocol = kSAI_BusI2S;
g_sai_tx_format.watermark = 4;
SAI_TxSetFormat(I2S0, &g_sai_tx_format, CLOCK_GetCoreSysClkFreq(), g_sai_tx_format.masterClockHz);
SAI_TxEnable(I2S0, true);
And here's my attempt to output some audio data (a 1kHz square wave)
#define I2S_BUFFER_SIZE 96
uint8_t buffer[I2S_BUFFER_SIZE];
int8_t amplitude = 1;
I2S0->TCSR |= I2S_TCSR_FEF_MASK; // Write 1 to clear transmit underrun flag
for(;;) { /* Infinite loop to avoid leaving the main function */
// Transmit a square wave - alternately send a full buffer of 0xFF then 0x00
for (int i = 0; i < I2S_BUFFER_SIZE; i++){
buffer[i] = (0xFF * amplitude);
}
amplitude ^= 1;
SAI_WriteBlocking(I2S0, 0, kSAI_WordWidth16bits, buffer, I2S_BUFFER_SIZE);
}
The problem is that I don't see any data being generated on the TX pin, pausing execution I can see the code is caught in this loop in the SAI_WriteBlocking method:
/* Wait until it can write data */
while (!(base->TCSR & I2S_TCSR_FWF_MASK))
This implies (and I have verified) that the I2S0->TCSR->FWF register (FIFO warning flag) is 0 which means "No enabled transmit FIFO is empty.". Why isn't the transmit FIFO being sent (and emptied) by the I2S controller?
It may also be relevant that when I pause execution I can see that the I2S0->TCSR->FEF (FIFO error flag) register is 1 indicating "Transmit underrun detected.". What could be causing the underrun? I've tried clearing this flag but as soon as I queue data again it is immediately set to 1 again.
Any help greatly appreciated.
Hi, Don,
which example in SDK2.0 are you using? Can you see the TX_FS, TX_BCLK?
BR
XiangJun Rong