I2s capture in vybrid is noisy

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

I2s capture in vybrid is noisy

Jump to solution
5,898 Views
abdulnihad
Contributor III

I want to capture audio using I2S protocol. I have connected my audio slave device to SAI2 of vybrid. I have configured vybrid as master and my audio device as slave.

We have configured vybid I2S as master Receiver and tuner I2S as slave transmitter. Here it is clear that we have to use vybrid receive channel. But according to vybrid reference manual I2S_RX_BCLK(Pin#58) and I2S_RX_SYNC (Pin#59) are bi-directional So vybrid master will provide all the clock signal for tuner through its I2S_RX_xx pins and vybrid receive PCM samples through its I2S_RX_DATA. But this configuration is not working and not able to get audio . But When I used SAI2_TX clock signals it worked. According to demo setup we are using SAI2_TX_BCLK (Y5) ,  SAI2_RX_WS (U6) , SAI2_RX_DATA (E17). But captured audio is noisy. How to fix this issue. I am pasting snaps of my initialization code here.

#define DEFAULT_SAMPLE_RATE_HZ   48000
#define DEFAULT_NUM_CHANNELS     2
#define DEFAULT_BITS_PER_SAMPLE  16
#define SAMPLE_SIZE_IN_BYTE     DEFAULT_BITS_PER_SAMPLE/8

_mqx_int InitTunerI2S(HTUNER h)

{

    TUNER* p = (TUNER*)h;

    _mqx_int     errcode = 0;

    uint_32        mclk_freq;

   // _mqx_int    param, temp;

    /* Prepare audio format struct */

    p->audio_format.ENDIAN         = AUDIO_LITTLE_ENDIAN;

    p->audio_format.ALIGNMENT     = AUDIO_ALIGNMENT_LEFT;

    p->audio_format.BITS         = DEFAULT_BITS_PER_SAMPLE;

    p->audio_format.SIZE         = SAMPLE_SIZE_IN_BYTE;

    p->audio_format.CHANNELS     = DEFAULT_NUM_CHANNELS;

    p->audioSamplingFreq         = DEFAULT_SAMPLE_RATE_HZ;

    mclk_freq = p->audioSamplingFreq * CLK_MULT;  /* Set master clock frequency so oversampling = 384 */

   uint_8 mode = I2S_MODE_MASTER;

    p->tunerI2S_fd = fopen(AUDIO_DEVICE, "r");

    if (p->tunerI2S_fd == NULL)

    {

        printf("\n  InitTunerI2S error: Unable to open audio device.\r\n");

        return(0xDEAD);

    }

    /* Setup device */

    if (ioctl(p->tunerI2S_fd, IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT, &(p->audio_format)) != I2S_OK)

    {

        printf("  Error: Input data format not supported.\n");

        fclose(p->tunerI2S_fd);

        return (MQX_ERROR);

    }

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_DATA_BITS, &(p->audio_format.BITS)))

        errcode = -1;

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_MODE_MASTER, &mode))

        errcode = -1;

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_MCLK_FREQ, &mclk_freq))

        errcode = -1;

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_FS_FREQ, &p->audioSamplingFreq))

        errcode = -1;

    _time_delay(50);

    if(errcode != -1)

    {

        ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_GET_FS_FREQ, &p->audioSamplingFreq);

        ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_GET_BCLK_FREQ, &p->audioBitClkFreq);

        printf("I2S Settings:\r\n");

        printf("  Sampling frequency:     %d Hz\r\n", p->audioSamplingFreq);

        printf("  Bit depth:              %d bits\r\n", p->audio_format.BITS);

        printf("  Bit rate :              %d bits/sec\r\n", p->audioBitClkFreq);

        printf("  Channels:               ");

        if (p->audio_format.CHANNELS == 1)

        {

          printf("mono\n");

        }

        else

        {

            printf("stereo\n");

        }

        printf("I2S initialised.....\r\n");

    }

    return (MQX_OK);

}

Labels (4)
0 Kudos
Reply
1 Solution
4,078 Views
juangutierrez
NXP Employee
NXP Employee

SAI and eSAI driver has been added in MQX 4.1.0 which is expected to be released during Februrary.

View solution in original post

0 Kudos
Reply
29 Replies
3,049 Views
juangutierrez
NXP Employee
NXP Employee

There is an MQX sample for I2S that you may want to take a look.

In your MQX installation directory look for:

