SAMV71 Xplained Ultra Software Package 1.5

sdmmc.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file */
00031 
00032 /** \addtogroup sdmmc_api
00033  *  @{
00034  */
00035 
00036 /*----------------------------------------------------------------------------
00037  *         Headers
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  *         Global variables
00048  *----------------------------------------------------------------------------*/
00049 
00050 /*----------------------------------------------------------------------------
00051  *         Local constants
00052  *----------------------------------------------------------------------------*/
00053 
00054 /** \addtogroup sdmmc_status_bm SD/MMC Status register constants
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                                       /*| STATUS_STATE*/))
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                                        /*| STATUS_STATE*/ \
00140                                        /*| STATUS_READY_FOR_DATA*/ \
00141                                        | STATUS_SWITCH_ERROR))
00142 /**     @}*/
00143 
00144 /** \addtogroup sdio_status_bm SDIO Status definitions
00145  *      @{*/
00146 /** The CRC check of the previous command failed. */
00147 #define SDIO_COM_CRC_ERROR   (1UL << 15)
00148 /** Command not legal for the card state. */
00149 #define SDIO_ILLEGAL_COMMAND (1UL << 14)
00150 
00151 /** Status bits mask for SDIO R6 */
00152 #define STATUS_SDIO_R6  (SDIO_COM_CRC_ERROR \
00153                          | SDIO_ILLEGAL_COMMAND \
00154                          | SDIO_R6_ERROR)
00155 /** Status bits mask for SDIO R5 */
00156 #define STATUS_SDIO_R5  (0/*SDIO_R5_STATE*/ \
00157                          | SDIO_R5_ERROR \
00158                          | SDIO_R5_FUNCN_ERROR \
00159                          | SDIO_R5_OUT_OF_RANGE)
00160 /**     @}*/
00161 
00162 /*----------------------------------------------------------------------------
00163  *         Macros
00164  *----------------------------------------------------------------------------*/
00165 
00166 /** Return SD/MMC card address */
00167 #define CARD_ADDR(pSd)          (pSd->wAddress)
00168 
00169 /** Return SD/MMC card block size (Default size now, 512B) */
00170 #define BLOCK_SIZE(pSd)         (pSd->wCurrBlockLen)
00171 
00172 /** Convert block address to SD/MMC command parameter */
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 /** Check if SD Spec version 1.10 or later */
00182 #define SD_IsVer1_10(pSd) \
00183     (SD_SCR_SD_SPEC(pSd->SCR) >= SD_SCR_SD_SPEC_1_10)
00184 
00185 /** Check if SD card support HS mode (1.10 or later) */
00186 #define SD_IsHsModeSupported(pSd)  \
00187     (/*SD_IsVer1_10(pSd)||*/(SD_CSD_STRUCTURE(pSd->CSD)>=1))
00188 
00189 /** Check if SD card support 4-bit mode (All SD card) */
00190 #define SD_IsBusModeSupported(pSd) (1)
00191 
00192 /** Check if MMC Spec version 4 */
00193 #define MMC_IsVer4(pSd)     (MMC_CSD_SPEC_VERS(pSd->CSD) >= 4)
00194 
00195 /** Check if MMC CSD structure is 1.2 (3.1 or later) */
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 /** Check if MMC card support boot mode (4.3 or later) */
00201 #define MMC_IsBootModeSupported(pSd) \
00202     ((MMC_IsVer4(pSd)&&(eMMC_CID_CBX(pSd->CID)==0x01))
00203 
00204 /** Check if MMC card support 8-bit mode (4.0 or later) */
00205 #define MMC_IsBusModeSupported(pSd) (MMC_IsVer4(pSd))
00206 
00207 /** Check if MMC card support HS mode (4.0 or later) */
00208 #define MMC_IsHsModeSupported(pSd)  \
00209     (MMC_IsCSDVer1_2(pSd)&&(MMC_EXT_CARD_TYPE(pSd->EXT)&0x2))
00210 
00211 /*----------------------------------------------------------------------------
00212  *         Local variables
00213  *----------------------------------------------------------------------------*/
00214 
00215 /** SD/MMC transfer rate unit codes (10K) list */
00216 static const uint32_t sdmmcTransUnits[7] = {
00217     10, 100, 1000, 10000,
00218     0, 0, 0
00219 };
00220 
00221 /** SD transfer multiplier factor codes (1/10) list */
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 /** MMC transfer multiplier factor codes (1/10) list */
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 /** Flag for dumping SSR register */
00231 static uint8_t ssr_is_dump = 0;
00232 
00233 /*----------------------------------------------------------------------------
00234  *         Local functions
00235  *----------------------------------------------------------------------------*/
00236 
00237 /**
00238  * Delay some loop
00239  */
00240 static void Delay(volatile unsigned int loop)
00241 {
00242     for (; loop > 0; loop --);
00243 }
00244 
00245 /**
00246  *  Swap uint32_t value
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  * Find SDIO ManfID, Fun0 tuple.
00361  * \param pSd         Pointer to \ref sSdCard instance.
00362  * \param address     Search area start address.
00363  * \param size        Search area size.
00364  * \param pAddrManfID Pointer to ManfID address value buffer.
00365  * \param pAddrFunc0  Pointer to Func0 address value buffer.
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; /* 1:Manf, 2:Func0 */
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         /* End */
00386         if (tmp[0] == CISTPL_END) break;
00387         /* ManfID */
00388         else if (tmp[0] == CISTPL_MANFID) {
00389             flagFound |= 1; addManfID = addr;
00390         }
00391         /* Func0 */
00392         else if (tmp[0] == CISTPL_FUNCE && tmp[2] == 0x00) {
00393             flagFound |= 2; addFunc0 = addr;
00394         }
00395 
00396         /* Tuple error ? */
00397         if (tmp[1] == 0) break;
00398 
00399         /* Next address */
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  * \brief Decode Trans Speed Value
00414  * \param code The trans speed code value.
00415  * \param unitCodes  Unit list in 10K, 0 as unused value.
00416  * \param multiCodes Multiplier list in 1/10, index 1 ~ 15 is valid.
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     /* Unit code is valid ? */
00426     unitI = (code & 0x7);
00427 
00428     if (unitCodes[unitI] == 0) return 0;
00429 
00430     /* Multi code is valid ? */
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  * Initialization delay: The maximum of 1 msec, 74 clock cycles and supply ramp
00441  * up time.
00442  * Returns the command transfer result (see SendMciCommand).
00443  * \param pSd Pointer to \ref sSdCard instance.
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     /* Fill command */
00454     pCmd->cmdOp.wVal = SDMMC_CMD_POWERONINIT;
00455 
00456     /* Send command */
00457     bRc = _SendCmd(pSd, NULL, NULL);
00458     return bRc;
00459 }
00460 
00461 /**
00462  * Resets all cards to idle state
00463  * \param pSd Pointer to \ref sSdCard instance.
00464  * \param arg  Argument used.
00465  * \return the command transfer result (see SendMciCommand).
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     /* Fill command */
00476     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(0);
00477     pCmd->dwArg      = arg;
00478     /* Send command */
00479     bRc = _SendCmd(pSd, NULL, NULL);
00480     return bRc;
00481 }
00482 
00483 /**
00484  * MMC send operation condition command.
00485  * Sends host capacity support information and activates the card's
00486  * initialization process.
00487  * Returns the command transfer result (see SendMciCommand).
00488  * \param pSd Pointer to \ref sSdCard instance.
00489  * \param pOCR Pointer to fill OCR value to send and get.
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     /* Fill command */
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     /* Send command */
00510     bRc = _SendCmd(pSd, NULL, NULL);
00511 
00512     /* Check result */
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  * Asks any card to send the CID numbers
00529  * on the CMD line (any card that is
00530  * connected to the host will respond)
00531  * Returns the command transfer result (see SendMciCommand).
00532  * \param pSd  Pointer to a SD card driver instance.
00533  * \param pCID Pointer to buffer for storing the CID numbers.
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     /* Fill command */
00544     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(2)
00545                        | SDMMC_CMD_bmOD;
00546     pCmd->bCmd       = 2;
00547     pCmd->pResp      = pSd->CID;
00548 
00549     /* Send command */
00550     bRc = _SendCmd(pSd, NULL, NULL);
00551     return bRc;
00552 }
00553 
00554 /**
00555  * Ask the SD card to publish a new relative address (RCA)
00556  *         or
00557  * Assign relative address to the MMC card
00558  * Returns the command transfer result (see SendMciCommand).
00559  * \param pSd   Pointer to a SD card driver instance.
00560  * \param pRsp  Pointer to buffer to fill response (address on 31:16).
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     /* Fill command */
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  * SDIO SEND OPERATION CONDITION (OCR) command.
00600  * Sends host capacity support information and activates the card's
00601  * initialization process.
00602  * \return The command transfer result (see SendMciCommand).
00603  * \param pSd     Pointer to a SD/MMC card driver instance.
00604  * \param pIo     Pointer to data sent as well as response buffer (32bit).
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     /* Fill command */
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     /* Send command */
00622     bRc = _SendCmd(pSd, NULL, NULL);
00623     return bRc;
00624 }
00625 
00626 /**
00627  * Switches the mode of operation of the selected card.
00628  * CMD6 is valid under the "trans" state.
00629  * \return The command transfer result (see SendMciCommand).
00630  * \param  pSd         Pointer to a SD/MMC card driver instance.
00631  * \param  pSwitchArg  Pointer to a MmcCmd6Arg instance.
00632  * \param  pStatus     Pointer to where the 512bit status is returned.
00633  * \param  pResp       Pointer to where the response is returned.
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  * Switches the mode of operation of the selected card or
00676  * Modifies the EXT_CSD registers.
00677  * CMD6 is valid under the "trans" state.
00678  * \return The command transfer result (see SendMciCommand).
00679  * \param  pSd         Pointer to a SD/MMC card driver instance.
00680  * \param  pSwitchArg  Pointer to a MmcCmd6Arg instance.
00681  * \param  pResp       Pointer to where the response is returned.
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  * Command toggles a card between the
00712  * stand-by and transfer states or between
00713  * the programming and disconnect states.
00714  * Returns the command transfer result (see SendMciCommand).
00715  * \param pSd       Pointer to a SD card driver instance.
00716  * \param cardAddr  Relative Card Address (0 deselects all).
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     /* Fill command */
00727     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(address ? 1 : 0);
00728     pCmd->bCmd       = 7;
00729     pCmd->dwArg      = address << 16;
00730 
00731     /* Send command */
00732     bRc = _SendCmd(pSd, NULL, NULL);
00733     return bRc;
00734 }
00735 
00736 /**
00737  * Sends SD Memory Card interface condition, which includes host supply
00738  * voltage information and asks the card whether card supports voltage.
00739  * Should be performed at initialization time to detect the card type.
00740  * \param pSd             Pointer to a SD card driver instance.
00741  * \param supplyVoltage   Expected supply voltage(SD).
00742  * \return 0 if successful;
00743  *         otherwise returns SD_ERROR_NORESPONSE if the card did not answer
00744  *         the command, or SDMMC_ERROR.
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     /* Fill command information */
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     /* Send command */
00764     bRc = _SendCmd(pSd, NULL, NULL);
00765 
00766     /* Check result */
00767     if (bRc == SDMMC_ERROR_NORESPONSE)
00768         return SDMMC_ERROR_NORESPONSE;
00769     /* SD_R7
00770      * Bit 0 - 7: check pattern (echo-back)
00771      * Bit 8 -11: voltage accepted
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  * SEND_EXT_CSD, to get EXT_CSD register as a block of data.
00782  * Valid under "trans" state.
00783  * \param pSd   Pointer to a SD card driver instance.
00784  * \param pEXT  512 byte buffer pointer for EXT_CSD data.
00785  * \return 0 if successful;
00786  *         otherwise returns SD_ERROR_NORESPONSE if the card did not answer
00787  *         the command, or SDMMC_ERROR.
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     /* Fill command */
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     /* Send command */
00806     bRc = _SendCmd(pSd, NULL, NULL);
00807     return bRc;
00808 }
00809 
00810 /**
00811  * Addressed card sends its card-specific
00812  * data (CSD) on the CMD line.
00813  * Returns the command transfer result (see SendMciCommand).
00814  * \param pSd       Pointer to a SD card driver instance.
00815  * \param cardAddr  Card Relative Address.
00816  * \param pCSD      Pointer to buffer for CSD data.
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     /* Fill command */
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     /* Send command */
00833     bRc = _SendCmd(pSd, NULL, NULL);
00834     return bRc;
00835 }
00836 
00837 /**
00838  * Forces the card to stop transmission
00839  * \param pSd      Pointer to a SD card driver instance.
00840  * \param pStatus  Pointer to a status variable.
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     /* Fill command */
00851     pCmd->bCmd       = 12;
00852     pCmd->cmdOp.wVal = SDMMC_CMD_CSTOP
00853                        | SDMMC_CMD_bmBUSY;
00854     pCmd->pResp      = pStatus;
00855 
00856     /* Send command */
00857     bRc = _SendCmd(pSd, NULL, NULL);
00858     return bRc;
00859 }
00860 
00861 /**
00862  * Addressed card sends its status register.
00863  * Returns the command transfer result (see SendMciCommand).
00864  * \param pSd       Pointer to a SD card driver instance.
00865  * \param pStatus   Pointer to a status variable.
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     /* Fill command */
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     /* Send command */
00882     bRc = _SendCmd(pSd, NULL, NULL);
00883     return bRc;
00884 }
00885 
00886 /**
00887  * In the case of a Standard Capacity SD Memory Card, this command sets the
00888  * block length (in bytes) for all following block commands
00889  * (read, write, lock).
00890  * Default block length is fixed to 512 Bytes.
00891  * Set length is valid for memory access commands only if partial block read
00892  * operation are allowed in CSD.
00893  * In the case of a High Capacity SD Memory Card, block length set by CMD16
00894  * command does not affect the memory read and write commands. Always 512
00895  * Bytes fixed block length is used. This command is effective for LOCK_UNLOCK
00896  * command. In both cases, if block length is set larger than 512Bytes, the
00897  * card sets the BLOCK_LEN_ERROR bit.
00898  * \param pSd  Pointer to a SD card driver instance.
00899  * \param blockLength  Block length in bytes.
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     /* Fill command */
00910     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
00911     pCmd->bCmd       = 16;
00912     pCmd->dwArg      = blkLen;
00913 
00914     /* Send command */
00915     bRc = _SendCmd(pSd, NULL, NULL);
00916     return bRc;
00917 }
00918 
00919 /**
00920  * Read single block command
00921  * \param pSd  Pointer to a SD card driver instance.
00922  * \param pData     Pointer to the DW aligned buffer to be filled.
00923  * \param address   Data Address on SD/MMC card.
00924  * \param pStatus   Pointer response buffer as status return.
00925  * \param fCallback Pointer to optional callback invoked on command end.
00926  *                  NULL:    Function return until command finished.
00927  *                  Pointer: Return immediately and invoke callback at end.
00928  *                  Callback argument is fixed to a pointer to sSdCard instance.
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     /* Fill command */
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     /* Send command */
00953     bRc = _SendCmd(pSd, NULL, NULL);
00954     return bRc;
00955 }
00956 
00957 /**
00958  * A host reads the reversed bus testing data pattern from a card
00959  * \param pSd  Pointer to a SD card driver instance.
00960  * \param pData     Pointer to the DW aligned buffer to be filled.
00961  * \param len       Length of data in byte
00962  * \param pStatus   Pointer response buffer as status return.
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     /* Fill command */
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     /* Send command */
00984     bRc = _SendCmd(pSd, NULL, NULL);
00985     return bRc;
00986 }
00987 
00988 /**
00989  * A host sends the bus test data pattern to a card.
00990  * \param pSd  Pointer to a SD card driver instance.
00991  * \param pData     Pointer to the DW aligned buffer to be filled.
00992  * \param len       Length of data in byte
00993  * \param pStatus   Pointer response buffer as status return.
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     /* Fill command */
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     /* Send command */
01015     bRc = _SendCmd(pSd, NULL, NULL);
01016     return bRc;
01017 }
01018 
01019 /**
01020  * Continuously transfers datablocks from card to host until interrupted by a
01021  * STOP_TRANSMISSION command.
01022  * \param pSd       Pointer to a SD card driver instance.
01023  * \param nbBlocks  Number of blocks to send.
01024  * \param pData     Pointer to the DW aligned buffer to be filled.
01025  * \param address   Data Address on SD/MMC card.
01026  * \param pStatus   Pointer to the response status.
01027  * \param fCallback Pointer to optional callback invoked on command end.
01028  *                  NULL:    Function return until command finished.
01029  *                  Pointer: Return immediately and invoke callback at end.
01030  *                  Callback argument is fixed to a pointer to sSdCard instance.
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     /* Fill command */
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     /* Send command */
01055     bRc = _SendCmd(pSd, NULL, NULL);
01056     return bRc;
01057 }
01058 
01059 
01060 /**
01061  * Defines the number of blocks (read/write) and the reliable writer parameter
01062  * (write) for a block read or write command
01063  * data (CSD) on the CMD line.
01064  * Returns the command transfer result (see SendMciCommand).
01065  * \param pSd       Pointer to a SD card driver instance.
01066  * \param write     Write Request parameter.
01067  * \param blocks    number of blocks.
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     /* Fill command */
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     /* Send command */
01086     bRc = _SendCmd(pSd, NULL, NULL);
01087     return bRc;
01088 }
01089 
01090 /**
01091  * Write single block command
01092  * \param pSd  Pointer to a SD card driver instance.
01093  * \param blockSize Block size (shall be set to 512 in case of high capacity).
01094  * \param pData     Pointer to the DW aligned buffer to be filled.
01095  * \param address   Data Address on SD/MMC card.
01096  * \param pStatus   Pointer to response buffer as status.
01097  * \param fCallback Pointer to optional callback invoked on command end.
01098  *                  NULL:    Function return until command finished.
01099  *                  Pointer: Return immediately and invoke callback at end.
01100  *                  Callback argument is fixed to a pointer to sSdCard instance.
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     /* Fill command */
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     /* Send command */
01124     bRc = _SendCmd(pSd, NULL, NULL);
01125     return bRc;
01126 }
01127 
01128 
01129 /**
01130  * Write multiple block command
01131  * \param pSd  Pointer to a SD card driver instance.
01132  * \param blockSize Block size (shall be set to 512 in case of high capacity).
01133  * \param nbBlock   Number of blocks to send.
01134  * \param pData     Pointer to the DW aligned buffer to be filled.
01135  * \param address   Data Address on SD/MMC card.
01136  * \param pStatus   Pointer to the response buffer as status.
01137  * \param fCallback Pointer to optional callback invoked on command end.
01138  *                  NULL:    Function return until command finished.
01139  *                  Pointer: Return immediately and invoke callback at end.
01140  *                  Callback argument is fixed to a pointer to sSdCard instance.
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     /* Fill command */
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     /* Send command */
01165     bRc = _SendCmd(pSd, NULL, NULL);
01166     return bRc;
01167 }
01168 
01169 /**
01170  * SDIO IO_RW_DIRECT command, response R5.
01171  * \return the command transfer result (see SendMciCommand).
01172  * \param pSd       Pointer to a SD card driver instance.
01173  * \param pIoData   Pointer to input argument (\ref SdioRwDirectArg) and
01174  *                  response (\ref SdmmcR5) buffer.
01175  * \param fCallback Pointer to optional callback invoked on command end.
01176  *                  NULL:    Function return until command finished.
01177  *                  Pointer: Return immediately and invoke callback at end.
01178  *                  Callback argument is fixed to a pointer to sSdCard instance.
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     /* Fill command */
01200     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(5);
01201     pCmd->bCmd       = 52;
01202     pCmd->dwArg      = *pIoData;
01203     pCmd->pResp      = pIoData;
01204 
01205     /* Send command */
01206     bRc = _SendCmd(pSd, NULL, NULL);
01207     return bRc;
01208 }
01209 
01210 /**
01211  * SDIO IO_RW_EXTENDED command, response R5.
01212  * \param pSd       Pointer to a SD card driver instance.
01213  * \param pArgResp  Pointer to input argument (\ref SdioRwExtArg)
01214  *                  and response (\ref SdmmcR5) buffer.
01215  * \param pData     Pointer to data buffer to transfer.
01216  * \param size      Transfer data size.
01217  * \param fCallback Pointer to optional callback invoked on command end.
01218  *                  NULL:    Function return until command finished.
01219  *                  Pointer: Return immediately and invoke callback at end.
01220  *                  Callback argument is fixed to a pointer to sSdCard instance.
01221  * \param pArg Callback argument.
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     /* Fill command */
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         /* Force byte mode */
01261         pCmd->wBlockSize = 0;
01262         //pCmd->wBlockSize = 1;
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  * Indicates to the card that the next command is an application specific
01278  * command rather than a standard command.
01279  * \return the command transfer result (see SendMciCommand).
01280  * \param pSd       Pointer to a SD card driver instance.
01281  * \param cardAddr  Card Relative Address.
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     /* Fill command information */
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     /* Send command */
01300     bRc = _SendCmd(pSd, NULL, NULL);
01301     return bRc;
01302 }
01303 
01304 /**
01305  * Sends the status register.
01306  * Should be invoked after Cmd55().
01307  * Returns the command transfer result (see SendMciCommand).
01308  * \param pSd       Pointer to a SD card driver instance.
01309  * \param pStatus   Pointer to a status variable.
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     /* Fill command */
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     /* Send command */
01328     bRc = _SendCmd(pSd, NULL, NULL);
01329     return bRc;
01330 }
01331 
01332 /**
01333  * To get the SSR register of SD card.
01334  * \param pSd     Pointer to a SD card driver instance.
01335  * \param pStatus Pointer to buffer for command response as status.
01336  * \return the command transfer result (see SendMciCommand).
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  * Defines the data bus width (00=1bit or 10=4 bits bus) to be used for data
01356  * transfer.
01357  * The allowed data bus widths are given in SCR register.
01358  * Should be invoked after SdmmcCmd55().
01359  * \param pSd     Pointer to a SD card driver instance.
01360  * \param arg     Argument for this command.
01361  * \param pStatus Pointer to buffer for command response as status.
01362  * \return the command transfer result (see SendMciCommand).
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     /* Fill command information */
01375     pCmd->bCmd       = 6;
01376     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(1);
01377     pCmd->pResp      = pStatus;
01378     pCmd->dwArg      = arg;
01379 
01380     /* Send command */
01381     bRc = _SendCmd(pSd, NULL, NULL);
01382     return bRc;
01383 }
01384 
01385 /**
01386  * Defines the data bus width (00=1bit or 10=4 bits bus) to be used for data
01387  * transfer.
01388  * The allowed data bus widths are given in SCR register.
01389  * \param pSd  Pointer to a SD card driver instance.
01390  * \param busWidth  Bus width in bits (4 or 1).
01391  * \return the command transfer result (see SendCommand).
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  * Asks to all cards to send their operations conditions.
01411  * Returns the command transfer result (see SendMciCommand).
01412  * Should be invoked after SdmmcCmd55().
01413  * \param pSd   Pointer to a SD card driver instance.
01414  * \param pOpIo Pointer to argument that should be sent and OCR content.
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     /* Fill command information */
01425     pCmd->bCmd       = 41;
01426     pCmd->cmdOp.wVal = SDMMC_CMD_CNODATA(3);
01427     pCmd->dwArg      = *pOpIo;
01428     pCmd->pResp      = pOpIo;
01429 
01430     /* Send command */
01431     bRc = _SendCmd(pSd, NULL, NULL);
01432     return bRc;
01433 }
01434 
01435 /**
01436  * Asks to all cards to send their operations conditions.
01437  * Returns the command transfer result (see SendCommand).
01438  * \param pSd  Pointer to a SD card driver instance.
01439  * \param hcs  Shall be true if Host support High capacity.
01440  * \param pCCS  Set the pointed flag to 1 if hcs != 0 and SD OCR CCS flag is set.
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  * Continue to transfer datablocks from card to host until interrupted by a
01474  * STOP_TRANSMISSION command.
01475  * \param pSd  Pointer to a SD card driver instance.
01476  * \param blockSize Block size (shall be set to 512 in case of high capacity).
01477  * \param nbBlock   Number of blocks to send.
01478  * \param pData     Pointer to the application buffer to be filled.
01479  * \param fCallback Pointer to optional callback invoked on command end.
01480  *                  NULL:    Function return until command finished.
01481  *                  Pointer: Return immediately and invoke callback at end.
01482  * \param pArg Callback argument.
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     /* Fill command information */
01498     pCmd->cmdOp.wVal = SDMMC_CMD_DATARX;
01499     pCmd->wBlockSize = blockSize;
01500     pCmd->wNbBlocks  = nbBlock;
01501     pCmd->pData      = pData;
01502 
01503     /* Send command */
01504     bRc = _SendCmd(pSd, fCallback, pArg);
01505     return bRc;
01506 }
01507 
01508 /**
01509  * Continue to transfer datablocks from host to card until interrupted by a
01510  * STOP_TRANSMISSION command.
01511  * \param pSd  Pointer to a SD card driver instance.
01512  * \param blockSize Block size (shall be set to 512 in case of high capacity).
01513  * \param nbBlock   Number of blocks to send.
01514  * \param pData  Pointer to the application buffer to be filled.
01515  * \param fCallback Pointer to optional callback invoked on command end.
01516  *                  NULL:    Function return until command finished.
01517  *                  Pointer: Return immediately and invoke callback at end.
01518  * \param pArg Callback argument.
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     /* Fill command information */
01534     pCmd->cmdOp.wVal = SDMMC_CMD_DATATX;
01535     pCmd->wBlockSize = blockSize;
01536     pCmd->wNbBlocks  = nbBlock;
01537     pCmd->pData      = (uint8_t *)pData;
01538 
01539     /* Send command */
01540     bRc = _SendCmd(pSd, fCallback, pArg);
01541     return bRc;
01542 }
01543 #endif
01544 /**
01545  * Try SW Reset several times (CMD0 with ARG 0)
01546  * \param pSd      Pointer to a SD card driver instance.
01547  * \param retry    Retry times.
01548  * \return 0 or MCI error code.
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  * Stop TX/RX
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     /* Retry stop for 9 times */
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         /* Check status for 299 times */
01586         for (j = 0; j < 299; j ++) {
01587             error = Cmd13(pSd, &status);
01588 
01589             // Wait
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             /* Invalid state */
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             /* Ready? */
01610             if ((status & STATUS_READY_FOR_DATA) == STATUS_READY_FOR_DATA
01611                    &&  state == STATUS_TRAN)
01612                 return SDMMC_SUCCESS;
01613 
01614         }
01615 
01616         /* For write, try stop command again */
01617         if (state != STATUS_RCV)
01618             break;
01619     }
01620 
01621     return SDMMC_ERROR_STATE;
01622 }
01623 
01624 
01625 /**
01626  * Perform sligle block transfer
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             /* Stop transfer */
01649             error = _StopCmd(pSd);
01650 
01651             if (error) return error;
01652 
01653             pSd->bState = SDMMC_STATE_TRAN;
01654             //pSd->dwPrevBlk = 0xFFFFFFFF;
01655         }
01656     }
01657 
01658     if (isRead) {
01659         /* Read single block */
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     /* Write */
01677     {
01678         /* Move to Sending data state */
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  * Move SD card to transfer state. The buffer size must be at
01703  * least 512 byte long. This function checks the SD card status register and
01704  * address the card if required before sending the transfer command.
01705  * Returns 0 if successful; otherwise returns an code describing the error.
01706  * \param pSd      Pointer to a SD card driver instance.
01707  * \param address  Address of the block to transfer.
01708  * \param nbBlocks Number of blocks to be transfer, 0 for infinite transfer.
01709  * \param pData    Data buffer whose size is at least the block size.
01710  * \param isRead   1 for read data and 0 for write data.
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         /* Defines the number of blocks read for a block read command */
01741         if (mmc) error = Cmd23(pSd, 0, nbBlocks, &status);
01742 
01743         /* Move to Receiving data state */
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         /* Defines the number of blocks write for a block write command */
01758         if (mmc) error = Cmd23(pSd, 0, nbBlocks, &status);
01759 
01760         /* Move to Sending data state */
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  * Switch card state between STBY and TRAN (or CMD and TRAN)
01786  * \param pSd       Pointer to a SD card driver instance.
01787  * \param address   Card address to TRAN, 0 to STBY
01788  * \param statCheck Whether to check the status before CMD7.
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     /* At this stage the Initialization and identification process is achieved
01798      * The SD card is supposed to be in Stand-by State */
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     /* witch to TRAN mode to Select the current SD/MMC
01823      * so that SD ACMD6 can process or EXT_CSD can read. */
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  * Get MMC EXT_CSD information
01835  * \param pSd      Pointer to a SD card driver instance.
01836  */
01837 static void MmcGetExtInformation(sSdCard *pSd)
01838 {
01839     uint8_t error;
01840 
01841     /* MMC 4.0 Higher version */
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  * Get SD/MMC memory max transfer speed in K.
01852  * \param pSd Pointer to a SD card driver instance.
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  * Get SDIO max transfer speed, in K.
01872  * \param pSd Pointer to a SD card driver instance.
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         /* Check Func0 tuple in CIS area */
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             /* Fun0 tuple: fn0_blk_siz & max_tran_speed */
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  * Get SD Status information
01913  * \param pSd      Pointer to a SD card driver instance.
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  * Update SD/MMC information.
01937  * Update CSD for card speed switch.
01938  * Update ExtDATA for any card function switch.
01939  * \param pSd      Pointer to a SD card driver instance.
01940  * \return error code when update CSD error.
01941  */
01942 static void SdMmcUpdateInformation(sSdCard *pSd,
01943                                    uint8_t csd,
01944                                    uint8_t extData)
01945 {
01946     uint8_t error;
01947 
01948     /* Update CSD for new TRAN_SPEED value */
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  * \brief Check HS capability and enable it
01978  * \param pSd Pointer to sSdCard instance.
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     /* Check host driver capability */
01990     if (_HwGetHsMode(pSd) == 0)
01991         return SDMMC_ERROR_NOT_SUPPORT;
01992 
01993     /* Check MMC */
01994     if (mmc) {
01995         /* MMC card type 3 (HS) */
01996         //if (SD_CSD_STRUCTURE(pSd) >= 2 && (MMC_EXT_CARD_TYPE(pSd) & 0x2)) {
01997         if (MMC_IsHsModeSupported(pSd)) {
01998             /* Try switch to HS mode */
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     /* SD (+IO) */
02022     else {
02023         if (io) {
02024             /* Check CIA.HS */
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             /* Enable HS mode */
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             /* Check version */
02054             if (SD_IsHsModeSupported(pSd)) {
02055                 /* Try enable HS mode */
02056                 SdCmd6Arg cmd6Arg = {
02057                     1, 0, 0xF, 0xF, 0xF, 0xF, 0, 1
02058                 };
02059                 //uint32_t switchStatus[512/32];
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     /* Enable Host HS mode */
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  * \brief Check bus width capability and enable it
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     /* using single line mode to avoid signal conflicts */
02187     busWidth = 1;
02188 #else
02189     /* Best width that the card support */
02190     busWidth = 4;
02191 #endif
02192     mmc = ((pSd->bCardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC);
02193 
02194     if (mmc) {
02195         /* Check MMC revision 4 or later (1/4/8 bit mode) */
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         /* SD(IO): switch to 4-bit mode ? */
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         /* No 8-bit mode, default to 4-bit mode */
02211         busWidth = 4;
02212 
02213         /* SDIO */
02214         if (io) {
02215             /* SDIO 1 bit only */
02216             busWidth = 1;
02217         }
02218 
02219         /* SD */
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         /* Switch to selected bus mode */
02232         pSd->bBusMode = busWidth;
02233         _HwSetBusWidth(pSd, busWidth);
02234     }
02235 
02236     return 0;
02237 }
02238 
02239 /**
02240  * \brief Run the SD/MMC/SDIO Mode initialization sequence.
02241  * This function runs the initialization procedure and the identification
02242  * process. Then it leaves the card in ready state. The following procedure must
02243  * check the card type and continue to put the card into tran(for memory card)
02244  * or cmd(for io card) state for data exchange.
02245  * \param pSd  Pointer to a SD card driver instance.
02246  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "SD_ERROR code".
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     /* Reset HC to default HS and BusMode */
02254     _HwSetHsMode(pSd, 0);
02255     _HwSetBusWidth(pSd, 1);
02256     /* Reset SDIO: CMD52, write 1 to RES bit in CCCR (bit 3 of register 6) */
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     /* Reset MEM: CMD0 */
02266     error = SwReset(pSd, 1);
02267 
02268     if (error)
02269         TRACE_DEBUG("SdMmcIdentify.SwReset fail: %u\n\r", error);
02270 
02271     /* CMD8 is newly added in the Physical Layer Specification Version 2.00 to
02272      * support multiple voltage ranges and used to check whether the card
02273      * supports supplied voltage. The version 2.00 host shall issue CMD8 and
02274      * verify voltage before card initialization.
02275      * The host that does not support CMD8 shall supply high voltage range... */
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     /* Delay after "no response" */
02284     else Delay(8000);
02285 
02286     /* CMD5 is newly added for SDIO initialize & power on */
02287     status = 0;
02288     error = Cmd5(pSd, &status);
02289 
02290     if (error) {
02291         TRACE_INFO("SdMmcIdentify.Cmd5: %d\n\r", error)
02292     }
02293     /* Card has SDIO function */
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         /* IO only ?*/
02312         mp = ((status & SDIO_OCR_MP) > 0);
02313     }
02314 
02315     /* Has memory: SD/MMC/COMBO */
02316     if (mp) {
02317         /* Try SD memory initialize */
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             /* Try MMC initialize */
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             /* MMC card identification OK */
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     /* SD(IO) + MEM ? */
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     /* SD(HC) combo */
02362     else if (io)
02363         pSd->bCardType = ccs ? CARD_SDHCCOMBO : CARD_SDCOMBO;
02364     /* SD(HC) */
02365     else
02366         pSd->bCardType = ccs ? CARD_SDHC : CARD_SD;
02367 
02368     return 0;
02369 }
02370 
02371 /**
02372  * \brief Run the SD/MMC/SDIO enumeration sequence.
02373  * This function runs after the initialization and identification procedure. It
02374  * gets all necessary information from the card and deside transfer block size,
02375  * clock speed and bus width. It sets the SD/MMC/SDIO card in transfer
02376  * (or command) state.
02377  * \param pSd  Pointer to a SD card driver instance.
02378  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "SD_ERROR code".
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     /* - has Memory/IO/High-Capacigy - */
02388     mem = ((pSd->bCardType & CARD_TYPE_bmSDMMC) > 0);
02389     io  = ((pSd->bCardType & CARD_TYPE_bmSDIO)  > 0);
02390 
02391     /* For MEMORY cards:
02392      * The host then issues the command ALL_SEND_CID (CMD2) to the card to get
02393      * its unique card identification (CID) number.
02394      * Card that is unidentified (i.e. which is in Ready State) sends its CID
02395      * number as the response (on the CMD line). */
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     /* For MEMORY and SDIO cards:
02406      * Thereafter, the host issues CMD3 (SEND_RELATIVE_ADDR) asks the
02407      * card to publish a new relative card address (RCA), which is shorter than
02408      * CID and which is used to address the card in the future data transfer
02409      * mode. Once the RCA is received the card state changes to the Stand-by
02410      * State. At this point, if the host wants to assign another RCA number, it
02411      * can ask the card to publish a new number by sending another CMD3 command
02412      * to the card. The last published RCA is the actual RCA number of the
02413      * card. */
02414     error = Cmd3(pSd);
02415 
02416     if (error) {
02417         TRACE_ERROR("SdMmcInit.cmd3(%d)\n\r", error);
02418         return error;
02419     }
02420 
02421     /* For MEMORY cards:
02422      * SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register),
02423      * e.g. block length, card storage capacity, etc... */
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     /* Now select the card, to TRAN state */
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     /* - Now in TRAN, obtain extended setup information - */
02442 
02443     /* If the card support EXT_CSD, read it! */
02444     TRACE_INFO("Card Type %u, CSD_STRUCTURE %u\n\r",
02445                (unsigned int)pSd->bCardType, (unsigned int)SD_CSD_STRUCTURE(pSd));
02446 
02447     /* Get extended information of the card */
02448     SdMmcUpdateInformation(pSd, 1, 1);
02449 
02450     /* Calculate transfer speed */
02451     if (io)     ioSpeed = SdioGetMaxSpeed(pSd);
02452 
02453     if (mem)    memSpeed = SdmmcGetMaxSpeed(pSd);
02454 
02455 
02456     /* Combo, min speed */
02457     if (io && mem)
02458         pSd->dwTranSpeed = (ioSpeed > memSpeed) ? memSpeed : ioSpeed;
02459     /* SDIO only */
02460     else if (io)
02461         pSd->dwTranSpeed = ioSpeed;
02462     /* Memory card only */
02463     else if (mem)
02464         pSd->dwTranSpeed = memSpeed;
02465 
02466     pSd->dwTranSpeed *= 1000;
02467 
02468     /* Enable more bus width Mode */
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     /* Enable High-Speed Mode */
02478     error = SdMmcEnableHighSpeed(pSd);
02479 
02480     if (!error) hsExec = 1;
02481     else if (error != SDMMC_ERROR_NOT_SUPPORT)
02482         return SDMMC_ERROR;
02483 
02484     /* In HS mode transfer speed *2 */
02485     if (hsExec) pSd->dwTranSpeed *= 2;
02486 
02487     /* Update card information since status changed */
02488     if (bwExec || hsExec) SdMmcUpdateInformation(pSd, hsExec, 0);
02489 
02490     return 0;
02491 }
02492 
02493 
02494 /*----------------------------------------------------------------------------
02495  *         Global functions
02496  *----------------------------------------------------------------------------*/
02497 /** \brief Dump register.
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  * Read Blocks of data in a buffer pointed by pData. The buffer size must be at
02516  * least 512 byte long. This function checks the SD card status register and
02517  * address the card if required before sending the read command.
02518  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
02519  * \param pSd      Pointer to a SD card driver instance.
02520  * \param address  Address of the block to read.
02521  * \param pData    Data buffer whose size is at least the block size, it can
02522  *            be 1,2 or 4-bytes aligned when used with DMA.
02523  * \param length   Number of blocks to be read.
02524  * \param pCallback Pointer to callback function that invoked when read done.
02525  *                  0 to start a blocked read.
02526  * \param pArgs     Pointer to callback function arguments.
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     /*dummy*/
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  * Write Blocks of data in a buffer pointed by pData. The buffer size must be at
02551  * least 512 byte long. This function checks the SD card status register and
02552  * address the card if required before sending the read command.
02553  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
02554  * \param pSd      Pointer to a SD card driver instance.
02555  * \param address  Address of the block to write.
02556  * \param pData    Data buffer whose size is at least the block size, it can
02557  *            be 1,2 or 4-bytes aligned when used with DMA.
02558  * \param length   Number of blocks to be write.
02559  * \param pCallback Pointer to callback function that invoked when write done.
02560  *                  0 to start a blocked write.
02561  * \param pArgs     Pointer to callback function arguments.
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     /*dummy*/
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  * Read Blocks of data in a buffer pointed by pData. The buffer size must be at
02584  * least 512 byte long. This function checks the SD card status register and
02585  * address the card if required before sending the read command.
02586  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
02587  * \param pSd  Pointer to a SD card driver instance.
02588  * \param address  Address of the block to read.
02589  * \param nbBlocks Number of blocks to be read.
02590  * \param pData    Data buffer whose size is at least the block size, it can
02591  *            be 1,2 or 4-bytes aligned when used with DMA.
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  * Write Block of data pointed by pData. The buffer size must be at
02622  * least 512 byte long. This function checks the SD card status register and
02623  * address the card if required before sending the read command.
02624  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
02625  * \param pSd  Pointer to a SD card driver instance.
02626  * \param address  Address of block to write.
02627  * \param nbBlocks Number of blocks to be read
02628  * \param pData    Data buffer whose size is at least the block size, it can
02629  *            be 1,2 or 4-bytes aligned when used with DMA.
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  * Reset SD/MMC driver runtime parameters.
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     /* Clear CID, CSD, EXT_CSD data */
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  * Initialize SD/MMC driver structure.
02692  * \param pSd   Pointer to a SD card driver instance.
02693  * \param pDrv  Pointer to low level driver instance.
02694  * \param bSlot Slot number.
02695  * \param pHalf Pointer to hardware access functions.
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  * Run the SDcard initialization sequence. This function runs the
02711  * initialisation procedure and the identification process, then it sets the
02712  * SD card in transfer state to set the block length and the bus width.
02713  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
02714  * \param pSd  Pointer to a SD card driver instance.
02715  */
02716 uint8_t SD_Init(sSdCard *pSd)
02717 {
02718     uint8_t  error;
02719     uint32_t clock;
02720 
02721     _SdParamReset(pSd);
02722 
02723     /* Set low speed for device identification (LS device max speed) */
02724     clock = 400000;
02725     _HwSetClock(pSd, &clock);
02726 
02727     /* Initialization delay: The maximum of 1 msec, 74 clock cycles and supply
02728      * ramp up time. Supply ramp up time provides the time that the power is
02729      * built up to the operating level (the bus master supply voltage) and the
02730      * time to wait until the SD card can accept the first command. */
02731     /* Power On Init Special Command */
02732     error = Pon(pSd);
02733 
02734     if (error) {
02735         TRACE_ERROR("SD_Init.PowON:%d\n\r", error);
02736         return error;
02737     }
02738 
02739     /* After power-on or CMD0, all cards?
02740      * CMD lines are in input mode, waiting for start bit of the next command.
02741      * The cards are initialized with a default relative card address
02742      * (RCA=0x0000) and with a default driver stage register setting
02743      * (lowest speed, highest driving current capability). */
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     /* In the case of a Standard Capacity SD Memory Card, this command sets the
02759      * block length (in bytes) for all following block commands
02760      * (read, write, lock).
02761      * Default block length is fixed to 512 Bytes.
02762      * Set length is valid for memory access commands only if partial block read
02763      * operation are allowed in CSD.
02764      * In the case of a High Capacity SD Memory Card, block length set by CMD16
02765      * command does not affect the memory read and write commands. Always 512
02766      * Bytes fixed block length is used. This command is effective for
02767      * LOCK_UNLOCK command.
02768      * In both cases, if block length is set larger than 512Bytes, the card sets
02769      * the BLOCK_LEN_ERROR bit. */
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     /* Reset status for R/W */
02782     pSd->bState = SDMMC_STATE_TRAN;
02783 
02784     /* If MMC Card & get size from EXT_CSD */
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         /* Block number less than 0x100000000/512 */
02790         if (pSd->dwNbBlocks > 0x800000)
02791             pSd->dwTotalSize = 0xFFFFFFFF;
02792         else
02793             pSd->dwTotalSize = MMC_EXT_SEC_COUNT(pSd->EXT) * 512;
02794     }
02795     /* If SD CSD v2.0 */
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     /* Normal SD/MMC card */
02803     else if (pSd->bCardType & CARD_TYPE_bmSDMMC) {
02804         pSd->wBlockSize  = 512; //SD_CSD_BLOCK_LEN(pSd->CSD);
02805         pSd->dwTotalSize = SD_CSD_TOTAL_SIZE(pSd->CSD);
02806         pSd->dwNbBlocks  = pSd->dwTotalSize / 512; //SD_CSD_BLOCKNR(pSd->CSD);
02807     }
02808 
02809     if (pSd->bCardType == CARD_UNKNOWN)
02810         return SDMMC_ERROR_NOT_INITIALIZED;
02811 
02812     /* Automatically select the max clock */
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  * De-initialize the driver. Invoked when SD card disconnected.
02822  * \param pSd  Pointer to a SD card driver instance.
02823  */
02824 void SD_DeInit(sSdCard *pSd)
02825 {
02826     if (pSd->pDrv) {
02827         _HwReset(pSd);
02828         _SdParamReset(pSd);
02829     }
02830 }
02831 
02832 /**
02833  * Return type of the card.
02834  * \param pSd Pointer to \ref sSdCard instance.
02835  * \sa sdmmc_cardtype
02836  */
02837 uint8_t SD_GetCardType(sSdCard *pSd)
02838 {
02839     assert(pSd != NULL);
02840 
02841     return pSd->bCardType;
02842 }
02843 
02844 /**
02845  * Return size of the SD/MMC card, in KB.
02846  * \param pSd Pointer to \ref sSdCard instance.
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  * Return reported block size of the SD/MMC card.
02860  * (SD/MMC access block size is always 512B for R/W).
02861  * \param pSd Pointer to \ref sSdCard instance.
02862  */
02863 uint32_t SD_GetBlockSize(sSdCard *pSd)
02864 {
02865     assert(pSd != NULL);
02866 
02867     return pSd->wBlockSize;
02868 }
02869 
02870 /**
02871  * Return reported number of blocks for the SD/MMC card.
02872  * \param pSd Pointer to \ref sSdCard instance.
02873  */
02874 uint32_t SD_GetNumberBlocks(sSdCard *pSd)
02875 {
02876     assert(pSd != NULL);
02877 
02878     return pSd->dwNbBlocks;
02879 }
02880 
02881 /**
02882  * Read one or more bytes from SDIO card, using RW_DIRECT command.
02883  * \param pSd         Pointer to SdCard instance.
02884  * \param functionNum Function number.
02885  * \param address     First register address to read from.
02886  * \param pData       Pointer to data buffer.
02887  * \param size        Buffer size, number of bytes to read.
02888  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
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  * Write one byte to SDIO card, using RW_DIRECT command.
02927  * \param pSd         Pointer to SdCard instance.
02928  * \param functionNum Function number.
02929  * \param address     Register address to write to.
02930  * \param dataByte    Data to write.
02931  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
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  * Read byte by byte from SDIO card, using RW_EXTENDED command.
02963  * \param pSd            Pointer to SdCard instance.
02964  * \param functionNum    Function number.
02965  * \param address        First byte address of data in SDIO card.
02966  * \param isFixedAddress During transfer the data address is never increased.
02967  * \param pData          Pointer to data buffer.
02968  * \param size           Size of data to read (1 ~ 512).
02969  * \param fCallback      Callback function invoked when transfer finished.
02970  * \param pArg           Pointer to callback argument.
02971  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
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  * Write byte by byte to SDIO card, using RW_EXTENDED command.
03011  * \param pSd            Pointer to SdCard instance.
03012  * \param functionNum    Function number.
03013  * \param address        First byte address of data in SDIO card.
03014  * \param isFixedAddress During transfer the data address is never increased.
03015  * \param pData          Pointer to data buffer.
03016  * \param size           Size of data to write (1 ~ 512).
03017  * \param fCallback      Callback function invoked when transfer finished.
03018  * \param pArg           Pointer to callback argument.
03019  * \return 0 if successful; otherwise returns an \ref sdmmc_rc "error code".
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  * Display SDIO card informations (CIS, tuple ...)
03062  * \param pSd Pointer to \ref sSdCard instance.
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     //printf("** trace : %d %x %X\n\r", DYN_TRACES, TRACE_LEVEL, dwTraceLevel);
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     /* CCCR */
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     /* Metaformat */
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  * Display the content of the CID register
03160  * \param pCID Pointer to CID data.
03161  */
03162 void SD_DumpCID(void *pCID)
03163 {
03164     TRACE_INFO("======= CID =======");
03165     //_DumpREG(pCID, 128/8);
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  * Display the content of the CSD register
03222  * \param pSd Pointer to \ref sSdCard instance.
03223  */
03224 void SD_DumpCSD(void *pCSD)
03225 {
03226     TRACE_INFO("======== CSD ========");
03227     //_DumpREG(pCSD, 128/8);
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  * Display the content of the EXT_CSD register
03309  * \param pExtCSD Pointer to extended CSD data.
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  * Display the content of the SCR register
03387  * \param pSCR  Pointer to SCR data.
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  * Display the content of the SD Status
03408  * \param pSdST  Pointer to SD card status data.
03409  */
03410 void SD_DumpSdStatus(void *pSdST)
03411 {
03412     /*The swap operation only can be done once*/
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 /**@}*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines