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 Smoothie by
SDCard.cpp
00001 /* mbed SDFileSystem Library, for providing file access to SD cards 00002 * Copyright (c) 2008-2010, sford 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 00020 * THE SOFTWARE. 00021 * 00022 * 00023 * This version significantly altered by Michael Moon and is (c) 2012 00024 */ 00025 00026 /* Introduction 00027 * ------------ 00028 * SD and MMC cards support a number of interfaces, but common to them all 00029 * is one based on SPI. This is the one I'm implmenting because it means 00030 * it is much more portable even though not so performant, and we already 00031 * have the mbed SPI Interface! 00032 * 00033 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00034 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00035 * 00036 * SPI Startup 00037 * ----------- 00038 * The SD card powers up in SD mode. The SPI interface mode is selected by 00039 * asserting CS low and sending the reset command (CMD0). The card will 00040 * respond with a (R1) response. 00041 * 00042 * CMD8 is optionally sent to determine the voltage range supported, and 00043 * indirectly determine whether it is a version 1.x SD/non-SD card or 00044 * version 2.x. I'll just ignore this for now. 00045 * 00046 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00047 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00048 * 00049 * You should also indicate whether the host supports High Capicity cards, 00050 * and check whether the card is high capacity - i'll also ignore this 00051 * 00052 * SPI Protocol 00053 * ------------ 00054 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00055 * the host starting every bus transaction by asserting the CS signal low. The 00056 * card always responds to commands, data blocks and errors. 00057 * 00058 * The protocol supports a CRC, but by default it is off (except for the 00059 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00060 * I'll leave the CRC off I think! 00061 * 00062 * Standard capacity cards have variable data block sizes, whereas High 00063 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00064 * just always use the Standard Capacity cards with a block size of 512 bytes. 00065 * This is set with CMD16. 00066 * 00067 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00068 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00069 * the card gets a read command, it responds with a response token, and then 00070 * a data token or an error. 00071 * 00072 * SPI Command Format 00073 * ------------------ 00074 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00075 * 00076 * +---------------+------------+------------+-----------+----------+--------------+ 00077 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00078 * +---------------+------------+------------+-----------+----------+--------------+ 00079 * 00080 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00081 * 00082 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00083 * 00084 * SPI Response Format 00085 * ------------------- 00086 * The main response format (R1) is a status byte (normally zero). Key flags: 00087 * idle - 1 if the card is in an idle state/initialising 00088 * cmd - 1 if an illegal command code was detected 00089 * 00090 * +-------------------------------------------------+ 00091 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00092 * +-------------------------------------------------+ 00093 * 00094 * R1b is the same, except it is followed by a busy signal (zeros) until 00095 * the first non-zero byte when it is ready again. 00096 * 00097 * Data Response Token 00098 * ------------------- 00099 * Every data block written to the card is acknowledged by a byte 00100 * response token 00101 * 00102 * +----------------------+ 00103 * | xxx | 0 | status | 1 | 00104 * +----------------------+ 00105 * 010 - OK! 00106 * 101 - CRC Error 00107 * 110 - Write Error 00108 * 00109 * Single Block Read and Write 00110 * --------------------------- 00111 * 00112 * Block transfers have a byte header, followed by the data, followed 00113 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00114 * 00115 * +------+---------+---------+- - - -+---------+-----------+----------+ 00116 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00117 * +------+---------+---------+- - - -+---------+-----------+----------+ 00118 */ 00119 00120 #include <stdio.h> 00121 #include <stdlib.h> 00122 00123 #include "SDCard.h" 00124 00125 static const uint8_t OXFF = 0xFF; 00126 00127 #define SD_COMMAND_TIMEOUT 5000 00128 00129 SDCard::SDCard(PinName mosi, PinName miso, PinName sclk, PinName cs) : 00130 _spi(mosi, miso, sclk), _cs(cs) { 00131 _cs.output(); 00132 _cs = 1; 00133 busyflag = false; 00134 _sectors = 0; 00135 } 00136 00137 #define R1_IDLE_STATE (1 << 0) 00138 #define R1_ERASE_RESET (1 << 1) 00139 #define R1_ILLEGAL_COMMAND (1 << 2) 00140 #define R1_COM_CRC_ERROR (1 << 3) 00141 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00142 #define R1_ADDRESS_ERROR (1 << 5) 00143 #define R1_PARAMETER_ERROR (1 << 6) 00144 00145 // Types 00146 // - v1.x Standard Capacity 00147 // - v2.x Standard Capacity 00148 // - v2.x High Capacity 00149 // - Not recognised as an SD Card 00150 00151 // #define SDCARD_FAIL 0 00152 // #define SDCARD_V1 1 00153 // #define SDCARD_V2 2 00154 // #define SDCARD_V2HC 3 00155 00156 #define BUSY_FLAG_MULTIREAD 1 00157 #define BUSY_FLAG_MULTIWRITE 2 00158 #define BUSY_FLAG_ENDREAD 4 00159 #define BUSY_FLAG_ENDWRITE 8 00160 #define BUSY_FLAG_WAITNOTBUSY (1<<31) 00161 00162 #define SDCMD_GO_IDLE_STATE 0 00163 #define SDCMD_ALL_SEND_CID 2 00164 #define SDCMD_SEND_RELATIVE_ADDR 3 00165 #define SDCMD_SET_DSR 4 00166 #define SDCMD_SELECT_CARD 7 00167 #define SDCMD_SEND_IF_COND 8 00168 #define SDCMD_SEND_CSD 9 00169 #define SDCMD_SEND_CID 10 00170 #define SDCMD_STOP_TRANSMISSION 12 00171 #define SDCMD_SEND_STATUS 13 00172 #define SDCMD_GO_INACTIVE_STATE 15 00173 #define SDCMD_SET_BLOCKLEN 16 00174 #define SDCMD_READ_SINGLE_BLOCK 17 00175 #define SDCMD_READ_MULTIPLE_BLOCK 18 00176 #define SDCMD_WRITE_BLOCK 24 00177 #define SDCMD_WRITE_MULTIPLE_BLOCK 25 00178 #define SDCMD_PROGRAM_CSD 27 00179 #define SDCMD_SET_WRITE_PROT 28 00180 #define SDCMD_CLR_WRITE_PROT 29 00181 #define SDCMD_SEND_WRITE_PROT 30 00182 #define SDCMD_ERASE_WR_BLOCK_START 32 00183 #define SDCMD_ERASE_WR_BLK_END 33 00184 #define SDCMD_ERASE 38 00185 #define SDCMD_LOCK_UNLOCK 42 00186 #define SDCMD_APP_CMD 55 00187 #define SDCMD_GEN_CMD 56 00188 00189 #define SD_ACMD_SET_BUS_WIDTH 6 00190 #define SD_ACMD_SD_STATUS 13 00191 #define SD_ACMD_SEND_NUM_WR_BLOCKS 22 00192 #define SD_ACMD_SET_WR_BLK_ERASE_COUNT 23 00193 #define SD_ACMD_SD_SEND_OP_COND 41 00194 #define SD_ACMD_SET_CLR_CARD_DETECT 42 00195 #define SD_ACMD_SEND_CSR 51 00196 00197 #define SD_CARD_HIGH_CAPACITY (1UL<<30) 00198 00199 #define BLOCK2ADDR(block) (((cardtype == SDCARD_V1) || (cardtype == SDCARD_V2))?(block << 9):((cardtype == SDCARD_V2HC)?(block):0)) 00200 00201 SDCard::CARD_TYPE SDCard::initialise_card() { 00202 // Set to 25kHz for initialisation, and clock card with cs = 1 00203 _spi.frequency(25000); 00204 _cs = 1; 00205 00206 for(int i=0; i<24; i++) { 00207 _spi.write(0xFF); 00208 } 00209 00210 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00211 if(_cmd(SDCMD_GO_IDLE_STATE, 0) != R1_IDLE_STATE) { 00212 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); 00213 return cardtype = SDCARD_FAIL; 00214 } 00215 00216 // send CMD8 to determine whther it is ver 2.x 00217 int r = _cmd8(); 00218 if(r == R1_IDLE_STATE) { 00219 return initialise_card_v2(); 00220 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00221 return initialise_card_v1(); 00222 } else { 00223 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); 00224 return cardtype = SDCARD_FAIL; 00225 } 00226 } 00227 00228 SDCard::CARD_TYPE SDCard::initialise_card_v1() { 00229 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00230 _cmd(SDCMD_APP_CMD, 0); 00231 if(_cmd(SD_ACMD_SD_SEND_OP_COND, 0) == 0) { 00232 return cardtype = SDCARD_V1; 00233 } 00234 } 00235 00236 fprintf(stderr, "Timeout waiting for v1.x card\n"); 00237 return SDCARD_FAIL; 00238 } 00239 00240 SDCard::CARD_TYPE SDCard::initialise_card_v2() { 00241 00242 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00243 _cmd(SDCMD_APP_CMD, 0); 00244 if(_cmd(SD_ACMD_SD_SEND_OP_COND, SD_CARD_HIGH_CAPACITY) == 0) { 00245 uint32_t ocr; 00246 _cmd58(&ocr); 00247 if (ocr & SD_CARD_HIGH_CAPACITY) 00248 return cardtype = SDCARD_V2HC; 00249 else 00250 return cardtype = SDCARD_V2; 00251 } 00252 } 00253 00254 fprintf(stderr, "Timeout waiting for v2.x card\n"); 00255 return cardtype = SDCARD_FAIL; 00256 } 00257 00258 int SDCard::disk_initialize() 00259 { 00260 busyflag = true; 00261 00262 _sectors = 0; 00263 00264 CARD_TYPE i = initialise_card(); 00265 00266 if (i == SDCARD_FAIL) { 00267 busyflag = false; 00268 return 1; 00269 } 00270 00271 _sectors = _sd_sectors(); 00272 00273 // Set block length to 512 (CMD16) 00274 if(_cmd(SDCMD_SET_BLOCKLEN, 512) != 0) { 00275 fprintf(stderr, "Set 512-byte block timed out\n"); 00276 busyflag = false; 00277 return 1; 00278 } 00279 00280 _spi.frequency(2500000); // Set to 2.5MHz for data transfer 00281 00282 busyflag = false; 00283 00284 return 0; 00285 } 00286 00287 int SDCard::disk_write(const char *buffer, uint32_t block_number) 00288 { 00289 if (busyflag) 00290 return 0; 00291 00292 busyflag = true; 00293 00294 if (cardtype == SDCARD_FAIL) 00295 return -1; 00296 // set write address for single block (CMD24) 00297 if(_cmd(SDCMD_WRITE_BLOCK, BLOCK2ADDR(block_number)) != 0) { 00298 return 1; 00299 } 00300 00301 // send the data block 00302 _write(buffer, 512); 00303 00304 busyflag = false; 00305 00306 return 0; 00307 } 00308 00309 int SDCard::disk_read(char *buffer, uint32_t block_number) 00310 { 00311 if (busyflag) 00312 return 0; 00313 00314 busyflag = true; 00315 00316 if (cardtype == SDCARD_FAIL) 00317 return -1; 00318 // set read address for single block (CMD17) 00319 if(_cmd(SDCMD_READ_SINGLE_BLOCK, BLOCK2ADDR(block_number)) != 0) { 00320 return 1; 00321 } 00322 00323 // receive the data 00324 _read(buffer, 512); 00325 00326 busyflag = false; 00327 00328 return 0; 00329 } 00330 00331 int SDCard::disk_status() { return (_sectors > 0)?0:1; } 00332 int SDCard::disk_sync() { 00333 // TODO: wait for DMA, wait for card not busy 00334 return 0; 00335 } 00336 uint32_t SDCard::disk_sectors() { return _sectors; } 00337 uint64_t SDCard::disk_size() { return ((uint64_t) _sectors) << 9; } 00338 uint32_t SDCard::disk_blocksize() { return (1<<9); } 00339 bool SDCard::disk_canDMA() { return false; } 00340 00341 SDCard::CARD_TYPE SDCard::card_type() 00342 { 00343 return cardtype; 00344 } 00345 00346 // PRIVATE FUNCTIONS 00347 00348 int SDCard::_cmd(int cmd, uint32_t arg) { 00349 _cs = 0; 00350 00351 // send a command 00352 _spi.write(0x40 | cmd); 00353 _spi.write(arg >> 24); 00354 _spi.write(arg >> 16); 00355 _spi.write(arg >> 8); 00356 _spi.write(arg >> 0); 00357 _spi.write(0x95); 00358 00359 // wait for the repsonse (response[7] == 0) 00360 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00361 int response = _spi.write(0xFF); 00362 if(!(response & 0x80)) { 00363 _cs = 1; 00364 _spi.write(0xFF); 00365 return response; 00366 } 00367 } 00368 _cs = 1; 00369 _spi.write(0xFF); 00370 return -1; // timeout 00371 } 00372 int SDCard::_cmdx(int cmd, uint32_t arg) { 00373 _cs = 0; 00374 00375 // send a command 00376 _spi.write(0x40 | cmd); 00377 _spi.write(arg >> 24); 00378 _spi.write(arg >> 16); 00379 _spi.write(arg >> 8); 00380 _spi.write(arg >> 0); 00381 _spi.write(0x95); 00382 00383 // wait for the repsonse (response[7] == 0) 00384 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00385 int response = _spi.write(0xFF); 00386 if(!(response & 0x80)) { 00387 return response; 00388 } 00389 } 00390 _cs = 1; 00391 _spi.write(0xFF); 00392 return -1; // timeout 00393 } 00394 00395 00396 int SDCard::_cmd58(uint32_t *ocr) { 00397 _cs = 0; 00398 int arg = 0; 00399 00400 // send a command 00401 _spi.write(0x40 | 58); 00402 _spi.write(arg >> 24); 00403 _spi.write(arg >> 16); 00404 _spi.write(arg >> 8); 00405 _spi.write(arg >> 0); 00406 _spi.write(0x95); 00407 00408 // wait for the repsonse (response[7] == 0) 00409 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00410 int response = _spi.write(0xFF); 00411 if(!(response & 0x80)) { 00412 *ocr = _spi.write(0xFF) << 24; 00413 *ocr |= _spi.write(0xFF) << 16; 00414 *ocr |= _spi.write(0xFF) << 8; 00415 *ocr |= _spi.write(0xFF) << 0; 00416 // printf("OCR = 0x%08X\n", ocr); 00417 _cs = 1; 00418 _spi.write(0xFF); 00419 return response; 00420 } 00421 } 00422 _cs = 1; 00423 _spi.write(0xFF); 00424 return -1; // timeout 00425 } 00426 00427 int SDCard::_cmd8() { 00428 _cs = 0; 00429 00430 // send a command 00431 _spi.write(0x40 | SDCMD_SEND_IF_COND); // CMD8 00432 _spi.write(0x00); // reserved 00433 _spi.write(0x00); // reserved 00434 _spi.write(0x01); // 3.3v 00435 _spi.write(0xAA); // check pattern 00436 _spi.write(0x87); // crc 00437 00438 // wait for the repsonse (response[7] == 0) 00439 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00440 char response[5]; 00441 response[0] = _spi.write(0xFF); 00442 if(!(response[0] & 0x80)) { 00443 for(int j=1; j<5; j++) { 00444 response[i] = _spi.write(0xFF); 00445 } 00446 _cs = 1; 00447 _spi.write(0xFF); 00448 return response[0]; 00449 } 00450 } 00451 _cs = 1; 00452 _spi.write(0xFF); 00453 return -1; // timeout 00454 } 00455 00456 int SDCard::_read(char *buffer, int length) { 00457 _cs = 0; 00458 00459 // read until start byte (0xFF) 00460 while(_spi.write(0xFF) != 0xFE); 00461 // uint8_t r; 00462 // while((r = _spi.write(0xFF)) != 0xFE) 00463 // { 00464 // iprintf("0x%02X ", r); 00465 // for (volatile uint32_t j = 262144; j; j--); 00466 // } 00467 // 00468 // iprintf("Got start byte, reading data\n"); 00469 00470 // read data 00471 for(int i=0; i<length; i++) { 00472 buffer[i] = _spi.write(0xFF); 00473 } 00474 _spi.write(0xFF); // checksum 00475 _spi.write(0xFF); 00476 00477 _cs = 1; 00478 _spi.write(0xFF); 00479 return 0; 00480 } 00481 00482 int SDCard::_write(const char *buffer, int length) { 00483 _cs = 0; 00484 00485 // indicate start of block 00486 _spi.write(0xFE); 00487 00488 // write the data 00489 for(int i=0; i<length; i++) { 00490 _spi.write(buffer[i]); 00491 } 00492 00493 // write the checksum 00494 _spi.write(0xFF); 00495 _spi.write(0xFF); 00496 00497 // check the repsonse token 00498 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00499 _cs = 1; 00500 _spi.write(0xFF); 00501 return 1; 00502 } 00503 00504 // wait for write to finish 00505 while(_spi.write(0xFF) == 0); 00506 00507 _cs = 1; 00508 _spi.write(0xFF); 00509 return 0; 00510 } 00511 00512 static int ext_bits(char *data, int msb, int lsb) { 00513 int bits = 0; 00514 int size = 1 + msb - lsb; 00515 for(int i=0; i<size; i++) { 00516 int position = lsb + i; 00517 int byte = 15 - (position >> 3); 00518 int bit = position & 0x7; 00519 int value = (data[byte] >> bit) & 1; 00520 bits |= value << i; 00521 } 00522 return bits; 00523 } 00524 00525 uint32_t SDCard::_sd_sectors() { 00526 00527 // CMD9, Response R2 (R1 byte + 16-byte block read) 00528 if(_cmdx(SDCMD_SEND_CSD, 0) != 0) { 00529 fprintf(stderr, "Didn't get a response from the disk\n"); 00530 return 0; 00531 } 00532 00533 char csd[16]; 00534 if(_read(csd, 16) != 0) { 00535 fprintf(stderr, "Couldn't read csd response from disk\n"); 00536 return 0; 00537 } 00538 00539 // csd_structure : csd[127:126] 00540 // c_size : csd[73:62] 00541 // c_size_mult : csd[49:47] 00542 // read_bl_len : csd[83:80] - the *maximum* read block length 00543 00544 int csd_structure = ext_bits(csd, 127, 126); 00545 00546 if (csd_structure == 0) 00547 { 00548 if (cardtype == SDCARD_V2HC) 00549 { 00550 fprintf(stderr, "SDHC card with regular SD descriptor!\n"); 00551 return 0; 00552 } 00553 uint32_t c_size = ext_bits(csd, 73, 62); 00554 uint32_t c_size_mult = ext_bits(csd, 49, 47); 00555 uint32_t read_bl_len = ext_bits(csd, 83, 80); 00556 00557 uint32_t block_len = 1 << read_bl_len; 00558 uint32_t mult = 1 << (c_size_mult + 2); 00559 uint32_t blocknr = (c_size + 1) * mult; 00560 00561 if (block_len >= 512) 00562 return blocknr * (block_len >> 9); 00563 else 00564 return (blocknr * block_len) >> 9; 00565 } 00566 else if (csd_structure == 1) 00567 { 00568 if (cardtype != SDCARD_V2HC) 00569 { 00570 fprintf(stderr, "SD V1 or V2 card with SDHC descriptor!\n"); 00571 return 0; 00572 } 00573 uint32_t c_size = ext_bits(csd, 69, 48); 00574 uint32_t blocknr = (c_size + 1) * 1024; 00575 00576 return blocknr; 00577 } 00578 fprintf(stderr, "This disk tastes funny! (%d) I only know about type 0 or 1 CSD structures\n", csd_structure); 00579 return 0; 00580 } 00581 00582 bool SDCard::busy() 00583 { 00584 return busyflag; 00585 }
Generated on Tue Jul 12 2022 20:09:02 by
1.7.2
