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 _transfer_sck = 1000000; 00129 } 00130 00131 #define R1_IDLE_STATE (1 << 0) 00132 #define R1_ERASE_RESET (1 << 1) 00133 #define R1_ILLEGAL_COMMAND (1 << 2) 00134 #define R1_COM_CRC_ERROR (1 << 3) 00135 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00136 #define R1_ADDRESS_ERROR (1 << 5) 00137 #define R1_PARAMETER_ERROR (1 << 6) 00138 00139 // Types 00140 // - v1.x Standard Capacity 00141 // - v2.x Standard Capacity 00142 // - v2.x High Capacity 00143 // - Not recognised as an SD Card 00144 #define SDCARD_FAIL 0 00145 #define SDCARD_V1 1 00146 #define SDCARD_V2 2 00147 #define SDCARD_V2HC 3 00148 00149 int SDFileSystem::initialise_card() { 00150 // Set to SCK for initialisation, and clock card with cs = 1 00151 _spi.frequency(_init_sck); 00152 _cs = 1; 00153 for (int i = 0; i < 16; i++) { 00154 _spi.write(0xFF); 00155 } 00156 00157 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00158 if (_cmd(0, 0) != R1_IDLE_STATE) { 00159 debug("No disk, or could not put SD card in to SPI idle state\n"); 00160 return SDCARD_FAIL; 00161 } 00162 00163 // send CMD8 to determine whther it is ver 2.x 00164 int r = _cmd8(); 00165 if (r == R1_IDLE_STATE) { 00166 return initialise_card_v2(); 00167 } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00168 return initialise_card_v1(); 00169 } else { 00170 debug("Not in idle state after sending CMD8 (not an SD card?)\n"); 00171 return SDCARD_FAIL; 00172 } 00173 } 00174 00175 int SDFileSystem::initialise_card_v1() { 00176 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00177 _cmd(55, 0); 00178 if (_cmd(41, 0) == 0) { 00179 cdv = 512; 00180 debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r"); 00181 return SDCARD_V1; 00182 } 00183 } 00184 00185 debug("Timeout waiting for v1.x card\n"); 00186 return SDCARD_FAIL; 00187 } 00188 00189 int SDFileSystem::initialise_card_v2() { 00190 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00191 wait_ms(50); 00192 _cmd58(); 00193 _cmd(55, 0); 00194 if (_cmd(41, 0x40000000) == 0) { 00195 _cmd58(); 00196 debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r"); 00197 cdv = 1; 00198 return SDCARD_V2; 00199 } 00200 } 00201 00202 debug("Timeout waiting for v2.x card\n"); 00203 return SDCARD_FAIL; 00204 } 00205 00206 int SDFileSystem::disk_initialize() { 00207 _is_initialized = initialise_card(); 00208 if (_is_initialized == 0) { 00209 debug("Fail to initialize card\n"); 00210 return 1; 00211 } 00212 debug_if(SD_DBG, "init card = %d\n", _is_initialized); 00213 _sectors = _sd_sectors(); 00214 00215 // Set block length to 512 (CMD16) 00216 if (_cmd(16, 512) != 0) { 00217 debug("Set 512-byte block timed out\n"); 00218 return 1; 00219 } 00220 00221 // Set SCK for data transfer 00222 _spi.frequency(_transfer_sck); 00223 return 0; 00224 } 00225 00226 int SDFileSystem::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { 00227 if (!_is_initialized) { 00228 return -1; 00229 } 00230 00231 for (uint32_t b = block_number; b < block_number + count; b++) { 00232 // set write address for single block (CMD24) 00233 if (_cmd(24, b * cdv) != 0) { 00234 return 1; 00235 } 00236 00237 // send the data block 00238 _write(buffer, 512); 00239 buffer += 512; 00240 } 00241 00242 return 0; 00243 } 00244 00245 int SDFileSystem::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { 00246 if (!_is_initialized) { 00247 return -1; 00248 } 00249 00250 for (uint32_t b = block_number; b < block_number + count; b++) { 00251 // set read address for single block (CMD17) 00252 if (_cmd(17, b * cdv) != 0) { 00253 return 1; 00254 } 00255 00256 // receive the data 00257 _read(buffer, 512); 00258 buffer += 512; 00259 } 00260 00261 return 0; 00262 } 00263 00264 int SDFileSystem::disk_status() { 00265 // FATFileSystem::disk_status() returns 0 when initialized 00266 if (_is_initialized) { 00267 return 0; 00268 } else { 00269 return 1; 00270 } 00271 } 00272 00273 int SDFileSystem::disk_sync() { return 0; } 00274 uint32_t SDFileSystem::disk_sectors() { return _sectors; } 00275 00276 00277 // PRIVATE FUNCTIONS 00278 int SDFileSystem::_cmd(int cmd, int arg) { 00279 _cs = 0; 00280 00281 // send a command 00282 _spi.write(0x40 | cmd); 00283 _spi.write(arg >> 24); 00284 _spi.write(arg >> 16); 00285 _spi.write(arg >> 8); 00286 _spi.write(arg >> 0); 00287 _spi.write(0x95); 00288 00289 // wait for the repsonse (response[7] == 0) 00290 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00291 int response = _spi.write(0xFF); 00292 if (!(response & 0x80)) { 00293 _cs = 1; 00294 _spi.write(0xFF); 00295 return response; 00296 } 00297 } 00298 _cs = 1; 00299 _spi.write(0xFF); 00300 return -1; // timeout 00301 } 00302 int SDFileSystem::_cmdx(int cmd, int arg) { 00303 _cs = 0; 00304 00305 // send a command 00306 _spi.write(0x40 | cmd); 00307 _spi.write(arg >> 24); 00308 _spi.write(arg >> 16); 00309 _spi.write(arg >> 8); 00310 _spi.write(arg >> 0); 00311 _spi.write(0x95); 00312 00313 // wait for the repsonse (response[7] == 0) 00314 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00315 int response = _spi.write(0xFF); 00316 if (!(response & 0x80)) { 00317 return response; 00318 } 00319 } 00320 _cs = 1; 00321 _spi.write(0xFF); 00322 return -1; // timeout 00323 } 00324 00325 00326 int SDFileSystem::_cmd58() { 00327 _cs = 0; 00328 int arg = 0; 00329 00330 // send a command 00331 _spi.write(0x40 | 58); 00332 _spi.write(arg >> 24); 00333 _spi.write(arg >> 16); 00334 _spi.write(arg >> 8); 00335 _spi.write(arg >> 0); 00336 _spi.write(0x95); 00337 00338 // wait for the repsonse (response[7] == 0) 00339 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00340 int response = _spi.write(0xFF); 00341 if (!(response & 0x80)) { 00342 int ocr = _spi.write(0xFF) << 24; 00343 ocr |= _spi.write(0xFF) << 16; 00344 ocr |= _spi.write(0xFF) << 8; 00345 ocr |= _spi.write(0xFF) << 0; 00346 _cs = 1; 00347 _spi.write(0xFF); 00348 return response; 00349 } 00350 } 00351 _cs = 1; 00352 _spi.write(0xFF); 00353 return -1; // timeout 00354 } 00355 00356 int SDFileSystem::_cmd8() { 00357 _cs = 0; 00358 00359 // send a command 00360 _spi.write(0x40 | 8); // CMD8 00361 _spi.write(0x00); // reserved 00362 _spi.write(0x00); // reserved 00363 _spi.write(0x01); // 3.3v 00364 _spi.write(0xAA); // check pattern 00365 _spi.write(0x87); // crc 00366 00367 // wait for the repsonse (response[7] == 0) 00368 for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) { 00369 char response[5]; 00370 response[0] = _spi.write(0xFF); 00371 if (!(response[0] & 0x80)) { 00372 for (int j = 1; j < 5; j++) { 00373 response[i] = _spi.write(0xFF); 00374 } 00375 _cs = 1; 00376 _spi.write(0xFF); 00377 return response[0]; 00378 } 00379 } 00380 _cs = 1; 00381 _spi.write(0xFF); 00382 return -1; // timeout 00383 } 00384 00385 int SDFileSystem::_read(uint8_t *buffer, uint32_t length) { 00386 _cs = 0; 00387 00388 // read until start byte (0xFF) 00389 while (_spi.write(0xFF) != 0xFE); 00390 00391 // read data 00392 for (uint32_t i = 0; i < length; i++) { 00393 buffer[i] = _spi.write(0xFF); 00394 } 00395 _spi.write(0xFF); // checksum 00396 _spi.write(0xFF); 00397 00398 _cs = 1; 00399 _spi.write(0xFF); 00400 return 0; 00401 } 00402 00403 int SDFileSystem::_write(const uint8_t*buffer, uint32_t length) { 00404 _cs = 0; 00405 00406 // indicate start of block 00407 _spi.write(0xFE); 00408 00409 // write the data 00410 for (uint32_t i = 0; i < length; i++) { 00411 _spi.write(buffer[i]); 00412 } 00413 00414 // write the checksum 00415 _spi.write(0xFF); 00416 _spi.write(0xFF); 00417 00418 // check the response token 00419 if ((_spi.write(0xFF) & 0x1F) != 0x05) { 00420 _cs = 1; 00421 _spi.write(0xFF); 00422 return 1; 00423 } 00424 00425 // wait for write to finish 00426 while (_spi.write(0xFF) == 0); 00427 00428 _cs = 1; 00429 _spi.write(0xFF); 00430 return 0; 00431 } 00432 00433 static uint32_t ext_bits(unsigned char *data, int msb, int lsb) { 00434 uint32_t bits = 0; 00435 uint32_t size = 1 + msb - lsb; 00436 for (uint32_t i = 0; i < size; i++) { 00437 uint32_t position = lsb + i; 00438 uint32_t byte = 15 - (position >> 3); 00439 uint32_t bit = position & 0x7; 00440 uint32_t value = (data[byte] >> bit) & 1; 00441 bits |= value << i; 00442 } 00443 return bits; 00444 } 00445 00446 uint32_t SDFileSystem::_sd_sectors() { 00447 uint32_t c_size, c_size_mult, read_bl_len; 00448 uint32_t block_len, mult, blocknr, capacity; 00449 uint32_t hc_c_size; 00450 uint32_t blocks; 00451 00452 // CMD9, Response R2 (R1 byte + 16-byte block read) 00453 if (_cmdx(9, 0) != 0) { 00454 debug("Didn't get a response from the disk\n"); 00455 return 0; 00456 } 00457 00458 uint8_t csd[16]; 00459 if (_read(csd, 16) != 0) { 00460 debug("Couldn't read csd response from disk\n"); 00461 return 0; 00462 } 00463 00464 // csd_structure : csd[127:126] 00465 // c_size : csd[73:62] 00466 // c_size_mult : csd[49:47] 00467 // read_bl_len : csd[83:80] - the *maximum* read block length 00468 00469 int csd_structure = ext_bits(csd, 127, 126); 00470 00471 switch (csd_structure) { 00472 case 0: 00473 cdv = 512; 00474 c_size = ext_bits(csd, 73, 62); 00475 c_size_mult = ext_bits(csd, 49, 47); 00476 read_bl_len = ext_bits(csd, 83, 80); 00477 00478 block_len = 1 << read_bl_len; 00479 mult = 1 << (c_size_mult + 2); 00480 blocknr = (c_size + 1) * mult; 00481 capacity = blocknr * block_len; 00482 blocks = capacity / 512; 00483 debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks); 00484 break; 00485 00486 case 1: 00487 cdv = 1; 00488 hc_c_size = ext_bits(csd, 63, 48); 00489 blocks = (hc_c_size+1)*1024; 00490 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); 00491 break; 00492 00493 default: 00494 debug("CSD struct unsupported\r\n"); 00495 return 0; 00496 }; 00497 return blocks; 00498 }
Generated on Sun Jul 17 2022 22:15:02 by
