You are here: HomeMMC/SD/SDHC card library

MMC/SD/SDHC card library

This project provides a general purpose library which implements read and write support for MMC, SD and SDHC memory cards.

It includes

The circuit

The circuit which was mainly used during development consists of an Atmel AVR microcontroller with some passive components. It is quite simple and provides an easy test environment. The circuit which can be downloaded here has been improved with regard to operation stability.

I used different microcontrollers during development, the ATmega8 with 8kBytes of flash, and its pin-compatible alternative, the ATmega168 with 16kBytes flash. The first one is the one I started with, but when I implemented FAT16 write support, I ran out of flash space and switched to the ATmega168. For FAT32, an ATmega328 is required.

The circuit board is a self-made and self-soldered board consisting of a single copper layer and standard DIL components, except of the MMC/SD card connector.

The connector is soldered to the bottom side of the board. It has a simple eject button which, when a card is inserted, needs some space behind the connector itself. As an additional feature the connector has two electrical switches to detect wether a card is inserted and wether this card is write-protected.


The software

The software is written in C (ISO C99). It might not be the smallest or the fastest one, but I think it is quite flexible. See the benchmark page to get an idea of the possible data rates.

I implemented an example application providing a simple command prompt which is accessible via the UART at 9600 Baud. With commands similiar to the Unix shell you can browse different directories, read and write files, create new ones and delete them again. Not all commands are available in all software configurations.

The following table shows some typical code sizes in bytes, using the 20090330 release with a buffered read-write MMC/SD configuration, FAT16 and static memory allocation:

layer code size static RAM usage
MMC/SD 2410 518
Partition 456 17
FAT16 7928 188

The static RAM is mostly used for buffering memory card access, which improves performance and reduces implementation complexity.

Please note that the numbers above do not include the C library functions used, e.g. some string functions. These will raise the numbers somewhat if they are not already used in other program parts.

When opening a partition, filesystem, file or directory, a little amount of RAM is used, as listed in the following table. Depending on the library configuration, the memory is either allocated statically or dynamically.

descriptor dynamic/static RAM
partition 17
filesystem 26
file 53
directory 49

Adapting the software to your needs

The only hardware dependent part is the communication layer talking to the memory card. The other parts like partition table and FAT support are completely independent, you could use them even for managing Compact Flash cards or standard ATAPI hard disks.

By changing the MCU* variables in the Makefile, you can use other Atmel microcontrollers or different clock speeds. You might also want to change the configuration defines in the files fat_config.h, partition_config.h, sd_raw_config.h and sd-reader_config.h. For example, you could disable write support completely if you only need read support.

Bugs or comments?

If you have comments or found a bug in the software - there might be some of them - you may contact me per mail at feedback@roland-riegel.de.


Thanks go to Ulrich Radig, who explained on his homepage how to interface MMC cards to the Atmel microcontroller (http://www.ulrichradig.de/). I adapted his work for my circuit.

Copyright © 2006-2012 by Roland Riegel

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation (http://www.gnu.org/copyleft/gpl.html). At your option, you can alternatively redistribute and/or modify the following files under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation (http://www.gnu.org/copyleft/lgpl.html):


This section is continuously updated with the newest software revisions. The circuit can be downloaded here and the documentation is available online, but it is also included in the software package. For some frequently asked questions visit the FAQ page. For possible data rates, have a look at the benchmark page.

date comments files
  • Fix capacity readout from CSD register depending on format version.
  • Fix gcc strict-aliasing warnings (also somewhat enlarges code size).
software sources (301kB)
patch since last release (12kB)
  • Fix FAT access for cluster numbers beyond 2^15 (for FAT16) and 2^30 (for FAT32) (thanks to Darwin Engwer for testing).
  • Correctly return disk-full condition from fat_write_file() on certain conditions.
  • Use byteorder memory access functions for fat_fs_get_free().
  • Be more specific on the return value of fat_write_file().
software sources (293kB)
patch since last release (9kB)
  • Implement renaming a file or directory.
  • Rewrite byteorder handling to fix unaligned memory accesses on 32-bit and probably 16-bit architectures.
  • Make fat_create_file() not return failure if the file already exists.
  • Make the "cat" output respect the count of bytes actually read.
  • Document how to use fat_seek_file() for retrieving the file position.
software sources (293kB)
patch since last release (36kB)
  • Fix equal file names when reading two successive 8.3 directory entries.
  • Fix calculation of cluster positions beyond 4GB (32 bit integer overflow).
  • Fix endless looping of directory listing (occured with valid entry at end of last cluster).
software sources (285kB)
patch since last release (3kB)
  • Make LFN support configurable.
  • Ignore LFN directory entries without 8.3 name.
  • Ignore LFN directory entries which do not match the 8.3 name's checksum.
  • Implement delayed directory entry updates (see benchmarks) (disabled by default) (thanks to Adam Mayer).
  • Speedup search for free cluster.
  • Fix memory leak when using the "init" command (thanks to Tibor Vilhan).
  • Fix ATmega328P-specific pin mappings.
  • Add some of the picoPower MCU variants.
software sources (284kB)
patch since last release (135kB)
  • Make 8.3 basename and/or extension lowercase when told by Windows NT and later.
  • Add ATmega328 pin configuration.
  • Fix MMC/SD/SDHC distinction.
  • Fix raw block read/write buffering (thanks to Kurt Sterckx).
  • Fix fat size calculation for FAT16 when configured with FAT32.
  • Fix compilation for read-only configurations.
  • Fix card lock detection.
  • Make it easier to link with a C++ application (thanks to Jérôme Despatis).
software sources (273kB)
patch since last release (27kB)
schematics (211kB)
  • Support for SDHC cards (disabled by default).
  • Support for FAT32 (disabled by default).
software sources (272kB)
patch since last release (121kB)
  • New "init" command to allow reinitialization of memory card.
  • Fix searching through multi-cluster directories.
  • Fix reading directory entries spanning a cluster border (backport from mega-eth).
  • Do not abort the whole lfn entry when the file name is too long, just drop single characters (backport from mega-eth).
  • Change fat16_get_dir_entry_of_path() to ignore a slash at the end (backport from mega-eth).
  • Make listing a directory's content much faster (backport from mega-eth).
  • Shrink code size by centralizing cluster offset calculation (backport from mega-eth).
  • Some other small fixes and optimizations.
software sources (261kB)
patch since last release (53kB)
  • Dual-license major code modules under GPLv2 or LGPLv2.1.
software sources (261kB)
patch since last release (67kB)
  • Fix reading beyond cached block (by Benjamin Meier).
  • Implement support for reading and writing file modification dates/times.
    (Thanks to Torsten Seeboth for testing.)
software sources (243kB)
patch since last release (11kB)
  • Avoid LFN directory entries for the "." and ".." directory references.
    This prevented Windows from deleting directories.
  • Handle special case where the 8.3 filename begins with 0xe5.
  • Fix return value of fat16_delete_file() when deleting empty files.
  • Fix fat16_clear_cluster() which was zeroing only 16 of every 32 bytes.
software sources (240kB)
patch since last release (6kB)
  • Fix directory creation.
    • Correctly create "." and ".." directory entries (8.3 <-> lfn versions).
    • Correctly clear cluster containing the directory entries for new directory.
software sources (239kB)
patch since last release (9kB)
  • Implement creation and deletion of directories.
  • Clear the directory entries of new directory clusters.
  • Prevent linkage against printf().
  • Make the use of malloc()/free() optional.
software sources (241kB)
patch since last release (50kB)
  • Fix shortening files.
  • Fix free disk space calculation.
software sources (230kB)
patch since last release (7kB)
  • Improve sleep handling.
  • Display extended card information on boot and when executing the "disk" shell command.
  • Correctly determine FAT type by cluster count.
  • Fix cluster allocation beyond card capacity.
software sources (230kB)
patch since last release (19kB)
  • Provide FAT16 capacity and usage information.
  • Implement the backspace key in the mini shell.
  • Enter idle mode when waiting for uart activity.
  • Make the Card Select pin MCU dependent as well.
  • Add mini shell commands to documentation.
software sources (223kB)
patch since last release (16kB)
  • Thanks go to Torsten Seeboth for his ongoing efforts to test changes, fix regressions and give suggestions. Many of the changes below were initiated by him.
  • Much more reliable card initialization.
  • Highly improved performance:
    • optional write buffering
    • better cluster handling
    • remove unneeded SPI access when reading from buffered block
    • use highest SPI frequency after card initialization
  • Add superfloppy support.
  • Better checks when opening a FAT16 filesystem.
  • Provide SPI pin mappings for commonly used ATmegas.
  • Fix resizing files, hangs could occur.
  • Fix overflow when creating files with names longer than 31 characters.
  • Fix numerous other small things.
software sources (220kB)
patch since last release (41kB)
  • Fix speed regression.
software sources (218kB)
patch since last release (8kB)
  • First release.
software sources (217kB)
schematics (264kB)

Last modification: 06-12-2012 06:30pm