00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <assert.h>
00041 #include <string.h>
00042 #include <stdint.h>
00043 #include "libsdmmc.h"
00044 #include "sdmmc_trace.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define STATUS_APP_CMD (1UL << 5)
00057 #define STATUS_SWITCH_ERROR (1UL << 7)
00058 #define STATUS_READY_FOR_DATA (1UL << 8)
00059 #define STATUS_IDLE (0UL << 9)
00060 #define STATUS_READY (1UL << 9)
00061 #define STATUS_IDENT (2UL << 9)
00062 #define STATUS_STBY (3UL << 9)
00063 #define STATUS_TRAN (4UL << 9)
00064 #define STATUS_DATA (5UL << 9)
00065 #define STATUS_RCV (6UL << 9)
00066 #define STATUS_PRG (7UL << 9)
00067 #define STATUS_DIS (8UL << 9)
00068 #define STATUS_STATE (0xFUL << 9)
00069 #define STATUS_ERASE_RESET (1UL << 13)
00070 #define STATUS_WP_ERASE_SKIP (1UL << 15)
00071 #define STATUS_CIDCSD_OVERWRITE (1UL << 16)
00072 #define STATUS_OVERRUN (1UL << 17)
00073 #define STATUS_UNERRUN (1UL << 18)
00074 #define STATUS_ERROR (1UL << 19)
00075 #define STATUS_CC_ERROR (1UL << 20)
00076 #define STATUS_CARD_ECC_FAILED (1UL << 21)
00077 #define STATUS_ILLEGAL_COMMAND (1UL << 22)
00078 #define STATUS_COM_CRC_ERROR (1UL << 23)
00079 #define STATUS_UN_LOCK_FAILED (1UL << 24)
00080 #define STATUS_CARD_IS_LOCKED (1UL << 25)
00081 #define STATUS_WP_VIOLATION (1UL << 26)
00082 #define STATUS_ERASE_PARAM (1UL << 27)
00083 #define STATUS_ERASE_SEQ_ERROR (1UL << 28)
00084 #define STATUS_BLOCK_LEN_ERROR (1UL << 29)
00085 #define STATUS_ADDRESS_MISALIGN (1UL << 30)
00086 #define STATUS_ADDR_OUT_OR_RANGE (1UL << 31)
00087
00088 #define STATUS_STOP ((uint32_t)( STATUS_CARD_IS_LOCKED \
00089 | STATUS_COM_CRC_ERROR \
00090 | STATUS_ILLEGAL_COMMAND \
00091 | STATUS_CC_ERROR \
00092 | STATUS_ERROR \
00093 | STATUS_STATE \
00094 | STATUS_READY_FOR_DATA ))
00095
00096 #define STATUS_WRITE ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \
00097 | STATUS_ADDRESS_MISALIGN \
00098 | STATUS_BLOCK_LEN_ERROR \
00099 | STATUS_WP_VIOLATION \
00100 | STATUS_CARD_IS_LOCKED \
00101 | STATUS_COM_CRC_ERROR \
00102 | STATUS_ILLEGAL_COMMAND \
00103 | STATUS_CC_ERROR \
00104 | STATUS_ERROR \
00105 | STATUS_ERASE_RESET \
00106 | STATUS_STATE \
00107 | STATUS_READY_FOR_DATA ))
00108
00109 #define STATUS_READ ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \
00110 | STATUS_ADDRESS_MISALIGN \
00111 | STATUS_BLOCK_LEN_ERROR \
00112 | STATUS_CARD_IS_LOCKED \
00113 | STATUS_COM_CRC_ERROR \
00114 | STATUS_ILLEGAL_COMMAND \
00115 | STATUS_CARD_ECC_FAILED \
00116 | STATUS_CC_ERROR \
00117 | STATUS_ERROR \
00118 | STATUS_ERASE_RESET \
00119 | STATUS_STATE \
00120 | STATUS_READY_FOR_DATA ))
00121
00122 #define STATUS_SD_SWITCH ((uint32_t)( STATUS_ADDR_OUT_OR_RANGE \
00123 | STATUS_CARD_IS_LOCKED \
00124 | STATUS_COM_CRC_ERROR \
00125 | STATUS_ILLEGAL_COMMAND \
00126 | STATUS_CARD_ECC_FAILED \
00127 | STATUS_CC_ERROR \
00128 | STATUS_ERROR \
00129 | STATUS_UNERRUN \
00130 | STATUS_OVERRUN \
00131 ))
00132
00133 #define STATUS_MMC_SWITCH ((uint32_t)( STATUS_CARD_IS_LOCKED \
00134 | STATUS_COM_CRC_ERROR \
00135 | STATUS_ILLEGAL_COMMAND \
00136 | STATUS_CC_ERROR \
00137 | STATUS_ERROR \
00138 | STATUS_ERASE_RESET \
00139 \
00140 \
00141 | STATUS_SWITCH_ERROR ))
00142
00143
00144
00145
00146
00147 #define SDIO_COM_CRC_ERROR (1UL << 15)
00148
00149 #define SDIO_ILLEGAL_COMMAND (1UL << 14)
00150
00151
00152 #define STATUS_SDIO_R6 (SDIO_COM_CRC_ERROR \
00153 | SDIO_ILLEGAL_COMMAND \
00154 | SDIO_R6_ERROR)
00155
00156 #define STATUS_SDIO_R5 (0 \
00157 | SDIO_R5_ERROR \
00158 | SDIO_R5_FUNCN_ERROR \
00159 | SDIO_R5_OUT_OF_RANGE)
00160
00161
00162
00163
00164
00165
00166
00167 #define CARD_ADDR(pSd) (pSd->wAddress)
00168
00169
00170 #define BLOCK_SIZE(pSd) (pSd->wCurrBlockLen)
00171
00172
00173 #define SD_ADDRESS(pSd, address) \
00174 ( ((pSd)->dwTotalSize >= 0xFFFFFFFF) ? \
00175 (address):((address) << 9) )
00176
00177 #define MMC_ADDRESS(pSd, address) \
00178 ( ((pSd)->dwTotalSize >= 0x7FFFFFFF) ? \
00179 (address):((address) << 9) )
00180
00181
00182 #define SD_IsVer1_10(pSd) \
00183 ( SD_SCR_SD_SPEC(pSd->SCR) >= SD_SCR_SD_SPEC_1_10 )
00184
00185
00186 #define SD_IsHsModeSupported(pSd) \
00187 ( (SD_CSD_STRUCTURE(pSd->CSD)>=1) )
00188
00189
00190 #define SD_IsBusModeSupported(pSd) (1)
00191
00192
00193 #define MMC_IsVer4(pSd) ( MMC_CSD_SPEC_VERS(pSd->CSD) >= 4 )
00194
00195
00196 #define MMC_IsCSDVer1_2(pSd) \
00197 ( (SD_CSD_STRUCTURE(pSd->CSD)==2) \
00198 ||(SD_CSD_STRUCTURE(pSd->CSD)>2&&MMC_EXT_CSD_STRUCTURE(pSd->EXT)>=2) )
00199
00200
00201 #define MMC_IsBootModeSupported(pSd) \
00202 ( (MMC_IsVer4(pSd)&&(eMMC_CID_CBX(pSd->CID)==0x01) )
00203
00204
00205 #define MMC_IsBusModeSupported(pSd) (MMC_IsVer4(pSd))
00206
00207
00208 #define MMC_IsHsModeSupported(pSd) \
00209 (MMC_IsCSDVer1_2(pSd)&&(MMC_EXT_CARD_TYPE(pSd->EXT)&0x2))
00210
00211
00212
00213
00214
00215
00216 static const uint32_t sdmmcTransUnits[7] = {
00217 10, 100, 1000, 10000,
00218 0, 0, 0
00219 };
00220
00221
00222 static const uint32_t sdTransMultipliers[16] = {
00223 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
00224 };
00225
00226
00227 static const uint32_t mmcTransMultipliers[16] = {
00228 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
00229 };
00230
00231
00232
00233
00234
00235
00236
00237
00238 static void Delay(volatile unsigned int loop)
00239 {
00240 for(;loop > 0; loop --);
00241 }
00242
00243
00244
00245 static void _ResetCmd(sSdmmcCommand *pCmd)
00246 {
00247 memset(pCmd, 0, sizeof(sSdmmcCommand));
00248 }
00249
00250
00251
00252 static uint8_t _SendCmd(sSdCard *pSd, fSdmmcCallback fCallback, void* pCbArg)
00253 {
00254 sSdmmcCommand *pCmd = &pSd->sdCmd;
00255 sSdHalFunctions *pHal = pSd->pHalf;
00256 void *pDrv = pSd->pDrv;
00257 uint8_t bRc;
00258
00259 pCmd->fCallback = fCallback;
00260 pCmd->pArg = pCbArg;
00261 bRc = pHal->fCommand(pSd->pDrv, pCmd);
00262 if (fCallback == NULL) {
00263 uint32_t busy = 1;
00264 uint32_t to = 0;
00265 for (; busy == 1;) {
00266 pHal->fIOCtrl(pDrv, SDMMC_IOCTL_BUSY_CHECK, (uint32_t)&busy);
00267 if (++to > 0xF0000000UL)
00268 {
00269 pHal->fIOCtrl(pDrv, SDMMC_IOCTL_CANCEL_CMD, 0);
00270 pCmd->bStatus = SDMMC_NO_RESPONSE;
00271 break;
00272 }
00273 }
00274 return pCmd->bStatus;
00275 }
00276 return bRc;
00277 }
00278
00279
00280
00281 static uint8_t _HwSetBusWidth(sSdCard *pSd, uint8_t newWidth)
00282 {
00283 sSdHalFunctions *pHal = pSd->pHalf;
00284 void *pDrv = pSd->pDrv;
00285 uint32_t busWidth = newWidth;
00286 uint32_t rc;
00287
00288 rc = pHal->fIOCtrl(pDrv, SDMMC_IOCTL_SET_BUSMODE, (uint32_t)&busWidth);
00289 return rc;
00290 }
00291
00292
00293
00294 static uint8_t _HwGetHsMode(sSdCard *pSd)
00295 {
00296 sSdHalFunctions *pHal = pSd->pHalf;
00297 void *pDrv = pSd->pDrv;
00298 uint32_t hsMode = 0;
00299 pHal->fIOCtrl(pDrv, SDMMC_IOCTL_GET_HSMODE, (uint32_t)&hsMode);
00300 return hsMode;
00301 }
00302
00303
00304
00305 static uint8_t _HwSetHsMode(sSdCard *pSd, uint8_t newHsMode)
00306 {
00307 sSdHalFunctions *pHal = pSd->pHalf;
00308 void *pDrv = pSd->pDrv;
00309 uint32_t hsMode = newHsMode;
00310 uint32_t rc;
00311 rc = pHal->fIOCtrl(pDrv, SDMMC_IOCTL_SET_HSMODE, (uint32_t)&hsMode);
00312 return rc;
00313 }
00314
00315
00316
00317 static uint8_t _HwSetClock(sSdCard *pSd, uint32_t *pIoValClk)
00318 {
00319 sSdHalFunctions *pHal = pSd->pHalf;
00320 void *pDrv = pSd->pDrv;
00321 uint32_t clock = *pIoValClk;
00322 uint32_t rc;
00323 rc = pHal->fIOCtrl(pDrv, SDMMC_IOCTL_SET_CLOCK, (uint32_t)&clock);
00324 if (rc == SDMMC_SUCCESS || rc == SDMMC_CHANGED) {
00325 *pIoValClk = clock;
00326 }
00327 return rc;
00328 }
00329
00330
00331
00332 static uint8_t _HwReset(sSdCard *pSd)
00333 {
00334 sSdHalFunctions *pHal = pSd->pHalf;
00335 void *pDrv = pSd->pDrv;
00336 uint32_t rc;
00337 rc = pHal->fIOCtrl(pDrv, SDMMC_IOCTL_RESET, 0);
00338 return rc;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 static uint8_t SdioFindTuples(sSdCard *pSd,
00350 uint32_t address, uint32_t size,
00351 uint32_t *pAddrManfID,
00352 uint32_t *pAddrFunc0)
00353 {
00354 uint8_t error, tmp[3];
00355 uint32_t addr = address;
00356 uint8_t flagFound = 0;
00357 uint32_t addManfID = 0, addFunc0 = 0;
00358 for(;flagFound != 3;) {
00359 error = SDIO_ReadDirect(pSd, SDIO_CIA, addr, tmp, 3);
00360 if (error) {
00361 TRACE_ERROR("SdioFindTuples.RdDirect: %d\n\r", error);
00362 return error;
00363 }
00364
00365 if (tmp[0] == CISTPL_END) break;
00366
00367 else if (tmp[0] == CISTPL_MANFID) {
00368 flagFound |= 1; addManfID = addr;
00369 }
00370
00371 else if (tmp[0] == CISTPL_FUNCE && tmp[2] == 0x00) {
00372 flagFound |= 2; addFunc0 = addr;
00373 }
00374
00375 if (tmp[1] == 0) break;
00376
00377 addr += (tmp[1] + 2);
00378 if (addr > (address + size)) break;
00379 }
00380 if (pAddrManfID) *pAddrManfID = addManfID;
00381 if (pAddrFunc0) *pAddrFunc0 = addFunc0;
00382 return 0;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 static uint32_t SdmmcDecodeTransSpeed(uint32_t code,
00392 const uint32_t *unitCodes,
00393 const uint32_t *multiCodes)
00394 {
00395 uint32_t speed;
00396 uint8_t unitI, mulI;
00397
00398
00399 unitI = (code & 0x7);
00400 if (unitCodes[unitI] == 0) return 0;
00401
00402
00403 mulI = (code >> 3) & 0xF;
00404 if (multiCodes[mulI] == 0) return 0;
00405
00406 speed = unitCodes[unitI] * multiCodes[mulI];
00407 return speed;
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 static inline uint8_t Pon(sSdCard *pSd)
00417 {
00418 sSdmmcCommand *pCmd = &pSd->sdCmd;
00419 uint8_t bRc;
00420
00421 TRACE_DEBUG("PwrOn()\n\r");
00422 _ResetCmd(pCmd);
00423
00424
00425 pCmd->cmdOp.wVal = SDMMC_CMD_POWERONINIT;
00426
00427
00428 bRc = _SendCmd(pSd, NULL, NULL);
00429 return bRc;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438 static inline uint8_t Cmd0(sSdCard *pSd, uint8_t arg)
00439 {
00440 sSdmmcCommand *pCmd = &pSd->sdCmd;
00441 uint8_t bRc;
00442
00443 TRACE_DEBUG("Cmd0()\n\r");
00444 _ResetCmd(pCmd);
00445
00446
00447 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(0);
00448 pCmd->dwArg = arg;
00449
00450 bRc = _SendCmd(pSd, NULL, NULL);
00451 return bRc;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 static inline uint8_t Cmd1(sSdCard *pSd, uint8_t* pHd)
00463 {
00464 sSdmmcCommand *pCmd = &pSd->sdCmd;
00465 uint8_t bRc;
00466 uint32_t dwArg;
00467
00468 TRACE_DEBUG("Cmd1()\n\r");
00469 _ResetCmd(pCmd);
00470
00471 dwArg = SD_HOST_VOLTAGE_RANGE | MMC_OCR_ACCESS_SECTOR;
00472
00473
00474 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(3)
00475 | SDMMC_CMD_bmOD;
00476 pCmd->bCmd = 1;
00477 pCmd->dwArg = dwArg;
00478 pCmd->pResp = &dwArg;
00479
00480
00481 bRc = _SendCmd(pSd, NULL, NULL);
00482
00483
00484 if (bRc) return bRc;
00485
00486 if (dwArg & SD_OCR_BUSY) {
00487 *pHd = 0;
00488 if ((dwArg & MMC_OCR_ACCESS_MODE) == MMC_OCR_ACCESS_SECTOR) {
00489 *pHd = 1;
00490 }
00491 return 0;
00492 }
00493 return SDMMC_ERROR_NOT_INITIALIZED;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 static inline uint8_t Cmd2(sSdCard *pSd)
00505 {
00506 sSdmmcCommand *pCmd = &pSd->sdCmd;
00507 uint8_t bRc;
00508
00509 TRACE_DEBUG("Cmd2()\n\r");
00510 _ResetCmd(pCmd);
00511
00512
00513 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(2)
00514 | SDMMC_CMD_bmOD;
00515 pCmd->bCmd = 2;
00516 pCmd->pResp = pSd->CID;
00517
00518
00519 bRc = _SendCmd(pSd, NULL, NULL);
00520 return bRc;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 static uint8_t Cmd3(sSdCard *pSd)
00532 {
00533 sSdmmcCommand *pCmd = &pSd->sdCmd;
00534 uint32_t dwResp;
00535 uint8_t bRc;
00536
00537 TRACE_DEBUG("Cmd3()\n\r");
00538 _ResetCmd(pCmd);
00539
00540
00541 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(6)
00542 | SDMMC_CMD_bmOD;
00543 pCmd->bCmd = 3;
00544 pCmd->pResp = &dwResp;
00545
00546 if (pSd->bCardType == CARD_MMC || pSd->bCardType == CARD_MMCHD) {
00547 uint16_t wNewAddr = CARD_ADDR(pSd) + 1;
00548 if (wNewAddr == 0) wNewAddr ++;
00549 pCmd->dwArg = wNewAddr << 16;
00550
00551 bRc = _SendCmd(pSd, NULL, NULL);
00552 if (bRc == SDMMC_OK) {
00553 CARD_ADDR(pSd) = wNewAddr;
00554 }
00555 } else {
00556 bRc = _SendCmd(pSd, NULL, NULL);
00557 if (bRc == SDMMC_OK) {
00558 CARD_ADDR(pSd) = dwResp >> 16;
00559 }
00560 }
00561 return bRc;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 static uint8_t Cmd5(sSdCard *pSd, uint32_t *pIo)
00573 {
00574 sSdmmcCommand *pCmd = &pSd->sdCmd;
00575 uint8_t bRc;
00576
00577 TRACE_DEBUG("Cmd5()\n\r");
00578 _ResetCmd(pCmd);
00579
00580
00581 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(4)
00582 | SDMMC_CMD_bmOD;
00583 pCmd->bCmd = 5;
00584 pCmd->dwArg = *pIo;
00585 pCmd->pResp = pIo;
00586
00587
00588 bRc = _SendCmd(pSd, NULL, NULL);
00589 return bRc;
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 static uint8_t SdCmd6(sSdCard *pSd,
00602 const void * pSwitchArg,
00603 uint32_t * pStatus,
00604 uint32_t * pResp)
00605 {
00606 sSdmmcCommand *pCmd = &pSd->sdCmd;
00607 uint8_t bRc;
00608 SdCmd6Arg * pSdSwitch;
00609
00610 assert(pSd);
00611 assert(pSwitchArg);
00612
00613 TRACE_DEBUG("Cmd6()\n\r");
00614 _ResetCmd(pCmd);
00615
00616 pSdSwitch = (SdCmd6Arg*)pSwitchArg;
00617 pCmd->bCmd = 6;
00618 pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1);
00619 pCmd->dwArg = (pSdSwitch->mode << 31)
00620 | (pSdSwitch->reserved << 30)
00621 | (pSdSwitch->reserveFG6 << 20)
00622 | (pSdSwitch->reserveFG5 << 16)
00623 | (pSdSwitch->reserveFG4 << 12)
00624 | (pSdSwitch->reserveFG3 << 8)
00625 | (pSdSwitch->command << 4)
00626 | (pSdSwitch->accessMode << 0);
00627 if (pStatus) {
00628 pCmd->wBlockSize = 512/8;
00629 pCmd->wNbBlocks = 1;
00630 pCmd->pData = (uint8_t*)pStatus;
00631 }
00632 pCmd->pResp = pResp;
00633
00634 bRc = _SendCmd(pSd, NULL, NULL);
00635 return bRc;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 static uint8_t MmcCmd6(sSdCard *pSd,
00648 const void * pSwitchArg,
00649 uint32_t * pResp)
00650 {
00651 sSdmmcCommand *pCmd = &pSd->sdCmd;
00652 uint8_t bRc;
00653 MmcCmd6Arg * pMmcSwitch;
00654
00655 assert(pSd);
00656 assert(pSwitchArg);
00657
00658 TRACE_DEBUG("Cmd6()\n\r");
00659 _ResetCmd(pCmd);
00660
00661 pMmcSwitch = (MmcCmd6Arg*)pSwitchArg;
00662 pCmd->bCmd = 6;
00663 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
00664 pCmd->dwArg = (pMmcSwitch->access << 24)
00665 | (pMmcSwitch->index << 16)
00666 | (pMmcSwitch->value << 8)
00667 | (pMmcSwitch->cmdSet << 0);
00668 pCmd->pResp = pResp;
00669
00670 bRc = _SendCmd(pSd, NULL, NULL);
00671 return bRc;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 static uint8_t Cmd7(sSdCard *pSd, uint16_t address)
00683 {
00684 sSdmmcCommand *pCmd = &pSd->sdCmd;
00685 uint8_t bRc;
00686
00687 TRACE_DEBUG("Cmd7()\n\r");
00688 _ResetCmd(pCmd);
00689
00690
00691 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(address ? 1 : 0);
00692 pCmd->bCmd = 7;
00693 pCmd->dwArg = address << 16;
00694
00695
00696 bRc = _SendCmd(pSd, NULL, NULL);
00697 return bRc;
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 static uint8_t SdCmd8(sSdCard *pSd,
00711 uint8_t supplyVoltage)
00712 {
00713 sSdmmcCommand *pCmd = &pSd->sdCmd;
00714 uint32_t dwResp;
00715 uint8_t bRc;
00716
00717 TRACE_DEBUG("Cmd8()\n\r");
00718 _ResetCmd(pCmd);
00719
00720
00721 pCmd->bCmd = 8;
00722 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(7)
00723 | SDMMC_CMD_bmOD;
00724 pCmd->dwArg = (supplyVoltage << 8) | (0xAA);
00725 pCmd->pResp = &dwResp;
00726
00727
00728 bRc = _SendCmd(pSd, NULL, NULL);
00729
00730
00731 if (bRc == SDMMC_ERROR_NORESPONSE) {
00732 return SDMMC_ERROR_NORESPONSE;
00733 }
00734
00735
00736
00737
00738 else if (!bRc &&
00739 ((dwResp & 0x00000FFF) == ((uint32_t)(supplyVoltage << 8) | 0xAA))) {
00740 return 0;
00741 } else {
00742 return SDMMC_ERROR;
00743 }
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 static uint8_t MmcCmd8(sSdCard *pSd,
00756 uint8_t* pEXT)
00757 {
00758 sSdmmcCommand *pCmd = &pSd->sdCmd;
00759 uint8_t bRc;
00760
00761 TRACE_DEBUG("Cmd8()\n\r");
00762 _ResetCmd(pCmd);
00763
00764
00765 pCmd->bCmd = 8;
00766 pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1);
00767 pCmd->wBlockSize = 512;
00768 pCmd->wNbBlocks = 1;
00769 pCmd->pData = pEXT;
00770
00771
00772 bRc = _SendCmd(pSd, NULL, NULL);
00773 return bRc;
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 static uint8_t Cmd9(sSdCard *pSd)
00785 {
00786 sSdmmcCommand *pCmd = &pSd->sdCmd;
00787 uint8_t bRc;
00788
00789 TRACE_DEBUG("Cmd9()\n\r");
00790 _ResetCmd(pCmd);
00791
00792
00793 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(2);
00794 pCmd->bCmd = 9;
00795 pCmd->dwArg = CARD_ADDR(pSd) << 16;
00796 pCmd->pResp = pSd->CSD;
00797
00798
00799 bRc = _SendCmd(pSd, NULL, NULL);
00800 return bRc;
00801 }
00802
00803
00804
00805
00806
00807
00808 static uint8_t Cmd12(sSdCard *pSd, uint32_t *pStatus)
00809 {
00810 sSdmmcCommand *pCmd = &pSd->sdCmd;
00811 uint8_t bRc;
00812
00813 TRACE_DEBUG("Cmd12()\n\r");
00814 _ResetCmd(pCmd);
00815
00816
00817 pCmd->bCmd = 12;
00818 pCmd->cmdOp.wVal = SDMMC_CMD_CSTOP
00819 | SDMMC_CMD_bmBUSY;
00820 pCmd->pResp = pStatus;
00821
00822
00823 bRc = _SendCmd(pSd, NULL, NULL);
00824 return bRc;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833 static uint8_t Cmd13(sSdCard *pSd, uint32_t *pStatus)
00834 {
00835 sSdmmcCommand *pCmd = &pSd->sdCmd;
00836 uint8_t bRc;
00837
00838 TRACE_DEBUG("Cmd13()\n\r");
00839 _ResetCmd(pCmd);
00840
00841
00842 pCmd->bCmd = 13;
00843 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
00844 pCmd->dwArg = CARD_ADDR(pSd) << 16;
00845 pCmd->pResp = pStatus;
00846
00847
00848 bRc = _SendCmd(pSd, NULL, NULL);
00849 return bRc;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 static uint8_t Cmd16(sSdCard *pSd, uint16_t blkLen)
00868 {
00869 sSdmmcCommand *pCmd = &pSd->sdCmd;
00870 uint8_t bRc;
00871
00872 TRACE_DEBUG("Cmd16()\n\r");
00873 _ResetCmd(pCmd);
00874
00875
00876 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
00877 pCmd->bCmd = 16;
00878 pCmd->dwArg = blkLen;
00879
00880
00881 bRc = _SendCmd(pSd, NULL, NULL);
00882 return bRc;
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 static uint8_t Cmd17(sSdCard *pSd,
00897 uint8_t *pData,
00898 uint32_t address,
00899 uint32_t *pStatus,
00900 fSdmmcCallback callback)
00901 {
00902 sSdmmcCommand *pCmd = &pSd->sdCmd;
00903 uint8_t bRc;
00904
00905 TRACE_DEBUG("Cmd17()\n\r");
00906 _ResetCmd(pCmd);
00907
00908
00909 pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1);
00910 pCmd->bCmd = 17;
00911 pCmd->dwArg = address;
00912 pCmd->pResp = pStatus;
00913 pCmd->wBlockSize = BLOCK_SIZE(pSd);
00914 pCmd->wNbBlocks = 1;
00915 pCmd->pData = pData;
00916 pCmd->fCallback = callback;
00917
00918
00919 bRc = _SendCmd(pSd, NULL, NULL);
00920 return bRc;
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930 static uint8_t Cmd14(sSdCard *pSd,
00931 uint8_t *pData,
00932 uint8_t len,
00933 uint32_t *pStatus)
00934 {
00935 sSdmmcCommand *pCmd = &pSd->sdCmd;
00936 uint8_t bRc;
00937
00938 TRACE_DEBUG("Cmd17()\n\r");
00939 _ResetCmd(pCmd);
00940
00941
00942 pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1);
00943 pCmd->bCmd = 14;
00944 pCmd->pResp = pStatus;
00945 pCmd->wBlockSize = len;
00946 pCmd->wNbBlocks = 1;
00947 pCmd->pData = pData;
00948
00949
00950 bRc = _SendCmd(pSd, NULL, NULL);
00951 return bRc;
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961 static uint8_t Cmd19(sSdCard *pSd,
00962 uint8_t *pData,
00963 uint8_t len,
00964 uint32_t *pStatus)
00965 {
00966 sSdmmcCommand *pCmd = &pSd->sdCmd;
00967 uint8_t bRc;
00968
00969 TRACE_DEBUG("Cmd17()\n\r");
00970 _ResetCmd(pCmd);
00971
00972
00973 pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1);
00974 pCmd->bCmd = 19;
00975 pCmd->pResp = pStatus;
00976 pCmd->wBlockSize = len;
00977 pCmd->wNbBlocks = 1;
00978 pCmd->pData = pData;
00979
00980
00981 bRc = _SendCmd(pSd, NULL, NULL);
00982 return bRc;
00983 }
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 static uint8_t Cmd18(sSdCard *pSd,
00999 uint16_t nbBlock,
01000 uint8_t *pData,
01001 uint32_t address,
01002 uint32_t *pStatus,
01003 fSdmmcCallback callback)
01004 {
01005 sSdmmcCommand *pCmd = &pSd->sdCmd;
01006 uint8_t bRc;
01007
01008 TRACE_DEBUG("Cmd18()\n\r");
01009 _ResetCmd(pCmd);
01010
01011
01012 pCmd->cmdOp.wVal = SDMMC_CMD_CDATARX(1);
01013 pCmd->bCmd = 18;
01014 pCmd->dwArg = address;
01015 pCmd->pResp = pStatus;
01016 pCmd->wBlockSize = BLOCK_SIZE(pSd);
01017 pCmd->wNbBlocks = nbBlock;
01018 pCmd->pData = pData;
01019 pCmd->fCallback = callback;
01020
01021 bRc = _SendCmd(pSd, NULL, NULL);
01022 return bRc;
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 static uint8_t Cmd23(sSdCard *pSd , uint8_t write, uint32_t blocks, uint32_t *pStatus)
01036 {
01037 sSdmmcCommand *pCmd = &pSd->sdCmd;
01038 uint8_t bRc;
01039
01040 TRACE_DEBUG("Cmd23()\n\r");
01041 _ResetCmd(pCmd);
01042
01043
01044 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
01045 pCmd->bCmd = 23;
01046 pCmd->wNbBlocks = 0;
01047 pCmd->dwArg = write << 31 | blocks;
01048 pCmd->pResp = pStatus;
01049
01050
01051 bRc = _SendCmd(pSd, NULL, NULL);
01052 return bRc;
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 static inline uint8_t Cmd24(sSdCard *pSd,
01068 uint8_t *pData,
01069 uint32_t address,
01070 uint32_t *pStatus,
01071 fSdmmcCallback callback)
01072 {
01073 sSdmmcCommand *pCmd = &pSd->sdCmd;
01074 uint8_t bRc;
01075
01076 TRACE_DEBUG("Cmd24()\n\r");
01077 _ResetCmd(pCmd);
01078
01079
01080 pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1);
01081 pCmd->bCmd = 24;
01082 pCmd->dwArg = address;
01083 pCmd->pResp = pStatus;
01084 pCmd->wBlockSize = BLOCK_SIZE(pSd);
01085 pCmd->wNbBlocks = 1;
01086 pCmd->pData = pData;
01087 pCmd->fCallback = callback;
01088
01089 bRc = _SendCmd(pSd, NULL, NULL);
01090 return bRc;
01091 }
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 static uint8_t Cmd25(sSdCard *pSd,
01108 uint16_t nbBlock,
01109 uint8_t *pData,
01110 uint32_t address,
01111 uint32_t *pStatus,
01112 fSdmmcCallback callback)
01113 {
01114 sSdmmcCommand *pCmd = &pSd->sdCmd;
01115 uint8_t bRc;
01116
01117 TRACE_DEBUG("Cmd25()\n\r");
01118 _ResetCmd(pCmd);
01119
01120
01121 pCmd->cmdOp.wVal = SDMMC_CMD_CDATATX(1);
01122 pCmd->bCmd = 25;
01123 pCmd->dwArg = address;
01124 pCmd->pResp = pStatus;
01125 pCmd->wBlockSize = BLOCK_SIZE(pSd);
01126 pCmd->wNbBlocks = nbBlock;
01127 pCmd->pData = pData;
01128 pCmd->fCallback = callback;
01129
01130 bRc = _SendCmd(pSd, NULL, NULL);
01131 return bRc;
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 static uint8_t Cmd52(sSdCard *pSd,
01146 uint8_t wrFlag,
01147 uint8_t funcNb,
01148 uint8_t rdAfterWr,
01149 uint32_t addr,
01150 uint32_t *pIoData)
01151 {
01152 SdioCmd52Arg *pArg52 = (SdioCmd52Arg*)pIoData;
01153 sSdmmcCommand *pCmd = &pSd->sdCmd;
01154 uint8_t bRc;
01155
01156 pArg52->rwFlag = wrFlag;
01157 pArg52->functionNum = funcNb;
01158 pArg52->rawFlag = rdAfterWr;
01159 pArg52->regAddress = addr;
01160
01161 TRACE_DEBUG("Cmd52()\n\r");
01162 _ResetCmd(pCmd);
01163
01164
01165 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(5);
01166 pCmd->bCmd = 52;
01167 pCmd->dwArg = *pIoData;
01168 pCmd->pResp = pIoData;
01169
01170
01171 bRc = _SendCmd(pSd, NULL, NULL);
01172 return bRc;
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 static uint8_t Cmd53(sSdCard *pSd,
01189 uint8_t wrFlag,
01190 uint8_t funcNb,
01191 uint8_t blockMode,
01192 uint8_t incAddr,
01193 uint32_t addr,
01194 uint8_t *pIoData,
01195 uint16_t len,
01196 uint32_t *pArgResp,
01197 fSdmmcCallback fCallback,
01198 void* pCbArg)
01199 {
01200 sSdmmcCommand *pCmd = &pSd->sdCmd;
01201 uint8_t bRc;
01202
01203 SdioCmd53Arg* pArg53;
01204 pArg53 = (SdioCmd53Arg*)pArgResp;
01205 pArg53->rwFlag = wrFlag;
01206 pArg53->functionNum = funcNb;
01207 pArg53->blockMode = blockMode;
01208 pArg53->opCode = incAddr;
01209 pArg53->regAddress = addr;
01210 pArg53->count = len;
01211
01212
01213 pCmd->bCmd = 53;
01214 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(5)
01215 | SDMMC_CMD_bmIO;
01216 if (wrFlag) {
01217 pCmd->cmdOp.wVal |= SDMMC_CMD_bmDATATX;
01218 } else {
01219 pCmd->cmdOp.wVal |= SDMMC_CMD_bmDATARX;
01220 }
01221 if (blockMode) {
01222 pCmd->wBlockSize = pSd->wCurrBlockLen;
01223 } else {
01224
01225 pCmd->wBlockSize = 0;
01226
01227 }
01228 pCmd->dwArg = *pArgResp;
01229 pCmd->pResp = pArgResp;
01230 pCmd->pData = pIoData;
01231 pCmd->wNbBlocks = len;
01232 pCmd->fCallback = fCallback;
01233 pCmd->pArg = pCbArg;
01234
01235 bRc = _SendCmd(pSd, NULL, NULL);
01236 return bRc;
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246 static uint8_t Cmd55(sSdCard *pSd, uint16_t cardAddr)
01247 {
01248 sSdmmcCommand *pCmd = &pSd->sdCmd;
01249 uint32_t dwResp;
01250 uint8_t bRc;
01251
01252 TRACE_DEBUG( "Cmd55()\n\r" ) ;
01253 _ResetCmd(pCmd);
01254
01255
01256 pCmd->bCmd = 55;
01257 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1)
01258 | (cardAddr ? 0 : SDMMC_CMD_bmOD);
01259 pCmd->dwArg = cardAddr << 16;
01260 pCmd->pResp = &dwResp;
01261
01262
01263 bRc = _SendCmd(pSd, NULL, NULL);
01264 return bRc;
01265 }
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 static uint8_t SdAcmd6(sSdCard *pSd,
01278 uint32_t arg,
01279 uint32_t *pStatus)
01280 {
01281 sSdmmcCommand *pCmd = &pSd->sdCmd;
01282 uint8_t bRc;
01283
01284 TRACE_DEBUG( "Acmd6()\n\r" ) ;
01285 _ResetCmd(pCmd);
01286
01287
01288 pCmd->bCmd = 6;
01289 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
01290 pCmd->pResp = pStatus;
01291 pCmd->dwArg = arg;
01292
01293
01294 bRc = _SendCmd(pSd, NULL, NULL);
01295 return bRc;
01296 }
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 static uint8_t Acmd6(sSdCard *pSd, uint8_t busWidth)
01307 {
01308 uint8_t error;
01309 uint32_t arg;
01310 error = Cmd55(pSd, CARD_ADDR(pSd));
01311 if (error) {
01312 TRACE_ERROR("Acmd6.cmd55:%d\n\r", error);
01313 return error;
01314 }
01315 arg = (busWidth == 4)
01316 ? SD_ST_DATA_BUS_WIDTH_4BIT : SD_ST_DATA_BUS_WIDTH_1BIT;
01317 return SdAcmd6(pSd, arg, NULL);
01318 }
01319
01320
01321
01322
01323
01324
01325
01326
01327 static uint8_t SdAcmd41(sSdCard *pSd, uint32_t* pOpIo)
01328 {
01329 sSdmmcCommand *pCmd = &pSd->sdCmd;
01330 uint8_t bRc;
01331
01332 TRACE_DEBUG( "Acmd41()\n\r" ) ;
01333 _ResetCmd(pCmd);
01334
01335
01336 pCmd->bCmd = 41;
01337 pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(3);
01338 pCmd->dwArg = *pOpIo;
01339 pCmd->pResp = pOpIo;
01340
01341
01342 bRc = _SendCmd(pSd, NULL, NULL);
01343 return bRc;
01344 }
01345
01346
01347
01348
01349
01350
01351
01352
01353 static uint8_t Acmd41(sSdCard *pSd, uint8_t hcs, uint8_t *pCCS)
01354 {
01355 uint8_t error;
01356 uint32_t arg;
01357 do {
01358 error = Cmd55(pSd, 0);
01359 if (error) {
01360 TRACE_ERROR("Acmd41.cmd55:%d\n\r", error);
01361 return error;
01362 }
01363 arg = SD_HOST_VOLTAGE_RANGE;
01364 if (hcs) arg |= SD_OCR_CCS;
01365 error = SdAcmd41(pSd, &arg);
01366 if (error) {
01367 TRACE_ERROR("Acmd41.cmd41:%d\n\r", error);
01368 return error;
01369 }
01370 *pCCS = ((arg & SD_OCR_CCS)!=0);
01371 } while ((arg & SD_OCR_BUSY) != SD_OCR_BUSY);
01372 return 0;
01373 }
01374 #if 0
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 static uint8_t SdmmcRead(sSdCard *pSd,
01388 uint16_t blockSize,
01389 uint16_t nbBlock,
01390 uint8_t *pData,
01391 fSdmmcCallback fCallback,
01392 void* pArg)
01393 {
01394 sSdmmcCommand *pCmd = &pSd->sdCmd;
01395 uint8_t bRc;
01396
01397 TRACE_DEBUG( "Read()\n\r" ) ;
01398 _ResetCmd(pCmd);
01399
01400
01401 pCmd->cmdOp.wVal = SDMMC_CMD_DATARX;
01402 pCmd->wBlockSize = blockSize;
01403 pCmd->wNbBlocks = nbBlock;
01404 pCmd->pData = pData;
01405
01406
01407 bRc = _SendCmd(pSd, fCallback, pArg);
01408 return bRc;
01409 }
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 static uint8_t SdmmcWrite(sSdCard *pSd,
01424 uint16_t blockSize,
01425 uint16_t nbBlock,
01426 const uint8_t *pData,
01427 fSdmmcCallback fCallback,
01428 void* pArg)
01429 {
01430 sSdmmcCommand *pCmd = &pSd->sdCmd;
01431 uint8_t bRc;
01432
01433 TRACE_DEBUG( "Write()\n\r" ) ;
01434 _ResetCmd(pCmd);
01435
01436
01437 pCmd->cmdOp.wVal = SDMMC_CMD_DATATX;
01438 pCmd->wBlockSize = blockSize;
01439 pCmd->wNbBlocks = nbBlock;
01440 pCmd->pData = (uint8_t*)pData;
01441
01442
01443 bRc = _SendCmd(pSd, fCallback, pArg);
01444 return bRc;
01445 }
01446 #endif
01447
01448
01449
01450
01451
01452
01453 static uint8_t SwReset(sSdCard *pSd, uint32_t retry)
01454 {
01455 uint32_t i;
01456 uint8_t error = 0;
01457
01458 for (i = 0; i < retry; i ++) {
01459 error = Cmd0(pSd, 0);
01460 if (error != SDMMC_ERROR_NORESPONSE)
01461 break;
01462 }
01463 return error;
01464 }
01465
01466
01467
01468
01469
01470 static uint8_t _StopCmd(sSdCard *pSd)
01471 {
01472 uint32_t status;
01473 uint32_t state;
01474 volatile uint32_t i, j;
01475 uint8_t error = 0;
01476
01477 for (i = 0; i < 9; i ++) {
01478 error = Cmd12(pSd, &status);
01479
01480 if (error) {
01481 TRACE_ERROR("_StopC.Cmd12: st%x, er%d\n\r", pSd->bState, error);
01482 return error;
01483 }
01484
01485 for (j = 0; j < 299; j ++) {
01486 error = Cmd13(pSd, &status);
01487
01488 for (i = 0; i < 0x1600 ; i++);
01489 if (error) {
01490 TRACE_ERROR("_StopC.Cmd13: st%x, er%d\n\r", pSd->bState, error);
01491 return error;
01492 }
01493 state = status & STATUS_STATE;
01494
01495
01496 if( state == STATUS_IDLE
01497 || state == STATUS_READY
01498 || state == STATUS_IDENT
01499 || state == STATUS_STBY
01500 || state == STATUS_DIS ) {
01501 TRACE_ERROR("_StopC.state\n\r");
01502 return SDMMC_ERROR_NOT_INITIALIZED;
01503 }
01504
01505
01506 if ( (status & STATUS_READY_FOR_DATA) == STATUS_READY_FOR_DATA
01507 && state == STATUS_TRAN )
01508 return SDMMC_SUCCESS;
01509
01510 }
01511
01512 if (state != STATUS_RCV)
01513 break;
01514 }
01515 return SDMMC_ERROR_STATE;
01516 }
01517
01518
01519
01520
01521
01522 static uint8_t PerformSingleTransfer(sSdCard *pSd,
01523 uint32_t address,
01524 uint8_t *pData,
01525 uint8_t isRead)
01526 {
01527 uint32_t status;
01528 uint8_t error = 0;
01529 uint8_t sd, mmc;
01530 uint32_t sdmmc_address;
01531 sdmmc_address = 0;
01532 sd = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD);
01533 mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
01534 if(mmc) sdmmc_address = MMC_ADDRESS(pSd,address);
01535 if(sd) {
01536 sdmmc_address = SD_ADDRESS(pSd,address);
01537 if((pSd->bState == SDMMC_STATE_DATA_RD)
01538 || (pSd->bState == SDMMC_STATE_DATA_WR)) {
01539
01540 error = _StopCmd(pSd);
01541 if (error) return error;
01542 pSd->bState = SDMMC_STATE_TRAN;
01543
01544 }
01545 }
01546 if ( isRead ) {
01547
01548 error = Cmd17( pSd, pData, sdmmc_address, &status, NULL ) ;
01549 if ( error ) {
01550 TRACE_ERROR("SingleTx.Cmd17: %d\n\r", error);
01551 return error;
01552 }
01553
01554 if (status & ~(STATUS_READY_FOR_DATA | STATUS_STATE)) {
01555 TRACE_ERROR("CMD17.stat: %lx\n\r",
01556 status & ~(STATUS_READY_FOR_DATA | STATUS_STATE));
01557 return SDMMC_ERROR;
01558 }
01559 return error;
01560 }
01561
01562 {
01563
01564 error = Cmd24(pSd,
01565 pData, sdmmc_address,
01566 &status,
01567 NULL);
01568 if (error) {
01569 TRACE_DEBUG("SingleTx.Cmd24: %d\n\r", error);
01570 return error;
01571 }
01572
01573 if (status & (STATUS_WRITE & ~(STATUS_READY_FOR_DATA | STATUS_STATE))) {
01574 TRACE_ERROR("CMD24(0x%x).stat: %x\n\r",
01575 (unsigned int) sdmmc_address,
01576 (unsigned int)(status & (STATUS_WRITE & ~(STATUS_READY_FOR_DATA
01577 | STATUS_STATE))));
01578 return SDMMC_ERROR;
01579 }
01580 }
01581
01582 return error;
01583 }
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596 static uint8_t MoveToTransferState(sSdCard *pSd,
01597 uint32_t address,
01598 uint16_t nbBlocks,
01599 uint8_t *pData,
01600 uint8_t isRead)
01601 {
01602 uint32_t status;
01603 uint8_t error;
01604 uint8_t sd, mmc;
01605 uint32_t sdmmc_address;
01606 sd = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD);
01607 mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
01608 sdmmc_address = 0;
01609 if(mmc) sdmmc_address = MMC_ADDRESS(pSd,address);
01610 if(sd) {
01611 sdmmc_address = SD_ADDRESS(pSd,address);
01612 if ( (pSd->bState == SDMMC_STATE_DATA_RD)
01613 || (pSd->bState == SDMMC_STATE_DATA_WR) ) {
01614 error = _StopCmd(pSd);
01615 if (error) return error;
01616 }
01617 }
01618 if ( isRead ) {
01619
01620 if(mmc) error = Cmd23(pSd, 0, nbBlocks, &status);
01621
01622 error = Cmd18(pSd, nbBlocks, pData, sdmmc_address, &status, NULL);
01623 if (error) {
01624 TRACE_ERROR("MTranState.Cmd18: %d\n\r", error);
01625 return error;
01626 }
01627 if (status & ~(STATUS_READY_FOR_DATA | STATUS_STATE)) {
01628 TRACE_ERROR("CMD18.stat: %lx\n\r",
01629 status & ~(STATUS_READY_FOR_DATA | STATUS_STATE));
01630 return SDMMC_ERROR;
01631 }
01632 } else {
01633
01634 if(mmc) error = Cmd23(pSd, 0, nbBlocks, &status);
01635
01636 error = Cmd25(pSd,
01637 nbBlocks,
01638 pData, sdmmc_address,
01639 &status,
01640 NULL);
01641 if (error) {
01642 TRACE_DEBUG("MoveToTransferState.Cmd25: %d\n\r", error);
01643 return error;
01644 }
01645 if (status & (STATUS_WRITE & ~(STATUS_READY_FOR_DATA | STATUS_STATE))) {
01646 TRACE_ERROR("CMD25(0x%x, %u).stat: %x\n\r",
01647 (unsigned int)sdmmc_address, (unsigned int)nbBlocks,
01648 (unsigned int)(status & (STATUS_WRITE &
01649 ~(STATUS_READY_FOR_DATA | STATUS_STATE))));
01650 return SDMMC_ERROR;
01651 }
01652 }
01653 return error;
01654 }
01655
01656
01657
01658
01659
01660
01661
01662 static uint8_t MmcSelectCard(sSdCard *pSd, uint16_t address, uint8_t statCheck)
01663 {
01664 uint8_t error;
01665 uint32_t status;
01666 uint32_t targetState = address ? STATUS_TRAN : STATUS_STBY;
01667 uint32_t srcState = address ? STATUS_STBY : STATUS_TRAN;
01668
01669
01670
01671 while(statCheck) {
01672 error = Cmd13(pSd, &status);
01673 if (error) {
01674 TRACE_ERROR("MmcSelectCard.Cmd13 (%d)\n\r", error);
01675 return error;
01676 }
01677 if ((status & STATUS_READY_FOR_DATA)) {
01678 uint32_t currState = status & STATUS_STATE;
01679 if (currState == targetState) return 0;
01680 if (currState != srcState) {
01681 TRACE_ERROR("MmcSelectCard, wrong state %x\n\r",
01682 (unsigned int)currState);
01683 return SDMMC_ERROR;
01684 }
01685 break;
01686 }
01687 }
01688
01689
01690
01691 error = Cmd7(pSd, address);
01692 if (error == SDMMC_ERROR_NOT_INITIALIZED && address == 0) {}
01693 else if (error) {
01694 TRACE_ERROR("MmcSelectCard.Cmd7 (%d)\n\r", error);
01695 }
01696
01697 return error;
01698 }
01699
01700
01701
01702
01703
01704 static void MmcGetExtInformation(sSdCard *pSd)
01705 {
01706 uint8_t error;
01707
01708 if(SD_CSD_STRUCTURE(pSd->CSD) >= 2 && MMC_IsVer4(pSd)) {
01709 error = MmcCmd8(pSd, (uint8_t*)pSd->EXT);
01710 if (error) {
01711 TRACE_ERROR("MmcGetExt.Cmd8: %d\n\r", error);
01712 }
01713 }
01714 }
01715
01716
01717
01718
01719
01720 static uint32_t SdmmcGetMaxSpeed(sSdCard *pSd)
01721 {
01722 uint32_t speed = 0;
01723 TRACE_INFO(" .TRAN_SPEED 0x%X\r\n",
01724 (unsigned int)SD_CSD_TRAN_SPEED(pSd->CSD));
01725 if (pSd->bCardType & CARD_TYPE_bmSDMMC) {
01726 speed = SdmmcDecodeTransSpeed(SD_CSD_TRAN_SPEED(pSd->CSD),
01727 sdmmcTransUnits,
01728 ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD) ?
01729 sdTransMultipliers : mmcTransMultipliers);
01730 }
01731 return speed;
01732 }
01733
01734
01735
01736
01737
01738 static uint32_t SdioGetMaxSpeed(sSdCard *pSd)
01739 {
01740 uint8_t error;
01741 uint32_t speed = 0;
01742 uint32_t addr = 0;
01743 uint8_t buf[6];
01744 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
01745
01746 error = SDIO_ReadDirect(pSd,
01747 SDIO_CIA, SDIO_CIS_PTR_REG,
01748 (uint8_t*)&addr, 3);
01749 if (error) {
01750 TRACE_ERROR("SdioUpdateCardInformation.RdDirect: %d\n\r", error);
01751 return error;
01752 }
01753 error = SdioFindTuples(pSd, addr, 256, NULL, &addr);
01754 if (error) {
01755 TRACE_ERROR("SdioUpdateCardInformation.FindTuple: %d\n\r", error);
01756 return error;
01757 }
01758 if (addr) {
01759
01760 SDIO_ReadDirect(pSd, SDIO_CIA, addr, buf, 6);
01761 speed = SdmmcDecodeTransSpeed(buf[5],
01762 sdmmcTransUnits,
01763 sdTransMultipliers);
01764 }
01765 }
01766 return speed;
01767 }
01768
01769
01770
01771
01772
01773 static void SdGetExtInformation(sSdCard *pSd)
01774 {
01775 }
01776
01777
01778
01779
01780
01781
01782
01783
01784 static void SdMmcUpdateInformation(sSdCard *pSd,
01785 uint8_t csd,
01786 uint8_t extData)
01787 {
01788 uint8_t error;
01789
01790
01791 if (csd) {
01792 MmcSelectCard(pSd, 0, 1);
01793 Delay(800);
01794 error = Cmd9(pSd);
01795 if (error ) {
01796 TRACE_ERROR("SdMmcUpdateInfo.Cmd9 (%d)\n\r", error);
01797 return;
01798 }
01799 error = MmcSelectCard(pSd, pSd->wAddress, 1);
01800 }
01801 if (extData) {
01802 switch(pSd->bCardType & CARD_TYPE_bmSDMMC) {
01803 case CARD_TYPE_bmSD: SdGetExtInformation(pSd); break;
01804 case CARD_TYPE_bmMMC: MmcGetExtInformation(pSd); break;
01805 default: break;
01806 }
01807 }
01808 }
01809
01810
01811 uint32_t switchStatus[512/32];
01812
01813
01814
01815
01816
01817 static uint8_t SdMmcEnableHighSpeed(sSdCard *pSd)
01818 {
01819 uint8_t error;
01820 uint8_t io, sd, mmc;
01821 uint32_t status;
01822 io = ((pSd->bCardType & CARD_TYPE_bmSDIO) > 0);
01823 sd = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD);
01824 mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
01825
01826
01827 if (_HwGetHsMode(pSd) == 0) {
01828 return SDMMC_ERROR_NOT_SUPPORT;
01829 }
01830
01831 if (mmc) {
01832
01833
01834 if (MMC_IsHsModeSupported(pSd)) {
01835
01836 MmcCmd6Arg cmd6Arg = {
01837 0x3,
01838 MMC_EXT_HS_TIMING_I,
01839 MMC_EXT_HS_TIMING_EN,
01840 0};
01841 error = MmcCmd6(pSd, &cmd6Arg, &status);
01842 if (error) {
01843 TRACE_ERROR("SdMmcEnableHS.Cmd6: %d\n\r", error);
01844 return SDMMC_ERROR;
01845 }
01846 else if (status & STATUS_MMC_SWITCH) {
01847 TRACE_ERROR("Mmc Switch HS: %x\n\r", (unsigned int)status);
01848 return SDMMC_ERROR_NOT_SUPPORT;
01849 }
01850 } else {
01851 TRACE_INFO("MMC without HS support\n\r");
01852 return SDMMC_ERROR_NOT_SUPPORT;
01853 }
01854 TRACE_WARNING("MMC HS Enabled\n\r");
01855 }
01856
01857 else {
01858 if (io) {
01859
01860 status = 0;
01861 error = Cmd52(pSd, 0, SDIO_CIA, 0, SDIO_HS_REG, &status);
01862 if (error) {
01863 TRACE_ERROR("SdMmcEnableHS.Cmd52: %d\n\r", error);
01864 return SDMMC_ERROR;
01865 }
01866 if ((status & SDIO_SHS) == 0) {
01867 TRACE_INFO("HS Mode not supported by SDIO\n\r");
01868 return SDMMC_ERROR_NOT_SUPPORT;
01869 }
01870
01871 else {
01872 status = SDIO_EHS;
01873 error = Cmd52(pSd, 1, SDIO_CIA, 1, SDIO_HS_REG, &status);
01874 if (error) {
01875 TRACE_ERROR("SdMmcEnableHS.Cmd52 H: %d\n\r", error);
01876 return SDMMC_ERROR;
01877 }
01878 if (status & SDIO_EHS) {
01879 TRACE_WARNING("SDIO HS Enabled\n\r");
01880 }
01881 }
01882 }
01883 if (sd) {
01884
01885 if (SD_IsHsModeSupported(pSd)) {
01886
01887 SdCmd6Arg cmd6Arg = {
01888 1, 0, 0xF, 0xF, 0xF, 0xF, 0, 1
01889 };
01890
01891 error = SdCmd6(pSd, &cmd6Arg, switchStatus, &status);
01892 if (error || (status & STATUS_SWITCH_ERROR)) {
01893 TRACE_ERROR("SD HS Fail\n\r");
01894 return SDMMC_ERROR;
01895 }
01896 else if (SD_SWITCH_ST_FUN_GRP1_RC(switchStatus)
01897 == SD_SWITCH_ST_FUN_GRP_RC_ERROR) {
01898 TRACE_WARNING("SD HS Not Supported\n\r");
01899 return SDMMC_ERROR_NOT_SUPPORT;
01900 }
01901 else if (SD_SWITCH_ST_FUN_GRP1_BUSY(switchStatus)) {
01902 TRACE_ERROR("SD HS Locked\n\r");
01903 return SDMMC_ERROR_BUSY;
01904 } else {
01905 TRACE_INFO("SD HS Enabled\n\r");
01906 }
01907 } else {
01908 TRACE_INFO("HS Not Supported in SD Rev 0x%x\n\r",
01909 (unsigned)SD_SCR_SD_SPEC(pSd));
01910 return SDMMC_ERROR_NOT_SUPPORT;
01911 }
01912 }
01913 }
01914
01915
01916 _HwSetHsMode(pSd, 1);
01917 return 0;
01918 }
01919
01920 static uint8_t mmcSelectBuswidth(sSdCard *pSd, uint8_t busWidth)
01921 {
01922 uint8_t error;
01923 uint32_t status;
01924 MmcCmd6Arg cmd6Arg = { 0x1, MMC_EXT_BUS_WIDTH_I, MMC_EXT_BUS_WIDTH_1BIT, 0};
01925 switch(busWidth) {
01926 case 4:
01927 cmd6Arg.value = MMC_EXT_BUS_WIDTH_4BITS;
01928 break;
01929 case 8:
01930 cmd6Arg.value = MMC_EXT_BUS_WIDTH_8BUTS;
01931 break;
01932 case 1:
01933 return SDMMC_ERROR_NOT_SUPPORT;
01934 }
01935 error = MmcCmd6(pSd, &cmd6Arg, &status);
01936 if (error) {
01937 TRACE_ERROR("SdMmcSetBuswidth.Cmd6: %d\n\r", error);
01938 return SDMMC_ERROR;
01939 } else {
01940 if (status & STATUS_MMC_SWITCH) {
01941 TRACE_ERROR("MMC Bus Switch error %x\n\r", (unsigned int)status);
01942 return SDMMC_ERROR_NOT_SUPPORT;
01943 }
01944 TRACE_WARNING("MMC Bus mode %x\n\r", busWidth);
01945 }
01946 return SDMMC_OK;
01947 }
01948
01949
01950 static uint8_t data_8bits[8];
01951 static uint8_t data_4bits[4];
01952 static uint8_t read_data[8];
01953
01954 static uint8_t mmcDetectBuswidth(sSdCard *pSd)
01955 {
01956 uint8_t *pData;
01957 uint8_t busWidth;
01958 uint32_t len;
01959 uint32_t i;
01960 uint8_t error;
01961 uint32_t status;
01962
01963 data_8bits[0] = 0xaa;
01964 data_8bits[1] = 0x55;
01965 data_8bits[2] = 0x0;
01966 data_8bits[3] = 0x0;
01967 data_8bits[4] = 0x0;
01968 data_8bits[5] = 0x0;
01969 data_8bits[6] = 0x0;
01970 data_8bits[7] = 0x0;
01971
01972 for (busWidth = 8, len = 2; busWidth != 0; busWidth -= 4,len--) {
01973 error = mmcSelectBuswidth(pSd, busWidth);
01974 if (error) {
01975 TRACE_ERROR("mmcDetectBuswidth %d\n\r", error);
01976 return 0;
01977 }
01978 pSd->bBusMode = busWidth;
01979 _HwSetBusWidth(pSd, busWidth);
01980 pData = (busWidth == 8)?data_8bits:data_4bits;
01981 error = Cmd19(pSd, pData, busWidth, &status);
01982 if (error) {
01983 TRACE_ERROR("Cmd19 %u, %x\n\r",
01984 (unsigned int)error, (unsigned int)status);
01985 return 0;
01986 }
01987 error = Cmd14(pSd, read_data, busWidth, &status);
01988 if (error) {
01989 TRACE_ERROR("Cmd14 %d\n\r", error);
01990 return 0;
01991 }
01992 for (i = 0; i < len; i++) {
01993 if ((pData[i] ^ read_data[i]) != 0xff)
01994 break;
01995 }
01996 if (i == len) {
01997 printf ("MMC: %d-bit bus width detected\n\r", busWidth);
01998 break;
01999 }
02000 }
02001 return busWidth;
02002 }
02003
02004
02005
02006
02007 static uint8_t SdMmcDesideBuswidth(sSdCard *pSd)
02008 {
02009 uint8_t error, busWidth;
02010 uint8_t mmc;
02011
02012
02013 busWidth = 4;
02014 mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
02015 if (mmc) {
02016
02017 if (MMC_CSD_SPEC_VERS(pSd->CSD) >= 4) {
02018 busWidth = mmcDetectBuswidth(pSd);
02019 } else {
02020 TRACE_WARNING("MMC 1-bit only\n\r");
02021 return SDMMC_ERROR_NOT_SUPPORT;
02022 }
02023 } else {
02024
02025 uint8_t io = ((pSd->bCardType & CARD_TYPE_bmSDIO) > 0);
02026 uint8_t sd = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD);
02027 if (busWidth == 1)
02028 return SDMMC_ERROR_NOT_SUPPORT;
02029
02030 busWidth = 4;
02031
02032
02033 if (io) {
02034
02035 busWidth = 1;
02036 }
02037
02038
02039 if (sd) {
02040 error = Acmd6(pSd, busWidth);
02041 if (error) {
02042 TRACE_ERROR("SdMmcSetBusWidth.Acmd6: %d\n\r", error);
02043 return SDMMC_ERROR;
02044 }
02045 TRACE_WARNING("SD 4-bit mode\n\r");
02046 }
02047
02048 pSd->bBusMode = busWidth;
02049 _HwSetBusWidth(pSd, busWidth);
02050 }
02051 return 0;
02052 }
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063 static uint8_t SdMmcIdentify(sSdCard *pSd)
02064 {
02065 uint8_t mem = 0, io = 0, f8 = 0, mp = 1, ccs = 0;
02066 uint32_t status;
02067 uint8_t error;
02068
02069 _HwSetHsMode(pSd, 0);
02070 _HwSetBusWidth(pSd, 1);
02071
02072 status = SDIO_RES;
02073 error = Cmd52(pSd, 1, SDIO_CIA, 0, SDIO_IOA_REG, &status);
02074 if (!error && ((status & STATUS_SDIO_R5)==0)){}
02075 else if (error == SDMMC_ERROR_NORESPONSE){}
02076 else {
02077 TRACE_DEBUG("SdMmcIdentify.Cmd52 fail: %u, %x\n\r", error, status);
02078 }
02079
02080 error = SwReset(pSd, 1);
02081 if (error) {
02082 TRACE_DEBUG("SdMmcIdentify.SwReset fail: %u\n\r", error);
02083 }
02084
02085
02086
02087
02088
02089
02090 error = SdCmd8(pSd, 1);
02091 if (error == 0) f8 = 1;
02092 else if (error != SDMMC_ERROR_NORESPONSE) {
02093 TRACE_ERROR("SdMmcIdentify.Cmd8: %d\n\r", error);
02094 return SDMMC_ERROR;
02095 }
02096
02097 else Delay(8000);
02098
02099
02100 status = 0;
02101 error = Cmd5(pSd, &status);
02102 if (error) {
02103 TRACE_INFO("SdMmcIdentify.Cmd5: %d\n\r", error)
02104 }
02105
02106 else if ((status & SDIO_OCR_NF) > 0) {
02107 unsigned int cmd5Retries = 10000;
02108 do {
02109 status &= SD_HOST_VOLTAGE_RANGE;
02110 error = Cmd5(pSd, &status);
02111 if (status & SD_OCR_BUSY) break;
02112 } while(!error && cmd5Retries --);
02113 if (error) {
02114 TRACE_ERROR("SdMmcIdentify.Cmd5 V: %d\n\r", error);
02115 return SDMMC_ERROR;
02116 }
02117 io = 1;
02118 TRACE_INFO("SDIO\n\r");
02119
02120 mp = ((status & SDIO_OCR_MP) > 0);
02121 }
02122
02123 if (mp) {
02124
02125 error = Acmd41(pSd, f8, &ccs);
02126 if (error) {
02127 unsigned int cmd1Retries = 10000;
02128 TRACE_DEBUG("SdMmcIdentify.Acmd41: %u, try MMC\n\r", error);
02129
02130 error = SwReset(pSd, 10);
02131 if (error) {
02132 TRACE_ERROR("SdMmcIdentify.Mmc.SwReset: %d\n\r", error);
02133 return SDMMC_ERROR;
02134 }
02135 ccs = 1;
02136 do { error = Cmd1(pSd, &ccs); }while(error && cmd1Retries -- > 0);
02137 if (error) {
02138 TRACE_ERROR("SdMmcIdentify.Cmd1: %d\n\r", error);
02139 return SDMMC_ERROR;
02140 }
02141 else if (ccs) pSd->bCardType = CARD_MMCHD;
02142 else pSd->bCardType = CARD_MMC;
02143
02144 TRACE_INFO("MMC Card\n\r");
02145 return 0;
02146 }
02147 else if (ccs) { TRACE_INFO("SDHC MEM\n\r");}
02148 else { TRACE_INFO("SD MEM\n\r");}
02149 mem = 1;
02150 }
02151
02152 if (!mem) {
02153 if (io) pSd->bCardType = CARD_SDIO;
02154 else {
02155 TRACE_ERROR("Unknown card\n\r");
02156 return SDMMC_ERROR;
02157 }
02158 }
02159
02160 else if (io)
02161 pSd->bCardType = ccs ? CARD_SDHCCOMBO : CARD_SDCOMBO;
02162
02163 else
02164 pSd->bCardType = ccs ? CARD_SDHC : CARD_SD;
02165
02166 return 0;
02167 }
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 static uint8_t SdMmcEnum(sSdCard *pSd)
02179 {
02180 uint8_t mem , io;
02181 uint8_t error;
02182 uint32_t ioSpeed = 0, memSpeed = 0;
02183 uint8_t hsExec = 0, bwExec = 0;
02184
02185
02186 mem = ((pSd->bCardType & CARD_TYPE_bmSDMMC) > 0);
02187 io = ((pSd->bCardType & CARD_TYPE_bmSDIO) > 0);
02188
02189
02190
02191
02192
02193
02194 if (mem) {
02195 error = Cmd2(pSd);
02196 if (error) {
02197 TRACE_ERROR("SdMmcInit.cmd2(%d)\n\r", error);
02198 return error;
02199 }
02200 }
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 error = Cmd3(pSd);
02212 if (error) {
02213 TRACE_ERROR("SdMmcInit.cmd3(%d)\n\r", error);
02214 return error;
02215 }
02216
02217
02218
02219
02220 if (mem) {
02221 error = Cmd9(pSd);
02222 if (error) {
02223 TRACE_ERROR("SdMmcInit.cmd9(%d)\n\r", error);
02224 return error;
02225 }
02226 }
02227
02228
02229 error = MmcSelectCard(pSd, CARD_ADDR(pSd), 0);
02230 if (error) {
02231 TRACE_ERROR("SdMmcInit.SelCard(%d)\n\r", error);
02232 return error;
02233 }
02234
02235
02236
02237
02238 TRACE_INFO("Card Type %u, CSD_STRUCTURE %u\n\r",
02239 (unsigned int)pSd->bCardType, (unsigned int)SD_CSD_STRUCTURE(pSd));
02240
02241
02242 SdMmcUpdateInformation(pSd, 1, 1);
02243
02244
02245 if (io) ioSpeed = SdioGetMaxSpeed(pSd);
02246 if (mem) memSpeed = SdmmcGetMaxSpeed(pSd);
02247
02248
02249
02250 if (io && mem) {
02251 pSd->dwTranSpeed = (ioSpeed > memSpeed) ? memSpeed : ioSpeed;
02252 }
02253
02254 else if (io) {
02255 pSd->dwTranSpeed = ioSpeed;
02256 }
02257
02258 else if (mem) {
02259 pSd->dwTranSpeed = memSpeed;
02260 }
02261 pSd->dwTranSpeed *= 1000;
02262
02263
02264 error = SdMmcDesideBuswidth(pSd);
02265 if (!error) bwExec = 1;
02266 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
02267 TRACE_ERROR("SdmmcEnum.DesideBusWidth: %d\n\r", error);
02268 return SDMMC_ERROR;
02269 }
02270
02271
02272 error = SdMmcEnableHighSpeed(pSd);
02273 if (!error) hsExec = 1;
02274 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
02275 return SDMMC_ERROR;
02276 }
02277
02278
02279 if (hsExec) pSd->dwTranSpeed *= 2;
02280
02281
02282 if (bwExec || hsExec) SdMmcUpdateInformation(pSd, hsExec, 1);
02283
02284 return 0;
02285 }
02286
02287
02288
02289
02290
02291
02292
02293 void _DumpREG(void* pREG, uint32_t dwSize)
02294 {
02295 uint8_t *p = (uint8_t*)pREG;
02296 uint32_t i;
02297 for (i = 0; i < dwSize; i ++)
02298 {
02299 if ((i % 16) == 0) printf("\n\r [%04X]", (unsigned int)i);
02300 printf(" %02X", p[i]);
02301 }
02302 printf("\n\r");
02303 }
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 uint8_t SD_Read(sSdCard *pSd,
02321 uint32_t address,
02322 void *pData,
02323 uint32_t length,
02324 fSdmmcCallback pCallback,
02325 void *pArgs)
02326 {
02327 assert( pSd != NULL ) ;
02328 assert( pData != NULL ) ;
02329 pSd->bState = SDMMC_STATE_DATA_RD;
02330 TRACE_DEBUG("MMCT_ReadFun(pSd,0x%x,%d,pBuffer); \n\r",address,length);
02331 TRACE_DEBUG("R %x,%x ",address,length);
02332 MoveToTransferState(pSd, address, length, (uint8_t*)pData, 1);
02333 TRACE_DEBUG("SDrd(%u,%u)\n\r", address, length);
02334 return 0;
02335 }
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 uint8_t SD_Write(sSdCard *pSd,
02352 uint32_t address,
02353 const void *pData,
02354 uint32_t length,
02355 fSdmmcCallback pCallback,
02356 void *pArgs)
02357 {
02358 assert( pSd != NULL ) ;
02359 pSd->bState = SDMMC_STATE_DATA_WR;
02360 TRACE_DEBUG("W %x,%x ",address,length);
02361 MoveToTransferState(pSd, address, length, (uint8_t*)pData, 0);
02362 TRACE_DEBUG("SDwr(%u,%u)\n\r", address, length);
02363 return 0;
02364 }
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377 uint8_t SD_ReadBlocks(sSdCard *pSd,
02378 uint32_t address,
02379 void *pData,
02380 uint32_t nbBlocks)
02381 {
02382 uint8_t error = 0;
02383 uint8_t *pBytes = (uint8_t*)pData;
02384
02385 assert( pSd != NULL ) ;
02386 assert( pData != NULL ) ;
02387 assert( nbBlocks != 0 ) ;
02388
02389 TRACE_DEBUG("RdBlks(%d,%d)\n\r", address, nbBlocks);
02390 while(nbBlocks --) {
02391 error = PerformSingleTransfer(pSd, address, pBytes, 1);
02392 if (error)
02393 break;
02394 address += 1;
02395 pBytes = &pBytes[512];
02396 }
02397 return error;
02398 }
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411 uint8_t SD_WriteBlocks(sSdCard *pSd,
02412 uint32_t address,
02413 const void *pData,
02414 uint32_t nbBlocks)
02415 {
02416 uint8_t error = 0;
02417 uint8_t *pB = (uint8_t*)pData;
02418
02419 assert( pSd != NULL ) ;
02420 assert( pData != NULL ) ;
02421 assert( nbBlocks != 0 ) ;
02422
02423 TRACE_DEBUG("WrBlks(%d,%d)\n\r", address, nbBlocks);
02424
02425 while(nbBlocks --) {
02426 error = PerformSingleTransfer(pSd, address, pB, 0);
02427 if (error)
02428 break;
02429 address += 1;
02430 pB = &pB[512];
02431 }
02432 return error;
02433 }
02434
02435
02436
02437
02438 static void _SdParamReset(sSdCard *pSd)
02439 {
02440 uint32_t i;
02441
02442 pSd->dwTranSpeed = 0;
02443 pSd->dwTotalSize = 0;
02444 pSd->dwNbBlocks = 0;
02445 pSd->wBlockSize = 0;
02446
02447 pSd->wCurrBlockLen = 0;
02448 pSd->dwCurrSpeed = 0;
02449 pSd->wAddress = 0;
02450
02451 pSd->bCardType = 0;
02452 pSd->bStatus = 0;
02453 pSd->bState = SDMMC_STATE_IDENT;
02454
02455
02456
02457 for (i = 0; i < 128/8/4; i ++) pSd->CID[i] = 0;
02458 for (i = 0; i < 128/8/4; i ++) pSd->CSD[i] = 0;
02459 for (i = 0; i < 512/4; i ++) pSd->EXT[i] = 0;
02460
02461 }
02462
02463
02464
02465
02466
02467
02468
02469
02470 void SDD_Initialize(sSdCard * pSd,
02471 const void * pDrv, uint8_t bSlot,
02472 const sSdHalFunctions * pHalf)
02473 {
02474 pSd->pDrv = (void *)pDrv;
02475 pSd->pHalf = (sSdHalFunctions *)pHalf;
02476 pSd->pExt = NULL;
02477 pSd->bSlot = bSlot;
02478
02479 _SdParamReset(pSd);
02480 }
02481
02482
02483
02484
02485
02486
02487
02488
02489 uint8_t SD_Init(sSdCard *pSd)
02490 {
02491 uint8_t error;
02492 uint32_t clock;
02493
02494 _SdParamReset(pSd);
02495
02496
02497 clock = 400000;
02498 _HwSetClock(pSd, &clock);
02499
02500
02501
02502
02503
02504
02505 error = Pon(pSd);
02506 if (error) {
02507 TRACE_ERROR("SD_Init.PowON:%d\n\r", error);
02508 return error;
02509 }
02510
02511
02512
02513
02514
02515
02516 error = SdMmcIdentify(pSd);
02517 if (error) {
02518 TRACE_ERROR("SD_Init.Identify: %d\n\r", error);
02519 return error;
02520 }
02521 error = SdMmcEnum(pSd);
02522 if (error) {
02523 TRACE_ERROR("SD_Init.Enum: %d\n\r", error);
02524 return error;
02525 }
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539 if (pSd->bCardType == CARD_SD) {
02540 error = Cmd16(pSd, SDMMC_BLOCK_SIZE);
02541 if (error) {
02542 TRACE_ERROR("SD_Init.Enum: %d\n\r", error);
02543 return error;
02544 }
02545 }
02546 pSd->wCurrBlockLen = SDMMC_BLOCK_SIZE;
02547
02548
02549 pSd->bState = SDMMC_STATE_TRAN;
02550
02551
02552 if ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC
02553 && SD_CSD_C_SIZE(pSd->CSD) == 0xFFF) {
02554 pSd->dwNbBlocks = MMC_EXT_SEC_COUNT(pSd->EXT);
02555
02556 if (pSd->dwNbBlocks > 0x800000)
02557 pSd->dwTotalSize = 0xFFFFFFFF;
02558 else
02559 pSd->dwTotalSize = MMC_EXT_SEC_COUNT(pSd->EXT)*512;
02560 }
02561
02562 else if((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD
02563 && SD_CSD_STRUCTURE(pSd->CSD) >= 1) {
02564 pSd->wBlockSize = 512;
02565 pSd->dwNbBlocks = SD_CSD_BLOCKNR_HC(pSd->CSD);
02566 pSd->dwTotalSize = 0xFFFFFFFF;
02567 }
02568
02569 else if (pSd->bCardType & CARD_TYPE_bmSDMMC) {
02570 pSd->wBlockSize = 512;
02571 pSd->dwTotalSize = SD_CSD_TOTAL_SIZE(pSd->CSD);
02572 pSd->dwNbBlocks = pSd->dwTotalSize/ 512;
02573 }
02574
02575 if (pSd->bCardType == CARD_UNKNOWN) {
02576 return SDMMC_ERROR_NOT_INITIALIZED;
02577 }
02578
02579 clock = pSd->dwTranSpeed;
02580 _HwSetClock(pSd, &clock);
02581 TRACE_WARNING_WP("-I- Set SD/MMC clock to %uK\n\r", (unsigned int)clock/1000);
02582 pSd->dwCurrSpeed = clock;
02583 return 0;
02584 }
02585
02586
02587
02588
02589
02590 void SD_DeInit(sSdCard *pSd)
02591 {
02592 if (pSd->pDrv) {
02593 _HwReset(pSd);
02594 _SdParamReset(pSd);
02595 }
02596 }
02597
02598
02599
02600
02601
02602
02603 uint8_t SD_GetCardType(sSdCard *pSd)
02604 {
02605 assert( pSd != NULL ) ;
02606
02607 return pSd->bCardType;
02608 }
02609
02610
02611
02612
02613
02614 uint32_t SD_GetTotalSizeKB(sSdCard *pSd)
02615 {
02616 assert( pSd != NULL ) ;
02617
02618 if (pSd->dwTotalSize == 0xFFFFFFFF) {
02619 return pSd->dwNbBlocks / 2;
02620 }
02621 return pSd->dwTotalSize / 1024;
02622 }
02623
02624
02625
02626
02627
02628
02629 uint32_t SD_GetBlockSize( sSdCard *pSd )
02630 {
02631 assert( pSd != NULL ) ;
02632
02633 return pSd->wBlockSize;
02634 }
02635
02636
02637
02638
02639
02640 uint32_t SD_GetNumberBlocks( sSdCard *pSd )
02641 {
02642 assert( pSd != NULL ) ;
02643
02644 return pSd->dwNbBlocks ;
02645 }
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656 uint8_t SDIO_ReadDirect(sSdCard *pSd,
02657 uint8_t functionNum,
02658 uint32_t address,
02659 uint8_t *pData,
02660 uint32_t size)
02661 {
02662 uint8_t error;
02663 uint32_t status;
02664
02665 assert( pSd != NULL ) ;
02666
02667 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02668 if (size == 0) return SDMMC_ERROR_PARAM;
02669 while(size --) {
02670 status = 0;
02671 error = Cmd52(pSd, 0, functionNum, 0, address ++, &status);
02672 if (pData) *pData ++ = (uint8_t)status;
02673 if (error) {
02674 TRACE_ERROR("IO_RdDirect.Cmd52: %d\n\r", error);
02675 return SDMMC_ERROR;
02676 }
02677 else if (status & STATUS_SDIO_R5) {
02678 TRACE_ERROR("RD_DIRECT(%u, %u) st %x\n\r",
02679 (unsigned int)address, (unsigned int)size, (unsigned int)status);
02680 return SDMMC_ERROR;
02681 }
02682 }
02683 } else {
02684 return SDMMC_ERROR_NOT_SUPPORT;
02685 }
02686 return 0;
02687 }
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697 uint8_t SDIO_WriteDirect(sSdCard *pSd,
02698 uint8_t functionNum,
02699 uint32_t address,
02700 uint8_t dataByte)
02701 {
02702 uint8_t error;
02703 uint32_t status;
02704
02705 assert( pSd != NULL ) ;
02706
02707 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02708 status = dataByte;
02709 error = Cmd52(pSd, 1, functionNum, 0, address, &status);
02710 if (error) {
02711 TRACE_ERROR("SDIO_WrDirect.Cmd52: %d\n\r", error);
02712 return SDMMC_ERROR;
02713 } else if (status & STATUS_SDIO_R5) {
02714 TRACE_ERROR("WR_DIRECT(%u) st %x\n\r",
02715 (unsigned int)address, (unsigned int)status);
02716 return SDMMC_ERROR;
02717 }
02718 } else {
02719 return SDMMC_ERROR_NOT_SUPPORT;
02720 }
02721 return 0;
02722 }
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736 uint8_t SDIO_ReadBytes(sSdCard *pSd,
02737 uint8_t functionNum,
02738 uint32_t address,
02739 uint8_t isFixedAddress,
02740 uint8_t *pData,
02741 uint16_t size,
02742 fSdmmcCallback fCallback,
02743 void* pArg)
02744 {
02745 uint8_t error;
02746 uint32_t status;
02747
02748 assert( pSd != NULL ) ;
02749
02750 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02751 if (size == 0) return SDMMC_ERROR_PARAM;
02752 error = Cmd53(pSd,
02753 0, functionNum, 0, !isFixedAddress,
02754 address, pData, size,
02755 &status,
02756 fCallback, pArg);
02757 if (error) {
02758 TRACE_ERROR("IO_RdBytes.Cmd53: %d\n\r", error);
02759 return SDMMC_ERROR;
02760 } else if (status & STATUS_SDIO_R5) {
02761 TRACE_ERROR("RD_EXT st %x\n\r", (unsigned int)status);
02762 return SDMMC_ERROR;
02763 }
02764 } else {
02765 return SDMMC_ERROR_NOT_SUPPORT;
02766 }
02767 return 0;
02768 }
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782 uint8_t SDIO_WriteBytes(sSdCard *pSd,
02783 uint8_t functionNum,
02784 uint32_t address,
02785 uint8_t isFixedAddress,
02786 uint8_t *pData,
02787 uint16_t size,
02788 fSdmmcCallback fCallback,
02789 void* pArg)
02790 {
02791 uint8_t error;
02792 uint32_t status;
02793
02794 assert( pSd != NULL ) ;
02795
02796 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02797 if (size == 0) return SDMMC_ERROR_PARAM;
02798 error = Cmd53(pSd,
02799 1, functionNum, 0, !isFixedAddress,
02800 address, pData, size,
02801 (uint32_t*)&status,
02802 fCallback, pArg);
02803 Delay(100);
02804 if (error) {
02805 TRACE_ERROR("IO_WrBytes.Cmd53: %d\n\r", error);
02806 return SDMMC_ERROR;
02807 } else if (status & STATUS_SDIO_R5) {
02808 TRACE_ERROR("WR_EXT st %x\n\r", (unsigned int)status);
02809 return SDMMC_ERROR;
02810 }
02811 } else {
02812 return SDMMC_ERROR_NOT_SUPPORT;
02813 }
02814 return 0;
02815 }
02816
02817
02818
02819
02820
02821
02822
02823 void SDIO_DumpCardInformation(sSdCard * pSd)
02824 {
02825 uint32_t tmp = 0, addrCIS = 0, addrManfID = 0, addrFunc0 = 0;
02826 uint8_t *p = (uint8_t*)&tmp;
02827 uint8_t buf[8];
02828
02829 switch(pSd->bCardType)
02830 {
02831 case CARD_SDIO:
02832 TRACE_INFO("** SDIO ONLY card\n\r");
02833 break;
02834 case CARD_SDCOMBO: case CARD_SDHCCOMBO:
02835 TRACE_INFO("** SDIO Combo card\n\r");
02836 break;
02837 default:
02838 TRACE_INFO("** NO SDIO\n\r");
02839 return;
02840 }
02841
02842 TRACE_INFO("====== CCCR ======\n\r");
02843 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CCCR_REG, p, 1);
02844 TRACE_INFO(".SDIO %02lX\n\r", (tmp & SDIO_SDIO) >> 4);
02845 TRACE_INFO(".CCCR %02lX\n\r", (tmp & SDIO_CCCR) >> 0);
02846 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_SD_REV_REG, p, 1);
02847 TRACE_INFO(".SD %02lX\n\r", (tmp & SDIO_SD) >> 0);
02848 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IOE_REG, p, 1);
02849 TRACE_INFO(".IOE %02lX\n\r", (tmp & SDIO_IOE) >> 0);
02850 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IOR_REG, p, 1);
02851 TRACE_INFO(".IOR %02lX\n\r", (tmp & SDIO_IOR) >> 0);
02852 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IEN_REG, p, 1);
02853 TRACE_INFO(".IEN %02lX\n\r", (tmp & SDIO_IEN) >> 0);
02854 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_INT_REG, p, 1);
02855 TRACE_INFO(".INT %u\n\r", (unsigned int)(tmp & SDIO_INT));
02856 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_BUS_CTRL_REG, p, 1);
02857 TRACE_INFO(".CD %lx\n\r", (tmp & SDIO_CD) >> 7);
02858 TRACE_INFO(".SCSI %lx\n\r", (tmp & SDIO_SCSI) >> 6);
02859 TRACE_INFO(".ECSI %lx\n\r", (tmp & SDIO_ECSI) >> 5);
02860 TRACE_INFO(".BUS_WIDTH %lx\n\r", (tmp & SDIO_BUSWIDTH) >> 0);
02861 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CAP_REG, p, 1);
02862 TRACE_INFO(".4BLS %lx\n\r", (tmp & SDIO_4BLS) >> 7);
02863 TRACE_INFO(".LSC %lx\n\r", (tmp & SDIO_LSC) >> 6);
02864 TRACE_INFO(".E4MI %lx\n\r", (tmp & SDIO_E4MI) >> 5);
02865 TRACE_INFO(".S4MI %lx\n\r", (tmp & SDIO_S4MI) >> 4);
02866 TRACE_INFO(".SBS %lx\n\r", (tmp & SDIO_SBS) >> 3);
02867 TRACE_INFO(".SRW %lx\n\r", (tmp & SDIO_SRW) >> 2);
02868 TRACE_INFO(".SMB %lx\n\r", (tmp & SDIO_SMB) >> 1);
02869 TRACE_INFO(".SDC %lx\n\r", (tmp & SDIO_SDC) >> 0);
02870 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CIS_PTR_REG, p, 3);
02871 TRACE_INFO(".CIS_PTR %06X\n\r", (unsigned int)tmp);
02872 addrCIS = tmp; tmp = 0;
02873 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_BUS_SUSP_REG, p, 1);
02874 TRACE_INFO(".BR %lx\n\r", (tmp & SDIO_BR) >> 1);
02875 TRACE_INFO(".BS %lx\n\r", (tmp & SDIO_BS) >> 0);
02876 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_FUN_SEL_REG, p, 1);
02877 TRACE_INFO(".DF %lx\n\r", (tmp & SDIO_DF) >> 7);
02878 TRACE_INFO(".FS %lx\n\r", (tmp & SDIO_FS) >> 0);
02879 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_EXEC_REG, p, 1);
02880 TRACE_INFO(".EX %lx\n\r", (tmp & SDIO_EX));
02881 TRACE_INFO(".EXM %lx\n\r", (tmp & SDIO_EXM) >> 0);
02882 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_READY_REG, p, 1);
02883 TRACE_INFO(".RF %lx\n\r", (tmp & SDIO_RF));
02884 TRACE_INFO(".RFM %lx\n\r", (tmp & SDIO_RFM) >> 0);
02885 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_FN0_BLKSIZ_REG, p, 2);
02886 TRACE_INFO(".FN0_SIZE %u(%04X)\n\r", (unsigned int)tmp, (unsigned int)tmp);
02887 tmp = 0;
02888 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_POWER_REG, p, 1);
02889 TRACE_INFO(".EMPC %lx\n\r", (tmp & SDIO_EMPC) >> 1);
02890 TRACE_INFO(".SMPC %lx\n\r", (tmp & SDIO_SMPC) >> 0);
02891 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_HS_REG, p, 1);
02892 TRACE_INFO(".EHS %lx\n\r", (tmp & SDIO_EHS) >> 1);
02893 TRACE_INFO(".SHS %lx\n\r", (tmp & SDIO_SHS) >> 0);
02894
02895 SdioFindTuples(pSd, addrCIS, 128, &addrManfID, &addrFunc0);
02896 if (addrManfID != 0) {
02897 SDIO_ReadDirect(pSd, SDIO_CIA, addrManfID, buf, 6);
02898 TRACE_INFO("==== CISTPL_MANFID ====\n\r");
02899 TRACE_INFO("._MANF %04X\n\r", buf[2] + (buf[3] << 8));
02900 TRACE_INFO("._CARD %04X\n\r", buf[4] + (buf[5] << 8));
02901 }
02902 if (addrFunc0 != 0) {
02903 SDIO_ReadDirect(pSd, SDIO_CIA, addrFunc0, buf, 6);
02904 TRACE_INFO("== CISTPL_FUNCE Fun0 ==\n\r");
02905 TRACE_INFO("._FN0_BLK_SIZE %d(0x%04X)\n\r",
02906 buf[3] + (buf[4] << 8), buf[3] + (buf[4] << 8));
02907 TRACE_INFO("._MAX_TRAN_SPEED %02X\n\r", buf[5]);
02908 }
02909 }
02910
02911
02912
02913
02914
02915
02916 void SD_DumpCID(void* pCID)
02917 {
02918 TRACE_INFO("======= CID =======");
02919
02920 TRACE_INFO("===================\n\r");
02921 TRACE_INFO(" .MID Manufacturer ID %02X\n\r",
02922 (unsigned int)SD_CID_MID(pCID));
02923
02924 TRACE_INFO(" .CBX Card/BGA (eMMC) %X\n\r",
02925 (unsigned int)eMMC_CID_CBX(pCID));
02926
02927 TRACE_INFO(" .OID OEM/Application ID (SD) %c%c\n\r",
02928 (char)SD_CID_OID1(pCID),
02929 (char)SD_CID_OID0(pCID));
02930 TRACE_INFO(" .OID OEM/Application ID (MMC) %x\n\r",
02931 (unsigned int)eMMC_CID_OID(pCID));
02932
02933 TRACE_INFO(" .PNM Product name (SD) %c%c%c%c%c\n\r",
02934 (char)SD_CID_PNM4(pCID),
02935 (char)SD_CID_PNM3(pCID),
02936 (char)SD_CID_PNM2(pCID),
02937 (char)SD_CID_PNM1(pCID),
02938 (char)SD_CID_PNM0(pCID));
02939 TRACE_INFO(" .PNM Product name (MMC) %c%c%c%c%c%c\n\r",
02940 (char)MMC_CID_PNM5(pCID),
02941 (char)MMC_CID_PNM4(pCID),
02942 (char)MMC_CID_PNM3(pCID),
02943 (char)MMC_CID_PNM2(pCID),
02944 (char)MMC_CID_PNM1(pCID),
02945 (char)MMC_CID_PNM0(pCID));
02946
02947 TRACE_INFO(" .PRV Product revision (SD) %x\n\r",
02948 (unsigned int)SD_CID_PRV(pCID));
02949 TRACE_INFO(" .PRV Product revision (MMC) %x\n\r",
02950 (unsigned int)MMC_CID_PRV(pCID));
02951
02952 TRACE_INFO(" .PSN Product serial number (SD) %02X%02X%02X%02X\n\r",
02953 (unsigned int)SD_CID_PSN3(pCID),
02954 (unsigned int)SD_CID_PSN2(pCID),
02955 (unsigned int)SD_CID_PSN1(pCID),
02956 (unsigned int)SD_CID_PSN0(pCID));
02957 TRACE_INFO(" .PSN Product serial number (MMC) %02X%02X%02X%02X\n\r",
02958 (unsigned int)MMC_CID_PSN3(pCID),
02959 (unsigned int)MMC_CID_PSN2(pCID),
02960 (unsigned int)MMC_CID_PSN1(pCID),
02961 (unsigned int)MMC_CID_PSN0(pCID));
02962
02963 TRACE_INFO(" .MDT Manufacturing date (SD) %04d/%02d\n\r",
02964 (uint16_t)(SD_CID_MDT_Y(pCID) + 2000),
02965 (uint8_t)SD_CID_MDT_M(pCID));
02966 TRACE_INFO(" .MDT Manufacturing date (MMC) %04d/%02d\n\r",
02967 (uint16_t)(MMC_CID_MDT_Y(pCID) + 1997),
02968 (uint8_t)SD_CID_MDT_M(pCID));
02969
02970 TRACE_INFO(" .CRC checksum %02X\n\r",
02971 (unsigned int)SD_CID_CRC(pCID));
02972 }
02973
02974
02975
02976
02977
02978 void SD_DumpCSD(void* pCSD)
02979 {
02980 TRACE_INFO("======== CSD ========");
02981
02982 TRACE_INFO("===================\n\r");
02983 TRACE_INFO(" .CSD_STRUCTURE 0x%x\r\n", (unsigned int)SD_CSD_STRUCTURE(pCSD));
02984 TRACE_INFO(" .SPEC_VERS (eMMC) 0x%x\r\n", (unsigned int)MMC_CSD_SPEC_VERS(pCSD));
02985 TRACE_INFO(" .TAAC 0x%X\r\n", (unsigned int)SD_CSD_TAAC(pCSD) );
02986 TRACE_INFO(" .NSAC 0x%X\r\n", (unsigned int)SD_CSD_NSAC(pCSD) );
02987 TRACE_INFO(" .TRAN_SPEED 0x%X\r\n", (unsigned int)SD_CSD_TRAN_SPEED(pCSD) );
02988 TRACE_INFO(" .CCC 0x%X\r\n", (unsigned int)SD_CSD_CCC(pCSD) );
02989 TRACE_INFO(" .READ_BL_LEN 0x%X\r\n", (unsigned int)SD_CSD_READ_BL_LEN(pCSD) );
02990 TRACE_INFO(" .READ_BL_PARTIAL 0x%X\r\n", (unsigned int)SD_CSD_READ_BL_PARTIAL(pCSD) );
02991 TRACE_INFO(" .WRITE_BLK_MISALIGN 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BLK_MISALIGN(pCSD));
02992 TRACE_INFO(" .READ_BLK_MISALIGN 0x%X\r\n", (unsigned int)SD_CSD_READ_BLK_MISALIGN(pCSD) );
02993 TRACE_INFO(" .DSR_IMP 0x%X\r\n", (unsigned int)SD_CSD_DSR_IMP(pCSD) );
02994 TRACE_INFO(" .C_SIZE 0x%X\r\n", (unsigned int)SD_CSD_C_SIZE(pCSD) );
02995 TRACE_INFO(" .C_SIZE_HC 0x%X\r\n", (unsigned int)SD2_CSD_C_SIZE(pCSD) );
02996 TRACE_INFO(" .VDD_R_CURR_MIN 0x%X\r\n", (unsigned int)SD_CSD_VDD_R_CURR_MIN(pCSD) );
02997 TRACE_INFO(" .VDD_R_CURR_MAX 0x%X\r\n", (unsigned int)SD_CSD_VDD_R_CURR_MAX(pCSD) );
02998 TRACE_INFO(" .VDD_W_CURR_MIN 0x%X\r\n", (unsigned int)SD_CSD_VDD_W_CURR_MIN(pCSD) );
02999 TRACE_INFO(" .VDD_W_CURR_MAX 0x%X\r\n", (unsigned int)SD_CSD_VDD_W_CURR_MAX(pCSD) );
03000 TRACE_INFO(" .C_SIZE_MULT 0x%X\r\n", (unsigned int)SD_CSD_C_SIZE_MULT(pCSD) );
03001 TRACE_INFO(" .ERASE_BLK_EN 0x%X\r\n", (unsigned int)SD_CSD_ERASE_BLK_EN(pCSD) );
03002 TRACE_INFO(" .SECTOR_SIZE 0x%X\r\n", (unsigned int)SD_CSD_SECTOR_SIZE(pCSD) );
03003 TRACE_INFO(" .WP_GRP_SIZE 0x%X\r\n", (unsigned int)SD_CSD_WP_GRP_SIZE(pCSD) );
03004 TRACE_INFO(" .WP_GRP_ENABLE 0x%X\r\n", (unsigned int)SD_CSD_WP_GRP_ENABLE(pCSD) );
03005 TRACE_INFO(" .R2W_FACTOR 0x%X\r\n", (unsigned int)SD_CSD_R2W_FACTOR(pCSD) );
03006 TRACE_INFO(" .WRITE_BL_LEN 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BL_LEN(pCSD) );
03007 TRACE_INFO(" .WRITE_BL_PARTIAL 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BL_PARTIAL(pCSD) );
03008 TRACE_INFO(" .FILE_FORMAT_GRP 0x%X\r\n", (unsigned int)SD_CSD_FILE_FORMAT_GRP(pCSD) );
03009 TRACE_INFO(" .COPY 0x%X\r\n", (unsigned int)SD_CSD_COPY(pCSD) );
03010 TRACE_INFO(" .PERM_WRITE_PROTECT 0x%X\r\n", (unsigned int)SD_CSD_PERM_WRITE_PROTECT(pCSD));
03011 TRACE_INFO(" .TMP_WRITE_PROTECT 0x%X\r\n", (unsigned int)SD_CSD_TMP_WRITE_PROTECT(pCSD) );
03012 TRACE_INFO(" .FILE_FORMAT 0x%X\r\n", (unsigned int)SD_CSD_FILE_FORMAT(pCSD) );
03013 TRACE_INFO(" .ECC (MMC) 0x%X\r\n", (unsigned int)MMC_CSD_ECC(pCSD) );
03014 TRACE_INFO(" .CRC 0x%X\r\n", (unsigned int)SD_CSD_CRC(pCSD) );
03015 TRACE_INFO(" .MULT 0x%X\r\n", (unsigned int)SD_CSD_MULT(pCSD) );
03016 TRACE_INFO(" .BLOCKNR 0x%X\r\n", (unsigned int)SD_CSD_BLOCKNR(pCSD) );
03017 TRACE_INFO(" .BLOCKNR_HC 0x%X\r\n", (unsigned int)SD_CSD_BLOCKNR_HC(pCSD) );
03018 TRACE_INFO(" .BLOCK_LEN 0x%X\r\n", (unsigned int)SD_CSD_BLOCK_LEN(pCSD) );
03019 TRACE_INFO(" -TOTAL_SIZE 0x%X\r\n", (unsigned int)SD_CSD_TOTAL_SIZE(pCSD) );
03020 TRACE_INFO(" -TOTAL_SIZE_HC 0x%X\r\n", (unsigned int)SD_CSD_TOTAL_SIZE_HC(pCSD) );
03021 }
03022
03023
03024
03025
03026
03027 void SD_DumpExtCSD(void* pExtCSD)
03028 {
03029 TRACE_INFO("======= EXT_CSD =======");
03030 TRACE_INFO_WP("\n\r");
03031 TRACE_INFO(" .S_CMD_SET : 0x%X\n\r",
03032 MMC_EXT_S_CMD_SET(pExtCSD));
03033 TRACE_INFO(" .BOOT_INFO : 0x%X\n\r",
03034 MMC_EXT_BOOT_INFO(pExtCSD));
03035 TRACE_INFO(" .BOOT_SIZE_MULTI : 0x%X\n\r",
03036 MMC_EXT_BOOT_SIZE_MULTI(pExtCSD));
03037 TRACE_INFO(" .ACC_SIZE : 0x%X\n\r",
03038 MMC_EXT_ACC_SIZE(pExtCSD));
03039 TRACE_INFO(" .HC_ERASE_GRP_SIZE : 0x%X\n\r",
03040 MMC_EXT_HC_ERASE_GRP_SIZE(pExtCSD));
03041 TRACE_INFO(" .ERASE_TIMEOUT_MULT : 0x%X\n\r",
03042 MMC_EXT_ERASE_TIMEOUT_MULT(pExtCSD));
03043 TRACE_INFO(" .REL_WR_SEC_C : 0x%X\n\r",
03044 MMC_EXT_REL_WR_SEC_C(pExtCSD));
03045 TRACE_INFO(" .HC_WP_GRP_SIZE : 0x%X\n\r",
03046 MMC_EXT_HC_WP_GRP_SIZE(pExtCSD));
03047 TRACE_INFO(" .S_C_VCC : 0x%X\n\r",
03048 MMC_EXT_S_C_VCC(pExtCSD));
03049 TRACE_INFO(" .S_C_VCCQ : 0x%X\n\r",
03050 MMC_EXT_S_C_VCCQ(pExtCSD));
03051 TRACE_INFO(" .S_A_TIMEOUT : 0x%X\n\r",
03052 MMC_EXT_S_A_TIMEOUT(pExtCSD));
03053 TRACE_INFO(" .SEC_COUNT : 0x%X\n\r",
03054 MMC_EXT_SEC_COUNT(pExtCSD));
03055 TRACE_INFO(" .MIN_PERF_W_8_52 : 0x%X\n\r",
03056 MMC_EXT_MIN_PERF_W_8_52(pExtCSD));
03057 TRACE_INFO(" .MIN_PERF_R_8_52 : 0x%X\n\r",
03058 MMC_EXT_MIN_PERF_R_8_52(pExtCSD));
03059 TRACE_INFO(" .MIN_PERF_W_8_26_4_52 : 0x%X\n\r",
03060 MMC_EXT_MIN_PERF_W_8_26_4_52(pExtCSD));
03061 TRACE_INFO(" .MIN_PERF_R_8_26_4_52 : 0x%X\n\r",
03062 MMC_EXT_MIN_PERF_R_8_26_4_52(pExtCSD));
03063 TRACE_INFO(" .MIN_PERF_W_4_26 : 0x%X\n\r",
03064 MMC_EXT_MIN_PERF_W_4_26(pExtCSD));
03065 TRACE_INFO(" .MIN_PERF_R_4_26 : 0x%X\n\r",
03066 MMC_EXT_MIN_PERF_R_4_26(pExtCSD));
03067 TRACE_INFO(" .PWR_CL_26_360 : 0x%X\n\r",
03068 MMC_EXT_PWR_CL_26_360(pExtCSD));
03069 TRACE_INFO(" .PWR_CL_52_360 : 0x%X\n\r",
03070 MMC_EXT_PWR_CL_52_360(pExtCSD));
03071 TRACE_INFO(" .PWR_CL_26_195 : 0x%X\n\r",
03072 MMC_EXT_PWR_CL_26_195(pExtCSD));
03073 TRACE_INFO(" .PWR_CL_52_195 : 0x%X\n\r",
03074 MMC_EXT_PWR_CL_52_195(pExtCSD));
03075 TRACE_INFO(" .CARD_TYPE : 0x%X\n\r",
03076 MMC_EXT_CARD_TYPE(pExtCSD));
03077 TRACE_INFO(" .CSD_STRUCTURE : 0x%X\n\r",
03078 MMC_EXT_CSD_STRUCTURE(pExtCSD));
03079 TRACE_INFO(" .EXT_CSD_REV : 0x%X\n\r",
03080 MMC_EXT_EXT_CSD_REV(pExtCSD));
03081 TRACE_INFO(" .CMD_SET : 0x%X\n\r",
03082 MMC_EXT_CMD_SET(pExtCSD));
03083 TRACE_INFO(" .CMD_SET_REV : 0x%X\n\r",
03084 MMC_EXT_CMD_SET_REV(pExtCSD));
03085 TRACE_INFO(" .POWER_CLASS : 0x%X\n\r",
03086 MMC_EXT_POWER_CLASS(pExtCSD));
03087 TRACE_INFO(" .HS_TIMING : 0x%X\n\r",
03088 MMC_EXT_HS_TIMING(pExtCSD));
03089 TRACE_INFO(" .BUS_WIDTH : 0x%X\n\r",
03090 MMC_EXT_BUS_WIDTH(pExtCSD));
03091 TRACE_INFO(" .ERASED_MEM_CONT : 0x%X\n\r",
03092 MMC_EXT_ERASED_MEM_CONT(pExtCSD));
03093 TRACE_INFO(" .BOOT_CONFIG : 0x%X\n\r",
03094 MMC_EXT_BOOT_CONFIG(pExtCSD));
03095 TRACE_INFO(" .BOOT_BUS_WIDTH : 0x%X\n\r",
03096 MMC_EXT_BOOT_BUS_WIDTH(pExtCSD));
03097 TRACE_INFO(" .ERASE_GROUP_DEF : 0x%X\n\r",
03098 MMC_EXT_ERASE_GROUP_DEF(pExtCSD));
03099 }
03100
03101
03102
03103
03104
03105 void SD_DumpSCR(void *pSCR)
03106 {
03107 TRACE_INFO("========== SCR ==========");
03108 TRACE_INFO_WP("\n\r");
03109
03110 TRACE_INFO(" .SCR_STRUCTURE :0x%X\n\r",
03111 (unsigned int)SD_SCR_STRUCTURE(pSCR));
03112 TRACE_INFO(" .SD_SPEC :0x%X\n\r",
03113 (unsigned int)SD_SCR_SD_SPEC(pSCR));
03114 TRACE_INFO(" .DATA_STAT_AFTER_ERASE :0x%X\n\r",
03115 (unsigned int)SD_SCR_DATA_STAT_AFTER_ERASE(pSCR));
03116 TRACE_INFO(" .SD_SECURITY :0x%X\n\r",
03117 (unsigned int)SD_SCR_SD_SECURITY(pSCR));
03118 TRACE_INFO(" .SD_BUS_WIDTHS :0x%X\n\r",
03119 (unsigned int)SD_SCR_SD_BUS_WIDTHS(pSCR));
03120 }
03121
03122
03123
03124
03125
03126 void SD_DumpSdStatus(void* pSdST)
03127 {
03128 TRACE_INFO("=========== STAT ============");
03129 TRACE_INFO_WP("\n\r");
03130
03131 TRACE_INFO(" .DAT_BUS_WIDTH :0x%X\n\r",
03132 (unsigned int)SD_ST_DAT_BUS_WIDTH(pSdST));
03133 TRACE_INFO(" .SECURED_MODE :0x%X\n\r",
03134 (unsigned int)SD_ST_SECURED_MODE(pSdST));
03135 TRACE_INFO(" .SD_CARD_TYPE :0x%X\n\r",
03136 (unsigned int)SD_ST_CARD_TYPE(pSdST));
03137 TRACE_INFO(" .SIZE_OF_PROTECTED_AREA :0x%X\n\r",
03138 (unsigned int)SD_ST_SIZE_OF_PROTECTED_AREA(pSdST));
03139 TRACE_INFO(" .SPEED_CLASS :0x%X\n\r",
03140 (unsigned int)SD_ST_SPEED_CLASS(pSdST));
03141 TRACE_INFO(" .PERFORMANCE_MOVE :0x%X\n\r",
03142 (unsigned int)SD_ST_PERFORMANCE_MOVE(pSdST));
03143 TRACE_INFO(" .AU_SIZE :0x%X\n\r",
03144 (unsigned int)SD_ST_AU_SIZE(pSdST));
03145 TRACE_INFO(" .ERASE_SIZE :0x%X\n\r",
03146 (unsigned int)SD_ST_ERASE_SIZE(pSdST));
03147 TRACE_INFO(" .ERASE_TIMEOUT :0x%X\n\r",
03148 (unsigned int)SD_ST_ERASE_TIMEOUT(pSdST));
03149 TRACE_INFO(" .ERASE_OFFSET :0x%X\n\r",
03150 (unsigned int)SD_ST_ERASE_OFFSET(pSdST));
03151 }
03152