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.
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