SDHI_driver patch (mbedOS 5.11.5)
Embed:
(wiki syntax)
Show/hide line numbers
SDHIBlockDevice.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 00023 #if (defined(TARGET_VK_RZ_A1H) || defined(TARGET_VK_RZ_A1LU)) 00024 00025 #include "SDHIBlockDevice.h" 00026 #include "mbed_debug.h" 00027 #include <errno.h> 00028 00029 #include "iodefine.h" 00030 #include "PeripheralPins.h" 00031 00032 /* Required version: 5.6.1 and above */ 00033 #ifdef MBED_MAJOR_VERSION 00034 #if (MBED_VERSION < MBED_ENCODE_VERSION(5,6,1)) 00035 #error "Incompatible mbed-os version detected! Required 5.5.4 and above" 00036 #endif 00037 #else 00038 #warning "mbed-os version 5.6.1 or above required" 00039 #endif 00040 00041 00042 00043 //#define SD_COMMAND_TIMEOUT 5000 /*!< Timeout in ms for response */ 00044 //#define SD_CMD0_GO_IDLE_STATE_RETRIES 5 /*!< Number of retries for sending CMDO */ 00045 #define SD_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */ 00046 00047 //#define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */ 00048 #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */ 00049 #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */ 00050 #define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */ 00051 #define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */ 00052 #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */ 00053 #define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */ 00054 #define SD_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /*!< No response from device */ 00055 #define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */ 00056 #define SD_BLOCK_DEVICE_ERROR_ERASE -5010 /*!< Erase error: reset/sequence */ 00057 #define SD_BLOCK_DEVICE_ERROR_WRITE -5011 /*!< SPI Write error: !SPI_DATA_ACCEPTED */ 00058 00059 #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */ 00060 #define WRITE_BL_PARTIAL 0 /*!< Partial block write - Not supported */ 00061 // 00062 // Types 00063 #define SDCARD_NONE 0 /**< No card is present */ 00064 #define SDCARD_V1 1 /**< v1.x Standard Capacity */ 00065 #define SDCARD_V2 2 /**< v2.x Standard capacity SD card */ 00066 #define SDCARD_V2HC 3 /**< v2.x High capacity SD card */ 00067 #define CARD_UNKNOWN 4 /**< Unknown or unsupported card */ 00068 00069 /* R3 Response : OCR Register */ 00070 #define OCR_HCS_CCS (0x1 << 30) 00071 #define OCR_LOW_VOLTAGE (0x01 << 24) 00072 #define OCR_3_3V (0x1 << 20) 00073 00074 #define ESD_SECTOR_SIZE BLOCK_SIZE_HC 00075 00076 #define REG_CSD_HACK 00077 00078 #define CSD_CID_LENGTH 16 00079 00080 #define ARRAYSIZE(arr) (size_t)(sizeof(arr)/sizeof(arr[0])) 00081 00082 static uint32_t _sd_workbuf[SD_SIZE_OF_INIT/ sizeof(uint32_t)] __attribute__ ((section ("NC_BSS"))); 00083 static uint32_t _sd_rw_buf[ESD_SECTOR_SIZE/sizeof(uint32_t)] __attribute__ ((section ("NC_BSS"))); 00084 //static uint8_t _sectorBuff[ESD_SECTOR_SIZE] __attribute__ ((section ("NC_BSS"))); 00085 00086 00087 static uint32_t ext_bits(unsigned char *data, size_t datasize, unsigned int msb, unsigned int lsb) { 00088 uint32_t bits = 0; 00089 00090 if ((datasize > 0) && (msb < (datasize<<3))) 00091 { 00092 uint32_t size = 1 + msb - lsb; 00093 for (uint32_t i = 0; i < size; i++) 00094 { 00095 uint32_t position = lsb + i; 00096 int32_t byte = (datasize-1) - (position >> 3); 00097 if( byte < 0 ) 00098 break; 00099 uint32_t bit = position & 0x7; 00100 uint32_t value = (data[byte] >> bit) & 1; 00101 bits |= value << i; 00102 } 00103 } 00104 return bits; 00105 } 00106 00107 #if SDHI_DBG 00108 const sderr_t SDHIBlockDevice::_sd_error_msg[]= { 00109 {"SD_OK", 0}, /* OK */ 00110 {"SD_ERR", -1}, /* general error */ 00111 {"SD_ERR_WP", -2}, /* write protect error */ 00112 {"SD_ERR_RO", -3}, /* read only error */ 00113 {"SD_ERR_RES_TOE", -4}, /* response time out error */ 00114 {"SD_ERR_CARD_TOE", -5}, /* card time out error */ 00115 {"SD_ERR_END_BIT", -6}, /* end bit error */ 00116 {"SD_ERR_CRC", -7}, /* CRC error */ 00117 {"SD_ERR_CARD_RES", -8}, /* card response error */ 00118 {"SD_ERR_HOST_TOE", -9}, /* host time out error */ 00119 {"SD_ERR_CARD_ERASE", -10}, /* card erase error */ 00120 {"SD_ERR_CARD_LOCK", -11}, /* card lock error */ 00121 {"SD_ERR_CARD_UNLOCK", -12}, /* card unlock error */ 00122 {"SD_ERR_HOST_CRC", -13}, /* host CRC error */ 00123 {"SD_ERR_CARD_ECC", -14}, /* card internal ECC error */ 00124 {"SD_ERR_CARD_CC", -15}, /* card internal error */ 00125 {"SD_ERR_CARD_ERROR", -16}, /* unknown card error */ 00126 {"SD_ERR_CARD_TYPE", -17}, /* non support card type */ 00127 {"SD_ERR_NO_CARD", -18}, /* no card */ 00128 {"SD_ERR_ILL_READ", -19}, /* illegal buffer read */ 00129 {"SD_ERR_ILL_WRITE", -20}, /* illegal buffer write */ 00130 {"SD_ERR_AKE_SEQ", -21}, /* the sequence of authentication process */ 00131 {"SD_ERR_OVERWRITE", -22}, /* CID/CSD overwrite error */ 00132 /* 23-29 */ 00133 {"SD_ERR_CPU_IF", -30}, /* target CPU interface function error */ 00134 {"SD_ERR_STOP", -31}, /* user stop */ 00135 /* 32-49 */ 00136 {"SD_ERR_CSD_VER", -50}, /* CSD register version error */ 00137 {"SD_ERR_SCR_VER", -51}, /* SCR register version error */ 00138 {"SD_ERR_FILE_FORMAT", -52}, /* CSD register file format error */ 00139 {"SD_ERR_NOTSUP_CMD", -53}, /* not supported command */ 00140 /* 54-59 */ 00141 {"SD_ERR_ILL_FUNC", -60}, /* invalid function request error */ 00142 {"SD_ERR_IO_VERIFY", -61}, /* direct write verify error */ 00143 {"SD_ERR_IO_CAPAB", -62}, /* IO capability error */ 00144 /* 63-69 */ 00145 {"SD_ERR_IFCOND_VER", -70}, /* Interface condition version error */ 00146 {"SD_ERR_IFCOND_VOLT", -71}, /* Interface condition voltage error */ 00147 {"SD_ERR_IFCOND_ECHO", -72}, /* Interface condition echo back pattern error */ 00148 /* 73-79 */ 00149 {"SD_ERR_OUT_OF_RANGE", -80}, /* the argument was out of range */ 00150 {"SD_ERR_ADDRESS_ERROR", -81}, 00151 {"SD_ERR_BLOCK_LEN_ERROR", -82}, 00152 {"SD_ERR_ILLEGAL_COMMAND", -83}, 00153 {"SD_ERR_RESERVED_ERROR18", -84}, 00154 {"SD_ERR_RESERVED_ERROR17", -85}, 00155 {"SD_ERR_CMD_ERROR", -86}, 00156 {"SD_ERR_CBSY_ERROR", -87}, 00157 {"SD_ERR_NO_RESP_ERROR", -88}, 00158 /* 89 */ 00159 /* 90-95 */ 00160 {"SD_ERR_ERROR", -96}, 00161 {"SD_ERR_FUNCTION_NUMBER", -97}, 00162 {"SD_ERR_COM_CRC_ERROR", -98}, 00163 {"SD_ERR_INTERNAL", -99}, /* driver software internal error */ 00164 }; 00165 00166 #endif 00167 00168 SDHIBlockDevice::SDHIBlockDevice(uint32_t sdport) 00169 { 00170 _init_ref_count = 0; 00171 Initialize(sdport); 00172 // for( uint32_t n=0; n < ARRAYSIZE(_sd_error_msg); n++ ) 00173 // { 00174 // _sd_err_map[_sd_error_msg[n].errorno] = _sd_error_msg[n].msg; 00175 // } 00176 // 00177 // if ( sdport < SDHI_COUNT ) 00178 // { 00179 // _sd_channel = sdport; 00180 // _regbase = (uint32_t)((_sd_channel == 0ul) ? &SDHI0 : &SDHI1); 00181 // 00182 // _card_type = SDCARD_NONE; 00183 // 00184 // // Set default to 100kHz for initialisation and 1MHz for data transfer 00185 // _init_sck = 100000; 00186 // _transfer_sck = hz; 00187 // 00188 // // Only HC block size is supported. 00189 // _block_size = BLOCK_SIZE_HC; 00190 // _erase_size = BLOCK_SIZE_HC; 00191 // _mtx_lock = false; 00192 // 00193 // int32_t sd_err = sd_init( _sd_channel, _regbase, &_sd_workbuf[0], SD_CD_SOCKET ); 00194 // if ( sd_err != SD_OK) 00195 // { 00196 // _error(sd_err); 00197 //// return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; 00198 // } 00199 // 00200 // void *rw_buff = (void *)&_sd_rw_buf[0]; 00201 // 00202 // sd_err = sd_set_buffer( _sd_channel, rw_buff, (unsigned long)sizeof(_sd_rw_buf) ); 00203 // if ( sd_err != SD_OK ) 00204 // { 00205 // _error(sd_err); 00206 // } 00207 // 00208 // } 00209 // else 00210 // { 00211 // _sd_channel = -1; 00212 // _regbase = 0ul; 00213 // 00214 // } 00215 } 00216 00217 SDHIBlockDevice::SDHIBlockDevice(PinName sd_CLK, PinName sd_CMD, PinName sd_CD, PinName sd_WP, 00218 PinName sd_D0, PinName sd_D1, PinName sd_D2, PinName sd_D3 ) 00219 { 00220 _init_ref_count = 0; 00221 00222 uint32_t sd_wp = pinmap_peripheral(sd_WP, PinMap_SDHI_WP); 00223 uint32_t sd_cd = pinmap_peripheral(sd_CD, PinMap_SDHI_CD); 00224 uint32_t sd_clk = pinmap_peripheral(sd_CLK, PinMap_SDHI_CLK); 00225 uint32_t sd_cmd = pinmap_peripheral(sd_CMD, PinMap_SDHI_CMD); 00226 uint32_t sd_d0 = pinmap_peripheral(sd_D0, PinMap_SDHI_D0); 00227 uint32_t sd_d1 = pinmap_peripheral(sd_D1, PinMap_SDHI_D1); 00228 uint32_t sd_d2 = pinmap_peripheral(sd_D2, PinMap_SDHI_D2); 00229 uint32_t sd_d3 = pinmap_peripheral(sd_D3, PinMap_SDHI_D3); 00230 00231 uint32_t sd_cntl_1 = pinmap_merge(sd_wp, sd_cd); 00232 uint32_t sd_cntl_2 = pinmap_merge(sd_clk, sd_cmd); 00233 uint32_t sd_cntl = pinmap_merge(sd_cntl_1, sd_cntl_2); 00234 00235 uint32_t sd_data_1 = pinmap_merge(sd_d0, sd_d1); 00236 uint32_t sd_data_2 = pinmap_merge(sd_d2, sd_d3); 00237 uint32_t sd_data = pinmap_merge(sd_data_1, sd_data_2); 00238 00239 uint32_t sdport = pinmap_merge(sd_cntl, sd_data); 00240 00241 MBED_ASSERT((int)sdport != NC); 00242 00243 Initialize(sdport); 00244 } 00245 00246 00247 00248 SDHIBlockDevice::~SDHIBlockDevice() 00249 { 00250 if (_is_initialized) { 00251 deinit(); 00252 } 00253 } 00254 00255 void SDHIBlockDevice::Initialize( uint32_t sdport ) 00256 { 00257 #if SDHI_DBG 00258 for( uint32_t n=0; n < ARRAYSIZE(_sd_error_msg); n++ ) 00259 { 00260 _sd_err_map[_sd_error_msg[n].errorno] = _sd_error_msg[n].msg; 00261 } 00262 #endif 00263 _sectors = 0; 00264 _is_initialized = 0; 00265 if ( sdport < SDHI_COUNT ) 00266 { 00267 _sd_channel = sdport; 00268 _regbase = (uint32_t)((_sd_channel == SDHI_0) ? &SDHI0 : &SDHI1); 00269 00270 _card_type = SDCARD_NONE; 00271 00272 // Only HC block size is supported. 00273 _block_size = BLOCK_SIZE_HC; 00274 _erase_size = BLOCK_SIZE_HC; 00275 00276 int32_t sd_err = sd_init( _sd_channel, _regbase, &_sd_workbuf[0], SD_CD_SOCKET ); 00277 if ( sd_err != SD_OK) 00278 { 00279 _error(sd_err); 00280 } 00281 00282 void *rw_buff = (void *)&_sd_rw_buf[0]; 00283 00284 sd_err = sd_set_buffer( _sd_channel, rw_buff, (unsigned long)sizeof(_sd_rw_buf) ); 00285 if ( sd_err != SD_OK ) 00286 { 00287 _error(sd_err); 00288 } 00289 } 00290 else 00291 { 00292 _sd_channel = -1; 00293 _regbase = 0ul; 00294 00295 } 00296 00297 } 00298 00299 int SDHIBlockDevice::_initialise_card() 00300 { 00301 // Detail debugging is for commands 00302 _dbg = SDHI_DBG ? SD_CMD_TRACE : 0; 00303 00304 int32_t status = BD_ERROR_OK; 00305 00306 int32_t sd_err; 00307 00308 if( _regbase ) 00309 { 00310 sd_err = sd_mount(_sd_channel, SDCFG_DRIVER_MODE, SD_VOLT_3_3); 00311 00312 if ( sd_err != SD_OK ) 00313 { 00314 _error(sd_err); 00315 return SD_BLOCK_DEVICE_ERROR_UNUSABLE; 00316 } 00317 uint8_t card_type; 00318 uint8_t card_speed; 00319 uint8_t card_capa; 00320 00321 sd_err=sd_get_type(_sd_channel, &card_type, &card_speed, &card_capa); 00322 if( sd_err != SD_OK) 00323 { 00324 return _error(sd_err); 00325 } 00326 00327 if( (card_type & SD_MEDIA_SD) != SD_MEDIA_SD ) 00328 { 00329 return SD_BLOCK_DEVICE_ERROR_UNUSABLE; 00330 } 00331 00332 uint32_t regOCR; 00333 uint8_t regCID[CSD_CID_LENGTH]; 00334 uint8_t regCSD[CSD_CID_LENGTH]; 00335 uint8_t regDSR[2]; 00336 uint8_t regSCR[8]; 00337 00338 sd_err = sd_get_reg(_sd_channel, (uint8_t *)®OCR, regCID, regCSD, regDSR, regSCR); 00339 if (sd_err != SD_OK) 00340 { 00341 return _error(sd_err); 00342 } 00343 regOCR = __REV(regOCR); 00344 // Check if card supports voltage range: 3.3V 00345 if (!(regOCR & OCR_3_3V)) { 00346 _card_type = CARD_UNKNOWN; 00347 status = SD_BLOCK_DEVICE_ERROR_UNUSABLE; 00348 return status; 00349 } 00350 } 00351 else 00352 { 00353 status = SD_BLOCK_DEVICE_ERROR_NO_INIT; 00354 } 00355 00356 return status; 00357 } 00358 00359 00360 int SDHIBlockDevice::init() 00361 { 00362 vMutex l(&_mutex); 00363 00364 if(!_is_initialized) 00365 _init_ref_count = 0; 00366 00367 _init_ref_count++; 00368 00369 if(_init_ref_count != 1) 00370 return BD_ERROR_OK; 00371 00372 int err = _initialise_card(); 00373 _is_initialized = (err == BD_ERROR_OK); 00374 if (!_is_initialized) { 00375 debug_if(SDHI_DBG, "Fail to initialize card\n"); 00376 return err; 00377 } 00378 debug_if(SDHI_DBG, "init card = %d\r\n", _is_initialized); 00379 _sectors = _sd_sectors(); 00380 00381 if (0 == _sectors) { 00382 return BD_ERROR_DEVICE_ERROR; 00383 } 00384 00385 return BD_ERROR_OK; 00386 } 00387 00388 int SDHIBlockDevice::deinit() 00389 { 00390 vMutex l(&_mutex); 00391 00392 if(!_is_initialized) 00393 _init_ref_count = 0; 00394 00395 _init_ref_count--; //!!! 00396 00397 if(_init_ref_count) 00398 return BD_ERROR_OK; 00399 00400 _sectors = 0; 00401 if ( _is_initialized ) 00402 { 00403 sd_unmount(_sd_channel); 00404 debug_if(SDHI_DBG, "card deinited![%d]\r\n", _is_initialized); 00405 _is_initialized = false; 00406 } 00407 return 0; 00408 } 00409 00410 00411 int SDHIBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) 00412 { 00413 if (!is_valid_program(addr, size)) { 00414 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00415 } 00416 00417 vMutex l(&_mutex); 00418 00419 if (!_is_initialized) { 00420 return SD_BLOCK_DEVICE_ERROR_NO_INIT; 00421 } 00422 00423 uint8_t* buffer = const_cast<uint8_t*>(static_cast<const uint8_t*>(b)); 00424 int status = BD_ERROR_OK; 00425 00426 // Get block count 00427 bd_addr_t blockCnt = size / _block_size; 00428 00429 addr = addr / _block_size; 00430 00431 // Send command to perform write operation 00432 int32_t sd_err = sd_write_sect( _sd_channel, buffer, addr, blockCnt, SD_WRITE_OVERWRITE); 00433 00434 if (sd_err != SD_OK) 00435 { 00436 _error(sd_err); 00437 status = SD_BLOCK_DEVICE_ERROR_WRITE; 00438 } 00439 00440 return status; 00441 } 00442 00443 int SDHIBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) 00444 { 00445 if (!is_valid_read(addr, size)) { 00446 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00447 } 00448 00449 vMutex l(&_mutex); 00450 00451 if (!_is_initialized) { 00452 return SD_BLOCK_DEVICE_ERROR_NO_INIT; 00453 } 00454 uint8_t *buffer = static_cast<uint8_t*>(b); 00455 int status = BD_ERROR_OK; 00456 bd_addr_t blockCnt = size / _block_size; 00457 00458 addr = addr / _block_size; 00459 00460 int32_t sd_err = sd_read_sect(_sd_channel, buffer, addr, blockCnt); 00461 00462 if (sd_err != SD_OK) 00463 { 00464 _error(sd_err); 00465 status = SD_BLOCK_DEVICE_ERROR_NO_RESPONSE; 00466 } 00467 00468 return status; 00469 } 00470 00471 int SDHIBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00472 { 00473 return 0; 00474 } 00475 00476 00477 bool SDHIBlockDevice::_is_valid_trim(bd_addr_t addr, bd_size_t size) 00478 { 00479 return ( 00480 addr % _erase_size == 0 && 00481 size % _erase_size == 0 && 00482 addr + size <= this->size()); 00483 } 00484 00485 int SDHIBlockDevice::trim(bd_addr_t addr, bd_size_t size) 00486 { 00487 if (!_is_valid_trim(addr, size)) { 00488 return SD_BLOCK_DEVICE_ERROR_PARAMETER; 00489 } 00490 00491 vMutex l(&_mutex); 00492 00493 if (!_is_initialized) { 00494 return SD_BLOCK_DEVICE_ERROR_NO_INIT; 00495 } 00496 int status = BD_ERROR_OK; 00497 00498 size -= _block_size; 00499 // SDSC Card (CCS=0) uses byte unit address 00500 // SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit) 00501 if (SDCARD_V2HC == _card_type) { 00502 size = size / _block_size; 00503 addr = addr / _block_size; 00504 } 00505 00506 return status; 00507 } 00508 00509 bd_size_t SDHIBlockDevice::get_read_size() const 00510 { 00511 return _block_size; 00512 } 00513 00514 bd_size_t SDHIBlockDevice::get_program_size() const 00515 { 00516 return _block_size; 00517 } 00518 00519 /* 00520 bd_size_t SDHIBlockDevice::get_erase_size() const 00521 { 00522 return _block_size; 00523 } 00524 */ 00525 00526 bd_size_t SDHIBlockDevice::size() const 00527 { 00528 return _block_size*_sectors; 00529 } 00530 00531 void SDHIBlockDevice::debug(bool dbg) 00532 { 00533 _dbg = dbg; 00534 } 00535 00536 const char *SDHIBlockDevice::get_type() const 00537 { 00538 return "RZ-SDHI"; 00539 } 00540 00541 // PRIVATE FUNCTIONS 00542 00543 bd_size_t SDHIBlockDevice::_sd_sectors() { 00544 uint32_t c_size, c_size_mult, read_bl_len; 00545 uint32_t block_len, mult, blocknr; 00546 uint32_t hc_c_size; 00547 bd_size_t blocks = 0, capacity = 0; 00548 uint8_t csd[CSD_CID_LENGTH]; 00549 00550 int32_t sd_err = sd_get_reg(_sd_channel, NULL, NULL, csd, NULL, NULL); 00551 if ( sd_err != SD_OK ) 00552 { 00553 debug_if(SDHI_DBG, "Couldn't read csd response from disk\r\n"); 00554 _error(sd_err); 00555 return 0; 00556 } 00557 for(int i = 0; i < (CSD_CID_LENGTH-1); i++) 00558 { 00559 csd[i] = csd[i+1]; 00560 } 00561 00562 debug_if(SDHI_DBG,"CSD is "); 00563 for(unsigned int i = 0; i < sizeof(csd); i++) 00564 { 00565 debug_if(SDHI_DBG, "%02X ", csd[i]); 00566 } 00567 debug_if(SDHI_DBG,"\r\n"); 00568 00569 // csd_structure : csd[127:126] 00570 int csd_structure = ext_bits(csd, CSD_CID_LENGTH, 127, 126); 00571 switch (csd_structure) { 00572 case 0: 00573 c_size = ext_bits(csd, CSD_CID_LENGTH, 73, 62); // c_size : csd[73:62] 00574 c_size_mult = ext_bits(csd, CSD_CID_LENGTH, 49, 47); // c_size_mult : csd[49:47] 00575 read_bl_len = ext_bits(csd, CSD_CID_LENGTH, 83, 80); // read_bl_len : csd[83:80] - the *maximum* read block length 00576 block_len = 1 << read_bl_len; // BLOCK_LEN = 2^READ_BL_LEN 00577 mult = 1 << (c_size_mult + 2); // MULT = 2^C_SIZE_MULT+2 (C_SIZE_MULT < 8) 00578 blocknr = (c_size + 1) * mult; // BLOCKNR = (C_SIZE+1) * MULT 00579 capacity = blocknr * block_len; // memory capacity = BLOCKNR * BLOCK_LEN 00580 blocks = capacity / _block_size; 00581 debug_if(SDHI_DBG, "Standard Capacity: c_size: %lu\r\n", c_size); 00582 debug_if(SDHI_DBG, "Sectors: 0x%llx : %llu\r\n", blocks, blocks); 00583 debug_if(SDHI_DBG, "Capacity: 0x%llx : %llu MB\r\n", capacity, (capacity/(1024U*1024U))); 00584 00585 // ERASE_BLK_EN = 1: Erase in multiple of 512 bytes supported 00586 if (ext_bits(csd, CSD_CID_LENGTH, 46, 46)) { 00587 _erase_size = BLOCK_SIZE_HC; 00588 } else { 00589 // ERASE_BLK_EN = 1: Erase in multiple of SECTOR_SIZE supported 00590 _erase_size = BLOCK_SIZE_HC * (ext_bits(csd, CSD_CID_LENGTH, 45, 39) + 1); 00591 } 00592 break; 00593 00594 case 1: 00595 hc_c_size = ext_bits(csd, CSD_CID_LENGTH, 69, 48); // device size : C_SIZE : [69:48] 00596 blocks = (hc_c_size+1) << 10; // block count = C_SIZE+1) * 1K byte (512B is block size) 00597 debug_if(SDHI_DBG, "SDHC/SDXC Card: hc_c_size: %lu\r\n", hc_c_size); 00598 debug_if(SDHI_DBG, "Sectors: 0x%llx : %llu\r\n", blocks, blocks); 00599 debug_if(SDHI_DBG, "Capacity: %llu MB\r\n", (blocks/(2048U))); 00600 // ERASE_BLK_EN is fixed to 1, which means host can erase one or multiple of 512 bytes. 00601 _erase_size = BLOCK_SIZE_HC; 00602 break; 00603 00604 default: 00605 debug_if(SDHI_DBG, "CSD struct unsupported\r\n"); 00606 return 0; 00607 }; 00608 return blocks; 00609 } 00610 00611 const char * SDHIBlockDevice::_sderr_msg(int32_t errorno) 00612 { 00613 #if SDHI_DBG 00614 map<int32_t, const char *>::iterator it = _sd_err_map.find(errorno); 00615 00616 if ( it != _sd_err_map.end() ) 00617 return it->second; 00618 else 00619 return "SD UNKNWON ERROR NO\n"; 00620 #else 00621 return (const char *)0; 00622 #endif 00623 } 00624 00625 int SDHIBlockDevice::_error(int32_t errcode) 00626 { 00627 int32_t sd_err = errcode; 00628 if(_sd_channel >= 0 && _sd_channel < SDHI_COUNT ) 00629 { 00630 int32_t err = sd_get_error(_sd_channel); 00631 if ( err != SD_OK) 00632 sd_err = err; 00633 debug_if(SDHI_DBG, _sderr_msg(sd_err)); 00634 } 00635 return sd_err; 00636 } 00637 00638 #endif
Generated on Mon Jul 18 2022 23:15:42 by
1.7.2