Why doesn't my I2S controller transmit data?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Why doesn't my I2S controller transmit data?

820 次查看
donturner
Contributor III

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.

标记 (5)
0 项奖励
回复
1 回复

558 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Don,

which example in SDK2.0 are you using? Can you see the TX_FS, TX_BCLK?

BR

XiangJun Rong

0 项奖励
回复