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
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
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
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
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
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, ¶m))
{
return IO_ERROR;
}
return 0;
}
Petr
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
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
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
hey,
yes it helped a lot. Thanks for posting the code.
Regards
Markus
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
Thanks, it works great. fno.lfname need a buffer. I am trying to reuse part of the code.
what's gsh_d4d_library_d.a? I thought it is your library not related to the SDHC, right?
What's the library for ?
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
Great, Thanks
you can attach it here? i thought.....
what about SDHC with normal SDHC card and not SDIO?
thanks.
Can you send me your code? If you can tell me the speed of your SDIO, that will be great.
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