4.2.1 Writing Raw Data to an SD Card via SPI
One of the example projects accompanying this application note utilizes an SD card for data storage without a file system. This means data is written to and read from the SD card in raw format. The interface used is SPI, and the process to do this is detailed here by ELM-Chan. The driver files included in the example project enables multiple-sector read and write, allowing raw data to be stored efficiently. This process minimizes code size and card busy time, but does not allow portability as there is no file system used; a PC can therefore not easily be used to read written raw data. See Get Source Code from Atmel | START for more information on how to download the example project.
SD Card Interfacing with SPI
Control of multimedia and SD cards without a native host interface is possible by using the SPI mode of the card. An AVR SPI peripheral can be used for this with ease. The communication protocol is relatively simple, using SPI mode 0. The pin setup for the SD card can be seen in the figure below. The MISO signal should be pulled high with a pull-up resistor.
SPI Command and Response
Any operation begins with a command sequence, as depicted in the figure below. A command frame is sent to the SD card and it replies with a response indicating the current status within command response time (NCR), which is zero to eight bytes for SD cards. The flags contained within the response byte can be seen in Figure 4-6, and additionally to this an R3 or R7 response is defined as an R1 response with trailing 32-bit data. For most commands, a response of 0 is considered successful. A table of the commands used for storing raw data on an SD card can be seen in Table 4-1. More information on commands can be found in the specification sheets from MMCA and SDCA.
CMD index | Abbreviation | Description |
---|---|---|
CMD0 | GO_IDLE | Software reset |
CMD1 | INIT | Initiate initialization process |
ACMD41(*) | APP_INIT | For SDC only. Initiate initialization process. |
CMD8 | CHECK_V | For SDC v2 only. Check voltage range. |
CMD12 | STOP_READ | Stop reading data |
CMD16 | SET_BLOCKLEN | Change R/W block size |
CMD18 | READ_MULTI_BLOCK | Read multiple blocks |
CMD25 | WRITE_MULTI_BLOCK | Write multiple blocks |
CMD55 | ACMD_LEADING | Leading command of ACMD<n> command |
CMD58 | READ_OCR | Read Operation Conditions Register |
Initialization
The initialization process for operating an SD card in SPI mode is depicted in the figure below. This function should be the first to be called when using the driver files accompanying this application note. When this process fails continually, the SD card may need to be re-inserted from the card slot on the extension kit.
Data Access
Once the SD card is correctly initialized, data transactions are possible. The format of data packets and relevant indicator bytes can be seen in the figure below. A data packet consists of a start token (Data Token), the data itself (Data Block), and a two-byte CRC value. This packet structure applies for both reading and writing; however, the Data Token will vary depending on the operation in progress. The Error Token will replace the Data Token during a Read in the event of an error. The Data Response byte contains status during a Write.
Different commands are used when reading or writing a single sector versus multiple sectors. The included driver files use multiple sector read and write, implemented in a set of Start, Continue, and Stop functions each for read and write. The operation can be split into multiple function calls with arbitrary pauses between calls because the card is only active when there is an SPI clock. For example, these arbitrary pauses can be used to collect more data. The figure below indicates the read process in its entirety. When using the included driver files to implement multiple sector read, it is necessary to call the function to start a read process, followed by a call to the continue Read function for each data packet to be read, and then the Stop read function, which tells the card to finalize the read process. The function to start a read includes sending a CMD18, receiving the command response and waiting for the Data Token to indicate the beginning of the first data packet. If this returns successfully, it is possible to receive data packets using the Continue read function. This receives data and keeps track of when the Data Block is ending and the CRC should be received, followed by waiting for the Data Token of the following packet. Data can be received continually by repeatedly calling the Continue read function. When all desired data has been read, the read process should be finalized with a call to the read stop function, which sends a CMD12 to the card, receives the command response, and waits until the card is no longer busy.
The multiple sector write process is depicted in the figure below. When using the driver files, the Start write function should be called first to begin a write process. This sends a CMD25 to the card, receives the command response, and sends one dummy byte, which is required before sending the first Data Packet. The Write continue function can then be used to send data. This function also keeps track of when the Data Block should be followed by two CRC bytes, and then verifies the Data Response and waits for the end of the card busy time. Data can be continually sent by repeatedly calling the write continue function. When all necessary data has been written to the card, the write process should be finalized using the Stop write function. This sends a Stop Token (Data Token for CMD25) to indicate to the card that all the data has been sent. The function will return after the final card busy time has ended.