is there any demo code for using I2S?

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

is there any demo code for using I2S?

Jump to solution
15,347 Views
JimCheng
Contributor II

is there any one can share with me the I2S reference code?

1 Solution
4,679 Views
carlos_neri
NXP Employee
NXP Employee

Attached is a sample code that enables SAI module as I2S (stereo) slave in synchronous mode (TX and RX share BCLK and Frame synch). Uses DMA for transfer and the TWR-AUDIO_SGTL Rev B1 (board with 24.576Mhz oscillator).

Adding a couple of more data:

- Configures the SGTL5000 as I2S master and a 48Khz audio

- The application takes the audio from the codec line in and sends it to line out and headphone outputs.

- Works on a TWR-K60D100M

- Enables the codec 5-band graphic equalizer when SW1 is pressed

- Compiled and tested on CW10.2 with latest patches.

View solution in original post

30 Replies
3,901 Views
carlos_neri
NXP Employee
NXP Employee

Catalin,

The sample code requires an audio source, in this case any media player connected to the Line In connector.

But if you had the media player with music and still no results, you could calculate a sine wave table using Excel and modify the code to output it. For your reference, here's a 1 Khz sine wave table @ 48Khz 16-bit:

0x10B5,0x10B5,

0x2120,0x2120,

0x30FB,0x30FB,

0x4000,0x4000,

0x4DEB,0x4DEB,

0x5A82,0x5A82,

0x658C,0x658C,

0x6ED9,0x6ED9,

0x7641,0x7641,

0x7BA3,0x7BA3,

0x7EE7,0x7EE7,

0x8000,0x8000,

0x7EE7,0x7EE7,

0x7BA3,0x7BA3,

0x7641,0x7641,

0x6ED9,0x6ED9,

0x658C,0x658C,

0x5A82,0x5A82,

0x4DEB,0x4DEB,

0x4000,0x4000,

0x30FB,0x30FB,

0x2120,0x2120,

0x10B5,0x10B5,

0x0,0x0,

0xEF4B,0xEF4B,

0xDEE0,0xDEE0,

0xCF05,0xCF05,

0xC000,0xC000,

0xB215,0xB215,

0xA57E,0xA57E,

0x9A74,0x9A74,

0x9127,0x9127,

0x89BF,0x89BF,

0x845D,0x845D,

0x8119,0x8119,

0x8000,0x8000,

0x8119,0x8119,

0x845D,0x845D,

0x89BF,0x89BF,

0x9127,0x9127,

0x9A74,0x9A74,

0xA57E,0xA57E,

0xB215,0xB215,

0xC000,0xC000,

0xCF05,0xCF05,

0xDEE0,0xDEE0,

0xEF4B,0xEF4B,

0x0,0x0,

If you have a scope with you, I recommend you to use it in order to confirm the output directly at the line out jack, if there is no scope then you can use your headphone but just for a little time because the sine wave can damage them.

Regards,

Carlos Neri

3,901 Views
HerascuIulian-C
Contributor II

Hi,

thank you very much for the help, do you have any idea on the changes I should do.

I tried to test it with a microphone and headphones and I had not gotten any results, I do not have a media player or a scope, so I still want to try with my headphones.

Thank you,

Catalin

0 Kudos
3,901 Views
HerascuIulian-C
Contributor II

I still do not know if it should have worked with a microphone connected as  well ?

0 Kudos
3,901 Views
carlos_neri
NXP Employee
NXP Employee

Catalin,

The sample code does not work with microphone, just with Line In as audio source and for output works with headphones and line out (so you can connect a set of active speakers).

Just want to make sure everything is ok on your side before any changes to the code, could you please do the following:

- Connect the headphone output of your computer to the Line In connector on your TWR-AUDIO-SGTL. To do this take a 3.5mm male to male cable (usally refere as aux cable)

- Connect your headphones on the TWR-AUDIO-SGTL headphone ouput

- Reproduce any sound on your computer (Youtube, audio file, etc).

Let me know the results.

Regards,

Carlos Neri

0 Kudos
3,901 Views
HerascuIulian-C
Contributor II

Hi,

I tried your idea, it works great, volume and everything, not certain on what exactly does SW1 does, I noticed it changes the sound a little,  so thank you very much for the help.

But if you could still guide me on how I could set my own in source/vector I would appreciate it, my main target would be to try and play a wav file from the sdcard on the out line (I already have something for reading the dscard).

Thank you,

Catalin.

0 Kudos
3,901 Views
carlos_neri
NXP Employee
NXP Employee

Catalin,

Attached is a sample code that could help you. To be honest I haven't tested it yet but the idea is there:

- On the "vfnTWRAudioStateIdle" wait for the TX flag instead of the RX flag.

- On the "vfnTWRAudioStateLoopback" instead of doing a read and then a write, do a write of your array. In this example I use a sine wave table. Try to write around 1ms of audio on each write call, this is, 96 samples (48 for the left and 48 for the right channels).

The button changes the volume on the 5-band GEQ.

Hope this helps.

Regards,

Carlos Neri

