Simple I2S DMA playback example for RT1010 needed for newbie

cancel
Showing results for 
Search instead for 
Did you mean: 

Simple I2S DMA playback example for RT1010 needed for newbie

262 Views
CarbonTony
Contributor II

Hello

[ newbie alert ! ]


I'm very new to NXP [ coming from PIC32Z world ] and finding the documentation increadibly obtuse/ dense and hard to understand.

 

Can anyone point or post any well documented code examples of simple LH Justified I2S playback.

All the examples I find seem to be very complex, codec specific with very little documentation of

the code. For example the pin assignments are not even mentioned . . .

Any help greatly appreciated

 

Thanks

Labels (1)
Tags (1)
0 Kudos
6 Replies

256 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @CarbonTony 

   Thank you for your interest in the NXP MIMXRT product, I would like to provide service for you.

   Welcome to the NXP RT world.

   About the I2S DMA examples, you can refer to our SDK for RT1010 directly:

https://mcuxpresso.nxp.com/en/builder?hw=EVK-MIMXRT1010

\SDK_2_10_0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\sai\edma_record_playback

You also can refer to my document, the basic about the SAI, maybe useful to you:

https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/RT10xx-SAI-basic-and-SDCard-wave-file-play/ta-p/...

 

Wish it helps you!

If you still have questions about it, please kindly let me know.

Best Regards,

Kerry

0 Kudos

241 Views
CarbonTony
Contributor II

Hello

I have followed the 2nd example, and have some questions:

I dont understand this part:

 

wm8960_config_t wm8960Config = {
.i2cConfig = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = BOARD_CODEC_I2C_CLOCK_FREQ},
.route = kWM8960_RoutePlaybackandRecord,
.rightInputSource = kWM8960_InputDifferentialMicInput2,
.playSource = kWM8960_PlaySourceDAC,
.slaveAddress = WM8960_I2C_ADDR,
.bus = kWM8960_BusI2S,
.format = {.mclk_HZ = 6144000U, .sampleRate = kWM8960_AudioSampleRate16KHz, .bitWidth = kWM8960_AudioBitWidth16bit},
.master_slave = false,
};
codec_config_t boardCodecConfig = {.codecDevType = kCODEC_WM8960, .codecDevConfig = &wm8960Config};

 

Why does the I2S need configuring again, after it has been setup with the SAI Peripheral setup already [ word size sample rate etc ]

Should I remove this code, as I am not using a WM8960 ?

 

Also can you explain the setup of the buffer for transmission

AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t buffer[BUFFER_NUM * BUFFER_SIZE], 4);

Why is it an 8bit array , with 4 dimensions ?

Surely it should be 16bit for the I2S, and why 4 dimensions ? Shouldnt this be 2 [ as there are 2 channels of audio L&R ]


Thanks again

0 Kudos

233 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @CarbonTony 

   I2S(SAI) code is for the interface, but in normal usage, eg, use the speaker, or mic, you still need to use the codec, please check the MIMXRT1010-EVK board:

kerryzhou_0-1642125792836.png

So, w8960 is used to configure the codec.

 You also can refer to the SDK code for RT1010:

https://mcuxpresso.nxp.com/en/builder?hw=EVK-MIMXRT1010

\SDK_2_10_0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\sai\edma_record_playback

You can consider, the flow is:  MIC->CODEC->SAI RX->SAI TX ->CODEC->speaker

 

Now, answer your questions:

1 Why does the I2S need configuring again, after it has been setup with the SAI Peripheral setup already [ word size sample rate etc ]

Answer:  your mentioned code is the codec configuration with I2C, not the I2S, which used to connect to the external mic and speaker, as the I2S need to use the codec to play to the speaker.

2 Should I remove this code, as I am not using a WM8960 ?

Answer: If you don't use the codec, you can get the I2S wave, but how do you get the mic data?

How to driver your external speaker?

If you just want to see the I2S wave, you totally can use the SAI TX, then check the SAI bus wave.

3 Why is it an 8bit array , with 4 dimensions ?

Answer: as you know, playback is record the mic and play it, as this array is the data buffer, which is used to save the mic received data, then use this buffer to transfer to the speaker again. So, use 4 dimension, just make sure, when you transfer the old received data, it also can receive the new data, as receive and tranfer using the same buffer, just with different data position, so it use 4 dimensions to roll it.

4 Surely it should be 16bit for the I2S, and why 4 dimensions ? Shouldnt this be 2 [ as there are 2 channels of audio L&R ]

