SAMV71 Xplained Ultra Software Package 1.4

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