Normally pre-formatted to the FAT12 or FAT16 standard (FAT32 for cards 2GB and above)

(Edit) And now pretty much obsolete, replaced by SD Cards.

MMC cards contain a microcontroller which allows the card to present itself to
whatever its connected to much like a hard drive. IE: the host just
sees lots of addressable sectors it can read/write to.

Of the access protocols available, the simplest and most accessible for hobbiests
is "SPI mode" and all the following info is specific to this mode. With SPI mode
selected, communication to the card is done serially via 4 pins; "Clock", "Data in",
"Data out" and "Card Select". Data direction is fixed and the host always supplies
the clock pulses. SPI mode 0 is generally employed - Data bits are latched into the
card on the rising edge of the clock, and out on the falling edge. Data is always transmitted in
byte-sized units (MSB first) and the clock can be anything up to 20Mhz. Note: The "Data In" line must be
kept high during read transfers and a card's CS line should be held low during all
operations aimed at it.

A protocol of command and data packets is used when reading and writing
the card. A command is a set of 6 bytes, in the following format:

$0 $1 $2 $3 $4 $5
-----------------
xx yy yy yy yy zz

The command code byte always has bits 7:6 set to "01" and bits 5:0 hold the command
number. The argument is a 32 bit value (contents depend on the command). The CRC byte
always has bit 0 set to zero, bits 7:1 hold the command packet's CRC checksum. However,
this is disabled in SPI mode unless you specifically switch it back on, so can normally be set
to 00h (remember to raise the Data In line afterwards if a read follows).

Following the sending of a command, there is a delay called the Card Response
time (NCR) which can take 1 to 8 bytes depending on the command (during this time
the D-out line will be high so FFh will be received by the host). The commands shown below
have a one byte gap - ideally you should read bytes until you get a valid card response.
When sent, this card response is normally a single byte (called "R1") with its MSB at 0.
The rest of the bits have the following meaning when set to 1:

Upon power up, MMC cards need to be instructed to change to SPI from
their default operating mode. The sequence to do so is as follows:

After power on, wait at least a millisecond and set CS and D-in High.
Send 80 clock pulses.
Set CS low and send a "CMD0" (40h,00h,00h,00h,00h,95h*) to reset the card
(The card checks the CS line when CMD0 is received and goes into SPI mode if CS is low.)
When CMD0 is accepted, the card enters idle state and so responds with "01h"
Repeatedly send CMD1 (41h,00h,00h,00h,00h,00h) and check the response..
When response is 00h, the card is ready (this can take hundreds of milliseconds)

(* Note the command CRC value is not 00h here as the card wont be in SPI mode yet
and actually requires a correct CRC code. "95h" is the "hardwired" value,
valid only for CMD0.)

Getting card ID info

Once the card is initialized, the first thing you might want to do is send it
commands which tell it to identify itself: CMD9 and CMD10 return data packets
of 16 bytes each which contain information such as size of card, maker's
name in ascii etc. Some key locations in these data packets are given below.
Full details can be found in the MMC spec sheet (see links).

When a command has an associated data packet (like CMD9 and CMD10), a data token
will follow the command response, this is then followed by the actual data
bytes and finally a 16 bit CRC checksum is sent. The data token for CMD9 and
CMD10 (as well as CMD17 and CMD24) is 0FEh.

The command to read single sector is CMD17. The argument is the BYTE address of
the sector you wish to read (so set it at sector number * 512). The CRC is 00h as usual.

Example: Reading from sector 1234h

Send: 51h,00h,24h,68h,00h,00h - CMD17, address, null CRC
Read: xx - NCR Time
Read: xx - Command Response - should be 00h
Read: until FEh is received - Wait for Data token (see note 1)
Read: yy * 512 - Get 512 bytes from sector
Read: zz - Read CRC lo byte
Read: zz - Read CRC hi byte
Note 1: In a simple implementation, you can simply wait for the
data response "FEh" in a loop with a time-out and report a
general error if it isn't received. What actually happens though
is this: If the card is unable to send the requested data, an
error token will be returned instead of the data token. This
is a single byte with the three MSBs set to zero. Other bits
have the following meaning when set:
Error Token Bit Meaning:
--------------------------
4 - Card Locked
3 - CC failed
2 - Card ECC failed
1 - CC error - card controller failure
0 - Error

Writing a sector:

The command to write a single sector is CMD24. The argument is the same as
for reading a sector and the CRC is 00h as normal. Following the command response,
a write delay byte is required (send an FFh), then the data token (FEh) should be sent.
Next, the data to fill the sector can be sent with a 2 byte CRC following on (ie:
send two zeros). After the last CRC byte is received the card will respond with a data
response byte with bits in the format "xxx0sss1" Here "xxx" aren't used, bit
4 is zero, bits 3:1 (sss) hold the status code and bit 0 is a one.

After the data response is received, the card will start programming the data
it buffered into the card. You must now wait for the busy signal to
clear (keep reading bytes and wait for a non-zero byte to be returned) before
carrying out further operations. Finally, its advisable to check the card's
status bytes to check the sector was actually programmed correctly.

You dont have to read and write just single sectors, there are commands to
send groups of them - of course this complicates things a little. More
information can be found in the links below.

Whilst experimenting I made a simple PC parallel port interface and some DOS
software to perform the above 3 commands. The interface drops the 5 volt logic
voltages from the parallel port down to something suitable for a 3.3 volt device,
and uses a 74HC245 IC as a buffer. Incidentally,
an edge connector from a old-type PC floppy drive lead makes a surprisingly
decent connector for experimenting with MMC cards, see this page for details
(note however, such a connector will not offer hot-pluggable connectivity as
all the contacts are the same length.) As it stands, the program is only suitable for testing/experimentation due to its slow
speed and the way it (unnecessarily) power cycles/initializes the card every
time it is run. Also, only the first 32MB of any card can be accessed (I only had a 32MB card
for testing purposes..) My MMC interface/program can be downloaded here. The zip file also contains
the x86 assembly source code and the schematic for the interface. [Edit: Updated 7-10-07 to use
my standard SPI interface].

A note about SD cards: They are functionally very similar to MMC, but need different
command codes in places - see links below for more info.

[EDIT] I recently made an MMC / SD card adapter for the V5Z80P, source code (Z80) for that
is here