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 00005 // VERY DRAFT CODE! Needs serious rework/refactoring 00006 00007 /* Introduction 00008 * ------------ 00009 * SD and MMC cards support a number of interfaces, but common to them all 00010 * is one based on SPI. This is the one I'm implmenting because it means 00011 * it is much more portable even though not so performant, and we already 00012 * have the mbed SPI Interface! 00013 * 00014 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00015 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00016 * 00017 * SPI Startup 00018 * ----------- 00019 * The SD card powers up in SD mode. The SPI interface mode is selected by 00020 * asserting CS low and sending the reset command (CMD0). The card will 00021 * respond with a (R1) response. 00022 * 00023 * CMD8 is optionally sent to determine the voltage range supported, and 00024 * indirectly determine whether it is a version 1.x SD/non-SD card or 00025 * version 2.x. I'll just ignore this for now. 00026 * 00027 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00028 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00029 * 00030 * You should also indicate whether the host supports High Capicity cards, 00031 * and check whether the card is high capacity - i'll also ignore this 00032 * 00033 * SPI Protocol 00034 * ------------ 00035 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00036 * the host starting every bus transaction by asserting the CS signal low. The 00037 * card always responds to commands, data blocks and errors. 00038 * 00039 * The protocol supports a CRC, but by default it is off (except for the 00040 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00041 * I'll leave the CRC off I think! 00042 * 00043 * Standard capacity cards have variable data block sizes, whereas High 00044 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00045 * just always use the Standard Capacity cards with a block size of 512 bytes. 00046 * This is set with CMD16. 00047 * 00048 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00049 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00050 * the card gets a read command, it responds with a response token, and then 00051 * a data token or an error. 00052 * 00053 * SPI Command Format 00054 * ------------------ 00055 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00056 * 00057 * +---------------+------------+------------+-----------+----------+--------------+ 00058 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00059 * +---------------+------------+------------+-----------+----------+--------------+ 00060 * 00061 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00062 * 00063 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00064 * 00065 * SPI Response Format 00066 * ------------------- 00067 * The main response format (R1) is a status byte (normally zero). Key flags: 00068 * idle - 1 if the card is in an idle state/initialising 00069 * cmd - 1 if an illegal command code was detected 00070 * 00071 * +-------------------------------------------------+ 00072 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00073 * +-------------------------------------------------+ 00074 * 00075 * R1b is the same, except it is followed by a busy signal (zeros) until 00076 * the first non-zero byte when it is ready again. 00077 * 00078 * Data Response Token 00079 * ------------------- 00080 * Every data block written to the card is acknowledged by a byte 00081 * response token 00082 * 00083 * +----------------------+ 00084 * | xxx | 0 | status | 1 | 00085 * +----------------------+ 00086 * 010 - OK! 00087 * 101 - CRC Error 00088 * 110 - Write Error 00089 * 00090 * Single Block Read and Write 00091 * --------------------------- 00092 * 00093 * Block transfers have a byte header, followed by the data, followed 00094 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00095 * 00096 * +------+---------+---------+- - - -+---------+-----------+----------+ 00097 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00098 * +------+---------+---------+- - - -+---------+-----------+----------+ 00099 */ 00100 00101 #include "SDFileSystem.h" 00102 00103 #define SD_COMMAND_TIMEOUT 5000 00104 00105 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : 00106 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { 00107 _cs = 1; 00108 } 00109 00110 #define R1_IDLE_STATE (1 << 0) 00111 #define R1_ERASE_RESET (1 << 1) 00112 #define R1_ILLEGAL_COMMAND (1 << 2) 00113 #define R1_COM_CRC_ERROR (1 << 3) 00114 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00115 #define R1_ADDRESS_ERROR (1 << 5) 00116 #define R1_PARAMETER_ERROR (1 << 6) 00117 00118 // Types 00119 // - v1.x Standard Capacity 00120 // - v2.x Standard Capacity 00121 // - v2.x High Capacity 00122 // - Not recognised as an SD Card 00123 00124 #define SDCARD_FAIL 0 00125 #define SDCARD_V1 1 00126 #define SDCARD_V2 2 00127 #define SDCARD_V2HC 3 00128 00129 int SDFileSystem::initialise_card() { 00130 // Set to 100kHz for initialisation, and clock card with cs = 1 00131 _spi.frequency(400000); 00132 _cs = 1; 00133 for(int i=0; i<16; i++) { 00134 _spi.write(0xFF); 00135 } 00136 00137 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00138 _cmd(0, 0); 00139 if(_cmd(0, 0) != R1_IDLE_STATE) { 00140 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); 00141 return SDCARD_FAIL; 00142 } 00143 00144 // send CMD8 to determine whther it is ver 2.x 00145 int r = _cmd8(); 00146 if(r == R1_IDLE_STATE) { 00147 return initialise_card_v2(); 00148 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00149 return initialise_card_v1(); 00150 } else { 00151 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); 00152 return SDCARD_FAIL; 00153 } 00154 } 00155 00156 int SDFileSystem::initialise_card_v1() { 00157 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00158 _cmd(55, 0); 00159 if(_cmd(41, 0) == 0) { 00160 return SDCARD_V1; 00161 } 00162 } 00163 00164 fprintf(stderr, "Timeout waiting for v1.x card\n"); 00165 return SDCARD_FAIL; 00166 } 00167 00168 int SDFileSystem::initialise_card_v2() { 00169 00170 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00171 _cmd(55, 0); 00172 if(_cmd(41, 0) == 0) { 00173 _cmd58(); 00174 return SDCARD_V2; 00175 } 00176 } 00177 00178 fprintf(stderr, "Timeout waiting for v2.x card\n"); 00179 return SDCARD_FAIL; 00180 } 00181 00182 int SDFileSystem::disk_initialize() { 00183 00184 int i = initialise_card(); 00185 // printf("init card = %d\n", i); 00186 // printf("OK\n"); 00187 00188 _sectors = _sd_sectors(); 00189 00190 // Set block length to 512 (CMD16) 00191 if(_cmd(16, 512) != 0) { 00192 fprintf(stderr, "Set 512-byte block timed out\n"); 00193 return 1; 00194 } 00195 00196 _spi.frequency(1000000); // Set to 1MHz for data transfer 00197 return 0; 00198 } 00199 00200 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00201 // set write address for single block (CMD24) 00202 if(_cmd(24, block_number * 512) != 0) { 00203 return 1; 00204 } 00205 00206 // send the data block 00207 _write(buffer, 512); 00208 return 0; 00209 } 00210 00211 int SDFileSystem::disk_read(char *buffer, int block_number) { 00212 // set read address for single block (CMD17) 00213 if(_cmd(17, block_number * 512) != 0) { 00214 return 1; 00215 } 00216 00217 // receive the data 00218 _read(buffer, 512); 00219 return 0; 00220 } 00221 00222 int SDFileSystem::disk_status() { return 0; } 00223 int SDFileSystem::disk_sync() { return 0; } 00224 int SDFileSystem::disk_sectors() { return _sectors; } 00225 00226 // PRIVATE FUNCTIONS 00227 00228 int SDFileSystem::_cmd(int cmd, int arg) { 00229 _cs = 0; 00230 00231 // send a command 00232 _spi.write(0x40 | cmd); 00233 _spi.write(arg >> 24); 00234 _spi.write(arg >> 16); 00235 _spi.write(arg >> 8); 00236 _spi.write(arg >> 0); 00237 _spi.write(0x95); 00238 00239 // wait for the repsonse (response[7] == 0) 00240 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00241 int response = _spi.write(0xFF); 00242 if(!(response & 0x80)) { 00243 _cs = 1; 00244 _spi.write(0xFF); 00245 return response; 00246 } 00247 } 00248 _cs = 1; 00249 _spi.write(0xFF); 00250 return -1; // timeout 00251 } 00252 int SDFileSystem::_cmdx(int cmd, int arg) { 00253 _cs = 0; 00254 00255 // send a command 00256 _spi.write(0x40 | cmd); 00257 _spi.write(arg >> 24); 00258 _spi.write(arg >> 16); 00259 _spi.write(arg >> 8); 00260 _spi.write(arg >> 0); 00261 _spi.write(0x95); 00262 00263 // wait for the repsonse (response[7] == 0) 00264 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00265 int response = _spi.write(0xFF); 00266 if(!(response & 0x80)) { 00267 return response; 00268 } 00269 } 00270 _cs = 1; 00271 _spi.write(0xFF); 00272 return -1; // timeout 00273 } 00274 00275 00276 int SDFileSystem::_cmd58() { 00277 _cs = 0; 00278 int arg = 0; 00279 00280 // send a command 00281 _spi.write(0x40 | 58); 00282 _spi.write(arg >> 24); 00283 _spi.write(arg >> 16); 00284 _spi.write(arg >> 8); 00285 _spi.write(arg >> 0); 00286 _spi.write(0x95); 00287 00288 // wait for the repsonse (response[7] == 0) 00289 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00290 int response = _spi.write(0xFF); 00291 if(!(response & 0x80)) { 00292 int ocr = _spi.write(0xFF) << 24; 00293 ocr |= _spi.write(0xFF) << 16; 00294 ocr |= _spi.write(0xFF) << 8; 00295 ocr |= _spi.write(0xFF) << 0; 00296 // printf("OCR = 0x%08X\n", ocr); 00297 _cs = 1; 00298 _spi.write(0xFF); 00299 return response; 00300 } 00301 } 00302 _cs = 1; 00303 _spi.write(0xFF); 00304 return -1; // timeout 00305 } 00306 00307 int SDFileSystem::_cmd8() { 00308 _cs = 0; 00309 00310 // send a command 00311 _spi.write(0x40 | 8); // CMD8 00312 _spi.write(0x00); // reserved 00313 _spi.write(0x00); // reserved 00314 _spi.write(0x01); // 3.3v 00315 _spi.write(0xAA); // check pattern 00316 _spi.write(0x87); // crc 00317 00318 // wait for the repsonse (response[7] == 0) 00319 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00320 char response[5]; 00321 response[0] = _spi.write(0xFF); 00322 if(!(response[0] & 0x80)) { 00323 for(int j=1; j<5; j++) { 00324 response[i] = _spi.write(0xFF); 00325 } 00326 _cs = 1; 00327 _spi.write(0xFF); 00328 return response[0]; 00329 } 00330 } 00331 _cs = 1; 00332 _spi.write(0xFF); 00333 return -1; // timeout 00334 } 00335 00336 int SDFileSystem::_read(char *buffer, int length) { 00337 _cs = 0; 00338 00339 // read until start byte (0xFF) 00340 while(_spi.write(0xFF) != 0xFE); 00341 00342 // read data 00343 for(int i=0; i<length; i++) { 00344 buffer[i] = _spi.write(0xFF); 00345 } 00346 _spi.write(0xFF); // checksum 00347 _spi.write(0xFF); 00348 00349 _cs = 1; 00350 _spi.write(0xFF); 00351 return 0; 00352 } 00353 00354 int SDFileSystem::_write(const char *buffer, int length) { 00355 _cs = 0; 00356 00357 // indicate start of block 00358 _spi.write(0xFE); 00359 00360 // write the data 00361 for(int i=0; i<length; i++) { 00362 _spi.write(buffer[i]); 00363 } 00364 00365 // write the checksum 00366 _spi.write(0xFF); 00367 _spi.write(0xFF); 00368 00369 // check the repsonse token 00370 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00371 _cs = 1; 00372 _spi.write(0xFF); 00373 return 1; 00374 } 00375 00376 // wait for write to finish 00377 while(_spi.write(0xFF) == 0); 00378 00379 _cs = 1; 00380 _spi.write(0xFF); 00381 return 0; 00382 } 00383 00384 static int ext_bits(char *data, int msb, int lsb) { 00385 int bits = 0; 00386 int size = 1 + msb - lsb; 00387 for(int i=0; i<size; i++) { 00388 int position = lsb + i; 00389 int byte = 15 - (position >> 3); 00390 int bit = position & 0x7; 00391 int value = (data[byte] >> bit) & 1; 00392 bits |= value << i; 00393 } 00394 return bits; 00395 } 00396 00397 int SDFileSystem::_sd_sectors() { 00398 00399 // CMD9, Response R2 (R1 byte + 16-byte block read) 00400 if(_cmdx(9, 0) != 0) { 00401 fprintf(stderr, "Didn't get a response from the disk\n"); 00402 return 0; 00403 } 00404 00405 char csd[16]; 00406 if(_read(csd, 16) != 0) { 00407 fprintf(stderr, "Couldn't read csd response from disk\n"); 00408 return 0; 00409 } 00410 00411 // csd_structure : csd[127:126] 00412 // c_size : csd[73:62] 00413 // c_size_mult : csd[49:47] 00414 // read_bl_len : csd[83:80] - the *maximum* read block length 00415 00416 int csd_structure = ext_bits(csd, 127, 126); 00417 int c_size = ext_bits(csd, 73, 62); 00418 int c_size_mult = ext_bits(csd, 49, 47); 00419 int read_bl_len = ext_bits(csd, 83, 80); 00420 00421 // printf("CSD_STRUCT = %d\n", csd_structure); 00422 00423 if(csd_structure != 0) { 00424 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); 00425 return 0; 00426 } 00427 00428 // memory capacity = BLOCKNR * BLOCK_LEN 00429 // where 00430 // BLOCKNR = (C_SIZE+1) * MULT 00431 // MULT = 2^(C_SIZE_MULT+2) (C_SIZE_MULT < 8) 00432 // BLOCK_LEN = 2^READ_BL_LEN, (READ_BL_LEN < 12) 00433 00434 int block_len = 1 << read_bl_len; 00435 int mult = 1 << (c_size_mult + 2); 00436 int blocknr = (c_size + 1) * mult; 00437 int capacity = blocknr * block_len; 00438 00439 int blocks = capacity / 512; 00440 00441 return blocks; 00442 }
Generated on Tue Jul 26 2022 05:54:56 by
1.7.2