SAMV71 Xplained Ultra Software Package 1.3

sdmmc.c

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