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