AnsweredAssumed Answered

how to use MQX SAI driver for FRDM-K64f

Question asked by Oleg Lavrukhin on Nov 20, 2014
Latest reply on May 7, 2018 by Oleg Lavrukhin

Hello everybody!

Firstly, I want to thank the team of developers MQX OS! this is my first experience with OS, and I really pleased to work with MQX! Many examples with detailed comments allow me to quickly build a working project! Thanks!

But I have some problems with SAI driver in MQX 4.1.1.

I want to build simply audio player on my FRDM-K64f: read WAV file from USB stick and  play sound via external DAC using SAI bus.

in my project I connected 2 example MQX projects: "mfs_usb" and "sai_dma_demo".

Using a "mfs_usb" i can open a WAV file from USB stick and read it,  from "sai_dma_demo" I took  a part of code which read WAV header, make a setting for SAI driver and sending data to SAI (function "Shell_play" from "sh_audio.c").

Now i have a partially working device: WAV header is correctly read, I have a BCLK and FrameSync signals in FRDM pins, but i don't have a data from SAI. 

A part of code from "sai_dma_demo" which must sending data to SAI:

/*Get the stats of the sai, this is the interface between application and driver which provides the status of sai.*/

    ioctl(device_ptr, IO_IOCTL_I2S_GET_STATISTICS, &stats);

    requests = header.DATA_SUBCHUNK.Subchunk2Size / stats.SIZE;

    remainder = header.DATA_SUBCHUNK.Subchunk2Size % stats.SIZE;

    if(remainder != 0)

    {

      requests += 1;

    }

    uint32_t num = 0;

    for(i = 0; i < requests; i ++)

    {

        /*Waiting for there are empty blocks*/

        ioctl(device_ptr, IO_IOCTL_I2S_WAIT_TX_EVENT,NULL);

        /* Get the info where to fill the data */

        ioctl(device_ptr, IO_IOCTL_I2S_GET_STATISTICS, &stats);

        if((i != requests - 1) || (remainder == 0))

        {

            num = fread(stats.IN_BUFFER, 1, stats.SIZE, file_ptr);

            if(!num)

            {

                return -1;

            }

        }

        else

        {

            num = fread(stats.IN_BUFFER, 1, remainder, file_ptr);

            if(!num)

            {

                return -1;

            }

            /*Fill zero to buffer*/

            uint32_t j = 0;

            for(j = remainder; j < stats.SIZE; j ++)

            {

                stats.IN_BUFFER[j] = 0;

            }

        }

        if (i == 0)

        {

            ioctl(device_ptr, IO_IOCTL_I2S_START_TX, NULL);

        }

        ioctl(device_ptr, IO_IOCTL_I2S_UPDATE_TX_STATUS, &stats.SIZE);

    }

when this cycle is working, i see what device  reading the data from USB stick, but actual time to read a 10-second WAV file is 70 seconds. i try to use some different USB sticks( because I read in the community that there is a problem with USB speed in older version MQX) , but time is come down to 45-50 second.

Then i try to send out data from flash memory. I included a file with 96-bytes sine wave table Hex code and changed part of code (SAI setting don't changed):

uint16_t a,b;

ioctl(i2s_ptr, IO_IOCTL_I2S_START_TX, NULL);

for (a=0; a<500; a++)

{

ioctl(i2s_ptr, IO_IOCTL_I2S_WAIT_TX_EVENT,NULL);

     for (b=0; b<96; b++)

       {

       stats.IN_BUFFER[b] = Sine_Wave_8_Bit[b];

       }

ioctl(device_ptr, IO_IOCTL_I2S_UPDATE_TX_STATUS, &stats.SIZE);

}

 

But i don't have a sound!

 

In "MQX_IO_User_Guide" in chapter "I2S Driver" i can't found a "IO_IOCTL_I2S_UPDATE_TX_STATUS", "IO_IOCTL_I2S_START_TX" and  "IO_IOCTL_I2S_WAIT_TX_EVENT" macros.

I would be grateful if the developers explain theirs functions.

 

I ask for help in solving two problems:

1) how is a correctly use a MQX SAI driver in FRDM-K64F?

2) Was the problem solved slow reading from USB in MQX 4.1.1?

 

Thanks, Oleg.

Outcomes