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(100000); 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 if(_cmd(0, 0) != R1_IDLE_STATE) { 00139 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); 00140 return SDCARD_FAIL; 00141 } 00142 00143 // send CMD8 to determine whther it is ver 2.x 00144 int r = _cmd8(); 00145 if(r == R1_IDLE_STATE) { 00146 return initialise_card_v2(); 00147 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00148 return initialise_card_v1(); 00149 } else { 00150 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); 00151 return SDCARD_FAIL; 00152 } 00153 } 00154 00155 int SDFileSystem::initialise_card_v1() { 00156 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00157 _cmd(55, 0); 00158 if(_cmd(41, 0) == 0) { 00159 return SDCARD_V1; 00160 } 00161 } 00162 00163 fprintf(stderr, "Timeout waiting for v1.x card\n"); 00164 return SDCARD_FAIL; 00165 } 00166 00167 int SDFileSystem::initialise_card_v2() { 00168 00169 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00170 _cmd(55, 0); 00171 if(_cmd(41, 0) == 0) { 00172 _cmd58(); 00173 return SDCARD_V2; 00174 } 00175 } 00176 00177 fprintf(stderr, "Timeout waiting for v2.x card\n"); 00178 return SDCARD_FAIL; 00179 } 00180 00181 int SDFileSystem::disk_initialize() { 00182 00183 int i = initialise_card(); 00184 // printf("init card = %d\n", i); 00185 // printf("OK\n"); 00186 00187 _sectors = _sd_sectors(); 00188 00189 // Set block length to 512 (CMD16) 00190 if(_cmd(16, 512) != 0) { 00191 fprintf(stderr, "Set 512-byte block timed out\n"); 00192 return 1; 00193 } 00194 00195 _spi.frequency(1000000); // Set to 1MHz for data transfer 00196 return 0; 00197 } 00198 00199 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00200 // set write address for single block (CMD24) 00201 if(_cmd(24, block_number * 512) != 0) { 00202 return 1; 00203 } 00204 00205 // send the data block 00206 _write(buffer, 512); 00207 return 0; 00208 } 00209 00210 int SDFileSystem::disk_read(char *buffer, int block_number) { 00211 // set read address for single block (CMD17) 00212 if(_cmd(17, block_number * 512) != 0) { 00213 return 1; 00214 } 00215 00216 // receive the data 00217 _read(buffer, 512); 00218 return 0; 00219 } 00220 00221 int SDFileSystem::disk_status() { return 0; } 00222 int SDFileSystem::disk_sync() { return 0; } 00223 int SDFileSystem::disk_sectors() { return _sectors; } 00224 00225 // PRIVATE FUNCTIONS 00226 00227 int SDFileSystem::_cmd(int cmd, int arg) { 00228 _cs = 0; 00229 00230 // send a command 00231 _spi.write(0x40 | cmd); 00232 _spi.write(arg >> 24); 00233 _spi.write(arg >> 16); 00234 _spi.write(arg >> 8); 00235 _spi.write(arg >> 0); 00236 _spi.write(0x95); 00237 00238 // wait for the repsonse (response[7] == 0) 00239 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00240 int response = _spi.write(0xFF); 00241 if(!(response & 0x80)) { 00242 _cs = 1; 00243 _spi.write(0xFF); 00244 return response; 00245 } 00246 } 00247 _cs = 1; 00248 _spi.write(0xFF); 00249 return -1; // timeout 00250 } 00251 int SDFileSystem::_cmdx(int cmd, int arg) { 00252 _cs = 0; 00253 00254 // send a command 00255 _spi.write(0x40 | cmd); 00256 _spi.write(arg >> 24); 00257 _spi.write(arg >> 16); 00258 _spi.write(arg >> 8); 00259 _spi.write(arg >> 0); 00260 _spi.write(0x95); 00261 00262 // wait for the repsonse (response[7] == 0) 00263 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00264 int response = _spi.write(0xFF); 00265 if(!(response & 0x80)) { 00266 return response; 00267 } 00268 } 00269 _cs = 1; 00270 _spi.write(0xFF); 00271 return -1; // timeout 00272 } 00273 00274 00275 int SDFileSystem::_cmd58() { 00276 _cs = 0; 00277 int arg = 0; 00278 00279 // send a command 00280 _spi.write(0x40 | 58); 00281 _spi.write(arg >> 24); 00282 _spi.write(arg >> 16); 00283 _spi.write(arg >> 8); 00284 _spi.write(arg >> 0); 00285 _spi.write(0x95); 00286 00287 // wait for the repsonse (response[7] == 0) 00288 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00289 int response = _spi.write(0xFF); 00290 if(!(response & 0x80)) { 00291 int ocr = _spi.write(0xFF) << 24; 00292 ocr |= _spi.write(0xFF) << 16; 00293 ocr |= _spi.write(0xFF) << 8; 00294 ocr |= _spi.write(0xFF) << 0; 00295 // printf("OCR = 0x%08X\n", ocr); 00296 _cs = 1; 00297 _spi.write(0xFF); 00298 return response; 00299 } 00300 } 00301 _cs = 1; 00302 _spi.write(0xFF); 00303 return -1; // timeout 00304 } 00305 00306 int SDFileSystem::_cmd8() { 00307 _cs = 0; 00308 00309 // send a command 00310 _spi.write(0x40 | 8); // CMD8 00311 _spi.write(0x00); // reserved 00312 _spi.write(0x00); // reserved 00313 _spi.write(0x01); // 3.3v 00314 _spi.write(0xAA); // check pattern 00315 _spi.write(0x87); // crc 00316 00317 // wait for the repsonse (response[7] == 0) 00318 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00319 char response[5]; 00320 response[0] = _spi.write(0xFF); 00321 if(!(response[0] & 0x80)) { 00322 for(int j=1; j<5; j++) { 00323 response[i] = _spi.write(0xFF); 00324 } 00325 _cs = 1; 00326 _spi.write(0xFF); 00327 return response[0]; 00328 } 00329 } 00330 _cs = 1; 00331 _spi.write(0xFF); 00332 return -1; // timeout 00333 } 00334 00335 int SDFileSystem::_read(char *buffer, int length) { 00336 _cs = 0; 00337 00338 // read until start byte (0xFF) 00339 while(_spi.write(0xFF) != 0xFE); 00340 00341 // read data 00342 for(int i=0; i<length; i++) { 00343 buffer[i] = _spi.write(0xFF); 00344 } 00345 _spi.write(0xFF); // checksum 00346 _spi.write(0xFF); 00347 00348 _cs = 1; 00349 _spi.write(0xFF); 00350 return 0; 00351 } 00352 00353 int SDFileSystem::_write(const char *buffer, int length) { 00354 _cs = 0; 00355 00356 // indicate start of block 00357 _spi.write(0xFE); 00358 00359 // write the data 00360 for(int i=0; i<length; i++) { 00361 _spi.write(buffer[i]); 00362 } 00363 00364 // write the checksum 00365 _spi.write(0xFF); 00366 _spi.write(0xFF); 00367 00368 // check the repsonse token 00369 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00370 _cs = 1; 00371 _spi.write(0xFF); 00372 return 1; 00373 } 00374 00375 // wait for write to finish 00376 while(_spi.write(0xFF) == 0); 00377 00378 _cs = 1; 00379 _spi.write(0xFF); 00380 return 0; 00381 } 00382 00383 static int ext_bits(char *data, int msb, int lsb) { 00384 int bits = 0; 00385 int size = 1 + msb - lsb; 00386 for(int i=0; i<size; i++) { 00387 int position = lsb + i; 00388 int byte = 15 - (position >> 3); 00389 int bit = position & 0x7; 00390 int value = (data[byte] >> bit) & 1; 00391 bits |= value << i; 00392 } 00393 return bits; 00394 } 00395 00396 int SDFileSystem::_sd_sectors() { 00397 00398 // CMD9, Response R2 (R1 byte + 16-byte block read) 00399 if(_cmdx(9, 0) != 0) { 00400 fprintf(stderr, "Didn't get a response from the disk\n"); 00401 return 0; 00402 } 00403 00404 char csd[16]; 00405 if(_read(csd, 16) != 0) { 00406 fprintf(stderr, "Couldn't read csd response from disk\n"); 00407 return 0; 00408 } 00409 00410 // csd_structure : csd[127:126] 00411 // c_size : csd[73:62] 00412 // c_size_mult : csd[49:47] 00413 // read_bl_len : csd[83:80] - the *maximum* read block length 00414 00415 int csd_structure = ext_bits(csd, 127, 126); 00416 int c_size = ext_bits(csd, 73, 62); 00417 int c_size_mult = ext_bits(csd, 49, 47); 00418 int read_bl_len = ext_bits(csd, 83, 80); 00419 00420 // printf("CSD_STRUCT = %d\n", csd_structure); 00421 00422 if(csd_structure != 0) { 00423 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); 00424 return 0; 00425 } 00426 00427 // memory capacity = BLOCKNR * BLOCK_LEN 00428 // where 00429 // BLOCKNR = (C_SIZE+1) * MULT 00430 // MULT = 2^(C_SIZE_MULT+2) (C_SIZE_MULT < 8) 00431 // BLOCK_LEN = 2^READ_BL_LEN, (READ_BL_LEN < 12) 00432 00433 int block_len = 1 << read_bl_len; 00434 int mult = 1 << (c_size_mult + 2); 00435 int blocknr = (c_size + 1) * mult; 00436 int capacity = blocknr * block_len; 00437 00438 int blocks = capacity / 512; 00439 00440 return blocks; 00441 }
Generated on Tue Jul 12 2022 21:39:37 by