0 Kudos
3,900 Views
HerascuIulian-C
Contributor II

Hi,

Thanks, but there is a problem I get that the function u16BandEQRegisters is not defined (at line 326) and that the include "Dialog7320.h" is not found as well, maybe it belonged to that ... so I think I will need the Dialog7320.h header and maybe the Dialog7320.c as well ... do not know if they should have been part of the initial project, but I do not find them.

Thank you,

Catalin

0 Kudos
3,901 Views
HerascuIulian-C
Contributor II

Hi. I added it even withought those files, and I get the sound but when I try to play a wav file all I hear is strange noise... similar sometimes to the sin function ... my guess would be that I am not getting the right sampling ... for the wav...

from the wave header these are the values I get :

8(bps),11025 (byte_rate),11025(sample_rate),1 (num_channels), I do not also know if the read is correct ... but fo you know if I could set the sampling for the audio ... or any changes I should do to get something close to the sound ... I can also send the wav file if you want ... it is pretty small ...for now I only write the entire data in a single u16 array ... and at inside the loop function I send 96 to the buffer... similar to the sine ...

0 Kudos
3,901 Views
ajaypatel
Contributor I

Hello,

Is there any same demo available for the TWR-KL46Z board? Or Can somebody help me out how to port the same demo for the KL46Z board ?. My aim to setup the audio playback demo for the KL46Z board.

Thanks,

Ajay

0 Kudos
4,680 Views
carlos_neri
NXP Employee
NXP Employee

Attached is a sample code that enables SAI module as I2S (stereo) slave in synchronous mode (TX and RX share BCLK and Frame synch). Uses DMA for transfer and the TWR-AUDIO_SGTL Rev B1 (board with 24.576Mhz oscillator).

Adding a couple of more data:

- Configures the SGTL5000 as I2S master and a 48Khz audio

- The application takes the audio from the codec line in and sends it to line out and headphone outputs.

- Works on a TWR-K60D100M

- Enables the codec 5-band graphic equalizer when SW1 is pressed

- Compiled and tested on CW10.2 with latest patches.

3,900 Views
rinipatel
Contributor III

Hello Carlos,

Do you happen to have the similar demo code which works with TWR-KL46Z48M board??

Thanks,

Rini

0 Kudos
3,921 Views
benjaminchang
Contributor V

Hello Carlos,

I have downloaded “TWRK60D100M_TWRAudioSGTL_Loopback.zip” and tested on the TWR board. It works fine. But as we need a case to disable all I2S transmission, so we tried to clear I2S0_TCSR TE and BCE bit. The data bus is stopped, but BCLK is always there. We have tried many ways, but just cannot stop all bus activity including BCLK. Can you help to check how to stop all of them? :smileyhappy:


Below is our revised main loop code just for testing,

Try to use abFlag to control the enable/disable process under debugger of CW10.6,

////

unsigned char abFlag = 0;

int main (void) {

  vfnTWRAudioInit();

  for(;;)

  {

   if (abFlag == 0) {

    //PORTE_PCR12 &= ~PORT_PCR_MUX_MASK;

    PORTE_PCR12 |= PORT_PCR_MUX(0x04);

    I2S0_TCSR |= I2S_TCSR_BCE_MASK; //enable, Bj

    I2S_TX_ENABLE;

    I2S0_RCSR |= I2S_RCSR_BCE_MASK; //enable

    I2S_RX_ENABLE;

    vfnapTWRAudio[sTWRAudioStateMachine.ActualState]();

    vfnapIICDriver[sIICStateMachine.ActualState]();

    vfnapSGTL5000ControlStateMachine[sSGTL5000ControlStateMachine.ActualState]();

   }

   else {

     //if (sTWRAudioStateMachine.ActualState == TWR_AUDIO_IDLE_STATE) {

     if (sTWRAudioStateMachine.ActualState == 0) {

      I2S_TX_DISABLE;

      I2S0_TCSR &= ~I2S_TCSR_BCE_MASK; // disable, Bj

      I2S_RX_DISABLE;

      I2S0_RCSR &= ~I2S_RCSR_BCE_MASK; // disable

      PORTE_PCR12 &= ~PORT_PCR_MUX_MASK;

      //PORTE_PCR12 |= PORT_PCR_MUX(0x01); /* PTE12 */

     }

   }

  }

}

////

Thank you!

Benjamin

0 Kudos
3,921 Views
carlos_neri
NXP Employee
NXP Employee

Benjamin,

Using I2S_TX_DISABLE should be enough to stop the TX portion. On the example you downloaded, Kinetis is the I2S slave, this means, it receives the I2S clocks and the audio codec is the I2S master, so the codec generates the clocks. Probably that's why you still have BCLK and LRCLK.

I'm not aware of a clean way to gate I2S clocks from SGTL5000, for now, I have two ideas on how you could achieve it:

- When you need to shutdown I2S, once TCE is disabled, change the SGTL5000 from master to slave by turning off bit MS of CHIP_I2S_CTRL. This not a very fancy way to do it, but if in  your use case is mandatory to have all clocks disabled, this might work, because by configuring the codec as slave, BCLK and LRCLK are set as inputs. You need to consider any pins conflicts, Kinetis and audio codec pins will be set as input.

