Secure Digital SD Card Source Code Driver Project

a) General

MMC (MultiMediaCard) and SD (Secure Digital) memory cards provide embedded devices with a very inexpensive and convenient way of storing anything from very small to very large amounts of data. Using a MMC or SD card in your embedded device with the FAT filing system allows you to very easily read and write multiple files and exchange this data with other embedded devices and PC’s. Apart from the convenience of such a powerful and flexible filing system, being able to read and write PC compatible files can add huge benefits to your product. However writing a MMC/SD FAT filing system driver is a complex and daunting task. This driver removes that complexity for you and allows you to read and write files with ease using either card type and the various mini versions of the MMC or SD card.

This driver has been specifically designed from the ground up for embedded applications using 8, 16 or 32 bit processors or microcontrollers. Whilst the code has been kept as small as possible, it hasn’t been reduced to such a point that the driver becomes difficult to use. Instead great importance has been put on being able to use as many of the standard ANSI-C file system functions as possible and with as many of each of their features as possible.

The MMC / SD card FAT16 / FAT32 driver code has been designed and tested using ANSI compliant C compliers. Using the driver with other ANSI compliant C compliers and with other processors / microcontrollers should not present significant problems, but you should ensure that you have sufficient programming expertise to carry out any modifications that may be required to the source code. Embedded-code.com source code is written to be very easy to understand by programmers of all levels. The code is very highly commented with no lazy programming techniques. All function, variable and constant names are fully descriptive to help you modify and expand the code with ease.

The MMC / SD card FAT16 / FAT32 driver and associated files are provided under a licence agreement. Please see www.embedded-code.com/licence.php for full details.

The remainder of this manual provides a wealth of technical information about the driver as well as useful guides to get you going. We welcome any feedback on this manual and the driver.

As with any development project you should ensure that backup copies are made of any files stored on a MMC or SD card that is used with the driver until you have completed your development and thoroughly tested the operation of the driver in your application.

b) Features

Designed for both FAT16 and FAT32 formatted SD, SDHC (high capacity), MMC and MMCplus (high capacity) cards with a 4 pin serial interface to a microcontroller or processor.

Optimised for embedded designs. Only a single 512 data buffer is required for all operations. (It is not possible to write to MMC or SD cards without a 512 byte buffer as sectors have to be read to local memory, modified and written back as a whole).

Intelligent use of the local ram sector buffer. Read and writes of sector data only occur when necessary, avoiding unnecessary and slow repeated read or write operations to the MMC or SD card.

Optimised file delete function for fast deleting of large files. Instead of altering each FAT table entry one at a time, a complete sector of FAT table entries are altered in one operation before writing back to the card, resulting in a large speed improvement.

Provides the following standard ANSI-C functions:

fopen, fseek, ftell, fgetpos, fsetpos, ffs_rewind, fputc, putc, fgetc, getc, fputs, fgets, fwrite, fread, fflush, fclose, remove, rename, clearer, feof and ferror

Standard DOS ‘*’ and ‘?’ wildcard characters may be used in file operations.

Multiple files may be opened at the same time.

Optional real time clock support for applications that include time keeping. File creation, last modified and last accessed time and date values are automatically stored.

c) Driver Technical Notes

The data area of MMC and SD memory cards is accessed through the use of a 512 byte sector buffer. All data read and write operations work through the reading and writing a 512 byte block of sector data. Therefore to modify a single byte, a complete sector of data must be read to local ram, modified and then the complete sector written back to the card.

Other flash memory devices, such as flash memory IC’s also typically use the same system whereby a complete block of data must be erased to reset all of the bytes in that block back to 0xFF ready for writing again, as many flash memory technologies work on the principal of turning individual bits from high bits to low, not low to high.

This 512 byte buffer is an issue when it comes to designing a driver to provide fast read and write access. The reason is that as a programmer you want to be able to access individual bytes of a file without worrying about sectors, but you don’t want the driver continuously reading and writing 512 bytes of data every time you modify a byte, resulting in painfully slow access. This driver overcomes these problems by only reading and writing when an operation needs to access a byte that is contained in a different sector on the card. Whilst this requires some instances of quite complex driver code, this complexity is worthwhile due to the massive speed improvements this approach provides.

If you want to gain an understanding of exactly how the driver works then this manual contains a thorough description of the layout of FAT based MMC / SD cards. Once you understand this each of the driver functions are relatively easy to understand. However you don’t need to do this and if you just want to read and write FAT16 or FAT32 MMC or SD cards then you can skip these in-depth parts of the manual.

Finally you should also note that different MMC / SD memory cards can take different amounts of time to complete internal operations, such as preparing to read or writing a new sector of data. If your application is very time sensitive you may need to consider using some processor RAM memory to act as some sort of FIFO buffer for read and write operations. For example say you are designing a MP3 player that needs to send MP3 file data to a MP3 decoder IC within a certain response time when it requests it. You may find that a slow MMC or SD card might not be able to provide the next byte of data fast enough when it moves from one sector to the next, resulting in your MP3 decoder IC temporarily running out of data. By using some form of circular FIFO RAM buffer in your application you could read data from the MMC or SD card as one process, always trying to fill the data buffer so its full, and read data from the buffer to send to the MP3 decoder IC when it requests it as a separate interrupt based process.