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