SDHC working with DMA

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

SDHC working with DMA

16,975 Views
jocelyn_massero
Contributor II

Hi,

 

I'm trying to develop a program which communicatee with WIFI card over SDIO protocol. The SDIO protocol part working fine but I want to use the simple internal DMA to read and write data. However I got at every time a DMA ERROR interrupt (the DMA TRANSFER COMPLETE flag is also fired up). Here is my configuration program:

 

SDIO_SetWriteWatermark(SDHC_BASE_PTR, (u32)(count&0xffff));SDIO_SetReadWatermark(SDHC_BASE_PTR, (u32)(count&0xffff));SDIO_SetDMAAddress(SDHC_BASE_PTR, (u32)data); // data is an pointer over my bufferSDIO_SetCommandArgument(SDHC_BASE_PTR, arg); SDIO_SendCommand(SDHC_BASE_PTR, SDIO_CMD53_IO_RW_EXTENDED,SDIO_ENABLE_DMA |                                                         SDIO_DATA_PRESENT |                                                         SDIO_DATA_READ |                                                        SDIO_RESPONSE_LENGTH_48);

 

Someone has an idea to get the SDIO working fine with the internal DMA?

 

Thanks,

 

Jocelyn

37 Replies

4,077 Views
Gargy
NXP Employee
NXP Employee

Hi,

OK - I have for you another source of information, some days ago I finished the updated MQX version of SDHC driver based on ADMA and it works pretty fine, the one not finished bug is that is not able to handle non alignment data buffers, but rest things seems to runs correctly.

This is not published yet version that after some updates will be part of some new release of MQX. I hope that this helps you.

Petr

4,075 Views
Masmiseim
Senior Contributor I

Hey Petr,

sorry for the long delay. With your code as a reference I got my board working. I also did some speed test. But I’m far away of the 17MB/s you mention.

Here are my numbers with different cards

The first column is the number of bytes read/write at a time.

The second is the write speed (Bytes per second)

The third is the read speed. (Bytes per second)

SanDiskUltra 8Gb UHs I

  512         255 616        1 576 115

1024        251 084        2 224 025

2048        636 518        3 734 220

4096     1 385 881        5 572 812

8192     1 412 300        5 634 457

16384    1 447 526        5 622 988

Kingston SD-Karte 8 GB Sc10

  512        178 335          654 822

1024       345 548        1 222 195

2048       689 049        2 603 622

4096    1 355 366        5 430 067

8192    2 674 278        4 871 372

16384   4 952 064        6 243 942

Lexar professional 32 GB UHs I

  512       146 662        1 987 993

1024      408 678        2 997 401

2048      868 966        4 860 928

4096     1630003        6 932 684

8192     2874982        8 706 867

16384    4622745        9 936 076

My Hardware is a tower Module (TWR-K60N512 R19). The Controller runs with 96 MHz and SDHC with 25 MHz. I’m using the FATfs File System.

My benchmark is quite simple. I’m just writing / reading for 20 seconds as much as possible. There is no RTOS which could interrupt the Benchmark.

How did you reach the 17MB/s? Did you use the 150 MHz Kinetis? How many bytes did you write at a time? Do you have any hints for me to reproduce your results.

Thanks and Regards

Markus

0 Kudos
Reply

4,075 Views
Gargy
NXP Employee
NXP Employee

Hi,

Don't be afraid and go to 50MHz on SDHC on card which support this frequency :-) Most of the current card already support it.

And let us know with new results.

Petr

0 Kudos
Reply

4,076 Views
Masmiseim
Senior Contributor I

Hey Petr,

The only reason why I’m using 25 MHz instead of 50 MHz is that I don’t have a card which supports the higher frequency. But when I look at the results of the “Lexar professional 32 GB UHs I” card again, it is close to the theoretic limit.

I set the clock to the maximum Frequency supported by the card (taken from the CSD Structure). Maybe I had made an error on reading this. I will check this again, and buy some more cards to check them.

By the way: Does the SDIO-Controller remove the CRC of the CSD Structure? It is always zero

Thanks and Regards

Markus

0 Kudos
Reply

4,077 Views
Gargy
NXP Employee
NXP Employee

Hi,

Try - if this helps you, this is my MQX function to determine the speed of card:

static int_32 _set_sd_high_speed_mode(SDCARD_STRUCT_PTR sdcard_ptr, uint_32 baudrate)

