SAI Multichannel confusion...

Showing results for 
Search instead for 
Did you mean: 

SAI Multichannel confusion...

Senior Contributor II

I am really struggling to understand how to work with multi-channel SAI.  This post is on top of my earlier post here.  Attached is a basic picture of my hardware, trying to follow the model used with AN12090 (which IMHO, have very little information specific to multi-channel SAI)...



Clocking and sync are all configured, and I am able to push into the FIFO and retrieve from the FIFO and "hear" something.  So far so good... 

Now for some terminology clarification...

It seems the term "channel" is used in two different ways in may places on the forum and in the documentation.  Sometimes it is referring to the TDM pipe on the digital side between SAI and CODEC and other times it is referring to the analog IO on the other side of the CODEC.  In my case I am running with one TDM pipe in each direction.  There are 8 output channels (speakers) and 6 input channels (microphones).  So from hereon, assume the term "channel" to refer to one of the analog endpoints (i.e. one of the 6 mics or one of the 8 spkrs).

For the sake of simplicity, lets just assume that all I am doing is receiving the incoming 6 microphone channels.  All I want to know is this:

How do I know which channel (microphone) I am retrieving data for when I pull words off the FIFO?

The only thing I've found that I thought would help with this is the WSF bit (word-start-flag) in SAI->RCSR.  Right now I have the code set up so that my custom interrupt handler is called to deal with all aspects of the SAI1's needs; and I've enabled all FIFO-Error and Word-Start interrupts using:

SAI_RxEnableInterrupts(SAI_BASE, kSAI_WordStartInterruptEnable | kSAI_FIFOErrorInterruptEnable);

In the interrupt handler I check RCSR's WSF bit figuring that it indicates when the next word retrieved from the fifo is the first channel of the frame.  Here is the code...




	static uint32_t rdr[16];
	static int bits[16];
	if (SAI_BASE->RCSR & SAI_ANYRCV_INT) {              // Any rcv interrupt flags set?
        if (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) {       // Start of frame
            SAI_RxClearStatusFlags(SAI_BASE, kSAI_WordStartFlag);
            rdr[0] = SAI_BASE->RDR[0];
            bits[0] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[1] = SAI_BASE->RDR[0];
            bits[1] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[2] = SAI_BASE->RDR[0];
            bits[2] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[3] = SAI_BASE->RDR[0];
            bits[3] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[4] = SAI_BASE->RDR[0];
            bits[4] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[5] = SAI_BASE->RDR[0];
            bits[5] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[6] = SAI_BASE->RDR[0];
            bits[6] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;
            rdr[7] = SAI_BASE->RDR[0];
            bits[7] = (SAI_BASE->RCSR & I2S_RCSR_WSF_MASK) == I2S_RCSR_WSF_MASK ? 1:0;




The bits[] array is 0 1 1 1 1 1 1 1.  Which means WSF clears after I clear it in the interrupt handler but immediately resets after reading one word from the FIFO.  Am I doing something wrong?  Is there a valid way to know when the first channel of an incoming frame is being read from the FIFO?

Labels (1)
0 Kudos
4 Replies

NXP TechSupport
NXP TechSupport

Hello @EdSutter,

Can you let me know which CODEC are you using? I think the channel identification is not related to the SAI registers and is more related to the CODEC format, for example, in this application note the CODED used is the CS42448 and the channel is identified by the position in the frame by the configuration previously set through I2C. For example:




Best Regards,

Alexis Andalon



0 Kudos

Senior Contributor II

Hi @Alexis_A,

Just me checking in.

Any ideas (see my earlier replies)?


0 Kudos

Senior Contributor II

Hi Alexis,

Sorry for the delay, I moved to a new home, so I was almost totally off-the-grid for the last few weeks.  Anyway...

My codec is the PCM3168A from TI.  Identifying the channel in the TDM stream on a scope is not the problem.  I get that part.  The TDM stream is fed into SAI1, then my firmware needs to retrieve the words for each channel.  The problem is: "how do I know what channel I am retrieving when I pull data out of the FIFO?".   This same issue would exist for the CS42448.  See what I mean? 


0 Kudos

Senior Contributor II


Thanks for the response... I just want you to know that I am out of the office for several weeks.  I  browsed my email for the first time in 2 weeks to see this... I can't respond but will get back to you as soon as I return (probably within 1-2 weeks).



0 Kudos