Answer: don't care about 4 dimension, it is the story between receive and transfer.

If you just use transfer, you can use 1 dimension array, then put your 2ch audio data in that array.

From now, I think you even can just use the transfer to test it at first, just learn it at first.

SDK_2_10_0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\sai\edma_transfer

This code, you can see the SAI bus will output the data in music[]  array.

Wish it helps you!

Best Regards,

Kerry

 

0 Kudos

218 Views
CarbonTony
Contributor II

Hello

Thanks for your answers, here are some further comments and questions


1] Yes sorry I have set up with SAI, So this is working as I2C or I2S. With the cofig tools it appears to
be setting up as I2S [ for Audio ] As mentioned in my previous post I DO NOT want audio in, Just audio out.

2] As above, I just want Audio Out, so can I just use the Config Tools settings for SAI and ignore the codec settings etc ?

3] Thanks that make sense, but the example code is for music output, it does not use the input,

4] I still don't understand why it is an 8bit array, when the SAI has been setup for 16bit transfers

AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t buffer[BUFFER_NUM * BUFFER_SIZE], 4);

 

The EDMA SAI example still uses the input codec.
Is there an SDK command that transmits a buffer direct to the SAI interface ?


I have a question about the SAI peripheral config tool [ almost not documentation available ! ]
When I select Interrupt as an option [ as opposed to EDMA ] doe this mean the transfer is initiated by
the interrupt call back, or does it mean a successful transfer generates an interrupt ?


Thanks very much.

 

0 Kudos

214 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @CarbonTony ,

   Answer your questions:


1] Yes sorry I have set up with SAI, So this is working as I2C or I2S. With the cofig tools it appears to
be setting up as I2S [ for Audio ] As mentioned in my previous post I DO NOT want audio in, Just audio out.

If you don't want audio in, just audio out, it is very easy, just use this code:

SDK_2_10_0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\sai\edma_transfer

2] As above, I just want Audio Out, so can I just use the Config Tools settings for SAI and ignore the codec settings etc ?

Yes, if you don't want to use the codec, just don't configure it is OK, then the SAI code is the same, you can use the oscillator or logic analyzer to check the SAI bus, it is the same.

3] Thanks that make sense, but the example code is for music output, it does not use the input,

I am a little confusing now, you say you need sai output, then you need input again.

If you need input, you can refer to :

SDK_2_10_0_EVK-MIMXRT1010\boards\evkmimxrt1010\driver_examples\sai\edma_record_playback

You can consider:

input is SAI RX, output is SAI TX. 

If you don't want codec, just don't add the codec code, then check the SAI bus directly, as I have tested two code which is using different board communicate through the SAI directly, use the SAI RX and SAI TX directly, it works without the codec.

4] I still don't understand why it is an 8bit array, when the SAI has been setup for 16bit transfers

AT_NONCACHEABLE_SECTON_ALIGN(static uint8_t buffer[BUFFER_NUM * BUFFER_SIZE], 4);

8bit is used to put the music data, as some tool will generate the 8bit array. you can see the music is also 8bit, then it will copy the music array to the buffer, then send to the SAI DMA to play it. If you need other size buffer, you also can use it.

The EDMASAI example still uses the input codec.
Is there an SDK command that transmits a buffer direct to the SAI interface ?

As I told you, if you don't need codec, just comment the following code:

if (CODEC_Init(&codecHandle, &boardCodecConfig) != kStatus_Success)
{
assert(false);
}
if (CODEC_SetVolume(&codecHandle, kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight,
DEMO_CODEC_VOLUME) != kStatus_Success)
{
assert(false);
}


I have a question about the SAI peripheral config tool [ almost not documentation available ! ]
When I select Interrupt as an option [ as opposed to EDMA ] doe this mean the transfer is initiated by
the interrupt call back, or does it mean a successful transfer generates an interrupt ?

If you use interrupt and register callback, then after successful, it will generate the itnerrupt and call the callback.

 

Wish it helps you!

If you still have questions about it, please kindly let me know.

Kerry

0 Kudos

244 Views
CarbonTony
Contributor II

Hello

 

Thanks for the quick reply.

I had looked at the SDK example [ although it is record and playback ]

and found it very hard to understand, as there is no documentation.


The 2nd example you give has good documentation

Although I dont need to have the RX [ record option ]

I will check to see how to disable this and the Master Clock, as I only

need BTCLK, LRSYNC, DATA for my I2S purpose.

Thanks

0 Kudos