General I2S Setup Question

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
MAC
Member
Posts: 8
Joined: Wed Nov 19, 2014 4:12 am

General I2S Setup Question

Post by MAC »

Hi
I'm working with the XR-USB-AUDIO-2.0-MC USB audio board.  I'm having a little bit of trouble understanding the correct way to enable the I2S interface with Xcore as the master, on board Cirrus codec as slave.

From all of the documentation about the module_i2s_master makes it sound very easy to get the interface up and running.  Basically it says: 1) set up the sturcture that has all the ports you are going to use 2) have a streaming channel end available 3) input the MCLK to BCLK ratio.  

I've gotten the loopback code example to work, but when I modify to my own code the stream doesn't turn on unless I use the #pragma loop unroll directive.  Can someone explain why this pragma is needed or let me know what I'm doing wrong that requires me to use it?

Here is part of my code that sets up I2C, programs the PLL and codec, then sets up I2S.  Finally the I try to collect data from the ADC.  I don't do anything with the data, I just want to see all the clocks and the ADC data line running when I check with my bench o-scope

Main Function

Code: Select all

void getADC_data(streaming chanend chan_x)
{
    unsigned x[I2S_MASTER_NUM_CHANS_ADC];

    for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
        {
            x[i] = 0;
        }

    while(1){
#pragma loop unroll
        for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
                {
                    chan_x :> x[i];
                }
#pragma loop unroll
        /* Do some processing - I will send the ADC data somewhere eventually */
        /*for(int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
        {
            if(i < I2S_MASTER_NUM_CHANS_ADC)
            {
                OUT_SOMEWHERE = x[i];
            }
        }*/
    }

}
getADC_data function 

Code: Select all

int main(void){
    streaming chan c_data;

    par{
        on stdcore[1] : {
            genclock();
        }

        on stdcore[1] : {
            codec_conf();
            //unsigned mclk_bclk_div = get_mclk_bclk_div(SAMP_FREQ, MCLK_FREQ);
            delay_milliseconds(300);
            i2s_master(i2sData, c_data, 4);
        }

        on stdcore[1] : {
            getADC_data(c_data);
            //loopback(c_data);
        }

    }
    return 0;
}
If I do not include the two #pragma loop unroll directives the I2S does not turn on.  If I comment out the call to getADC_data and uncomment the loopback functions, the I2S starts ( I think because the loopback function has the directives) The above code runs ok with the directives in the getADC_data function.  I just dont understand why this is.  Can someone educate me?

Thanks
MAC