Description: This is test program for running 192GC00(240 x 320 dot, 65K Color TFT LCD module ) on Star Board Orange.
SDHCFileSystem.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 //* Introduction 00024 // * ------------ 00025 // * SD and MMC cards support a number of interfaces, but common to them all 00026 // * is one based on SPI. This is the one I'm implmenting because it means 00027 // * it is much more portable even though not so performant, and we already 00028 // * have the mbed SPI Interface! 00029 // * 00030 // * The main reference I'm using is Chapter 7, "SPI Mode" of: 00031 // * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00032 // * 00033 // * SPI Startup 00034 // * ----------- 00035 // * The SD card powers up in SD mode. The SPI interface mode is selected by 00036 // * asserting CS low and sending the reset command (CMD0). The card will 00037 // * respond with a (R1) response. 00038 // * 00039 // * CMD8 is optionally sent to determine the voltage range supported, and 00040 // * indirectly determine whether it is a version 1.x SD/non-SD card or 00041 // * version 2.x. I'll just ignore this for now. 00042 // * 00043 // * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00044 // * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00045 // * 00046 // * You should also indicate whether the host supports High Capicity cards, 00047 // * and check whether the card is high capacity - i'll also ignore this 00048 // * 00049 // * SPI Protocol 00050 // * ------------ 00051 // * The SD SPI protocol is based on transactions made up of 8-bit words, with 00052 //* the host starting every bus transaction by asserting the CS signal low. The 00053 // * card always responds to commands, data blocks and errors. 00054 // * 00055 // * The protocol supports a CRC, but by default it is off (except for the 00056 // * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00057 // * I'll leave the CRC off I think! 00058 // * 00059 // * Standard capacity cards have variable data block sizes, whereas High 00060 // * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00061 // * just always use the Standard Capacity cards with a block size of 512 bytes. 00062 // * This is set with CMD16. 00063 // * 00064 // * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00065 // * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00066 // * the card gets a read command, it responds with a response token, and then 00067 // * a data token or an error. 00068 // * 00069 // * SPI Command Format 00070 // * ------------------ 00071 // * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00072 // * 00073 // * +---------------+------------+------------+-----------+----------+--------------+ 00074 // * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00075 // * +---------------+------------+------------+-----------+----------+--------------+ 00076 // * 00077 // * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00078 // * 00079 // * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00080 // * 00081 // * SPI Response Format 00082 // * ------------------- 00083 // * The main response format (R1) is a status byte (normally zero). Key flags: 00084 // * idle - 1 if the card is in an idle state/initialising 00085 // * cmd - 1 if an illegal command code was detected 00086 // * 00087 // * +-------------------------------------------------+ 00088 // * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00089 // * +-------------------------------------------------+ 00090 // * 00091 // * R1b is the same, except it is followed by a busy signal (zeros) until 00092 // * the first non-zero byte when it is ready again. 00093 // * 00094 // * Data Response Token 00095 // * ------------------- 00096 // * Every data block written to the card is acknowledged by a byte 00097 // * response token 00098 // * 00099 // * +----------------------+ 00100 // * | xxx | 0 | status | 1 | 00101 // * +----------------------+ 00102 // * 010 - OK! 00103 // * 101 - CRC Error 00104 // * 110 - Write Error 00105 // * 00106 // * Single Block Read and Write 00107 // * --------------------------- 00108 // * 00109 // * Block transfers have a byte header, followed by the data, followed 00110 // * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00111 // * 00112 // * +------+---------+---------+- - - -+---------+-----------+----------+ 00113 // * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00114 // * +------+---------+---------+- - - -+---------+-----------+----------+ 00115 // */ 00116 // 00117 //* 00118 // * Comment: Changes for SDHC support till 32GB 00119 // * Name: KB 00120 // * Date: 07/24/2010 00121 // * Release: 0.1 00122 // */ 00123 00124 /* mbed SDFileSystem Library, for providing file access to SD cards 00125 * Copyright (c) 2008-2010, sford 00126 * 00127 * Permission is hereby granted, free of charge, to any person obtaining a copy 00128 * of this software and associated documentation files (the "Software"), to deal 00129 * in the Software without restriction, including without limitation the rights 00130 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00131 * copies of the Software, and to permit persons to whom the Software is 00132 * furnished to do so, subject to the following conditions: 00133 * 00134 * The above copyright notice and this permission notice shall be included in 00135 * all copies or substantial portions of the Software. 00136 * 00137 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00138 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00139 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00140 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00141 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00142 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00143 * THE SOFTWARE. 00144 */ 00145 00146 //* Introduction 00147 // * ------------ 00148 // * SD and MMC cards support a number of interfaces, but common to them all 00149 // * is one based on SPI. This is the one I'm implmenting because it means 00150 // * it is much more portable even though not so performant, and we already 00151 // * have the mbed SPI Interface! 00152 // * 00153 // * The main reference I'm using is Chapter 7, "SPI Mode" of: 00154 // * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00155 // * 00156 // * SPI Startup 00157 // * ----------- 00158 // * The SD card powers up in SD mode. The SPI interface mode is selected by 00159 // * asserting CS low and sending the reset command (CMD0). The card will 00160 // * respond with a (R1) response. 00161 // * 00162 // * CMD8 is optionally sent to determine the voltage range supported, and 00163 // * indirectly determine whether it is a version 1.x SD/non-SD card or 00164 // * version 2.x. I'll just ignore this for now. 00165 // * 00166 // * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00167 // * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00168 // * 00169 // * You should also indicate whether the host supports High Capicity cards, 00170 // * and check whether the card is high capacity - i'll also ignore this 00171 // * 00172 // * SPI Protocol 00173 // * ------------ 00174 // * The SD SPI protocol is based on transactions made up of 8-bit words, with 00175 //* the host starting every bus transaction by asserting the CS signal low. The 00176 // * card always responds to commands, data blocks and errors. 00177 // * 00178 // * The protocol supports a CRC, but by default it is off (except for the 00179 // * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00180 // * I'll leave the CRC off I think! 00181 // * 00182 // * Standard capacity cards have variable data block sizes, whereas High 00183 // * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00184 // * just always use the Standard Capacity cards with a block size of 512 bytes. 00185 // * This is set with CMD16. 00186 // * 00187 // * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00188 // * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00189 // * the card gets a read command, it responds with a response token, and then 00190 // * a data token or an error. 00191 // * 00192 // * SPI Command Format 00193 // * ------------------ 00194 // * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00195 // * 00196 // * +---------------+------------+------------+-----------+----------+--------------+ 00197 // * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00198 // * +---------------+------------+------------+-----------+----------+--------------+ 00199 // * 00200 // * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00201 // * 00202 // * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00203 // * 00204 // * SPI Response Format 00205 // * ------------------- 00206 // * The main response format (R1) is a status byte (normally zero). Key flags: 00207 // * idle - 1 if the card is in an idle state/initialising 00208 // * cmd - 1 if an illegal command code was detected 00209 // * 00210 // * +-------------------------------------------------+ 00211 // * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00212 // * +-------------------------------------------------+ 00213 // * 00214 // * R1b is the same, except it is followed by a busy signal (zeros) until 00215 // * the first non-zero byte when it is ready again. 00216 // * 00217 // * Data Response Token 00218 // * ------------------- 00219 // * Every data block written to the card is acknowledged by a byte 00220 // * response token 00221 // * 00222 // * +----------------------+ 00223 // * | xxx | 0 | status | 1 | 00224 // * +----------------------+ 00225 // * 010 - OK! 00226 // * 101 - CRC Error 00227 // * 110 - Write Error 00228 // * 00229 // * Single Block Read and Write 00230 // * --------------------------- 00231 // * 00232 // * Block transfers have a byte header, followed by the data, followed 00233 // * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00234 // * 00235 // * +------+---------+---------+- - - -+---------+-----------+----------+ 00236 // * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00237 // * +------+---------+---------+- - - -+---------+-----------+----------+ 00238 // */ 00239 // 00240 //* 00241 // * Comment: Changes for SDHC support till 32GB 00242 // * Name: KB 00243 // * Date: 07/24/2010 00244 // * Release: 0.1 00245 // */ 00246 00247 #include "SDHCFileSystem.h" 00248 00249 #define DEBUG 00250 #define SD_COMMAND_TIMEOUT 5000 00251 00252 00253 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : 00254 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { 00255 _cs = 1; 00256 } 00257 00258 #define R1_IDLE_STATE (1 << 0) 00259 #define R1_ERASE_RESET (1 << 1) 00260 #define R1_ILLEGAL_COMMAND (1 << 2) 00261 #define R1_COM_CRC_ERROR (1 << 3) 00262 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00263 #define R1_ADDRESS_ERROR (1 << 5) 00264 #define R1_PARAMETER_ERROR (1 << 6) 00265 00266 // Types 00267 // - v1.x Standard Capacity 00268 // - v2.x Standard Capacity 00269 // - v2.x High Capacity 00270 // - Not recognised as an SD Card 00271 00272 #define SDCARD_FAIL 0 00273 #define SDCARD_V1 1 00274 #define SDCARD_V2 2 00275 #define SDCARD_V2HC 3 00276 00277 int SDFileSystem::initialise_card() { 00278 // Set to 100kHz for initialisation, and clock card with cs = 1 00279 _spi.frequency(40000000); 00280 _cs = 1; 00281 for(int i=0; i<16; i++) { 00282 _spi.write(0xFF); 00283 } 00284 00285 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00286 if(_cmd(0, 0) != R1_IDLE_STATE) { 00287 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); 00288 return SDCARD_FAIL; 00289 } 00290 00291 // send CMD8 to determine whther it is ver 2.x 00292 int r = _cmd8(); 00293 if(r == R1_IDLE_STATE) { 00294 return initialise_card_v2(); 00295 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00296 return initialise_card_v1(); 00297 } else { 00298 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); 00299 return SDCARD_FAIL; 00300 } 00301 } 00302 00303 int SDFileSystem::initialise_card_v1() { 00304 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00305 _cmd(55, 0); 00306 if(_cmd(41, 0) == 0) { 00307 cdv = 512; 00308 #ifdef DEBUG 00309 printf("\n\rInit: SEDCARD_V1\n\r"); 00310 #endif 00311 return SDCARD_V1; 00312 } 00313 } 00314 00315 fprintf(stderr, "Timeout waiting for v1.x card\n"); 00316 return SDCARD_FAIL; 00317 } 00318 00319 int SDFileSystem::initialise_card_v2() { 00320 00321 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00322 wait_ms(50); 00323 _cmd58(); 00324 _cmd(55, 0); 00325 if(_cmd(41, 0x40000000) == 0) { 00326 _cmd58(); 00327 #ifdef DEBUG 00328 printf("\n\rInit: SDCARD_V2\n\r"); 00329 #endif 00330 cdv = 1; 00331 return SDCARD_V2; 00332 } 00333 } 00334 00335 fprintf(stderr, "Timeout waiting for v2.x card\n"); 00336 return SDCARD_FAIL; 00337 } 00338 00339 int SDFileSystem::disk_initialize() { 00340 00341 int i = initialise_card(); 00342 #ifdef DEBUG 00343 printf("init card = %d\n", i); 00344 #endif 00345 _sectors = _sd_sectors(); 00346 00347 // Set block length to 512 (CMD16) 00348 if(_cmd(16, 512) != 0) { 00349 fprintf(stderr, "Set 512-byte block timed out\n"); 00350 return 1; 00351 } 00352 00353 _spi.frequency(40000000); // Set to 1MHz for data transfer 00354 return 0; 00355 } 00356 00357 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00358 // set write address for single block (CMD24) 00359 if(_cmd(24, block_number * cdv) != 0) { 00360 return 1; 00361 } 00362 00363 // send the data block 00364 _write(buffer, 512); 00365 return 0; 00366 } 00367 00368 int SDFileSystem::disk_read(char *buffer, int block_number) { 00369 // set read address for single block (CMD17) 00370 if(_cmd(17, block_number * cdv) != 0) { 00371 return 1; 00372 } 00373 00374 // receive the data 00375 _read(buffer, 512); 00376 return 0; 00377 } 00378 00379 int SDFileSystem::disk_status() { return 0; } 00380 int SDFileSystem::disk_sync() { return 0; } 00381 int SDFileSystem::disk_sectors() { return _sectors; } 00382 00383 // PRIVATE FUNCTIONS 00384 00385 int SDFileSystem::_cmd(int cmd, int arg) { 00386 _cs = 0; 00387 00388 // send a command 00389 _spi.write(0x40 | cmd); 00390 _spi.write(arg >> 24); 00391 _spi.write(arg >> 16); 00392 _spi.write(arg >> 8); 00393 _spi.write(arg >> 0); 00394 _spi.write(0x95); 00395 00396 // wait for the repsonse (response[7] == 0) 00397 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00398 int response = _spi.write(0xFF); 00399 if(!(response & 0x80)) { 00400 _cs = 1; 00401 _spi.write(0xFF); 00402 return response; 00403 } 00404 } 00405 _cs = 1; 00406 _spi.write(0xFF); 00407 return -1; // timeout 00408 } 00409 int SDFileSystem::_cmdx(int cmd, int arg) { 00410 _cs = 0; 00411 00412 // send a command 00413 _spi.write(0x40 | cmd); 00414 _spi.write(arg >> 24); 00415 _spi.write(arg >> 16); 00416 _spi.write(arg >> 8); 00417 _spi.write(arg >> 0); 00418 _spi.write(0x95); 00419 00420 // wait for the repsonse (response[7] == 0) 00421 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00422 int response = _spi.write(0xFF); 00423 if(!(response & 0x80)) { 00424 return response; 00425 } 00426 } 00427 _cs = 1; 00428 _spi.write(0xFF); 00429 return -1; // timeout 00430 } 00431 00432 00433 int SDFileSystem::_cmd58() { 00434 _cs = 0; 00435 int arg = 0; 00436 00437 // send a command 00438 _spi.write(0x40 | 58); 00439 _spi.write(arg >> 24); 00440 _spi.write(arg >> 16); 00441 _spi.write(arg >> 8); 00442 _spi.write(arg >> 0); 00443 _spi.write(0x95); 00444 00445 // wait for the repsonse (response[7] == 0) 00446 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00447 int response = _spi.write(0xFF); 00448 if(!(response & 0x80)) { 00449 int ocr = _spi.write(0xFF) << 24; 00450 ocr |= _spi.write(0xFF) << 16; 00451 ocr |= _spi.write(0xFF) << 8; 00452 ocr |= _spi.write(0xFF) << 0; 00453 // printf("OCR = 0x%08X\n", ocr); 00454 _cs = 1; 00455 _spi.write(0xFF); 00456 return response; 00457 } 00458 } 00459 _cs = 1; 00460 _spi.write(0xFF); 00461 return -1; // timeout 00462 } 00463 00464 int SDFileSystem::_cmd8() { 00465 _cs = 0; 00466 00467 // send a command 00468 _spi.write(0x40 | 8); // CMD8 00469 _spi.write(0x00); // reserved 00470 _spi.write(0x00); // reserved 00471 _spi.write(0x01); // 3.3v 00472 _spi.write(0xAA); // check pattern 00473 _spi.write(0x87); // crc 00474 00475 // wait for the repsonse (response[7] == 0) 00476 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00477 char response[5]; 00478 response[0] = _spi.write(0xFF); 00479 if(!(response[0] & 0x80)) { 00480 for(int j=1; j<5; j++) { 00481 response[i] = _spi.write(0xFF); 00482 } 00483 _cs = 1; 00484 _spi.write(0xFF); 00485 return response[0]; 00486 } 00487 } 00488 _cs = 1; 00489 _spi.write(0xFF); 00490 return -1; // timeout 00491 } 00492 00493 int SDFileSystem::_read(char *buffer, int length) { 00494 _cs = 0; 00495 00496 // read until start byte (0xFF) 00497 while(_spi.write(0xFF) != 0xFE); 00498 00499 // read data 00500 for(int i=0; i<length; i++) { 00501 buffer[i] = _spi.write(0xFF); 00502 } 00503 _spi.write(0xFF); // checksum 00504 _spi.write(0xFF); 00505 00506 _cs = 1; 00507 _spi.write(0xFF); 00508 return 0; 00509 } 00510 00511 int SDFileSystem::_write(const char *buffer, int length) { 00512 _cs = 0; 00513 00514 // indicate start of block 00515 _spi.write(0xFE); 00516 00517 // write the data 00518 for(int i=0; i<length; i++) { 00519 _spi.write(buffer[i]); 00520 } 00521 00522 // write the checksum 00523 _spi.write(0xFF); 00524 _spi.write(0xFF); 00525 00526 // check the repsonse token 00527 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00528 _cs = 1; 00529 _spi.write(0xFF); 00530 return 1; 00531 } 00532 00533 // wait for write to finish 00534 while(_spi.write(0xFF) == 0); 00535 00536 _cs = 1; 00537 _spi.write(0xFF); 00538 return 0; 00539 } 00540 00541 static int ext_bits(char *data, int msb, int lsb) { 00542 int bits = 0; 00543 int size = 1 + msb - lsb; 00544 for(int i=0; i<size; i++) { 00545 int position = lsb + i; 00546 int byte = 15 - (position >> 3); 00547 int bit = position & 0x7; 00548 int value = (data[byte] >> bit) & 1; 00549 bits |= value << i; 00550 } 00551 return bits; 00552 } 00553 00554 int SDFileSystem::_sd_sectors() { 00555 00556 int c_size, c_size_mult, read_bl_len; 00557 int block_len, mult, blocknr, capacity; 00558 int blocks, hc_c_size; 00559 uint64_t hc_capacity; 00560 00561 // CMD9, Response R2 (R1 byte + 16-byte block read) 00562 if(_cmdx(9, 0) != 0) { 00563 fprintf(stderr, "Didn't get a response from the disk\n"); 00564 return 0; 00565 } 00566 00567 char csd[16]; 00568 if(_read(csd, 16) != 0) { 00569 fprintf(stderr, "Couldn't read csd response from disk\n"); 00570 return 0; 00571 } 00572 00573 // csd_structure : csd[127:126] 00574 // c_size : csd[73:62] 00575 // c_size_mult : csd[49:47] 00576 // read_bl_len : csd[83:80] - the *maximum* read block length 00577 00578 int csd_structure = ext_bits(csd, 127, 126); 00579 00580 #ifdef DEBUG 00581 printf("\n\rCSD_STRUCT = %d\n", csd_structure); 00582 #endif 00583 00584 switch (csd_structure){ 00585 case 0: 00586 cdv = 512; 00587 c_size = ext_bits(csd, 73, 62); 00588 c_size_mult = ext_bits(csd, 49, 47); 00589 read_bl_len = ext_bits(csd, 83, 80); 00590 00591 block_len = 1 << read_bl_len; 00592 mult = 1 << (c_size_mult + 2); 00593 blocknr = (c_size + 1) * mult; 00594 capacity = blocknr * block_len; 00595 blocks = capacity / 512; 00596 #ifdef DEBUG 00597 printf("\n\rSDCard\n\rc_size: %.4X \n\rcapacity: %.ld \n\rsectors: %d\n\r", c_size, capacity, blocks); 00598 #endif 00599 break; 00600 00601 case 1: 00602 cdv = 1; 00603 hc_c_size = ext_bits(csd, 63, 48); 00604 int hc_read_bl_len = ext_bits(csd, 83, 80); 00605 hc_capacity = hc_c_size+1; 00606 blocks = (hc_c_size+1)*1024; 00607 #ifdef DEBUG 00608 printf("\n\rSDHC Card \n\rhc_c_size: %.4X \n\rcapacity: %.lld \n\rsectors: %d\n\r", hc_c_size, hc_capacity*512*1024, blocks); 00609 #endif 00610 break; 00611 00612 default: 00613 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); 00614 return 0; 00615 // break; 00616 }; 00617 return blocks; 00618 }
