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