Hi Rick and Paul,
I have made a few modifications and the attached code seems to work - I don't have a protocol analyzer to check if there is anything nasty happening under the hood, but it appears to work.
I reviewed Paul's code, and it is nicer in places - I think my changes are closer to the original code, which may make merging any updates easier, so I have chosen to stick with my approach.
Here is a brief list of the changes that were required to get things going:
1) Modified the card identification process so on timeout it falls through to a CMD1 (and then the MMC card identification succeeds)
2) Modified the _io_sdcard_esdhc_init check for MMC card type, and if it is an MMC to return the result of new function, _io_emmc_esdhc_init.
3) Modified the _esdhc_send_command function, setting BCEN on non-infinite rather than infinite transfers.
4) Changed the _esdhc_read and _esdhc_write so on lwsem timeout the function returns IO_ERROR (-1) and sets the file hand error to IO_ERROR_TIMEOUT, otherwise writes of 2576 bytes would be indistinguishable from the error code.
5) Added a wait for data lines to be available (thanks to Paul for that)
There are some other mods, not strictly required:
1) Changed to use read and write (and added divides on the results to put them back into sectors) rather the fread and fwrite - I get warnings since I am using EWL, so I changed it.
2) Added a structures and enums for storing info about the emmc, and an additional ioctl command to get it.
Additional note:
Unlike the previous driver you can only read and write a maximum of 127 blocks (65024 bytes).
I considered modifying the code so the read and write operations would chop up the requests, but it doesn't seem to cause a problem for MFS. We only hit the problem because we load a big firmware image into DDR from a raw partition (previously in one go), so I just modified our app code.
Chris
EDIT:
I have found 2 bugs in this code - the first is in the baud rate variable was not initialized prior to switching to high speed baud rate. to fix, insert the following at about line 296 of sdcard_esdhc.c
ESDHC_DEVICE_STRUCT_PTR esdhc_device_ptr = sdcard_ptr->COM_DEVICE->DEV_PTR->DRIVER_INIT_PTR;
baudrate = esdhc_device_ptr->INIT->MAX_BAUD_RATE;
The second is in esdhc.c, in _esdhc_init - the line that read
_esdhc_set_baudrate_low(esdhc_ptr, esdhc_init_ptr->CLOCK_SPEED, ESDHC_INIT_BAUDRATE);
should have read
_esdhc_set_baudrate_low(esdhc_ptr, _bsp_get_clock_freq( esdhc_init_ptr->CLOCK_SPEED ), ESDHC_INIT_BAUDRATE);
the _bsp_get_clock_freq function is a function of my own creation that returns the actual baud rate for a given clock, which is useful if you want the esdhc to function properly if it can be initialized in different clock modes.
This isn't the most robust bit of code, and if it isn't required that function can be removed from everywhere it is used.
If this was helpful, please give me a +1