Emfile read from sd card is slow. any way to increase speed?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
AbPa_4654881
Level 3
Level 3
10 replies posted 10 questions asked 10 likes given

Hi all,

I am using CY8Ckit-059 and reading data from sd card using Emfile. I want to implement in a faster way. As I am using sclk 12MHz. greater than 12MHz  it is not able to read from sd card. I am reading 1 byte in each iteration and according to data I am driving the GPIO. but as it seems it is taking so much time to read ~2Mb file size like this.

As I browse through this community I got to know using DMA with Emfile can work Much faster way. can anybody help me how to do DMA things with EMfile and is there any example to Implement DMA with Emfile? Is there any way I can Implement this thing in a very faster way?

Here is my code thing That I want to implement in a faster way.

  1.         while(FS_FEof(File)!=1 )
  2.         { 
  3.         FS_Read(File,buffer, 1);
  4.         if (buffer[0] == 'a')
  5.         { 
  6.             pin1_Write(1u); 
  7.         }
  8.         } 
0 Likes
1 Solution

AbPa,

It appears your FS_Read() of only one byte at a time is your bottleneck for the transfer.

The code below will attempt to read 1024 bytes at a time and parse the buffer for the 'a' character (for pin2 output).  It will also frame the pin2 (in sample()) for every byte processed.  Note: Processing sample for every byte is not very efficient.  If you place the sample() call outside the for() loop, it will toggle the pin2 for every 1024 bytes and the overall data rate is significantly improved.

void main()

{

U8 buffer[1024];

U32 bytes_read = 0;

...

    while(FS_FEof(File)!=1 )

    {

        bytes_read = FS_Read(File,buffer, sizeof(buffer));

        for(U16 i = 0; i<bytes_read; i++)

        {

            if (buffer == 'a')

            {

                pin1_Write(1u);

            }

            else

            {

                pin1_Write(0u);

            }

            sample();         ///calling to sample function

        }

    }

    ...

}

void sample()

{

    pin2_Write(0u);

    pin2_Write(1u);

}

If you want further FS_Read() data throughput, make the buffer[2048].

Len

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
8 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

AbPa,

Before you resort to DMA, have you considered trying to read more than one byte at a time from the file?

uint8_t buffer[1024];

U32 num_bytes_read = 0;

...

    num_bytes_read = FS_Read(File,buffer, sizeof(buffer));

...

    if(num_bytes_read < sizeof(buffer)

    {

          return(FS_FError());          /* if file error return FS_FError.  If EOF, FS_FError = no error. */

    }

With executing any code, there is overhead.  By reducing the number of times the FS_Read() is made you will automatically save time.  Additionally by reading larger amounts of file data at one time, you theoretically reduce the amount of SPI data sent.

Question:  You said the data transfer was a bit slow.  Are you using pin1 GPIO on a scope as your indicator?  I noticed in your code fragment that you only set pin1 when an 'a' appears in the data.  You don't have a clear of pin1 (pint1_Write(0)).

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Thanks LePo for quick response. I got your point that read more than one byte at a time that will surely save time. But here I require to read one byte at a time. my actual code is something like below. and I am Using pin2 GPIO on a scope as indicator that is giving me a delay in the range of msec. is there any way I can speed up this thing.

  1.         while(FS_FEof(File)!=1 )
  2.         {
  3.         FS_Read(File,buffer, 1);
  4.         if (buffer[0] == 'a')
  5.         {
  6.             pin1_Write(1u);
  7.         }
  8.        else
  9.         {
  10.             pin1_Write(0u);
  11.         }
  12.        sample();         ///calling to sample function
  13.          }
  14. void sample()
  15. {
  16. pin2_Write(0u);
  17. pin2_Write(1u);
  18. }
0 Likes

AbPa,

It appears your FS_Read() of only one byte at a time is your bottleneck for the transfer.

The code below will attempt to read 1024 bytes at a time and parse the buffer for the 'a' character (for pin2 output).  It will also frame the pin2 (in sample()) for every byte processed.  Note: Processing sample for every byte is not very efficient.  If you place the sample() call outside the for() loop, it will toggle the pin2 for every 1024 bytes and the overall data rate is significantly improved.

void main()

{

U8 buffer[1024];

U32 bytes_read = 0;

...

    while(FS_FEof(File)!=1 )

    {

        bytes_read = FS_Read(File,buffer, sizeof(buffer));

        for(U16 i = 0; i<bytes_read; i++)

        {

            if (buffer == 'a')

            {

                pin1_Write(1u);

            }

            else

            {

                pin1_Write(0u);

            }

            sample();         ///calling to sample function

        }

    }

    ...

}

void sample()

{

    pin2_Write(0u);

    pin2_Write(1u);

}

If you want further FS_Read() data throughput, make the buffer[2048].

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

what is the max size of buffer I can take? I tried with 16K size but it was not reading.

0 Likes

AbPa,

The CY8CKIT-059 PSoC5 has 64KB of RAM.  There might be a limitation of the emFile SW.

I assume from your previous post that my code suggestions worked at least at 1KB buffer size.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Len,

Thanks a lot, It is working fine with 16K size also, I was doing some silly mistakes. For now the problem resolved for me. but Can you please help to find DMA example thing if I want to implement read/write for Big files.

0 Likes

AbPa,

Refer to the file UM02001_emFile_V322c.pdf Section 6.1.3.  It refers to the API hooks for the FS_HW_Write() call.

There is at least one Cypress example on SPI transfer using DMA with SPIM_Example.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

AbPa,

If you're willing to share your project, I'll try to diagnose why it isn't reading buffer[16K].

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes