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 500000 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 fprintf(stderr, "\r\ninitialise_card\r\n"); 00131 // Set to 100kHz for initialisation, and clock card with cs = 1 00132 _spi.frequency(100000); 00133 _cs = 1; 00134 for (int i=0; i<16; i++) { 00135 _spi.write(0xFF); 00136 } 00137 00138 // send CMD0, should return with all zeros except IDLE STATE set (bit 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 fprintf(stderr, "\r\ninitialise_card_v2\r\n"); 00170 for (int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00171 _cmd(55, 0); 00172 // if(_cmd(41, 0) == 0) { 00173 if (_cmd41() == 0) { 00174 fprintf(stderr, "\r\ncmd41 returns idle - now initialised. Send cmd58\r\n"); 00175 _cmd58(); 00176 return SDCARD_V2; 00177 } 00178 } 00179 00180 fprintf(stderr, "Timeout waiting for v2.x card\r\n"); 00181 return SDCARD_FAIL; 00182 } 00183 00184 int SDFileSystem::disk_initialize() { 00185 00186 int i = initialise_card(); 00187 printf("init card = %d\r\n", i); 00188 // printf("OK\n"); 00189 00190 _sectors = _sd_sectors(); 00191 00192 // Set block length to 512 (CMD16) 00193 if (_cmd(16, 512) != 0) { 00194 fprintf(stderr, "Set 512-byte block timed out\r\n"); 00195 return 1; 00196 } 00197 00198 _spi.frequency(1000000); // Set to 1MHz for data transfer 00199 return 0; 00200 } 00201 00202 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00203 // set write address for single block (CMD24) 00204 if (_cmd(24, block_number * 512) != 0) { 00205 return 1; 00206 } 00207 00208 // send the data block 00209 _write(buffer, 512); 00210 return 0; 00211 } 00212 00213 int SDFileSystem::disk_read(char *buffer, int block_number) { 00214 // set read address for single block (CMD17) 00215 if (_cmd(17, block_number * 512) != 0) { 00216 return 1; 00217 } 00218 00219 // receive the data 00220 _read(buffer, 512); 00221 return 0; 00222 } 00223 00224 int SDFileSystem::disk_status() { 00225 return 0; 00226 } 00227 int SDFileSystem::disk_sync() { 00228 return 0; 00229 } 00230 int SDFileSystem::disk_sectors() { 00231 return _sectors; 00232 } 00233 00234 // PRIVATE FUNCTIONS 00235 00236 int SDFileSystem::_cmd(int cmd, int arg) { 00237 _cs = 0; 00238 00239 // send a command 00240 _spi.write(0x40 | cmd); 00241 _spi.write(arg >> 24); 00242 _spi.write(arg >> 16); 00243 _spi.write(arg >> 8); 00244 _spi.write(arg >> 0); 00245 _spi.write(0x95); 00246 00247 // wait for the repsonse (response[7] == 0) 00248 for (int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00249 int response = _spi.write(0xFF); 00250 if (!(response & 0x80)) { 00251 _cs = 1; 00252 _spi.write(0xFF); 00253 return response; 00254 } 00255 } 00256 _cs = 1; 00257 _spi.write(0xFF); 00258 return -1; // timeout 00259 } 00260 int SDFileSystem::_cmdx(int cmd, int arg) { 00261 _cs = 0; 00262 00263 // send a command 00264 _spi.write(0x40 | cmd); 00265 _spi.write(arg >> 24); 00266 _spi.write(arg >> 16); 00267 _spi.write(arg >> 8); 00268 _spi.write(arg >> 0); 00269 _spi.write(0x95); 00270 00271 // wait for the repsonse (response[7] == 0) 00272 for (int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00273 int response = _spi.write(0xFF); 00274 if (!(response & 0x80)) { 00275 return response; 00276 } 00277 } 00278 _cs = 1; 00279 _spi.write(0xFF); 00280 return -1; // timeout 00281 } 00282 00283 int SDFileSystem::_cmd41() { 00284 fprintf(stderr, "Issuing cmd41\r\n"); 00285 00286 _cs = 0; 00287 int arg = 0; 00288 00289 // send a command 00290 _spi.write(0x40 | 41); 00291 _spi.write(arg >> 24); 00292 _spi.write(arg >> 16); 00293 _spi.write(arg >> 8); 00294 _spi.write(arg >> 0); 00295 _spi.write(0x95); 00296 00297 union 00298 { 00299 unsigned int v; // register value 00300 struct CSD_REGISTER f; // register fields 00301 } csd; 00302 00303 int i; 00304 for (i=0; i<SD_COMMAND_TIMEOUT; i++) { 00305 int response = _spi.write(0xFF); 00306 fprintf(stderr, "cmd41 response=0x%08X\r\n", response); 00307 if (!(response & 0x80)) { 00308 csd.v = _spi.write(0xFF) << 24; 00309 csd.v |= _spi.write(0xFF) << 16; 00310 csd.v |= _spi.write(0xFF) << 8; 00311 csd.v |= _spi.write(0xFF) << 0; 00312 // _spi.write(0xFF); 00313 00314 fprintf(stderr, "cmd41 ocr=0x%08X\r\n", csd); 00315 00316 int test = csd.v; 00317 if (test & (1UL << 31)) 00318 fprintf(stderr, "Bit 31 = ON - Therefore - Card Powered up csd=0x%08X\r\n", csd); 00319 00320 // card_power_up_http://www.cs.cf.ac.uk/Dave/C/node13.html 00321 // if (csd_reg->card_power_up_status == 1) { 00322 if (csd.f.card_power_up_status == 1) { 00323 fprintf(stderr, "Card Powered up\r\n"); 00324 00325 if (csd.f.card_capacity_status == 1) { 00326 fprintf(stderr, "High Capacity Card\r\n"); 00327 } 00328 00329 _cs = 1; 00330 _spi.write(0xFF); 00331 return 0; 00332 } 00333 } 00334 } 00335 _cs = 1; 00336 _spi.write(0xFF); 00337 fprintf(stderr, "cmd41 timeout - exit with -1 i=%d, csd=0x%08X\r\n", i, csd); 00338 return -1; // timeout 00339 } 00340 00341 int SDFileSystem::_cmd58() { 00342 _cs = 0; 00343 int arg = 0; 00344 00345 // send a command 00346 _spi.write(0x40 | 58); 00347 _spi.write(arg >> 24); 00348 _spi.write(arg >> 16); 00349 _spi.write(arg >> 8); 00350 _spi.write(arg >> 0); 00351 _spi.write(0x95); 00352 00353 // wait for the repsonse (response[7] == 0) 00354 for (int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00355 int response = _spi.write(0xFF); 00356 if (!(response & 0x80)) { 00357 int ocr = _spi.write(0xFF) << 24; 00358 ocr |= _spi.write(0xFF) << 16; 00359 ocr |= _spi.write(0xFF) << 8; 00360 ocr |= _spi.write(0xFF) << 0; 00361 // printf("OCR = 0x%08X\n", ocr); 00362 _cs = 1; 00363 _spi.write(0xFF); 00364 return response; 00365 } 00366 } 00367 _cs = 1; 00368 _spi.write(0xFF); 00369 return -1; // timeout 00370 } 00371 00372 int SDFileSystem::_cmd8() { 00373 fprintf(stderr, "Issuing cmd8\r\n"); 00374 _cs = 0; 00375 00376 // send a command 00377 _spi.write(0x40 | 8); // CMD8 00378 _spi.write(0x00); // reserved 00379 _spi.write(0x00); // reserved 00380 _spi.write(0x01); // 3.3v 00381 _spi.write(0xAA); // check pattern 00382 _spi.write(0x87); // crc 00383 00384 // wait for the repsonse (response[7] == 0) 00385 for (int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00386 char response[5]; 00387 response[0] = _spi.write(0xFF); 00388 if (!(response[0] & 0x80)) { 00389 for (int j=1; j<5; j++) { 00390 response[i] = _spi.write(0xFF); 00391 fprintf(stderr, " %x,", response[i]); 00392 } 00393 fprintf(stderr, "\r\n"); 00394 _cs = 1; 00395 _spi.write(0xFF); 00396 return response[0]; 00397 } 00398 } 00399 _cs = 1; 00400 _spi.write(0xFF); 00401 return -1; // timeout 00402 } 00403 00404 int SDFileSystem::_read(char *buffer, int length) { 00405 _cs = 0; 00406 00407 // read until start byte (0xFF) 00408 while (_spi.write(0xFF) != 0xFE); 00409 00410 // read data 00411 for (int i=0; i<length; i++) { 00412 buffer[i] = _spi.write(0xFF); 00413 } 00414 _spi.write(0xFF); // checksum 00415 _spi.write(0xFF); 00416 00417 _cs = 1; 00418 _spi.write(0xFF); 00419 return 0; 00420 } 00421 00422 int SDFileSystem::_write(const char *buffer, int length) { 00423 _cs = 0; 00424 00425 // indicate start of block 00426 _spi.write(0xFE); 00427 00428 // write the data 00429 for (int i=0; i<length; i++) { 00430 _spi.write(buffer[i]); 00431 } 00432 00433 // write the checksum 00434 _spi.write(0xFF); 00435 _spi.write(0xFF); 00436 00437 // check the repsonse token 00438 if ((_spi.write(0xFF) & 0x1F) != 0x05) { 00439 _cs = 1; 00440 _spi.write(0xFF); 00441 return 1; 00442 } 00443 00444 // wait for write to finish 00445 while (_spi.write(0xFF) == 0); 00446 00447 _cs = 1; 00448 _spi.write(0xFF); 00449 return 0; 00450 } 00451 00452 static int ext_bits(char *data, int msb, int lsb) { 00453 int bits = 0; 00454 int size = 1 + msb - lsb; 00455 for (int i=0; i<size; i++) { 00456 int position = lsb + i; 00457 int byte = 15 - (position >> 3); 00458 int bit = position & 0x7; 00459 int value = (data[byte] >> bit) & 1; 00460 bits |= value << i; 00461 } 00462 return bits; 00463 } 00464 00465 int SDFileSystem::_sd_sectors() { 00466 00467 // CMD9, Response R2 (R1 byte + 16-byte block read) 00468 if (_cmdx(9, 0) != 0) { 00469 fprintf(stderr, "Didn't get a response from the disk\n"); 00470 return 0; 00471 } 00472 00473 char csd[16]; 00474 if (_read(csd, 16) != 0) { 00475 fprintf(stderr, "Couldn't read csd response from disk\n"); 00476 return 0; 00477 } 00478 00479 // csd_structure : csd[127:126] 00480 // c_size : csd[73:62] 00481 // c_size_mult : csd[49:47] 00482 // read_bl_len : csd[83:80] - the *maximum* read block length 00483 00484 int csd_structure = ext_bits(csd, 127, 126); 00485 int c_size = ext_bits(csd, 73, 62); 00486 int c_size_mult = ext_bits(csd, 49, 47); 00487 int read_bl_len = ext_bits(csd, 83, 80); 00488 00489 // printf("CSD_STRUCT = %d\n", csd_structure); 00490 00491 if (csd_structure != 0) { 00492 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); 00493 return 0; 00494 } 00495 00496 // memory capacity = BLOCKNR * BLOCK_LEN 00497 // where 00498 // BLOCKNR = (C_SIZE+1) * MULT 00499 // MULT = 2^(C_SIZE_MULT+2) (C_SIZE_MULT < 8) 00500 // BLOCK_LEN = 2^READ_BL_LEN, (READ_BL_LEN < 12) 00501 00502 int block_len = 1 << read_bl_len; 00503 int mult = 1 << (c_size_mult + 2); 00504 int blocknr = (c_size + 1) * mult; 00505 int capacity = blocknr * block_len; 00506 00507 int blocks = capacity / 512; 00508 00509 return blocks; 00510 }
Generated on Wed Jul 13 2022 03:35:30 by
1.7.2