- Change SAI and audio codec configuration, this is, configure Kinetis as I2S master and the audio codec as I2S slave. On this mode, disabling the SAI module will disable the clocks as well.

Hope this helps

3,914 Views
benjaminchang
Contributor V

Hi Carlos,

Yes, you are right.

After change the SGTL5000 from master to slave by turning off bit MS of CHIP_I2S_CTRL, and I2S0 as Master, then

  I2S_TX_DISABLE;

  I2S0_TCSR &= ~I2S_TCSR_BCE_MASK; // BCE needs disable also


The BCLK stopped.


Thank you!

Benjamin

0 Kudos
3,921 Views
aravindanv
Contributor I

Hi Carlos,

I reused your TWRK60D100M_TWRAudioSGTL_Loopback  code for ppc based controller, it is having SAI module , and my TWR_SGTL board version is(SCH-26816 REV B & 700-26816 REV X2), and in this codec board i have replaced only R1,R2,R3,R4 to 0 ohm based on errata, instead of 24.576MHz crystal i am using function generator as a clock source and gave that signal to (Y1- 3 rd pin). with this setup i gave signal to linein from PC but nothing i can hear from lineout, I have connected Oscilloscope to all the pins,i can see  BCLK(~3.07MHz) and FS(~48KHz),in linein and lineout i can see some of the data is going. if i change change x5r capacitors to x7r and line in and line out channels swapped with adapter (can u suggest me any website how it would be?) will solve my problem? or i need to change any codec related config? Can u please answer me above two questions?

Thanks,

V Aravindan

0 Kudos
3,921 Views
carlos_neri
NXP Employee
NXP Employee

Aravindan,

The swapped channels errata would impact your audio just in case you are sending mono audio and expecting it on a specific channel (usually left), if you're using stereo audio then you just will have swapped channels but should be audio out, so definitely not an issue on my perspective.

The capacitor rating shouldn't be an issue either, x7r provides a better performance on range temperature than x5r, I don't think this could be the cause of don't getting audio on your output.

On the codec side, if you're using the same initialization as the example for the Kinetis device, then everything should be ok on the codec side. I'd confirm with a scope that the codec is sending ACK to all the I2C configurations, just to confirm that is being correctly configured.

I think the issue is SAI/buffering relatead:

I would check first the line out section by sending a known signal thru I2S, this with two purposes:

- Confirm your TX portion is working

- Codec is working correctly

A full range sine wave would be more than enough (could be the same in both channels to simplify the test). You should see the same data from your table on the I2S bus (MSB first) and if you connect an auxiliar cable to Line out connector on your TWR-AUDIO-SGTL and connect the scope, the expectation is to see the sine wave on the same frequency  and amplitude as you calculated it. On this same thread there is a table for sine wave 1Khz @48Khz 16 bit for your reference.

Saludos,

Carlos Neri

0 Kudos
3,921 Views
HerascuIulian-C
Contributor II

Hi, I have downloaded your project, but does not seem to work at all ... I think it is also REV B1 SGTL, checked the oscilator it has 24.576M, when I connect the headphones I do hear some strange sound ... (as background noise ... in the heaphone jack), do you know a way if I want to generat like a sound wave or something on the heaphones ... too see if I can here anything. thanks.

0 Kudos
3,921 Views
brian64
Contributor I

Hi Carlos,

I now have a TWR-K60D100M, and have built and loaded the TWRK60D100M_TWRAudioSGTL_Loopback project on it. I am inputting a 1kHz 2Vp-p sinusoid into the Line In port of my TWR-AUDIO-SGTL board, yet I don't see any output on either the Line Out or Headphones. Can you suggest a debugging approach? What should I look at first?

Thanks!

-Brian

0 Kudos
3,921 Views
carlos_neri
NXP Employee
NXP Employee

Brian,

First thing I'd check is the TWR-AUDIO-SGTL you got. The code is ready for the board rev. B1. How do I know if my board is a rev. B1 one? well, the fastest way is to take a look to the board on Y1. If your board has a big 24.576 oscillator on Y1 then you have the correct board, if not, then the code must be modified to work with your board  (MCU as I2S master and  codec as salve).

If the board is the rev. B1, then I would check the audio clocks. The application runs 48Khz audio, this means that the I2S clocks are:

Frame synch = 48Khz

BCLK = 64*Fs = 3.072Mhz

Also check if there is traffic on the data lines (Rx and Tx).

Please take a look to the above and let me know your results :smileyhappy:

Regards,

Carlos

0 Kudos
3,921 Views
brian64
Contributor I

Carlos,

I confirmed that I have a Rev B1 SGTL board. I've made the following measurements right on the SGTL board:

I2S SCLK (J8) ~= 3.068 MHz

I2S LRCLK (J9) ~= 48 kHz

There appears to be traffic on both I2S DIN (J11) and I2S DOUT (J10)

So, it would seem that I might have an output volume level issue...what do you think? Maybe it's muted?

-Brian

0 Kudos