| Home Feature Space Science Atheism Paranonsense Technology Offsite About Search | ||
| Home : Technology : MMC to Serial Adapter Protocol |
|
This document specifies a protocol for communication with the MMCSerial adapter, which is designed to interface flash-based multimedia cards (MMCs) with any host device with an RS232 connection.
Commands and data are transferred between the host and the adapter using RS232 serial communications at 115,200 baud, one start bit, 8 data bits, one stop bit, no parity, with RTS/CTS flow control.
Note that the limited RAM space in the microcontroller in the adapter means that response to the CTS signal must be fast. In order to accommodate UARTs with built-in FIFOs, it is guaranteed that there will be sufficient space in the buffer to receive 16 more bytes after the CTS signal is de-asserted. Care should be taken to ensure that no more than 16 bytes are sent in this case.
The host initiates all transfers. Communication is half-duplex, in that data flows in one direction at a time.
On initial power up, the adapter goes through a card identification sequence, and then goes into a sleep mode to conserve power. It can be awakened by asserting the RTS line (see the Wake command).
The adapter uses a number of common status bytes to communicate certain conditions back to the host. These are:
| 0x10 | OK | Command completed successfully | |
| 0x11 | Fail | Command failed | |
| 0x12 | Unk | Command not recognised | |
| 0x13 | Awake | Waking from power-down | |
| 0x14 | Wait | Command in progress | |
| 0x15 | Data | Data follows |
Commands themselves are commonly finished with a 0x20 (space), which is used to check that the command byte has been read correctly and to ensure synchronisation.
Wake
| Command: | Assert RTS |
| Response: | CTS asserted |
If the adapter is in sleep mode, a +12v (asserted) level on RTS will wake it up. It will respond when awake by asserting CTS in the same way. This is the standard RS232 RTS/CTS flow control handshake.
If the adapter is present and asleep, CTS should be asserted within 100ms. If it is not, then the host should retry. If, after several retries, no response is received, the host should assume that no adapter is present.
In sleep mode, any byte sent to the adapter using the RTS/CTS protocol may wake it from its sleep, but it is recommended that a Nop command is used, since it will not be critical if this command is received incorrectly. An [OK] response should be received within 1ms of receiving the Nop command. If not, then the host may retry until it either receives an [OK] response or exhausts its retry count.
It is recommended that this sequence is followed both on initial power-up, and on waking from a previous "sleep" command.
Nop
| Command: | 0x00 |
| Response: | [OK] |
No operation.
This command does nothing, but will return an [OK] response. This is useful to establish synchronisation with the adapter - a sequence of Nop commands can be sent until an [OK] response is seen.
Sleep (S)
| Command: | 0x53 0x20 |
| Response: | [Wait][OK] [Wait][Fail] |
A [Wait] is sent immediately. The adapter waits for approximately 100ms for RTS to be de-asserted. If this happens in time, an [OK] response is sent, the adapter waits another 70ms, and then places itself in power-down mode. It can be awakened by asserting RTS again - see the Wake command description.
If RTS is not de-asserted within 100ms, the sleep request is cancelled, a [Fail] response is sent, and operation continues normally.
During sleep mode, the select line on the multimedia card is de-asserted, all LEDs are turned off, the RS232 transmitter is powered down, and the microcontroller itself put into power-down mode. This should reduce the power required in the adapter to a few microamps.
Identify Adapter (I)
| Command: | 0x49 0x20 |
| Response: | [Data] 0x50 0x46 HR SR[OK] |
Identifies the currently connected adapter. A [Data] identifier is returned. The first two bytes are a magic header and indicate the MMCSerial hardware ("PF"). Following this are two bytes indicating the hardware and software revision of the adapter. These are ASCII characters starting from '0'. This is followed with an [OK].
Identify Card (C)
| Command: | 0x43 cc 0x20 |
| Response: | [Wait][Data] …16 bytes… [OK] [Wait][Fail] |
Identifies the currently connected card. Immediately sends back a [Wait]. If bit 0 of cc is 0, returns the card's specific data register contents (CSD), else if 1, returns the card's identity data (CID).
If a card is successfully identified, a [Data] identifier follows, followed by the contents of the specific data register requested, finally finishing with an [OK]. If a card is not attached, or its status cannot be determined, a [Fail] is sent instead.
The CID contents include the serial number of the card. It is thus recommended that this command is issued before any read or write operations, in order to check that the card is still the same one as last time.
The CSD contents include the format and size of the card, along with flags indicating the presence or absence of capabilities such as partial-sector reads and writes.
Full details of the format of the CID and CSD register contents can be found in sections 4.5.3 and 4.5.4 of the MultiMediaCard Product Manual.
Read (R)
| Command: | 0x52 N3 N2 N1 N0 A3 A2 A1 A0 0x20 |
| Response: | [Wait][Data] D0 D1 D2 … Dn C1 C2 [OK] [Wait][Fail] |
Reads data from the card. The command data consists of the number of bytes to read, high byte first (N3...N0), followed by the address to read from, high byte first (A3…A0). A final 0x20 command terminator provides for basic checking and synching. A [Wait] response is sent immediately.
The address range indicated by A and N must not cross a sector boundary (i.e. offset + length <= sector size). The address must be valid. If any of these conditions is not met, a [Fail] is sent.
If the data is read successfully, then a [Data] response is sent, followed by the actual data bytes, in order of increasing address. These are raw data, and may contain any value. After the final data byte are the two CRC checksum bytes (as read from the card - derived using CRC16 on the data bytes). Finally, an [OK] byte indicates the end of the sequence.
Write (W)
| Command: | 0x57 N3 N2 N1 N0 A3 A2 A1 A0 D0 D1 D2 … Dn C1 C2 0x20 |
| Response: | [Wait][OK] [Wait][Fail] [Fail] |
Writes data to the card. The command data consists of the number of bytes to write, high byte first (N3...N0), followed by the address to write to, high byte first (A3…A0). The number of bytes written must be the same as the sector size, and the address indicate the start of a sector. If not, a [Fail] is sent immediately.
Following this are the actual data bytes, in order of increasing address. These are raw data, and may contain any value. After the final data byte are two checksum bytes derived using CRC16 on the data bytes. At present, these CRC bytes are ignored.
A final 0x20 command terminator provides for basic checking and synching. A [Wait] response is sent immediately on receipt of the 0x20.
If the data are written to the card correctly, then [OK] is returned, else [Fail].
Verification of each byte written can be done by reading the data back from the flash using the Read command, and checking that it is as expected.
Erase (E)
| Command: | 0x45 SG N3 N2 N1 N0 A3 A2 A1 A0 0x20 |
| Response: | [Wait][OK] [Wait][Fail] |
Erases sectors or groups on the card. The command data consists of a Sector/Group flag (bit 0 of which is 0 for erasing sectors, or 1 for erasing groups), the start and end addresses of the block to be erased in four bytes each, high byte first (A3…A0, B3…B0), then a command terminator, 0x20. A [Wait] response is sent immediately.
If the sectors or groups are in a valid range, the sectors are erased and an [OK] response is sent, otherwise a [Fail] response is sent. If a [Fail] is sent, there is no guarantee that the data on the card have not been erased.
Verification of the erase can be done by reading the data back from the flash using the Read command, and checking that it is in the erased state (all bytes set to 0x00).
Note that a separate erase is not strictly required, since a write to a non-empty sector will first perform an erase on that sector. However, erasing whole groups of sectors simultaneously can speed up the write process as the sectors will now be empty. Erasing multiple sectors takes the same amount of time as erasing a single sector.
Status (?)
| Command: | 0x3F 0x20 |
| Response: | [Data] S1 S2 [OK] |
Returns current card status. This is useful for retrieving additional information after a [Fail]. The meanings of the two bytes S1 and S2 are described in section 6.2.2.3 in the MultiMediaCard Product Manual.
Debug (!)
| Command: | 0x21 MM 0x20 |
| Response: | [OK] |
Enables or disables debug mode according to the low bit of MM. If debug mode is disabled all data are presented as raw bytes, both to and from the card.
In debug mode, data are presented in hex, and command prompts and feedback are also provided. This is intended to facilitate debugging via a simple dumb ASCII terminal.
Debug mode is disabled initially, and can be enabled from a terminal program by typing "!1 " without the quotes (the final space is important). Returning to raw mode can be accomplished by typing "210020", again without the quotes, at the command prompt.
Here is a session log of a typical communication (debug on, status, debug off again):
!1 10
-3F>20>15 00 00 10
-21>00>20>
Unrecognised Command
Command:
Response:
When expecting a command, any byte other than those listed above will result in an [Unk] return code. The same code is used in the case where a command is malformed - for example, a space was not used to terminate the command.