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 #ifdef SD_SINGLE_LINE_MODE
02013
02014 busWidth = 1;
02015 #else
02016
02017 busWidth = 4;
02018 #endif
02019 mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
02020 if (mmc) {
02021
02022 if (MMC_CSD_SPEC_VERS(pSd->CSD) >= 4) {
02023 busWidth = mmcDetectBuswidth(pSd);
02024 } else {
02025 TRACE_WARNING("MMC 1-bit only\n\r");
02026 return SDMMC_ERROR_NOT_SUPPORT;
02027 }
02028 } else {
02029
02030 uint8_t io = ((pSd->bCardType & CARD_TYPE_bmSDIO) > 0);
02031 uint8_t sd = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD);
02032 if (busWidth == 1)
02033 return SDMMC_ERROR_NOT_SUPPORT;
02034
02035 busWidth = 4;
02036
02037
02038 if (io) {
02039
02040 busWidth = 1;
02041 }
02042
02043
02044 if (sd) {
02045 error = Acmd6(pSd, busWidth);
02046 if (error) {
02047 TRACE_ERROR("SdMmcSetBusWidth.Acmd6: %d\n\r", error);
02048 return SDMMC_ERROR;
02049 }
02050 TRACE_WARNING("SD 4-bit mode\n\r");
02051 }
02052
02053 pSd->bBusMode = busWidth;
02054 _HwSetBusWidth(pSd, busWidth);
02055 }
02056 return 0;
02057 }
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068 static uint8_t SdMmcIdentify(sSdCard *pSd)
02069 {
02070 uint8_t mem = 0, io = 0, f8 = 0, mp = 1, ccs = 0;
02071 uint32_t status;
02072 uint8_t error;
02073
02074 _HwSetHsMode(pSd, 0);
02075 _HwSetBusWidth(pSd, 1);
02076
02077 status = SDIO_RES;
02078 error = Cmd52(pSd, 1, SDIO_CIA, 0, SDIO_IOA_REG, &status);
02079 if (!error && ((status & STATUS_SDIO_R5)==0)){}
02080 else if (error == SDMMC_ERROR_NORESPONSE){}
02081 else {
02082 TRACE_DEBUG("SdMmcIdentify.Cmd52 fail: %u, %x\n\r", error, status);
02083 }
02084
02085 error = SwReset(pSd, 1);
02086 if (error) {
02087 TRACE_DEBUG("SdMmcIdentify.SwReset fail: %u\n\r", error);
02088 }
02089
02090
02091
02092
02093
02094
02095 error = SdCmd8(pSd, 1);
02096 if (error == 0) f8 = 1;
02097 else if (error != SDMMC_ERROR_NORESPONSE) {
02098 TRACE_ERROR("SdMmcIdentify.Cmd8: %d\n\r", error);
02099 return SDMMC_ERROR;
02100 }
02101
02102 else Delay(8000);
02103
02104
02105 status = 0;
02106 error = Cmd5(pSd, &status);
02107 if (error) {
02108 TRACE_INFO("SdMmcIdentify.Cmd5: %d\n\r", error)
02109 }
02110
02111 else if ((status & SDIO_OCR_NF) > 0) {
02112 unsigned int cmd5Retries = 10000;
02113 do {
02114 status &= SD_HOST_VOLTAGE_RANGE;
02115 error = Cmd5(pSd, &status);
02116 if (status & SD_OCR_BUSY) break;
02117 } while(!error && cmd5Retries --);
02118 if (error) {
02119 TRACE_ERROR("SdMmcIdentify.Cmd5 V: %d\n\r", error);
02120 return SDMMC_ERROR;
02121 }
02122 io = 1;
02123 TRACE_INFO("SDIO\n\r");
02124
02125 mp = ((status & SDIO_OCR_MP) > 0);
02126 }
02127
02128 if (mp) {
02129
02130 error = Acmd41(pSd, f8, &ccs);
02131 if (error) {
02132 unsigned int cmd1Retries = 10000;
02133 TRACE_DEBUG("SdMmcIdentify.Acmd41: %u, try MMC\n\r", error);
02134
02135 error = SwReset(pSd, 10);
02136 if (error) {
02137 TRACE_ERROR("SdMmcIdentify.Mmc.SwReset: %d\n\r", error);
02138 return SDMMC_ERROR;
02139 }
02140 ccs = 1;
02141 do { error = Cmd1(pSd, &ccs); }while(error && cmd1Retries -- > 0);
02142 if (error) {
02143 TRACE_ERROR("SdMmcIdentify.Cmd1: %d\n\r", error);
02144 return SDMMC_ERROR;
02145 }
02146 else if (ccs) pSd->bCardType = CARD_MMCHD;
02147 else pSd->bCardType = CARD_MMC;
02148
02149 TRACE_INFO("MMC Card\n\r");
02150 return 0;
02151 }
02152 else if (ccs) { TRACE_INFO("SDHC MEM\n\r");}
02153 else { TRACE_INFO("SD MEM\n\r");}
02154 mem = 1;
02155 }
02156
02157 if (!mem) {
02158 if (io) pSd->bCardType = CARD_SDIO;
02159 else {
02160 TRACE_ERROR("Unknown card\n\r");
02161 return SDMMC_ERROR;
02162 }
02163 }
02164
02165 else if (io)
02166 pSd->bCardType = ccs ? CARD_SDHCCOMBO : CARD_SDCOMBO;
02167
02168 else
02169 pSd->bCardType = ccs ? CARD_SDHC : CARD_SD;
02170
02171 return 0;
02172 }
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 static uint8_t SdMmcEnum(sSdCard *pSd)
02184 {
02185 uint8_t mem , io;
02186 uint8_t error;
02187 uint32_t ioSpeed = 0, memSpeed = 0;
02188 uint8_t hsExec = 0, bwExec = 0;
02189
02190
02191 mem = ((pSd->bCardType & CARD_TYPE_bmSDMMC) > 0);
02192 io = ((pSd->bCardType & CARD_TYPE_bmSDIO) > 0);
02193
02194
02195
02196
02197
02198
02199 if (mem) {
02200 error = Cmd2(pSd);
02201 if (error) {
02202 TRACE_ERROR("SdMmcInit.cmd2(%d)\n\r", error);
02203 return error;
02204 }
02205 }
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216 error = Cmd3(pSd);
02217 if (error) {
02218 TRACE_ERROR("SdMmcInit.cmd3(%d)\n\r", error);
02219 return error;
02220 }
02221
02222
02223
02224
02225 if (mem) {
02226 error = Cmd9(pSd);
02227 if (error) {
02228 TRACE_ERROR("SdMmcInit.cmd9(%d)\n\r", error);
02229 return error;
02230 }
02231 }
02232
02233
02234 error = MmcSelectCard(pSd, CARD_ADDR(pSd), 0);
02235 if (error) {
02236 TRACE_ERROR("SdMmcInit.SelCard(%d)\n\r", error);
02237 return error;
02238 }
02239
02240
02241
02242
02243 TRACE_INFO("Card Type %u, CSD_STRUCTURE %u\n\r",
02244 (unsigned int)pSd->bCardType, (unsigned int)SD_CSD_STRUCTURE(pSd));
02245
02246
02247 SdMmcUpdateInformation(pSd, 1, 1);
02248
02249
02250 if (io) ioSpeed = SdioGetMaxSpeed(pSd);
02251 if (mem) memSpeed = SdmmcGetMaxSpeed(pSd);
02252
02253
02254
02255 if (io && mem) {
02256 pSd->dwTranSpeed = (ioSpeed > memSpeed) ? memSpeed : ioSpeed;
02257 }
02258
02259 else if (io) {
02260 pSd->dwTranSpeed = ioSpeed;
02261 }
02262
02263 else if (mem) {
02264 pSd->dwTranSpeed = memSpeed;
02265 }
02266 pSd->dwTranSpeed *= 1000;
02267
02268
02269 error = SdMmcDesideBuswidth(pSd);
02270 if (!error) bwExec = 1;
02271 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
02272 TRACE_ERROR("SdmmcEnum.DesideBusWidth: %d\n\r", error);
02273 return SDMMC_ERROR;
02274 }
02275
02276
02277 error = SdMmcEnableHighSpeed(pSd);
02278 if (!error) hsExec = 1;
02279 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
02280 return SDMMC_ERROR;
02281 }
02282
02283
02284 if (hsExec) pSd->dwTranSpeed *= 2;
02285
02286
02287 if (bwExec || hsExec) SdMmcUpdateInformation(pSd, hsExec, 1);
02288
02289 return 0;
02290 }
02291
02292
02293
02294
02295
02296
02297
02298 void _DumpREG(void* pREG, uint32_t dwSize)
02299 {
02300 uint8_t *p = (uint8_t*)pREG;
02301 uint32_t i;
02302 for (i = 0; i < dwSize; i ++)
02303 {
02304 if ((i % 16) == 0) printf("\n\r [%04X]", (unsigned int)i);
02305 printf(" %02X", p[i]);
02306 }
02307 printf("\n\r");
02308 }
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325 uint8_t SD_Read(sSdCard *pSd,
02326 uint32_t address,
02327 void *pData,
02328 uint32_t length,
02329 fSdmmcCallback pCallback,
02330 void *pArgs)
02331 {
02332 assert( pSd != NULL ) ;
02333 assert( pData != NULL ) ;
02334 pSd->bState = SDMMC_STATE_DATA_RD;
02335 TRACE_DEBUG("MMCT_ReadFun(pSd,0x%x,%d,pBuffer); \n\r",address,length);
02336 TRACE_DEBUG("R %x,%x ",address,length);
02337 MoveToTransferState(pSd, address, length, (uint8_t*)pData, 1);
02338 TRACE_DEBUG("SDrd(%u,%u)\n\r", address, length);
02339 return 0;
02340 }
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356 uint8_t SD_Write(sSdCard *pSd,
02357 uint32_t address,
02358 const void *pData,
02359 uint32_t length,
02360 fSdmmcCallback pCallback,
02361 void *pArgs)
02362 {
02363 assert( pSd != NULL ) ;
02364 pSd->bState = SDMMC_STATE_DATA_WR;
02365 TRACE_DEBUG("W %x,%x ",address,length);
02366 MoveToTransferState(pSd, address, length, (uint8_t*)pData, 0);
02367 TRACE_DEBUG("SDwr(%u,%u)\n\r", address, length);
02368 return 0;
02369 }
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382 uint8_t SD_ReadBlocks(sSdCard *pSd,
02383 uint32_t address,
02384 void *pData,
02385 uint32_t nbBlocks)
02386 {
02387 uint8_t error = 0;
02388 uint8_t *pBytes = (uint8_t*)pData;
02389
02390 assert( pSd != NULL ) ;
02391 assert( pData != NULL ) ;
02392 assert( nbBlocks != 0 ) ;
02393
02394 TRACE_DEBUG("RdBlks(%d,%d)\n\r", address, nbBlocks);
02395 while(nbBlocks --) {
02396 error = PerformSingleTransfer(pSd, address, pBytes, 1);
02397 if (error)
02398 break;
02399 address += 1;
02400 pBytes = &pBytes[512];
02401 }
02402 return error;
02403 }
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 uint8_t SD_WriteBlocks(sSdCard *pSd,
02417 uint32_t address,
02418 const void *pData,
02419 uint32_t nbBlocks)
02420 {
02421 uint8_t error = 0;
02422 uint8_t *pB = (uint8_t*)pData;
02423
02424 assert( pSd != NULL ) ;
02425 assert( pData != NULL ) ;
02426 assert( nbBlocks != 0 ) ;
02427
02428 TRACE_DEBUG("WrBlks(%d,%d)\n\r", address, nbBlocks);
02429
02430 while(nbBlocks --) {
02431 error = PerformSingleTransfer(pSd, address, pB, 0);
02432 if (error)
02433 break;
02434 address += 1;
02435 pB = &pB[512];
02436 }
02437 return error;
02438 }
02439
02440
02441
02442
02443 static void _SdParamReset(sSdCard *pSd)
02444 {
02445 uint32_t i;
02446
02447 pSd->dwTranSpeed = 0;
02448 pSd->dwTotalSize = 0;
02449 pSd->dwNbBlocks = 0;
02450 pSd->wBlockSize = 0;
02451
02452 pSd->wCurrBlockLen = 0;
02453 pSd->dwCurrSpeed = 0;
02454 pSd->wAddress = 0;
02455
02456 pSd->bCardType = 0;
02457 pSd->bStatus = 0;
02458 pSd->bState = SDMMC_STATE_IDENT;
02459
02460
02461
02462 for (i = 0; i < 128/8/4; i ++) pSd->CID[i] = 0;
02463 for (i = 0; i < 128/8/4; i ++) pSd->CSD[i] = 0;
02464 for (i = 0; i < 512/4; i ++) pSd->EXT[i] = 0;
02465
02466 }
02467
02468
02469
02470
02471
02472
02473
02474
02475 void SDD_Initialize(sSdCard * pSd,
02476 const void * pDrv, uint8_t bSlot,
02477 const sSdHalFunctions * pHalf)
02478 {
02479 pSd->pDrv = (void *)pDrv;
02480 pSd->pHalf = (sSdHalFunctions *)pHalf;
02481 pSd->pExt = NULL;
02482 pSd->bSlot = bSlot;
02483
02484 _SdParamReset(pSd);
02485 }
02486
02487
02488
02489
02490
02491
02492
02493
02494 uint8_t SD_Init(sSdCard *pSd)
02495 {
02496 uint8_t error;
02497 uint32_t clock;
02498
02499 _SdParamReset(pSd);
02500
02501
02502 clock = 400000;
02503 _HwSetClock(pSd, &clock);
02504
02505
02506
02507
02508
02509
02510 error = Pon(pSd);
02511 if (error) {
02512 TRACE_ERROR("SD_Init.PowON:%d\n\r", error);
02513 return error;
02514 }
02515
02516
02517
02518
02519
02520
02521 error = SdMmcIdentify(pSd);
02522 if (error) {
02523 TRACE_ERROR("SD_Init.Identify: %d\n\r", error);
02524 return error;
02525 }
02526 error = SdMmcEnum(pSd);
02527 if (error) {
02528 TRACE_ERROR("SD_Init.Enum: %d\n\r", error);
02529 return error;
02530 }
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544 if (pSd->bCardType == CARD_SD) {
02545 error = Cmd16(pSd, SDMMC_BLOCK_SIZE);
02546 if (error) {
02547 TRACE_ERROR("SD_Init.Enum: %d\n\r", error);
02548 return error;
02549 }
02550 }
02551 pSd->wCurrBlockLen = SDMMC_BLOCK_SIZE;
02552
02553
02554 pSd->bState = SDMMC_STATE_TRAN;
02555
02556
02557 if ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC
02558 && SD_CSD_C_SIZE(pSd->CSD) == 0xFFF) {
02559 pSd->dwNbBlocks = MMC_EXT_SEC_COUNT(pSd->EXT);
02560
02561 if (pSd->dwNbBlocks > 0x800000)
02562 pSd->dwTotalSize = 0xFFFFFFFF;
02563 else
02564 pSd->dwTotalSize = MMC_EXT_SEC_COUNT(pSd->EXT)*512;
02565 }
02566
02567 else if((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD
02568 && SD_CSD_STRUCTURE(pSd->CSD) >= 1) {
02569 pSd->wBlockSize = 512;
02570 pSd->dwNbBlocks = SD_CSD_BLOCKNR_HC(pSd->CSD);
02571 pSd->dwTotalSize = 0xFFFFFFFF;
02572 }
02573
02574 else if (pSd->bCardType & CARD_TYPE_bmSDMMC) {
02575 pSd->wBlockSize = 512;
02576 pSd->dwTotalSize = SD_CSD_TOTAL_SIZE(pSd->CSD);
02577 pSd->dwNbBlocks = pSd->dwTotalSize/ 512;
02578 }
02579
02580 if (pSd->bCardType == CARD_UNKNOWN) {
02581 return SDMMC_ERROR_NOT_INITIALIZED;
02582 }
02583
02584 clock = pSd->dwTranSpeed;
02585 _HwSetClock(pSd, &clock);
02586 TRACE_WARNING_WP("-I- Set SD/MMC clock to %uK\n\r", (unsigned int)clock/1000);
02587 pSd->dwCurrSpeed = clock;
02588 return 0;
02589 }
02590
02591
02592
02593
02594
02595 void SD_DeInit(sSdCard *pSd)
02596 {
02597 if (pSd->pDrv) {
02598 _HwReset(pSd);
02599 _SdParamReset(pSd);
02600 }
02601 }
02602
02603
02604
02605
02606
02607
02608 uint8_t SD_GetCardType(sSdCard *pSd)
02609 {
02610 assert( pSd != NULL ) ;
02611
02612 return pSd->bCardType;
02613 }
02614
02615
02616
02617
02618
02619 uint32_t SD_GetTotalSizeKB(sSdCard *pSd)
02620 {
02621 assert( pSd != NULL ) ;
02622
02623 if (pSd->dwTotalSize == 0xFFFFFFFF) {
02624 return pSd->dwNbBlocks / 2;
02625 }
02626 return pSd->dwTotalSize / 1024;
02627 }
02628
02629
02630
02631
02632
02633
02634 uint32_t SD_GetBlockSize( sSdCard *pSd )
02635 {
02636 assert( pSd != NULL ) ;
02637
02638 return pSd->wBlockSize;
02639 }
02640
02641
02642
02643
02644
02645 uint32_t SD_GetNumberBlocks( sSdCard *pSd )
02646 {
02647 assert( pSd != NULL ) ;
02648
02649 return pSd->dwNbBlocks ;
02650 }
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 uint8_t SDIO_ReadDirect(sSdCard *pSd,
02662 uint8_t functionNum,
02663 uint32_t address,
02664 uint8_t *pData,
02665 uint32_t size)
02666 {
02667 uint8_t error;
02668 uint32_t status;
02669
02670 assert( pSd != NULL ) ;
02671
02672 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02673 if (size == 0) return SDMMC_ERROR_PARAM;
02674 while(size --) {
02675 status = 0;
02676 error = Cmd52(pSd, 0, functionNum, 0, address ++, &status);
02677 if (pData) *pData ++ = (uint8_t)status;
02678 if (error) {
02679 TRACE_ERROR("IO_RdDirect.Cmd52: %d\n\r", error);
02680 return SDMMC_ERROR;
02681 }
02682 else if (status & STATUS_SDIO_R5) {
02683 TRACE_ERROR("RD_DIRECT(%u, %u) st %x\n\r",
02684 (unsigned int)address, (unsigned int)size, (unsigned int)status);
02685 return SDMMC_ERROR;
02686 }
02687 }
02688 } else {
02689 return SDMMC_ERROR_NOT_SUPPORT;
02690 }
02691 return 0;
02692 }
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702 uint8_t SDIO_WriteDirect(sSdCard *pSd,
02703 uint8_t functionNum,
02704 uint32_t address,
02705 uint8_t dataByte)
02706 {
02707 uint8_t error;
02708 uint32_t status;
02709
02710 assert( pSd != NULL ) ;
02711
02712 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02713 status = dataByte;
02714 error = Cmd52(pSd, 1, functionNum, 0, address, &status);
02715 if (error) {
02716 TRACE_ERROR("SDIO_WrDirect.Cmd52: %d\n\r", error);
02717 return SDMMC_ERROR;
02718 } else if (status & STATUS_SDIO_R5) {
02719 TRACE_ERROR("WR_DIRECT(%u) st %x\n\r",
02720 (unsigned int)address, (unsigned int)status);
02721 return SDMMC_ERROR;
02722 }
02723 } else {
02724 return SDMMC_ERROR_NOT_SUPPORT;
02725 }
02726 return 0;
02727 }
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741 uint8_t SDIO_ReadBytes(sSdCard *pSd,
02742 uint8_t functionNum,
02743 uint32_t address,
02744 uint8_t isFixedAddress,
02745 uint8_t *pData,
02746 uint16_t size,
02747 fSdmmcCallback fCallback,
02748 void* pArg)
02749 {
02750 uint8_t error;
02751 uint32_t status;
02752
02753 assert( pSd != NULL ) ;
02754
02755 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02756 if (size == 0) return SDMMC_ERROR_PARAM;
02757 error = Cmd53(pSd,
02758 0, functionNum, 0, !isFixedAddress,
02759 address, pData, size,
02760 &status,
02761 fCallback, pArg);
02762 if (error) {
02763 TRACE_ERROR("IO_RdBytes.Cmd53: %d\n\r", error);
02764 return SDMMC_ERROR;
02765 } else if (status & STATUS_SDIO_R5) {
02766 TRACE_ERROR("RD_EXT st %x\n\r", (unsigned int)status);
02767 return SDMMC_ERROR;
02768 }
02769 } else {
02770 return SDMMC_ERROR_NOT_SUPPORT;
02771 }
02772 return 0;
02773 }
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 uint8_t SDIO_WriteBytes(sSdCard *pSd,
02788 uint8_t functionNum,
02789 uint32_t address,
02790 uint8_t isFixedAddress,
02791 uint8_t *pData,
02792 uint16_t size,
02793 fSdmmcCallback fCallback,
02794 void* pArg)
02795 {
02796 uint8_t error;
02797 uint32_t status;
02798
02799 assert( pSd != NULL ) ;
02800
02801 if (pSd->bCardType & CARD_TYPE_bmSDIO) {
02802 if (size == 0) return SDMMC_ERROR_PARAM;
02803 error = Cmd53(pSd,
02804 1, functionNum, 0, !isFixedAddress,
02805 address, pData, size,
02806 (uint32_t*)&status,
02807 fCallback, pArg);
02808 Delay(100);
02809 if (error) {
02810 TRACE_ERROR("IO_WrBytes.Cmd53: %d\n\r", error);
02811 return SDMMC_ERROR;
02812 } else if (status & STATUS_SDIO_R5) {
02813 TRACE_ERROR("WR_EXT st %x\n\r", (unsigned int)status);
02814 return SDMMC_ERROR;
02815 }
02816 } else {
02817 return SDMMC_ERROR_NOT_SUPPORT;
02818 }
02819 return 0;
02820 }
02821
02822
02823
02824
02825
02826
02827
02828 void SDIO_DumpCardInformation(sSdCard * pSd)
02829 {
02830 uint32_t tmp = 0, addrCIS = 0, addrManfID = 0, addrFunc0 = 0;
02831 uint8_t *p = (uint8_t*)&tmp;
02832 uint8_t buf[8];
02833
02834 switch(pSd->bCardType)
02835 {
02836 case CARD_SDIO:
02837 TRACE_INFO("** SDIO ONLY card\n\r");
02838 break;
02839 case CARD_SDCOMBO: case CARD_SDHCCOMBO:
02840 TRACE_INFO("** SDIO Combo card\n\r");
02841 break;
02842 default:
02843 TRACE_INFO("** NO SDIO\n\r");
02844 return;
02845 }
02846
02847 TRACE_INFO("====== CCCR ======\n\r");
02848 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CCCR_REG, p, 1);
02849 TRACE_INFO(".SDIO %02lX\n\r", (tmp & SDIO_SDIO) >> 4);
02850 TRACE_INFO(".CCCR %02lX\n\r", (tmp & SDIO_CCCR) >> 0);
02851 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_SD_REV_REG, p, 1);
02852 TRACE_INFO(".SD %02lX\n\r", (tmp & SDIO_SD) >> 0);
02853 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IOE_REG, p, 1);
02854 TRACE_INFO(".IOE %02lX\n\r", (tmp & SDIO_IOE) >> 0);
02855 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IOR_REG, p, 1);
02856 TRACE_INFO(".IOR %02lX\n\r", (tmp & SDIO_IOR) >> 0);
02857 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IEN_REG, p, 1);
02858 TRACE_INFO(".IEN %02lX\n\r", (tmp & SDIO_IEN) >> 0);
02859 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_INT_REG, p, 1);
02860 TRACE_INFO(".INT %u\n\r", (unsigned int)(tmp & SDIO_INT));
02861 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_BUS_CTRL_REG, p, 1);
02862 TRACE_INFO(".CD %lx\n\r", (tmp & SDIO_CD) >> 7);
02863 TRACE_INFO(".SCSI %lx\n\r", (tmp & SDIO_SCSI) >> 6);
02864 TRACE_INFO(".ECSI %lx\n\r", (tmp & SDIO_ECSI) >> 5);
02865 TRACE_INFO(".BUS_WIDTH %lx\n\r", (tmp & SDIO_BUSWIDTH) >> 0);
02866 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CAP_REG, p, 1);
02867 TRACE_INFO(".4BLS %lx\n\r", (tmp & SDIO_4BLS) >> 7);
02868 TRACE_INFO(".LSC %lx\n\r", (tmp & SDIO_LSC) >> 6);
02869 TRACE_INFO(".E4MI %lx\n\r", (tmp & SDIO_E4MI) >> 5);
02870 TRACE_INFO(".S4MI %lx\n\r", (tmp & SDIO_S4MI) >> 4);
02871 TRACE_INFO(".SBS %lx\n\r", (tmp & SDIO_SBS) >> 3);
02872 TRACE_INFO(".SRW %lx\n\r", (tmp & SDIO_SRW) >> 2);
02873 TRACE_INFO(".SMB %lx\n\r", (tmp & SDIO_SMB) >> 1);
02874 TRACE_INFO(".SDC %lx\n\r", (tmp & SDIO_SDC) >> 0);
02875 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_CIS_PTR_REG, p, 3);
02876 TRACE_INFO(".CIS_PTR %06X\n\r", (unsigned int)tmp);
02877 addrCIS = tmp; tmp = 0;
02878 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_BUS_SUSP_REG, p, 1);
02879 TRACE_INFO(".BR %lx\n\r", (tmp & SDIO_BR) >> 1);
02880 TRACE_INFO(".BS %lx\n\r", (tmp & SDIO_BS) >> 0);
02881 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_FUN_SEL_REG, p, 1);
02882 TRACE_INFO(".DF %lx\n\r", (tmp & SDIO_DF) >> 7);
02883 TRACE_INFO(".FS %lx\n\r", (tmp & SDIO_FS) >> 0);
02884 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_EXEC_REG, p, 1);
02885 TRACE_INFO(".EX %lx\n\r", (tmp & SDIO_EX));
02886 TRACE_INFO(".EXM %lx\n\r", (tmp & SDIO_EXM) >> 0);
02887 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_READY_REG, p, 1);
02888 TRACE_INFO(".RF %lx\n\r", (tmp & SDIO_RF));
02889 TRACE_INFO(".RFM %lx\n\r", (tmp & SDIO_RFM) >> 0);
02890 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_FN0_BLKSIZ_REG, p, 2);
02891 TRACE_INFO(".FN0_SIZE %u(%04X)\n\r", (unsigned int)tmp, (unsigned int)tmp);
02892 tmp = 0;
02893 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_POWER_REG, p, 1);
02894 TRACE_INFO(".EMPC %lx\n\r", (tmp & SDIO_EMPC) >> 1);
02895 TRACE_INFO(".SMPC %lx\n\r", (tmp & SDIO_SMPC) >> 0);
02896 SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_HS_REG, p, 1);
02897 TRACE_INFO(".EHS %lx\n\r", (tmp & SDIO_EHS) >> 1);
02898 TRACE_INFO(".SHS %lx\n\r", (tmp & SDIO_SHS) >> 0);
02899
02900 SdioFindTuples(pSd, addrCIS, 128, &addrManfID, &addrFunc0);
02901 if (addrManfID != 0) {
02902 SDIO_ReadDirect(pSd, SDIO_CIA, addrManfID, buf, 6);
02903 TRACE_INFO("==== CISTPL_MANFID ====\n\r");
02904 TRACE_INFO("._MANF %04X\n\r", buf[2] + (buf[3] << 8));
02905 TRACE_INFO("._CARD %04X\n\r", buf[4] + (buf[5] << 8));
02906 }
02907 if (addrFunc0 != 0) {
02908 SDIO_ReadDirect(pSd, SDIO_CIA, addrFunc0, buf, 6);
02909 TRACE_INFO("== CISTPL_FUNCE Fun0 ==\n\r");
02910 TRACE_INFO("._FN0_BLK_SIZE %d(0x%04X)\n\r",
02911 buf[3] + (buf[4] << 8), buf[3] + (buf[4] << 8));
02912 TRACE_INFO("._MAX_TRAN_SPEED %02X\n\r", buf[5]);
02913 }
02914 }
02915
02916
02917
02918
02919
02920
02921 void SD_DumpCID(void* pCID)
02922 {
02923 TRACE_INFO("======= CID =======");
02924
02925 TRACE_INFO("===================\n\r");
02926 TRACE_INFO(" .MID Manufacturer ID %02X\n\r",
02927 (unsigned int)SD_CID_MID(pCID));
02928
02929 TRACE_INFO(" .CBX Card/BGA (eMMC) %X\n\r",
02930 (unsigned int)eMMC_CID_CBX(pCID));
02931
02932 TRACE_INFO(" .OID OEM/Application ID (SD) %c%c\n\r",
02933 (char)SD_CID_OID1(pCID),
02934 (char)SD_CID_OID0(pCID));
02935 TRACE_INFO(" .OID OEM/Application ID (MMC) %x\n\r",
02936 (unsigned int)eMMC_CID_OID(pCID));
02937
02938 TRACE_INFO(" .PNM Product name (SD) %c%c%c%c%c\n\r",
02939 (char)SD_CID_PNM4(pCID),
02940 (char)SD_CID_PNM3(pCID),
02941 (char)SD_CID_PNM2(pCID),
02942 (char)SD_CID_PNM1(pCID),
02943 (char)SD_CID_PNM0(pCID));
02944 TRACE_INFO(" .PNM Product name (MMC) %c%c%c%c%c%c\n\r",
02945 (char)MMC_CID_PNM5(pCID),
02946 (char)MMC_CID_PNM4(pCID),
02947 (char)MMC_CID_PNM3(pCID),
02948 (char)MMC_CID_PNM2(pCID),
02949 (char)MMC_CID_PNM1(pCID),
02950 (char)MMC_CID_PNM0(pCID));
02951
02952 TRACE_INFO(" .PRV Product revision (SD) %x\n\r",
02953 (unsigned int)SD_CID_PRV(pCID));
02954 TRACE_INFO(" .PRV Product revision (MMC) %x\n\r",
02955 (unsigned int)MMC_CID_PRV(pCID));
02956
02957 TRACE_INFO(" .PSN Product serial number (SD) %02X%02X%02X%02X\n\r",
02958 (unsigned int)SD_CID_PSN3(pCID),
02959 (unsigned int)SD_CID_PSN2(pCID),
02960 (unsigned int)SD_CID_PSN1(pCID),
02961 (unsigned int)SD_CID_PSN0(pCID));
02962 TRACE_INFO(" .PSN Product serial number (MMC) %02X%02X%02X%02X\n\r",
02963 (unsigned int)MMC_CID_PSN3(pCID),
02964 (unsigned int)MMC_CID_PSN2(pCID),
02965 (unsigned int)MMC_CID_PSN1(pCID),
02966 (unsigned int)MMC_CID_PSN0(pCID));
02967
02968 TRACE_INFO(" .MDT Manufacturing date (SD) %04d/%02d\n\r",
02969 (uint16_t)(SD_CID_MDT_Y(pCID) + 2000),
02970 (uint8_t)SD_CID_MDT_M(pCID));
02971 TRACE_INFO(" .MDT Manufacturing date (MMC) %04d/%02d\n\r",
02972 (uint16_t)(MMC_CID_MDT_Y(pCID) + 1997),
02973 (uint8_t)SD_CID_MDT_M(pCID));
02974
02975 TRACE_INFO(" .CRC checksum %02X\n\r",
02976 (unsigned int)SD_CID_CRC(pCID));
02977 }
02978
02979
02980
02981
02982
02983 void SD_DumpCSD(void* pCSD)
02984 {
02985 TRACE_INFO("======== CSD ========");
02986
02987 TRACE_INFO("===================\n\r");
02988 TRACE_INFO(" .CSD_STRUCTURE 0x%x\r\n", (unsigned int)SD_CSD_STRUCTURE(pCSD));
02989 TRACE_INFO(" .SPEC_VERS (eMMC) 0x%x\r\n", (unsigned int)MMC_CSD_SPEC_VERS(pCSD));
02990 TRACE_INFO(" .TAAC 0x%X\r\n", (unsigned int)SD_CSD_TAAC(pCSD) );
02991 TRACE_INFO(" .NSAC 0x%X\r\n", (unsigned int)SD_CSD_NSAC(pCSD) );
02992 TRACE_INFO(" .TRAN_SPEED 0x%X\r\n", (unsigned int)SD_CSD_TRAN_SPEED(pCSD) );
02993 TRACE_INFO(" .CCC 0x%X\r\n", (unsigned int)SD_CSD_CCC(pCSD) );
02994 TRACE_INFO(" .READ_BL_LEN 0x%X\r\n", (unsigned int)SD_CSD_READ_BL_LEN(pCSD) );
02995 TRACE_INFO(" .READ_BL_PARTIAL 0x%X\r\n", (unsigned int)SD_CSD_READ_BL_PARTIAL(pCSD) );
02996 TRACE_INFO(" .WRITE_BLK_MISALIGN 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BLK_MISALIGN(pCSD));
02997 TRACE_INFO(" .READ_BLK_MISALIGN 0x%X\r\n", (unsigned int)SD_CSD_READ_BLK_MISALIGN(pCSD) );
02998 TRACE_INFO(" .DSR_IMP 0x%X\r\n", (unsigned int)SD_CSD_DSR_IMP(pCSD) );
02999 TRACE_INFO(" .C_SIZE 0x%X\r\n", (unsigned int)SD_CSD_C_SIZE(pCSD) );
03000 TRACE_INFO(" .C_SIZE_HC 0x%X\r\n", (unsigned int)SD2_CSD_C_SIZE(pCSD) );
03001 TRACE_INFO(" .VDD_R_CURR_MIN 0x%X\r\n", (unsigned int)SD_CSD_VDD_R_CURR_MIN(pCSD) );
03002 TRACE_INFO(" .VDD_R_CURR_MAX 0x%X\r\n", (unsigned int)SD_CSD_VDD_R_CURR_MAX(pCSD) );
03003 TRACE_INFO(" .VDD_W_CURR_MIN 0x%X\r\n", (unsigned int)SD_CSD_VDD_W_CURR_MIN(pCSD) );
03004 TRACE_INFO(" .VDD_W_CURR_MAX 0x%X\r\n", (unsigned int)SD_CSD_VDD_W_CURR_MAX(pCSD) );
03005 TRACE_INFO(" .C_SIZE_MULT 0x%X\r\n", (unsigned int)SD_CSD_C_SIZE_MULT(pCSD) );
03006 TRACE_INFO(" .ERASE_BLK_EN 0x%X\r\n", (unsigned int)SD_CSD_ERASE_BLK_EN(pCSD) );
03007 TRACE_INFO(" .SECTOR_SIZE 0x%X\r\n", (unsigned int)SD_CSD_SECTOR_SIZE(pCSD) );
03008 TRACE_INFO(" .WP_GRP_SIZE 0x%X\r\n", (unsigned int)SD_CSD_WP_GRP_SIZE(pCSD) );
03009 TRACE_INFO(" .WP_GRP_ENABLE 0x%X\r\n", (unsigned int)SD_CSD_WP_GRP_ENABLE(pCSD) );
03010 TRACE_INFO(" .R2W_FACTOR 0x%X\r\n", (unsigned int)SD_CSD_R2W_FACTOR(pCSD) );
03011 TRACE_INFO(" .WRITE_BL_LEN 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BL_LEN(pCSD) );
03012 TRACE_INFO(" .WRITE_BL_PARTIAL 0x%X\r\n", (unsigned int)SD_CSD_WRITE_BL_PARTIAL(pCSD) );
03013 TRACE_INFO(" .FILE_FORMAT_GRP 0x%X\r\n", (unsigned int)SD_CSD_FILE_FORMAT_GRP(pCSD) );
03014 TRACE_INFO(" .COPY 0x%X\r\n", (unsigned int)SD_CSD_COPY(pCSD) );
03015 TRACE_INFO(" .PERM_WRITE_PROTECT 0x%X\r\n", (unsigned int)SD_CSD_PERM_WRITE_PROTECT(pCSD));
03016 TRACE_INFO(" .TMP_WRITE_PROTECT 0x%X\r\n", (unsigned int)SD_CSD_TMP_WRITE_PROTECT(pCSD) );
03017 TRACE_INFO(" .FILE_FORMAT 0x%X\r\n", (unsigned int)SD_CSD_FILE_FORMAT(pCSD) );
03018 TRACE_INFO(" .ECC (MMC) 0x%X\r\n", (unsigned int)MMC_CSD_ECC(pCSD) );
03019 TRACE_INFO(" .CRC 0x%X\r\n", (unsigned int)SD_CSD_CRC(pCSD) );
03020 TRACE_INFO(" .MULT 0x%X\r\n", (unsigned int)SD_CSD_MULT(pCSD) );
03021 TRACE_INFO(" .BLOCKNR 0x%X\r\n", (unsigned int)SD_CSD_BLOCKNR(pCSD) );
03022 TRACE_INFO(" .BLOCKNR_HC 0x%X\r\n", (unsigned int)SD_CSD_BLOCKNR_HC(pCSD) );
03023 TRACE_INFO(" .BLOCK_LEN 0x%X\r\n", (unsigned int)SD_CSD_BLOCK_LEN(pCSD) );
03024 TRACE_INFO(" -TOTAL_SIZE 0x%X\r\n", (unsigned int)SD_CSD_TOTAL_SIZE(pCSD) );
03025 TRACE_INFO(" -TOTAL_SIZE_HC 0x%X\r\n", (unsigned int)SD_CSD_TOTAL_SIZE_HC(pCSD) );
03026 }
03027
03028
03029
03030
03031
03032 void SD_DumpExtCSD(void* pExtCSD)
03033 {
03034 TRACE_INFO("======= EXT_CSD =======");
03035 TRACE_INFO_WP("\n\r");
03036 TRACE_INFO(" .S_CMD_SET : 0x%X\n\r",
03037 MMC_EXT_S_CMD_SET(pExtCSD));
03038 TRACE_INFO(" .BOOT_INFO : 0x%X\n\r",
03039 MMC_EXT_BOOT_INFO(pExtCSD));
03040 TRACE_INFO(" .BOOT_SIZE_MULTI : 0x%X\n\r",
03041 MMC_EXT_BOOT_SIZE_MULTI(pExtCSD));
03042 TRACE_INFO(" .ACC_SIZE : 0x%X\n\r",
03043 MMC_EXT_ACC_SIZE(pExtCSD));
03044 TRACE_INFO(" .HC_ERASE_GRP_SIZE : 0x%X\n\r",
03045 MMC_EXT_HC_ERASE_GRP_SIZE(pExtCSD));
03046 TRACE_INFO(" .ERASE_TIMEOUT_MULT : 0x%X\n\r",
03047 MMC_EXT_ERASE_TIMEOUT_MULT(pExtCSD));
03048 TRACE_INFO(" .REL_WR_SEC_C : 0x%X\n\r",
03049 MMC_EXT_REL_WR_SEC_C(pExtCSD));
03050 TRACE_INFO(" .HC_WP_GRP_SIZE : 0x%X\n\r",
03051 MMC_EXT_HC_WP_GRP_SIZE(pExtCSD));
03052 TRACE_INFO(" .S_C_VCC : 0x%X\n\r",
03053 MMC_EXT_S_C_VCC(pExtCSD));
03054 TRACE_INFO(" .S_C_VCCQ : 0x%X\n\r",
03055 MMC_EXT_S_C_VCCQ(pExtCSD));
03056 TRACE_INFO(" .S_A_TIMEOUT : 0x%X\n\r",
03057 MMC_EXT_S_A_TIMEOUT(pExtCSD));
03058 TRACE_INFO(" .SEC_COUNT : 0x%X\n\r",
03059 MMC_EXT_SEC_COUNT(pExtCSD));
03060 TRACE_INFO(" .MIN_PERF_W_8_52 : 0x%X\n\r",
03061 MMC_EXT_MIN_PERF_W_8_52(pExtCSD));
03062 TRACE_INFO(" .MIN_PERF_R_8_52 : 0x%X\n\r",
03063 MMC_EXT_MIN_PERF_R_8_52(pExtCSD));
03064 TRACE_INFO(" .MIN_PERF_W_8_26_4_52 : 0x%X\n\r",
03065 MMC_EXT_MIN_PERF_W_8_26_4_52(pExtCSD));
03066 TRACE_INFO(" .MIN_PERF_R_8_26_4_52 : 0x%X\n\r",
03067 MMC_EXT_MIN_PERF_R_8_26_4_52(pExtCSD));
03068 TRACE_INFO(" .MIN_PERF_W_4_26 : 0x%X\n\r",
03069 MMC_EXT_MIN_PERF_W_4_26(pExtCSD));
03070 TRACE_INFO(" .MIN_PERF_R_4_26 : 0x%X\n\r",
03071 MMC_EXT_MIN_PERF_R_4_26(pExtCSD));
03072 TRACE_INFO(" .PWR_CL_26_360 : 0x%X\n\r",
03073 MMC_EXT_PWR_CL_26_360(pExtCSD));
03074 TRACE_INFO(" .PWR_CL_52_360 : 0x%X\n\r",
03075 MMC_EXT_PWR_CL_52_360(pExtCSD));
03076 TRACE_INFO(" .PWR_CL_26_195 : 0x%X\n\r",
03077 MMC_EXT_PWR_CL_26_195(pExtCSD));
03078 TRACE_INFO(" .PWR_CL_52_195 : 0x%X\n\r",
03079 MMC_EXT_PWR_CL_52_195(pExtCSD));
03080 TRACE_INFO(" .CARD_TYPE : 0x%X\n\r",
03081 MMC_EXT_CARD_TYPE(pExtCSD));
03082 TRACE_INFO(" .CSD_STRUCTURE : 0x%X\n\r",
03083 MMC_EXT_CSD_STRUCTURE(pExtCSD));
03084 TRACE_INFO(" .EXT_CSD_REV : 0x%X\n\r",
03085 MMC_EXT_EXT_CSD_REV(pExtCSD));
03086 TRACE_INFO(" .CMD_SET : 0x%X\n\r",
03087 MMC_EXT_CMD_SET(pExtCSD));
03088 TRACE_INFO(" .CMD_SET_REV : 0x%X\n\r",
03089 MMC_EXT_CMD_SET_REV(pExtCSD));
03090 TRACE_INFO(" .POWER_CLASS : 0x%X\n\r",
03091 MMC_EXT_POWER_CLASS(pExtCSD));
03092 TRACE_INFO(" .HS_TIMING : 0x%X\n\r",
03093 MMC_EXT_HS_TIMING(pExtCSD));
03094 TRACE_INFO(" .BUS_WIDTH : 0x%X\n\r",
03095 MMC_EXT_BUS_WIDTH(pExtCSD));
03096 TRACE_INFO(" .ERASED_MEM_CONT : 0x%X\n\r",
03097 MMC_EXT_ERASED_MEM_CONT(pExtCSD));
03098 TRACE_INFO(" .BOOT_CONFIG : 0x%X\n\r",
03099 MMC_EXT_BOOT_CONFIG(pExtCSD));
03100 TRACE_INFO(" .BOOT_BUS_WIDTH : 0x%X\n\r",
03101 MMC_EXT_BOOT_BUS_WIDTH(pExtCSD));
03102 TRACE_INFO(" .ERASE_GROUP_DEF : 0x%X\n\r",
03103 MMC_EXT_ERASE_GROUP_DEF(pExtCSD));
03104 }
03105
03106
03107
03108
03109
03110 void SD_DumpSCR(void *pSCR)
03111 {
03112 TRACE_INFO("========== SCR ==========");
03113 TRACE_INFO_WP("\n\r");
03114
03115 TRACE_INFO(" .SCR_STRUCTURE :0x%X\n\r",
03116 (unsigned int)SD_SCR_STRUCTURE(pSCR));
03117 TRACE_INFO(" .SD_SPEC :0x%X\n\r",
03118 (unsigned int)SD_SCR_SD_SPEC(pSCR));
03119 TRACE_INFO(" .DATA_STAT_AFTER_ERASE :0x%X\n\r",
03120 (unsigned int)SD_SCR_DATA_STAT_AFTER_ERASE(pSCR));
03121 TRACE_INFO(" .SD_SECURITY :0x%X\n\r",
03122 (unsigned int)SD_SCR_SD_SECURITY(pSCR));
03123 TRACE_INFO(" .SD_BUS_WIDTHS :0x%X\n\r",
03124 (unsigned int)SD_SCR_SD_BUS_WIDTHS(pSCR));
03125 }
03126
03127
03128
03129
03130
03131 void SD_DumpSdStatus(void* pSdST)
03132 {
03133 TRACE_INFO("=========== STAT ============");
03134 TRACE_INFO_WP("\n\r");
03135
03136 TRACE_INFO(" .DAT_BUS_WIDTH :0x%X\n\r",
03137 (unsigned int)SD_ST_DAT_BUS_WIDTH(pSdST));
03138 TRACE_INFO(" .SECURED_MODE :0x%X\n\r",
03139 (unsigned int)SD_ST_SECURED_MODE(pSdST));
03140 TRACE_INFO(" .SD_CARD_TYPE :0x%X\n\r",
03141 (unsigned int)SD_ST_CARD_TYPE(pSdST));
03142 TRACE_INFO(" .SIZE_OF_PROTECTED_AREA :0x%X\n\r",
03143 (unsigned int)SD_ST_SIZE_OF_PROTECTED_AREA(pSdST));
03144 TRACE_INFO(" .SPEED_CLASS :0x%X\n\r",
03145 (unsigned int)SD_ST_SPEED_CLASS(pSdST));
03146 TRACE_INFO(" .PERFORMANCE_MOVE :0x%X\n\r",
03147 (unsigned int)SD_ST_PERFORMANCE_MOVE(pSdST));
03148 TRACE_INFO(" .AU_SIZE :0x%X\n\r",
03149 (unsigned int)SD_ST_AU_SIZE(pSdST));
03150 TRACE_INFO(" .ERASE_SIZE :0x%X\n\r",
03151 (unsigned int)SD_ST_ERASE_SIZE(pSdST));
03152 TRACE_INFO(" .ERASE_TIMEOUT :0x%X\n\r",
03153 (unsigned int)SD_ST_ERASE_TIMEOUT(pSdST));
03154 TRACE_INFO(" .ERASE_OFFSET :0x%X\n\r",
03155 (unsigned int)SD_ST_ERASE_OFFSET(pSdST));
03156 }
03157