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