Freescale\Freescale_MQX_4_0\mqx\examples\i2s_demo

Hopefully it helps for you.

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Hi,

I have written my application based on i2s_demo application. Instead of writing to a file in SD card I am sending captured PCM samples over Ethernet to my client application.

But output is noisy.

My dought is in I2s settings and the pin used. Please recheck and let me know is there any issue in I2S settings and the pins I used.

BR/-

Nihad

0 Kudos
Reply
3,049 Views
naoumgitnik
Senior Contributor V

Dear Nihad,

Regarding your "I am sending captured PCM samples over Ethernet to my client application. But output is noisy." phrase - is there any way to verify that this noise is not caused by the Ethernet portion of the path?

May you anyhow verify the I2S portion only?

Regards, Naoum Gitnik.

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Hi,

I have verified Ethernet portion by sending pure tone(480 Hz sine wave @ 48KHz sampling freq), it is working fine and no noise in audio output. But when I send captured I2S PCM samples there is noise in audio output.

BR/-

Nihad

0 Kudos
Reply
3,049 Views
naoumgitnik
Senior Contributor V

Dear Nihad,

Let me see if I can find the I2S code example.

Ross,

Is there any way to share the Auto EVB I2S code portion, please?

RossMcLuckie

Thanks, Naoum Gitnik.

0 Kudos
Reply
3,049 Views
RossMcLuckie
NXP Employee
NXP Employee

The auto EVB code is based on MQX, so the SAI driver used there should be the same, and perhaps as highlighted by Juan already. What hardware platform is in use here?

Is it MQX you are using, what harwdare is doing the audio capturing, what have you done to confirm there is no hardware/layout issues involved, what is providing the master audio clock, have you tried simple loop tests, feeding the input direct to the output, keeping the clocking the same, have you tried analysing the captured data, to see if noise is already present in capture before data sent out etc?

Ross

0 Kudos
Reply
3,049 Views
naoumgitnik
Senior Contributor V

Dear Nihad,

Is this your own board or our platform?

/Naoum.

Ross McLuckie

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Dear all,

I am using vybrid tower system and an ST microelectronics based Tuner daughter board. I have interfaced tuner board to vybrid using j8 header in primary peripheral board. The tuner board is a proven board and it is working with other micro controllers from ST.

I have already shared my I2S init routine in my first post. Also mentioned Pin I used. Please find the attached capture code.

0 Kudos
Reply
3,049 Views
naoumgitnik
Senior Contributor V

Hello Nihad,

Regarding the fact that you are using the Vybrid tower system - please, verify the signal integrity, possibly compromised by possible stubs on the lines (due to multiple functions practically every Vybrid's IO has on this board).

I also discussed your case with our audio expert, and according to him, briefly, while switching between Master and Slave, configuration settings cannot be kept unchanged. He specifically mentioned the Bit Clock and Frame division factors – from your description it is unclear if you did this or not. The reason for that is that the Master generates these signals for itself and the Slave based on its own, internal System Clock, and the Slave recovers System Clock for itself from the signals coming from the Master.

Based on the above, I would recommend you to review settings in our code, also used on our Auto EVB; the I2S “link partner” on this board is ADMP441ACEZ-RL7 InvenSense | ADMP441ACEZ-RL7CT-ND | DigiKey.

BTW, is my understanding of the "capture ... is noisy" phrase correct that there is noise on top of the proper sound? It is not just totally irregular noise, right?

Regards, Naoum.

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Hi All,


Below is my tuner I2S settings . Also attached the recorded i2S captured audio to feel the audio chopping issue. Could you please tell me what may be the reason for this audio chopping. 


1. Tuner has configured as slave with external clock. controller will provide BCLK and I2S_WS

2. sampling frequency 48KHz

3.  bit depth 16L+16R

4. audio little Indian

5. audio alignment left

6. Interface used: BCLK, I2S_DO, I2S_WS  (MCLK is not used)

7 50/50 duty cycle,

8. no sign extension,

9. WS polarity high,

10. MSB First, with data delay,

11. normal clock

0 Kudos
Reply
3,049 Views
haku_sato
NXP Employee
NXP Employee

Hi Abdul,

I listened to your audio file.  Here is my two cents.

1. music and voice are coming in clearly without any annoying audio noise artifact.  This suggests your clock and SAI settings may be correct

2. I hear 'skipping' at periodic locations longer than a few milliseconds. This suggests some buffer related issue rather than SAI/I2S clock timing.

You may need to focus on how the input and output buffers for audio data are handled.

This type of periodic skip usually mean one or more of the following

- Pointer may be looking at the wrong address ranges compared to the ranges allocated for buffer

- buffer content copy may not be done properly:  copying all but few of the data within the source.  leaving a few blank spots within output buffer.

- buffer access violation:  Usually occurs when DMA and copy is done in the same buffer location.  Pingpong buffer is usually used to avoid this, but DMA and copy location may be coinciding.

I would suggest you look at the copy and buffer management portion of your driver before looking further into SAI settings, since the audio quality does not suggest you have a setup issue. 

Thanks!

Haku

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Hi,

When I sent pure tone(480 Hz sine wave @ 48KHz sampling freq), it is working fine and no chopping noise in audio output. But when I send captured I2S PCM samples there is chopping noise in audio output.If it is a buffer problem then pure tone also produce chopping noise.

Today I tried to configure my tuner module as master and vybrid as slave. But I am not able to capture the audio. Below is the details. Could you please tell me how to configure vybrid as slave and all clocks will be provided by tuner module.

Pin used in primary elevator J8 Header to interface tuner module

1)  pin 24: RX_DATA