{

  ESDHC_COMMAND_STRUCT command;

  uint_32              param;

  uint_8 cmd6_data[64];

#define SFS_FUNC_GROUP1_BIT 400

#define SFS_FUNC_GROUP2_BIT 416

#define SFS_FUNC_GROUP3_BIT 432

#define SFS_FUNC_GROUP4_BIT 448

#define SFS_FUNC_GROUP5_BIT 464

#define SFS_FUNC_GROUP6_BIT 480

#define SFS_FUNC_GROUP1_FUNC 376

#define SFS_GET_BYTE_CNT(bit) (63 - (bit) / 8)

  //  set BLKCNT field to 1 (block), set BLKSIZE field to 64 (bytes);

  //  send CMD6, with argument 0xFFFFF1 and read 64 bytes of data accompanying the R1 response;

  //  wait data transfer done bit is set;

  /* Check the card capability of bus speed*/

  command.COMMAND = ESDHC_CREATE_CMD(6, ESDHC_COMMAND_TYPE_NORMAL, ESDHC_COMMAND_RESPONSE_R1, ESDHC_COMMAND_DATACMD_FLAG | ESDHC_COMMAND_DATA_READ_FLAG);

  command.ARGUMENT = 0xFFFFF1;

  command.BLOCKS = 1;

  command.BLOCKSIZE = 64;

  if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))

  {

      return IO_ERROR;

  }

  if (64 != fread (cmd6_data, 1, 64, sdcard_ptr->COM_DEVICE))

  {

      return IO_ERROR;

    

  }

  if (ESDHC_OK != fflush (sdcard_ptr->COM_DEVICE))

  {

      return IO_ERROR;

  }

  // Check the response

  // in the function group 1, check the first function availability

  if((cmd6_data[SFS_GET_BYTE_CNT(SFS_FUNC_GROUP1_BIT)] & 0x01) == 0)

    return MQX_IO_OPERATION_NOT_AVAILABLE; //  if (bit 401 is '0') report the SD card does not support high speed mode and return;

 

  /* Set the high speed of bus */

  command.COMMAND = ESDHC_CREATE_CMD(6, ESDHC_COMMAND_TYPE_NORMAL, ESDHC_COMMAND_RESPONSE_R1, ESDHC_COMMAND_DATACMD_FLAG | ESDHC_COMMAND_DATA_READ_FLAG);

  command.ARGUMENT = 0x80FFFFF1;

  command.BLOCKS = 1;

  command.BLOCKSIZE = 64;

  if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SEND_COMMAND, &command))

  {

      return IO_ERROR;

  }

  if (64 != fread (cmd6_data, 1, 64, sdcard_ptr->COM_DEVICE))

  {

      return IO_ERROR;

    

  }

  if (ESDHC_OK != fflush (sdcard_ptr->COM_DEVICE))

  {

      return IO_ERROR;

  }

  // Check the response

  // in the function group 1, check the first function availability

  if((cmd6_data[SFS_GET_BYTE_CNT(SFS_FUNC_GROUP1_FUNC)] & 0x0F) != 0x01)

    return MQX_IO_OPERATION_NOT_AVAILABLE; //  if (bit 401 is '0') report the SD card does not support high speed mode and return;

  param = baudrate;  

  if (ESDHC_OK != ioctl (sdcard_ptr->COM_DEVICE, IO_IOCTL_ESDHC_SET_BAUDRATE, &param))

  {

      return IO_ERROR;

  }

  return 0;

}

Petr

4,077 Views
Masmiseim
Senior Contributor I

Hey Petr,

I ported your code to my environment. It runs, but I don’t see that the throughput goes up.

When I have my oscilloscope back, I will check if the frequency has changed.

Regards

Markus

0 Kudos
Reply

4,077 Views
Masmiseim
Senior Contributor I

Hey,

I have some new numbers with 50 MHz SDIO. Looks quite good. But I'm still not at 17 MB/s. When I'm reading without any Filesytem I'm quite close.

Regards

Markus

SanDiskUltra 8Gb UHs I - 50 MHz SDIO

  512     244326    1660569        noFS:    -     2192819

1024     246528    2464000        noFS:    -     3139174

2048     629452    4440985        noFS:    -     5203558

4096    1442611    7450419        noFS:    -     8009523

8192    1384038    7477248        noFS:    -    12097536

16384    1417216    7472742        noFS:    -    16271769

Kingston SD-Karte 8 GB Sc10 - 50 MHz SDIO

  512     176218  673433        noFS:    -      962764

1024     357785    1198694        noFS:    -     1365913

2048     698777    2714316        noFS:    -     2619699

4096    1450188    6873497        noFS:    -     4853964

8192    2976153    5853184        noFS:    -     7927808

16384    6560972    8666316        noFS:    -    12076646

0 Kudos
Reply

4,077 Views
Gargy
NXP Employee
NXP Employee

Hi,

I think that you achieved realistic numbers. I have similar one. The 17MB/s I achieved just only on one pretty fast SanDisk 64GB card, that was already much faster on PC in compare to others.

Congratulation.

Did the algorithm to change the clocks to 50MHz helps you?

Petr

0 Kudos
Reply

4,077 Views
Masmiseim
Senior Contributor I

hey,

yes it helped a lot. Thanks for posting the code.

Regards

Markus

0 Kudos
Reply

4,077 Views
amassa
Contributor II

Is there example code showing how to use other drivers from this code (in the attached TWR_K60_SDHC.zip file)?  Specifically I'm looking at the SPI driver.  Thanks

0 Kudos
Reply

4,077 Views
Muffinman
Contributor I

Thanks, it works great. fno.lfname need a buffer. I am trying to reuse part of the code.

0 Kudos
Reply

4,085 Views
Muffinman
Contributor I

what's gsh_d4d_library_d.a? I thought it is your library not related to the SDHC, right? 

What's the library for ?

0 Kudos
Reply

4,079 Views
Gargy
NXP Employee
NXP Employee

Hi, good to hear that the driver works.

And regarding the d4d_library: It's my graphic (eGUI) library, I forgot to rmove it from project, sorry.

I tested the SDHC in bigger project and make just simpliest modification with only SDHC to copy on web.

 

Gargy

0 Kudos
Reply

4,086 Views
Muffinman
Contributor I

Great, Thanks

0 Kudos
Reply

4,086 Views
T_M_F
Contributor I

you can attach it here? i thought.....

 

what about SDHC with normal SDHC card and not SDIO?

 

thanks.

0 Kudos
Reply

4,086 Views
Muffinman
Contributor I

Can you send me your code? If you can tell me the speed of your SDIO, that will be great.

 

0 Kudos
Reply

4,086 Views
Muffinman
Contributor I

Can you send me your code? If you can tell me the speed of your SDIO, that will be great.

email me jack@engtech.ca

0 Kudos
Reply