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