I have done some extensive benchmarking of the SD interface on a LPC1778 and found some intersting things.
First of all the specs:
- crystal: 12 Mhz
- CPU clock 96 MHz (set to be able to come as close as possible to 50 MHz for the SD card (96/2 = 48 MHz)
- SD card: Apacer industrial SD SLC chips memory 4 GB
I have done both RAW multi-sector writes (64x512 bytes at a time) and FAT32 (Chan FatFs) writes.
First I see that when I do writes on the start of the card's adresses (sector 0) during RAW writes I get a considerable lower speed than at an offset of say 1 GB. The results are for 1 MB writes 2.81 MB/s vs 14.96 MB/s. This is with a bus speed off 48 Mhz.
But this is the problem. I can not do any FAT writes on this bus speed. Things go wrong when checking the FAT table during opening of a new file. All goes well at a 20 MHz bus speed.
Anyone seen this before?
BTW speeds are comparable at 20 MHz for RAW vs FAT writes (multi-sector writes, cluster aligned, and writing 1MB or more at a time).
Hello,
Your source code did not pass throught the test (see below). Do not worry, either my driver did not pass with the 4-wire interface. It seems that card or PL180 (arm prime cell used in nxp) is buggy. The lpcopen uses checking of state before sending the STOP command, maybe there is the catch.
my modification to your source code was to set max_transfer_sectors = 8 and speed to 1.000.000 Hz
Test code:
<code>
static uint8_t buffer[512*32];
#define SIZE_OF_ARRAY(array)(sizeof(array) / sizeof(array[0]))
#define SECTOR_BURST_MAX(23)
#define BLOCK_SIZE(512)
const unsigned int sector_bursts[] = {1,2,3,7,16,17,20, SECTOR_BURST_MAX};
const unsigned int sector_addresses[] =
{ 0, 1, 23, 500, 1235, 10689, 39784 };
int main(void)
{
int error;
mmc_inithardware();
mmc_init_card();
// write
for (unsigned i = 0; i < SIZE_OF_ARRAY(sector_addresses); ++i)
{
for (unsigned j = 0; j < SIZE_OF_ARRAY(sector_bursts); ++j)
{
//fill buffer to a known number.
memset(buffer, (i+1)*(j+1), BLOCK_SIZE * sector_bursts[j]);
error =mmc_writemultiplesector(buffer,sector_addresses, sector_bursts[j]);
if(error != 0)
{
__asm("BKPT 1\n");
}
//clear buffer.
memset(buffer, 0, BLOCK_SIZE * sector_bursts[j]);
//read block
error =mmc_readmultiplesector(buffer,sector_addresses, sector_bursts[j]);
if(error != 0)
{
__asm("BKPT 1\n");
break;
}
// Here comes checking
for (unsigned k = 0; k < BLOCK_SIZE * sector_bursts[j]; ++k)
{
if (buffer[k] != (i+1)*(j+1))
{
__asm("BKPT 1\n");
break;
}
}
}
}
while(1)
{
}
return 1;
}
</code>
You may want to try my driver:
http://www.lpcware.com/content/forum/lpc1788-mci-problems#comment-1866
(Please post results if you do!)
regards
Wolfgang