Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SDFileSystem.cpp
00001 /* mbed Microcontroller Library - SDFileSystem 00002 * Copyright (c) 2008-2009, sford 00003 * 00004 * Introduction 00005 * ------------ 00006 * SD and MMC cards support a number of interfaces, but common to them all 00007 * is one based on SPI. This is the one I'm implmenting because it means 00008 * it is much more portable even though not so performant, and we already 00009 * have the mbed SPI Interface! 00010 * 00011 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00012 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00013 * 00014 * SPI Startup 00015 * ----------- 00016 * The SD card powers up in SD mode. The SPI interface mode is selected by 00017 * asserting CS low and sending the reset command (CMD0). The card will 00018 * respond with a (R1) response. 00019 * 00020 * CMD8 is optionally sent to determine the voltage range supported, and 00021 * indirectly determine whether it is a version 1.x SD/non-SD card or 00022 * version 2.x. I'll just ignore this for now. 00023 * 00024 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00025 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00026 * 00027 * You should also indicate whether the host supports High Capicity cards, 00028 * and check whether the card is high capacity - i'll also ignore this 00029 * 00030 * SPI Protocol 00031 * ------------ 00032 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00033 * the host starting every bus transaction by asserting the CS signal low. The 00034 * card always responds to commands, data blocks and errors. 00035 * 00036 * The protocol supports a CRC, but by default it is off (except for the 00037 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00038 * I'll leave the CRC off I think! 00039 * 00040 * Standard capacity cards have variable data block sizes, whereas High 00041 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00042 * just always use the Standard Capacity cards with a block size of 512 bytes. 00043 * This is set with CMD16. 00044 * 00045 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00046 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00047 * the card gets a read command, it responds with a response token, and then 00048 * a data token or an error. 00049 * 00050 * SPI Command Format 00051 * ------------------ 00052 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00053 * 00054 * +---------------+------------+------------+-----------+----------+--------------+ 00055 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00056 * +---------------+------------+------------+-----------+----------+--------------+ 00057 * 00058 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00059 * 00060 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00061 * 00062 * SPI Response Format 00063 * ------------------- 00064 * The main response format (R1) is a status byte (normally zero). Key flags: 00065 * idle - 1 if the card is in an idle state/initialising 00066 * cmd - 1 if an illegal command code was detected 00067 * 00068 * +-------------------------------------------------+ 00069 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00070 * +-------------------------------------------------+ 00071 * 00072 * R1b is the same, except it is followed by a busy signal (zeros) until 00073 * the first non-zero byte when it is ready again. 00074 * 00075 * Data Response Token 00076 * ------------------- 00077 * Every data block written to the card is acknowledged by a byte 00078 * response token 00079 * 00080 * +----------------------+ 00081 * | xxx | 0 | status | 1 | 00082 * +----------------------+ 00083 * 010 - OK! 00084 * 101 - CRC Error 00085 * 110 - Write Error 00086 * 00087 * Single Block Read and Write 00088 * --------------------------- 00089 * 00090 * Block transfers have a byte header, followed by the data, followed 00091 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00092 * 00093 * +------+---------+---------+- - - -+---------+-----------+----------+ 00094 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00095 * +------+---------+---------+- - - -+---------+-----------+----------+ 00096 */ 00097 00098 #include "SDFileSystem.h" 00099 00100 #define SD_COMMAND_TIMEOUT 5000 00101 00102 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : 00103 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { 00104 _cs = 1; 00105 } 00106 00107 int SDFileSystem::disk_initialize() { 00108 00109 fprintf(stderr,"Initialising\n"); 00110 00111 00112 _spi.frequency(1000); // Set to 100kHz for initialisation 00113 00114 // Initialise the card by clocking it a bit (cs = 1) 00115 for(int i=0; i<16; i++) { 00116 _spi.write(0xFF); 00117 } 00118 00119 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00120 if(_cmd(0, 0) != 0x01) { 00121 fprintf(stderr, "Not in idle state\n"); 00122 return 1; 00123 } 00124 00125 // ACMD41 to give host capacity support (repeat until not busy) 00126 // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand 00127 for(int i=0;; i++) { 00128 _cmd(55, 0); 00129 int response = _cmd(41, 0); 00130 if(response == 0) { 00131 break; 00132 } else if(i > SD_COMMAND_TIMEOUT) { 00133 fprintf(stderr, "Timeout waiting for card\n"); 00134 return 1; 00135 } 00136 } 00137 00138 _sectors = _sd_sectors(); 00139 00140 // Set block length to 512 (CMD16) 00141 if(_cmd(16, 512) != 0) { 00142 fprintf(stderr, "Set block timeout\n"); 00143 return 1; 00144 } 00145 00146 _spi.frequency(1000000); // Set to 1MHz for data transfer 00147 return 0; 00148 } 00149 00150 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00151 // set write address for single block (CMD24) 00152 if(_cmd(24, block_number * 512) != 0) { 00153 return 1; 00154 } 00155 00156 // send the data block 00157 _write(buffer, 512); 00158 return 0; 00159 } 00160 00161 int SDFileSystem::disk_read(char *buffer, int block_number) { 00162 // set read address for single block (CMD17) 00163 if(_cmd(17, block_number * 512) != 0) { 00164 return 1; 00165 } 00166 00167 // receive the data 00168 _read(buffer, 512); 00169 return 0; 00170 } 00171 00172 int SDFileSystem::disk_status() { return 0; } 00173 int SDFileSystem::disk_sync() { return 0; } 00174 int SDFileSystem::disk_sectors() { return _sectors; } 00175 00176 // PRIVATE FUNCTIONS 00177 00178 int SDFileSystem::_cmd(int cmd, int arg) { 00179 _cs = 0; 00180 00181 // send a command 00182 _spi.write(0x40 | cmd); 00183 _spi.write(arg >> 24); 00184 _spi.write(arg >> 16); 00185 _spi.write(arg >> 8); 00186 _spi.write(arg >> 0); 00187 _spi.write(0x95); 00188 00189 // wait for the repsonse (response[7] == 0) 00190 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00191 int response = _spi.write(0xFF); 00192 if(!(response & 0x80)) { 00193 _cs = 1; 00194 return response; 00195 } 00196 } 00197 _cs = 1; 00198 return -1; // timeout 00199 } 00200 00201 int SDFileSystem::_read(char *buffer, int length) { 00202 _cs = 0; 00203 00204 // read until start byte (0xFF) 00205 while(_spi.write(0xFF) != 0xFE); 00206 00207 // read data 00208 for(int i=0; i<length; i++) { 00209 buffer[i] = _spi.write(0xFF); 00210 } 00211 _spi.write(0xFF); // checksum 00212 _spi.write(0xFF); 00213 00214 _cs = 1; 00215 return 0; 00216 } 00217 00218 int SDFileSystem::_write(const char *buffer, int length) { 00219 _cs = 0; 00220 00221 // indicate start of block 00222 _spi.write(0xFE); 00223 00224 // write the data 00225 for(int i=0; i<length; i++) { 00226 _spi.write(buffer[i]); 00227 } 00228 00229 // write the checksum 00230 _spi.write(0xFF); 00231 _spi.write(0xFF); 00232 00233 // check the repsonse token 00234 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00235 _cs = 1; 00236 return 1; 00237 } 00238 00239 // wait for write to finish 00240 while(_spi.write(0xFF) == 0); 00241 00242 _cs = 1; 00243 return 0; 00244 } 00245 00246 static int ext_bits(char *data, int msb, int lsb) { 00247 int bits = 0; 00248 int size = 1 + msb - lsb; 00249 for(int i=0; i<size; i++) { 00250 int position = lsb + i; 00251 int byte = 15 - (position >> 3); 00252 int bit = position & 0x7; 00253 int value = (data[byte] >> bit) & 1; 00254 bits |= value << i; 00255 } 00256 return bits; 00257 } 00258 00259 int SDFileSystem::_sd_sectors() { 00260 00261 // CMD9, Response R2 (R1 byte + 16-byte block read) 00262 if(_cmd(9, 0) != 0) { 00263 fprintf(stderr, "Didn't get a response from the disk\n"); 00264 return 0; 00265 } 00266 00267 char csd[16]; 00268 if(_read(csd, 16) != 0) { 00269 fprintf(stderr, "Couldn't read csd response from disk\n"); 00270 return 0; 00271 } 00272 00273 // csd_structure : csd[127:126] 00274 // c_size : csd[73:62] 00275 // c_size_mult : csd[49:47] 00276 // read_bl_len : csd[83:80] 00277 00278 int csd_structure = ext_bits(csd, 127, 126); 00279 int c_size = ext_bits(csd, 73, 62); 00280 int c_size_mult = ext_bits(csd, 49, 47); 00281 int read_bl_len = ext_bits(csd, 83, 80); 00282 00283 if(csd_structure != 0) { 00284 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures"); 00285 return 0; 00286 } 00287 00288 int blocks = (c_size + 1) * (1 << (c_size_mult + 2)); 00289 int block_size = 1 << read_bl_len; 00290 00291 if(block_size != 512) { 00292 fprintf(stderr, "This disk tastes funny! I only like 512-byte blocks"); 00293 return 0; 00294 } 00295 00296 return blocks; 00297 }
Generated on Thu Jul 14 2022 01:10:00 by
1.7.2