Trouble with I2S DMA in mono configuration LPC546

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Trouble with I2S DMA in mono configuration LPC546

1,395 Views
blair_smyth
Contributor I

Hi there,

I am trying to send sine wave data over I2S DMA to an audio amplifier, 16 bit samples @48kHz.

I have based my software on the SDK for the LPC54608 microcontroller.

The sine wave data is one channel, so i have configured the I2S to operate in mono mode.

What i have found is that when i play the audio data over normal I2S without DMA everything is as expected on the output.

However when i switch to a DMA setup, the data plays twice as fast, and when i try to counter this with reducing the clock speeds the output is distorted.

My theory is, that the I2S DMA, although is set up as 2 bytes per frame, the DMA is cycling through the data at twice the speed that it should. Below are the setups for both I2S, and I2S DMA setups i am using.

Below is a setup of our I2S DMA, which is modelled after the NXP SDK examples.

 

        static dma_handle_t s_DmaTxHandle;

        static i2s_config_t s_TxConfig;

        static i2s_dma_handle_t s_TxHandle;

        static i2s_transfer_t s_TxTransfer;

 

                  I2S_TxGetDefaultConfig(&s_TxConfig);

                  s_TxConfig.divider     = 16;                    // BCLK @ 1.536MHz

                  s_TxConfig.oneChannel  = true;            // mono mode

                  s_TxConfig.masterSlave = kI2S_MasterSlaveNormalMaster;

 

                   I2S_TxInit(I2S0, &s_TxConfig);

 

                    DMA_Init(DMA0);

 

                    DMA_EnableChannel(DMA0, 13U);

                    DMA_SetChannelPriority(DMA0, 13U, kDMA_ChannelPriority3);

                    DMA_CreateHandle(&s_DmaTxHandle, DMA0, 13U);

                             

                    s_TxTransfer.data     = (uint8_t*)messageSourceAddress;   // pointer to source address

                    s_TxTransfer.dataSize = messageSourceSizeBytes;

 

                    I2S_TxTransferCreateHandleDMA(I2S0, &s_TxHandle, &s_DmaTxHandle, TxCallback, (void *)&s_TxTransfer);

 

                    I2S_TxTransferSendDMA(I2S0, &s_TxHandle, s_TxTransfer);

 

When I run this code (above) my audio plays at twice the speed. When I reduce the clock speeds to counter this the sine wave output is distorted.

 

However when I run this code (below) without DMA, everything runs as expected, and the sine wave output is as expected.

 

        static i2s_config_t s_TxConfig;

        static i2s_transfer_t s_TxTransfer;

        static i2s_handle_t s_TxHandle;

 

                  I2S_TxGetDefaultConfig(&s_TxConfig);

                   s_TxConfig.divider     = 16;                   // BCLK @ 1.536MHz

                   s_TxConfig.oneChannel  = true;         // mono mode

                   s_TxConfig.masterSlave = kI2S_MasterSlaveNormalMaster;

 

                   I2S_TxInit(I2S0, &s_TxConfig);

                             

                   s_TxTransfer.data     = (uint8_t*)messageSourceAddress;

                   s_TxTransfer.dataSize = messageSourceSizeBytes;

 

                   I2S_TxTransferCreateHandle(I2S0, &s_TxHandle, TxCallback, (void *)&s_TxTransfer);

 

                   I2S_TxTransferNonBlocking(I2S0, & s_TxHandle, s_I2S_TxTransfer);

 

The I2S clock speeds are set up as:

MCLK = 12.288MHz

WCLK = 48kHz

BCLK = 1.536MHz

 

Any help on this is greatly appreciated.

Blair

0 Kudos
5 Replies

1,241 Views
chengcheng
NXP Employee
NXP Employee

 

@blair_smyth have you solved the issue?

If not, please share me the i2s interrupt &dma driver version, since I tried with newest MCUX SDK version and cannot reproduce your issue.

To use I2S dma&interrupt driver playback mono channel 16bit data, you should prepare wave data as below format,

L0,L1,L2,L3, that is means the data should combine tightly, please make sure your data format for interrupt and DMA is correct.

Per i2s DMA/interrupt driver configuration, the CPU/DMA will continuously fetch data from the stream and push to I2S fifo, then I2S will flush it out as below format

L0,  EMPTY, L1, EMPTY, L2.

 

1,377 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Blair,

Regarding your issue that the sine rate is faster then expected, I give you a clue, pls check if it is the cause.

The I2S transmitter interface has 3 signal(SCLK, WS,SDA), as you know that the I2S can transfer two channel each frame, when the WS is low, the data is for for example channel0, when the WS is high, the data is for channel1. for example, the audio PCM data is organized as following:

sample0, sample1, sample2, sample3, sample4,..., for the data structure, the even sample 0,sample2,sample4, sample6 ... will transferred to channel0, odd sample sample1, sample3, sample5, sample7... will transferred to channel1. Because you use only single channel, I suggest you organize the data as following:

sample0, sample0, sample1, sample1, sample2, sample3, ..., in this structure, the sample data sample0, sample1, sample2 ... will transfer to both channel. one channel is valid, another channel is a dummy channel.

 

This is  my guess, pls have a try.

BR

Xiangjun Rong

0 Kudos

1,371 Views
blair_smyth
Contributor I

Hi @xiangjun_rong,

Thank you for the reply and the idea.

Unfortunately when i tested what you had proposed it has not solved the issue.

I doubled each 16 bit sample to match the structure you defined, although i found that the sine wave frequency was now half of what is expected. The sine wave used in my tests is 3 seconds in length with a frequency of 5kHz.

I took some screenshots of my findings so far:

Figure 1 attached is the sine wave output from your test. As you can see the Delta is 400us (2500Hz).Figure 1 - xiangjun_testFigure 1 - xiangjun_test

Figure 2 attached is the sine wave output from the DMA example. Delta 200us (5000Hz).Figure 2 - DMA_testFigure 2 - DMA_test

Figure 3 attached is the sine wave otuput from normal I2S without DMA. Delta 200us (5000Hz).Figure 3 - Non_DMA_testFigure 3 - Non_DMA_test

In figure 1, doubling the data as you suggested the sine wave lasted 3 seconds, however the freq. is half of what is expected.

in figure 2, DMA test, the frequency of the sine wave is correct, however it only last 1.5 seconds.

in figure 3, without DMA, the test lasts 3 seconds and the output is as expected.

All of these tests are carried out with the same I2S configuration and clock speeds. But it appears that the DMA is somehow mishandling the data input.

Any other suggestions greatly appreciated.

Kind regards,

Blair

 

 

 

 

0 Kudos

1,357 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Blair,

 

From your description, I see the bit clock is 1.536MHz, frame clock is 48KHz, can you tell us the point number for ONE cycle sine signal in your data array? I would like to compute the correct sine frequency.

BR

XiangJun Rong

0 Kudos

1,353 Views
blair_smyth
Contributor I

Hi @xiangjun_rong

There are 10 points in one cycle of the sine wave. Each point is 16 bits of data.

Kind regards,

Blair

 

0 Kudos