2)  pin 58: RX_BCLK

3)  pin 59: RX_WS

modification in init_sai.c bsp file

------------------------------------------

KSAI_INIT_STRUCT _bsp_ksai_init = {

    2,                           /* Selected peripheral (HW channel) */

    0,                           /* TX channel */

    0,                           /* RX channel */

    I2S_TX_ASYNCHRONOUS |        /* TX is asynchronous */

    I2S_RX_ASYNCHRONOUS |      

    I2S_TX_BCLK_NORMAL  |        /* Both TX and RX are clocked by the transmitter */

    I2S_RX_BCLK_SWAPPED,        

    I2S_TX_MASTER |              /* SAI transmitter mode */

    I2S_RX_SLAVE,               /* SAI receiver mode */

    16,                          /* Data bits */

    I2S_CLK_EXT,                 /* Clock source */

    FALSE,                       /* Tx Dummy */

    5,                           /* Interrupt priority */

    2048,                        /* Buffer size */

    CM_CLOCK_SOURCE_PLL_AUDIO,   /* Internal master clock source */

    &_bsp_audio_data_init        /* Audio init */

};

I2s init application code:

---------------------------

_mqx_int InitTunerI2S(HTUNER h)

{

    TUNER* p = (TUNER*)h;

    _mqx_int     errcode = 0;

    uint_32        mclk_freq;

    _mqx_int    param = 0;// temp;

    char* modeString;

    /* Prepare audio format struct */

    p->audio_format.ENDIAN         = AUDIO_LITTLE_ENDIAN;

    p->audio_format.ALIGNMENT     = AUDIO_ALIGNMENT_LEFT;

    p->audio_format.BITS         = DEFAULT_BITS_PER_SAMPLE;

    p->audio_format.SIZE         = SAMPLE_SIZE_IN_BYTE;

    p->audio_format.CHANNELS     = DEFAULT_NUM_CHANNELS;

    p->audioSamplingFreq         = DEFAULT_SAMPLE_RATE_HZ;

    mclk_freq = p->audioSamplingFreq * CLK_MULT;  /* Set master clock frequency so oversampling = 384 */

#if BSPCFG_ENABLE_SAI

    uint_8 mode = (I2S_TX_SLAVE | I2S_RX_SLAVE);

#else

    uint_8 mode = I2S_MODE_MASTER;

#endif

    p->tunerI2S_fd = fopen(AUDIO_DEVICE, "r");

    if (p->tunerI2S_fd == NULL)

    {

        printf("\n  InitTunerI2S error: Unable to open audio device.\r\n");

        return(0xDEAD);

    }

    /* Setup device */

    if (ioctl(p->tunerI2S_fd, IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT, &(p->audio_format)) != I2S_OK)

    {

        printf("  Error: Input data format not supported.\n");

        fclose(p->tunerI2S_fd);

        return (MQX_ERROR);

    }

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_DATA_BITS, &(p->audio_format.BITS)))

        errcode = -1;

    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_MODE_SLAVE, &mode))

        errcode = -1;

//    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_MCLK_FREQ, &mclk_freq))

//        errcode = -1;

//    if(I2S_OK != ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_SET_FS_FREQ, &p->audioSamplingFreq))

//        errcode = -1;

    _time_delay(50);

    if(errcode != -1)

    {

        printf("I2S initialised.....\r\n");

    }

    return (MQX_OK);

}

0 Kudos
Reply
3,049 Views
haku_sato
NXP Employee
NXP Employee

Hi Abdul,

Thanks for checking... but your test mentioned below is not sufficient to rule out the buffer management as the root cause.

>>When I sent pure tone(480 Hz sine wave @ 48KHz sampling freq), it is working fine and no chopping noise in audio output. But when I send captured I2S PCM samples there is chopping noise in audio output.If it is a buffer problem then pure tone also produce chopping noise.

Listening test alone usually is not sufficient, and your frequency choice may be masking the issue.  Ear is highly unreliable and I strongly advise you to use proper equipment to visually confirm there is no issue.  Listening on the speaker or HP are always unreliable.  You must use some sort of digital audio analyzer to be sure.  In addition, 480Hz @ 48kHz is at the node frequency where the issue could be masked, meaning zero crossing can land within the buffer length that could mask the problem entirely.

In order to make sure there is NO issue with the buffer, I suggest the following test method to rule out buffer issue:

1.  Stream Stereo Sine waves consisting of L=1897kHz R=2975kHz at 0dBFS

2.  Swap between channels for Stream #1

3.  Stream Walking Ones and Walking Zeros to check input and output.  It can be L= Walking1 and R=Walking0

4.  Swap between channels for Stream #3

5.  Do the test 1-4 at 48kHzFS, 44.1kHzFS, 88.2kHzFS and 96kHzFS.

Above will give you the accurate results of what's going on with buffer management.  If there is truly no buffer management issues, the test will reveal no issue at all.

You need to rule out the buffer issue before moving to detailed clock settings.  At this point in time, I believe it is too early to rule out the buffer issue.

Thanks

Haku

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Hi,

I have dumped PCM samples to a file in SD card after capturing from I2S . When I played this using Cool edit, it plays very fast and also it have tick sound. Could you please tell me what is the reason for this. .

vybrid I2S configured for

Master

48KHz

16bit

Stereo

Mclk = 48KHz * 384

//snap of code:

/*read from I2S*/

msg_ptr->LENGTH = read(p->tunerI2S_fd, (msg_ptr->DATA), block_size);

#if (DUMP_TO_SDCARD && DUMP_IN_CAPTURE_THREAD)

/* Write data to SD card */

length = write(SDcardfile_ptr, msg_ptr->DATA, msg_ptr->LENGTH);

BR/-

Nihad

0 Kudos
Reply
3,049 Views
haku_sato
NXP Employee
NXP Employee

Hi Nihad,

Fast playback maybe due to your sample rate settings?

I cannot help you effectively without specific scope shot indicating the point of corruption.  Fast and tick noise explained with code snip does not provide us with enough information.

1.  please provide scope shot showing the data and suspected timing violation

2.  whether all of the clock frequencies provided to SAI, and all division are set properly (register values vs the intended frame and bit clock frequency). 

3.  can the same phenomenon be observed, recreated on FSL reference. 

Without above materials, I cannot provide assist you effectively.

regards,

Haku

0 Kudos
Reply
3,049 Views
abdulnihad
Contributor III

Below explains my finding When I debugged vybrid SAI driver in MQX.

There is a FIFO in I2S hardware. its size is 32x4 byte. it can hold 32 samples of 32 bit size each.

There is another internal buffer (2048*4 bytes) in i2s driver which can hold 2048 samples of 32 bit size each. When i2s interrupt occur, data will be copied from FIFO to internal buffer.

 

In my application there is a Capture thread which will copy data from i2s internal buffer to application buffer of size 13372 bytes. At a time I am copying 13372 bytes which is equivalent to 6686 samples of 16 bit size each.

I have validated SAI driver by injected 4 types of audio

1) music track,

2) pure sine wave at 480Hz,

3) sweep with 440Hz to 16KHz,

4) stereo tone with 2KHz tone on left and 3KHz tone on right channel with 0.3 sec delay

in i2s rx interrupt handler function '_ksai_rx_irq_handler' instead of I2S data from i2s_ptr->RDR register. and played on player thread. all plays fine. So I dumped three type of tone in vybrid playback thread in my application and played using cool edit. I got same out put as in player thread. 

This conclude that there is no problem between the i2s audio path shown below

i2s rx interrupt handler of MQX--->i2sread--->capture thread---->msg queue----> playback thread------> audio speaker out.

When I debugged the interrupt handler code, some time code flow shows FIFO full. If FIFO full persist for longer time then I think we will miss data on I2S line. Is it correct?. By default in MQX I2S interrupt priority set to 5 . my capture thread priority is set to 9. In MQX who is generating I2S interrupt and at what rate.? and I am not able to see any DMA involvement in data transfer.

In MQX release note it shows that SAI is not supported for vybrid in 4.0.2 release. Could you please tell me why it is not supported?. When can I expect MQX release with SAI support for vybrid.

BR/-

Nihad

0 Kudos
Reply
4,079 Views
juangutierrez
NXP Employee
NXP Employee

SAI and eSAI driver has been added in MQX 4.1.0 which is expected to be released during Februrary.

0 Kudos
Reply
3,046 Views
abdulnihad
Contributor III

Hi,

I am copying below the interrupt service routine for SAI which is available with MQX 4.0.2. This is copied from file sai_int_ksai.c. As per vybrid Reference manual Receive fifo read pointer will get increment when we read from RDR. But when I put break point in this routine and executed code line by line, I found out that Receive fifo read pointer increments automatically  before copying data from RDR to internal buffer. Is there any bug in this ISR?. also in the for loop which copy RDR to buffer, read pointer increment 2 in each loop. i.e suppose read pointer is 1 before entering  loop and it become 3 before copying data.next loop it become 5.

Is the noise which I explained earlier post is because of this?. I dought that data is getting corrupted while copying from RDR to internal buffer of 2048 samples

Some time read pointer is greater than write pointer. because of that data_n is negative. Why it is so. when I set watermark as 25 then interrupt will get generated when number of element in rx fifo is 26. So when I read 26 element then read pointer will equal to write pointer. when next interrupt come the write pointer should greater than read pointer. But here read pointer is greater than write pointer. Is there any issue with sai hardware in vybrid?.vybrid reference manual is not showing anything regarding writer pointer. how it is increased or decreased.

do you have any other working sai driver code for vybrid. We may drop vybrid if it will not support audio or if I am not able to fix this noise issue. Request you to sent your reply ASAP.

void _ksai_rx_irq_handler
(
    /* [IN] Parameter pointer */
    pointer param
)
{
    KSAI_INFO_STRUCT_PTR       ksai_info_ptr = (KSAI_INFO_STRUCT_PTR)param;
    I2S_MemMapPtr              i2s_ptr = ksai_info_ptr->SAI_PTR;
    KSAI_BUFFER_PTR            buffer = &(ksai_info_ptr->BUFFER);
    I2S_STATISTICS_STRUCT_PTR  stats = &(ksai_info_ptr->STATS);
    uint_32                    i = 0;
    uint_32                    data_n;
    uint_8                     rx_channel = ksai_info_ptr->RX_CHANNEL;
    uint_32                    read_ptr;
    uint_32                    write_ptr;
    boolean                    stop = FALSE;
    static uint_32 urun = 0;

    stats->INTERRUPTS++;
   
    read_ptr = i2s_ptr->RFR[rx_channel] & I2S_RFR_RFP_MASK;
    write_ptr = (i2s_ptr->RFR[rx_channel] & I2S_RFR_WFP_MASK) >> I2S_RFR_WFP_SHIFT;
   
    /* Check FIFO request flag */
    if (i2s_ptr->RCSR & I2S_RCSR_FRF_MASK)
    {
         int result;
        /* FIFO is full */
        if ((write_ptr ^ read_ptr) == I2S_RX_FIFO_FULL_MASK)
        {
            data_n = SIZE_OF_FIFO;
        }
        else /* FIFO is not full */
        {
            result = (write_ptr & I2S_RX_WRITE_PTR_MASK) - (read_ptr & I2S_RX_READ_PTR_MASK);
            data_n = (result < 0) ? -(unsigned)result : result;        
        }
        /* Copy data from FIFO to buffer */
        if (data_n + stats->PACKETS_QUEUED >= stats->PACKETS_REQUESTED)
        {
            data_n = stats->PACKETS_REQUESTED - stats->PACKETS_QUEUED;
        }
        /* Check software buffer overrun */
        if (data_n > buffer->SPACE)
        {
            data_n = buffer->SPACE;
            stats->BUFFER_ERROR++;
        }

        for (i = 0; i < data_n; i++)
        {
            (buffer->IN >= buffer->SIZE) ? (buffer->IN = 0) : (0);
            buffer->DATA[buffer->IN++] = i2s_ptr->RDR[ksai_info_ptr->RX_CHANNEL];
        }
        buffer->SPACE -= i;
        stats->PACKETS_QUEUED += i;
        stats->RX_PACKETS += i;
    }
   
    /* Check FIFO error flag */
    if (i2s_ptr->RCSR & I2S_RCSR_FEF_MASK)
    {
        /* Reset FIFO */
        i2s_ptr->RCSR |= I2S_RCSR_FEF_MASK;
        i2s_ptr->RCSR |= I2S_RCSR_FR_MASK;
        stats->FIFO_ERROR++;
    }
    /* All data received, disable receiver */
    if (stats->PACKETS_QUEUED >= stats->PACKETS_REQUESTED)
    {
        ksai_info_ptr->ONTHEWAY = FALSE;
        ksai_info_ptr->FIRST_IO = TRUE;

        /* Disable interrupts and receiver */
        i2s_ptr->RCSR &= ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FEIE_MASK);
        i2s_ptr->RCSR &= ~(I2S_RCSR_RE_MASK);
    }

    if (_lwsem_post(&(ksai_info_ptr->EVENT_IO_FINISHED)) != MQX_OK)
    {
        I2S_LOG("\n  i2s_rx_irq_handler: Error - Unable to set EVENT_IO_FINISHED.");
    }
}

0 Kudos
Reply
3,046 Views
juangutierrez
NXP Employee
NXP Employee

I think this is due to same problem SAI/I2S is not fully supported in current release.

Next release is coming soon. I suggest to wait for MQX 4.1.0

0 Kudos
Reply
3,046 Views
abdulnihad
Contributor III

Hi,

I have ported my audio application from MQX4.0.2 to MQX4.1. Now my application output only noise. I have modified my application based on the sai_dma_demo code.below is my i2s capture code using sai_dma driver. I am attaching pcm dump.

block_size=13372;

/*Get the status of the I2S*/

    ioctl(p->tunerI2S_fd, IO_IOCTL_I2S_GET_STATISTICS, &stats);

    /* Compute requested number of data blocks */

    requests = block_size / stats.SIZE;

    remainder = block_size % stats.SIZE;

    if (remainder > 0)

    {

       requests++;

    }

While(1)

{

          msg_ptr = (REC_MESSAGE_PTR) _msg_alloc(audio_msg_pool);

            if (msg_ptr != NULL)

            {

                /* Fill message header, record data and send message to audio_sent_task */

                msg_ptr->HEADER.TARGET_QID = audio_msg_qid;

                msg_ptr->HEADER.SOURCE_QID = audio_msg_qid;

                msg_ptr->HEADER.SIZE = audio_msg_sz;

                des_address = msg_ptr->DATA;

                buffer_end  = msg_ptr->DATA + block_size;

                msg_ptr->LENGTH =  block_size;

              

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

                {

                    ioctl(I2S_fd, IO_IOCTL_I2S_START_RX, NULL);

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

                    {

                        process_size = stats.SIZE;

                    }

                    else

                    {

                        process_size = remainder;

                    }

                    ioctl(I2S_fd, IO_IOCTL_I2S_WAIT_RX_EVENT, NULL);

                    ioctl(I2S_fd, IO_IOCTL_I2S_GET_STATISTICS, &stats);

                    //Copy data

                    if(des_address + process_size > buffer_end)

                    {

                        uint32_t up_data = buffer_end - des_address;

                        _mem_copy(stats.OUT_BUFFER, des_address, up_data);

                        ioctl(I2S_fd, IO_IOCTL_I2S_UPDATE_RX_STATUS, &up_data);

                    }

                    else

                    {

                        _mem_copy(stats.OUT_BUFFER, des_address, process_size);

                        des_address += process_size;

                        ioctl(I2S_fd, IO_IOCTL_I2S_UPDATE_RX_STATUS, &process_size);

                    }                  

                }

                if (!_msgq_send_queue(msg_ptr, audio_msg_qid))

                {

                    printf("  Error: Failed to send a message to queue. Free msg pointer\n");

                    /* Free message */

                    _msg_free(msg_ptr);

                }

}

0 Kudos
Reply