00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "board.h"
00042 #include "sdmmc.h"
00043
00044 #include <assert.h>
00045
00046
00047
00048
00049
00050
00051
00052
00053 #define MCI_ENABLE(pMciHw) HSMCI_Enable(pMciHw)
00054
00055 #define MCI_DISABLE(pMciHw) HSMCI_Disable(pMciHw)
00056
00057 #define MCI_RESET(pMciHw) HSMCI_Reset(pMciHw, 0)
00058
00059
00060 #define toHWCOUNT(byteCnt) (((byteCnt)&0x1) ? (((byteCnt)/2)+1) : ((byteCnt)/2))
00061
00062 #define toWCOUNT(byteCnt) (((byteCnt)&0x3) ? (((byteCnt)/4)+1) : ((byteCnt)/4))
00063
00064
00065
00066 #define STATUS_ERRORS ((uint32_t)(HSMCI_SR_UNRE \
00067 | HSMCI_SR_OVRE \
00068 | HSMCI_SR_ACKRCVE \
00069 | HSMCI_SR_CSTOE \
00070 | HSMCI_SR_DTOE \
00071 | HSMCI_SR_DCRCE \
00072 | HSMCI_SR_RTOE \
00073 | HSMCI_SR_RENDE \
00074 | HSMCI_SR_RCRCE \
00075 | HSMCI_SR_RDIRE \
00076 | HSMCI_SR_RINDE))
00077
00078
00079 #define STATUS_ERRORS_RESP ((uint32_t)(HSMCI_SR_CSTOE \
00080 | HSMCI_SR_RTOE \
00081 | HSMCI_SR_RENDE \
00082 | HSMCI_SR_RCRCE \
00083 | HSMCI_SR_RDIRE \
00084 | HSMCI_SR_RINDE))
00085
00086
00087 #define STATUS_ERRORS_DATA ((uint32_t)(HSMCI_SR_UNRE \
00088 | HSMCI_SR_OVRE \
00089 | HSMCI_SR_DTOE \
00090 | HSMCI_SR_DCRCE))
00091
00092
00093 #define MAX_DMA_SIZE (XDMAC_MAX_BT_SIZE & 0xFFFFFF00)
00094
00095
00096 #define _CMDR_SDMEM_SINGLE \
00097 (HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE)
00098
00099 #define _CMDR_SDMEM_MULTI \
00100 (HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_MULTIPLE)
00101
00102 #define _CMDR_SDIO_BYTE \
00103 (HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_BYTE)
00104
00105 #define _CMDR_SDIO_BLOCK \
00106 (HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_BLOCK)
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static sSdHalFunctions sdHal = {
00122 (fSdmmcLock)MCID_Lock,
00123 (fSdmmcRelease)MCID_Release,
00124 (fSdmmcSendCommand)MCID_SendCmd,
00125 (fSdmmcIOCtrl)MCID_IOCtrl
00126 };
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 static uint8_t _PeripheralEnable(uint32_t id)
00140 {
00141 if (PMC_IsPeriphEnabled(id)) return 0;
00142 PMC_EnablePeripheral(id);
00143 return 1;
00144 }
00145
00146
00147
00148
00149 static uint32_t _MciDMAPrepare(sMcid *pMcid, uint8_t bRd)
00150 {
00151 sXdmad *pXdmad = pMcid->pXdmad;
00152
00153 if (bRd) {
00154 pMcid->dwDmaCh = XDMAD_AllocateChannel
00155 (pXdmad, pMcid->bID, XDMAD_TRANSFER_MEMORY);
00156 } else {
00157 pMcid->dwDmaCh = XDMAD_AllocateChannel
00158 (pXdmad, XDMAD_TRANSFER_MEMORY, pMcid->bID);
00159 }
00160 if (pMcid->dwDmaCh == XDMAD_ALLOC_FAILED) {
00161 return SDMMC_ERROR_BUSY;
00162 }
00163 XDMAD_SetCallback(pXdmad, pMcid->dwDmaCh, NULL, NULL);
00164 XDMAD_PrepareChannel( pXdmad, pMcid->dwDmaCh );
00165 return SDMMC_SUCCESS;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 static LinkedListDescriporView1 dmaLinkList[256];
00175
00176 static uint32_t _MciDMA(sMcid *pMcid, uint32_t bFByte, uint8_t bRd)
00177 {
00178 Hsmci *pHw = pMcid->pMciHw;
00179 sXdmad *pXdmad = pMcid->pXdmad;
00180 sSdmmcCommand *pCmd = pMcid->pCmd;
00181 sXdmadCfg xdmadRxCfg,xdmadTxCfg;
00182 uint32_t xdmaCndc, xdmaInt;
00183 uint32_t hsmciId;
00184 uint8_t i;
00185 uint32_t totalSize = pCmd->wNbBlocks * pCmd->wBlockSize;
00186 uint32_t maxXSize;
00187 uint32_t memAddress;
00188 uint8_t bMByte;
00189
00190 if (pMcid->dwXfrNdx >= totalSize) return 0;
00191
00192 if(pCmd->wBlockSize != 1) {
00193 pMcid->dwXSize = totalSize - pMcid->dwXfrNdx;
00194 hsmciId = ID_HSMCI;
00195 if (bRd) {
00196 for ( i = 0; i < pCmd->wNbBlocks; i++) {
00197 dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00198 | (( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
00199 | XDMA_UBC_NDEN_UPDATED
00200 | pCmd->wBlockSize /4 ;
00201 dmaLinkList[i].mbr_sa = (uint32_t)&(pHw->HSMCI_FIFO[i]);
00202 dmaLinkList[i].mbr_da = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize];
00203 if ( i == pCmd->wNbBlocks - 1)
00204 dmaLinkList[i].mbr_nda = 0;
00205 else
00206 dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ];
00207 }
00208 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00209 | XDMAC_CC_MBSIZE_SINGLE
00210 | XDMAC_CC_DSYNC_PER2MEM
00211 | XDMAC_CC_CSIZE_CHK_1
00212 | XDMAC_CC_DWIDTH_WORD
00213 | XDMAC_CC_SIF_AHB_IF1
00214 | XDMAC_CC_DIF_AHB_IF0
00215 | XDMAC_CC_SAM_FIXED_AM
00216 | XDMAC_CC_DAM_INCREMENTED_AM
00217 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00218 (hsmciId, XDMAD_TRANSFER_RX ));
00219 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00220 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00221 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00222 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00223
00224
00225 if (XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh,
00226 &xdmadRxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0],
00227 XDMAC_CIE_LIE)) {
00228 return 0;
00229 }
00230
00231 SCB_CleanInvalidateDCache();
00232
00233 if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) {
00234 return 0;
00235 }
00236
00237 } else {
00238 for ( i = 0; i < pCmd->wNbBlocks; i++){
00239 dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
00240 |(( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
00241 | XDMA_UBC_NDEN_UPDATED
00242 | pCmd->wBlockSize /4 ;
00243 dmaLinkList[i].mbr_sa = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize];
00244 dmaLinkList[i].mbr_da = (uint32_t)&(pHw->HSMCI_FIFO[i]);
00245 if ( i == pCmd->wNbBlocks - 1) dmaLinkList[i].mbr_nda = 0;
00246 else dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ];
00247 }
00248 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00249 | XDMAC_CC_MBSIZE_SINGLE
00250 | XDMAC_CC_DSYNC_MEM2PER
00251 | XDMAC_CC_CSIZE_CHK_1
00252 | XDMAC_CC_DWIDTH_WORD
00253 | XDMAC_CC_SIF_AHB_IF0
00254 | XDMAC_CC_DIF_AHB_IF1
00255 | XDMAC_CC_SAM_INCREMENTED_AM
00256 | XDMAC_CC_DAM_FIXED_AM
00257 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(hsmciId, XDMAD_TRANSFER_TX ));
00258 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
00259 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
00260 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00261 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00262 if(XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh,
00263 &xdmadTxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0],
00264 XDMAC_CIE_LIE)){
00265 return 0;
00266 }
00267
00268 SCB_CleanInvalidateDCache();
00269
00270 if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) {
00271 return 0;
00272 }
00273 }
00274 } else {
00275
00276 memAddress = (uint32_t)&pCmd->pData[pMcid->dwXfrNdx];
00277 bMByte = bFByte ? 1 : (((memAddress & 0x3) || (totalSize & 0x3)));
00278
00279 if (bRd) {
00280 maxXSize = bFByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4);
00281 } else {
00282
00283 maxXSize = bMByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4);
00284 }
00285
00286 pMcid->dwXSize = totalSize - pMcid->dwXfrNdx;
00287 if (pMcid->dwXSize > maxXSize) {
00288 pMcid->dwXSize = maxXSize;
00289 }
00290
00291 if (bRd) {
00292 xdmadRxCfg.mbr_ubc = bFByte ? pMcid->dwXSize : toWCOUNT(pMcid->dwXSize);
00293 xdmadRxCfg.mbr_sa = (uint32_t)&(pHw->HSMCI_RDR);
00294 xdmadRxCfg.mbr_da = (uint32_t)memAddress;
00295 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00296 XDMAC_CC_MEMSET_NORMAL_MODE |
00297 XDMAC_CC_DSYNC_PER2MEM|
00298 XDMAC_CC_CSIZE_CHK_1 |
00299 (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) |
00300 XDMAC_CC_SIF_AHB_IF1 |
00301 XDMAC_CC_DIF_AHB_IF0 |
00302 XDMAC_CC_SAM_FIXED_AM |
00303 XDMAC_CC_DAM_INCREMENTED_AM;
00304 xdmadRxCfg.mbr_bc = 0;
00305 xdmaInt = (XDMAC_CIE_BIE |
00306 XDMAC_CIE_DIE |
00307 XDMAC_CIE_FIE |
00308 XDMAC_CIE_RBIE |
00309 XDMAC_CIE_WBIE |
00310 XDMAC_CIE_ROIE);
00311
00312 XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadRxCfg,
00313 0, 0, xdmaInt);
00314 } else {
00315 xdmadTxCfg.mbr_ubc = toWCOUNT(pMcid->dwXSize);
00316 xdmadTxCfg.mbr_sa = (uint32_t)memAddress;
00317 xdmadTxCfg.mbr_da = (uint32_t)&(pHw->HSMCI_TDR);
00318 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00319 XDMAC_CC_MEMSET_NORMAL_MODE |
00320 XDMAC_CC_DSYNC_MEM2PER |
00321 XDMAC_CC_CSIZE_CHK_1 |
00322 (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) |
00323 XDMAC_CC_SIF_AHB_IF0 |
00324 XDMAC_CC_DIF_AHB_IF1 |
00325 XDMAC_CC_SAM_INCREMENTED_AM |
00326 XDMAC_CC_DAM_FIXED_AM;
00327 xdmadTxCfg.mbr_bc = 0;
00328
00329 xdmaInt = (XDMAC_CIE_BIE |
00330 XDMAC_CIE_DIE |
00331 XDMAC_CIE_FIE |
00332 XDMAC_CIE_RBIE |
00333 XDMAC_CIE_WBIE |
00334 XDMAC_CIE_ROIE);
00335
00336 XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadTxCfg,
00337 0, 0, xdmaInt);
00338 }
00339 SCB_CleanInvalidateDCache();
00340 XDMAD_StartTransfer(pXdmad, pMcid->dwDmaCh);
00341 }
00342 return 1;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 static void MCI_Reset(sMcid *pMci, uint8_t keepSettings)
00355 {
00356 Hsmci *pMciHw = pMci->pMciHw;
00357
00358 assert(pMci);
00359 assert(pMci->pMciHw);
00360
00361 HSMCI_Reset( pMciHw, keepSettings );
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 static uint32_t MCI_SetSpeed( sMcid* pMci, uint32_t mciSpeed, uint32_t mck )
00373 {
00374 Hsmci *pMciHw = pMci->pMciHw;
00375 uint32_t clkdiv;
00376 assert(pMci);
00377 assert(pMciHw);
00378
00379 if((mck % mciSpeed) == 0) {
00380 clkdiv = mck /mciSpeed;
00381 } else {
00382 clkdiv = ((mck + mciSpeed)/mciSpeed);
00383 }
00384 mciSpeed = mck / clkdiv;
00385
00386
00387 HSMCI_DivCtrl( pMciHw, clkdiv, 0x7);
00388 return (mciSpeed);
00389 }
00390
00391
00392
00393 static void _FinishCmd( sMcid* pMcid, uint8_t bStatus )
00394 {
00395 sSdmmcCommand *pCmd = pMcid->pCmd;
00396 sXdmad *pXdmad = pMcid->pXdmad;
00397
00398
00399 if (pMcid->dwDmaCh != XDMAD_ALLOC_FAILED) {
00400 if (XDMAD_FreeChannel(pXdmad, pMcid->dwDmaCh)) {
00401 TRACE_ERROR(" Can't free channel \n\r" );
00402 TRACE_DEBUG(" Channel is in %d state\n\r",
00403 pXdmad->XdmaChannels[pMcid->dwDmaCh].state );
00404 }
00405 pMcid->dwDmaCh = XDMAD_ALLOC_FAILED;
00406 }
00407
00408 pMcid->pCmd = NULL;
00409 pMcid->bState = MCID_LOCKED;
00410 pCmd->bStatus = bStatus;
00411
00412 if (pCmd->fCallback) {
00413 (pCmd->fCallback)(pCmd->bStatus, pCmd->pArg);
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424 void MCID_SetSlot(Hsmci *pMci, uint8_t slot)
00425
00426 {
00427 HSMCI_SetSlot(pMci, slot);
00428 }
00429
00430
00431
00432
00433 void MCID_Init(sMcid *pMcid,
00434 Hsmci *pMci, uint8_t bID, uint32_t dwMck,
00435 sXdmad *pXdmad,
00436 uint8_t bPolling)
00437 {
00438 uint16_t clkDiv;
00439
00440 assert(pMcid);
00441 assert(pMci);
00442
00443
00444 pMcid->pMciHw = pMci;
00445 pMcid->pCmd = NULL;
00446
00447 pMcid->pXdmad = pXdmad;
00448 pMcid->dwDmaCh = XDMAD_ALLOC_FAILED;
00449 pMcid->dwXfrNdx = 0;
00450
00451 pMcid->dwMck = dwMck;
00452
00453 pMcid->bID = bID;
00454 pMcid->bPolling = bPolling;
00455 pMcid->bState = MCID_IDLE;
00456
00457 _PeripheralEnable( bID );
00458
00459 MCI_RESET( pMci );
00460 MCI_DISABLE ( pMci );
00461 HSMCI_DisableIt( pMci, 0xFFFFFFFF );
00462 HSMCI_ConfigureDataTO( pMci, HSMCI_DTOR_DTOCYC(0xFF)
00463 |HSMCI_DTOR_DTOMUL_1048576 );
00464 HSMCI_ConfigureCompletionTO( pMci , HSMCI_CSTOR_CSTOCYC(0xFF)
00465 |HSMCI_CSTOR_CSTOMUL_1048576 );
00466
00467 clkDiv = (dwMck / (MCI_INITIAL_SPEED << 1)) - 1;
00468 HSMCI_ConfigureMode( pMci, (clkDiv | HSMCI_MR_PWSDIV(0x7)) );
00469
00470 HSMCI_Enable( pMci );
00471 HSMCI_Configure( pMci, HSMCI_CFG_FIFOMODE | HSMCI_CFG_FERRCTRL );
00472
00473 HSMCI_EnableDma( pMci, 1 );
00474
00475 }
00476
00477
00478
00479
00480 uint32_t MCID_Lock(sMcid *pMcid, uint8_t bSlot)
00481 {
00482 Hsmci *pHw = pMcid->pMciHw;
00483 uint32_t sdcr;
00484
00485 assert(pMcid);
00486 assert(pMcid->pMciHw);
00487
00488 if (bSlot > 0) {
00489 return SDMMC_ERROR_PARAM;
00490 }
00491 if (pMcid->bState >= MCID_LOCKED) {
00492 return SDMMC_ERROR_LOCKED;
00493 }
00494 pMcid->bState = MCID_LOCKED;
00495 sdcr = pHw->HSMCI_SDCR & ~(uint32_t)HSMCI_SDCR_SDCSEL_Msk;
00496 pHw->HSMCI_SDCR = sdcr | (bSlot << HSMCI_SDCR_SDCSEL_Pos);
00497 return SDMMC_OK;
00498 }
00499
00500
00501
00502
00503 uint32_t MCID_Release(sMcid *pMcid)
00504 {
00505 assert(pMcid);
00506
00507 if (pMcid->bState >= MCID_CMD) {
00508 return SDMMC_ERROR_BUSY;
00509 }
00510 pMcid->bState = MCID_IDLE;
00511 return SDMMC_OK;
00512 }
00513
00514
00515
00516
00517 uint32_t MCID_SendCmd(sMcid *pMcid, void *pCommand)
00518 {
00519 Hsmci *pHw = pMcid->pMciHw;
00520 sSdmmcCommand *pCmd = pCommand;
00521 uint32_t mr, ier;
00522 uint32_t cmdr;
00523
00524 assert(pMcid);
00525 assert(pMcid->pMciHw);
00526 assert(pCmd);
00527
00528 if (!MCID_IsCmdCompleted(pMcid))
00529 {
00530 return SDMMC_ERROR_BUSY;
00531 }
00532 pMcid->bState = MCID_CMD;
00533 pMcid->pCmd = pCmd;
00534
00535
00536 MCI_DISABLE(pHw);
00537 mr = HSMCI_GetMode(pHw) & (~(uint32_t)(HSMCI_MR_WRPROOF |
00538 HSMCI_MR_RDPROOF |HSMCI_MR_FBYTE));
00539
00540 if (pCmd->cmdOp.wVal == SDMMC_CMD_POWERONINIT){
00541 HSMCI_ConfigureMode(pHw, mr);
00542 ier = HSMCI_IER_XFRDONE;
00543 } else if (pCmd->cmdOp.bmBits.xfrData == SDMMC_CMD_STOPXFR) {
00544
00545 HSMCI_ConfigureMode(pHw, mr);
00546 ier = HSMCI_IER_XFRDONE | STATUS_ERRORS_RESP;
00547 }
00548
00549 else if ((pCmd->cmdOp.wVal & SDMMC_CMD_CNODATA(0xF)) == SDMMC_CMD_CNODATA(0)) {
00550 ier = HSMCI_IER_XFRDONE | STATUS_ERRORS_RESP;
00551
00552 if (pCmd->cmdOp.bmBits.respType == 3) {
00553 ier &= ~(uint32_t)HSMCI_IER_RCRCE;
00554 }
00555 } else if (pCmd->wNbBlocks == 0 || pCmd->pData == 0) {
00556
00557 HSMCI_ConfigureMode(pHw, mr | HSMCI_MR_WRPROOF
00558 | HSMCI_MR_RDPROOF);
00559 HSMCI_ConfigureTransfer(pHw, pCmd->wBlockSize, pCmd->wNbBlocks);
00560 ier = HSMCI_IER_CMDRDY | STATUS_ERRORS_RESP;
00561 } else {
00562
00563
00564 if (pCmd->cmdOp.bmBits.sendCmd) {
00565 HSMCI_ConfigureTransfer(pHw, pCmd->wBlockSize, pCmd->wNbBlocks);
00566 }
00567
00568 if (pCmd->wBlockSize == 0)
00569 pCmd->wBlockSize = 1;
00570
00571
00572 if (pCmd->wBlockSize & 0x3) {
00573 mr |= HSMCI_MR_FBYTE;
00574 }
00575
00576 HSMCI_ConfigureMode(pHw, mr | HSMCI_MR_WRPROOF
00577 | HSMCI_MR_RDPROOF
00578 | (pCmd->wBlockSize << 16));
00579 SCB_CleanInvalidateDCache();
00580
00581 if (pCmd->cmdOp.bmBits.xfrData == SDMMC_CMD_TX) {
00582 if (_MciDMAPrepare(pMcid, 0)) {
00583 _FinishCmd(pMcid, SDMMC_ERROR_BUSY);
00584 return SDMMC_ERROR_BUSY;
00585 }
00586 _MciDMA(pMcid, (mr & HSMCI_MR_FBYTE),0);
00587 ier = HSMCI_IER_XFRDONE | STATUS_ERRORS_DATA;
00588 if( pCmd->wNbBlocks > 1 ) ier |= HSMCI_IER_FIFOEMPTY;
00589 } else {
00590 if (_MciDMAPrepare(pMcid, 1)) {
00591 _FinishCmd(pMcid, SDMMC_ERROR_BUSY);
00592 return SDMMC_ERROR_BUSY;
00593 }
00594 _MciDMA(pMcid, (mr & HSMCI_MR_FBYTE),1);
00595 ier = HSMCI_IER_XFRDONE | STATUS_ERRORS_DATA;
00596 if( pCmd->wNbBlocks > 1 ) ier |= HSMCI_IER_FIFOEMPTY;
00597 }
00598 }
00599 MCI_ENABLE(pHw);
00600 if (pCmd->cmdOp.wVal & (SDMMC_CMD_bmPOWERON | SDMMC_CMD_bmCOMMAND)) {
00601 cmdr = pCmd->bCmd;
00602
00603 if (pCmd->cmdOp.bmBits.powerON) {
00604 cmdr |= (HSMCI_CMDR_OPDCMD | HSMCI_CMDR_SPCMD_INIT);
00605 }
00606 if (pCmd->cmdOp.bmBits.odON) {
00607 cmdr |= HSMCI_CMDR_OPDCMD;
00608 }
00609 if (pCmd->cmdOp.bmBits.sendCmd) {
00610 cmdr |= HSMCI_CMDR_MAXLAT;
00611 }
00612 switch(pCmd->cmdOp.bmBits.xfrData) {
00613 case SDMMC_CMD_TX:
00614 if (pCmd->cmdOp.bmBits.ioCmd) {
00615 cmdr |= (pCmd->wBlockSize == 1) ?
00616 _CMDR_SDIO_BYTE :
00617 _CMDR_SDIO_BLOCK;
00618 } else {
00619 cmdr |= (pCmd->wNbBlocks == 1) ?
00620 _CMDR_SDMEM_SINGLE :
00621 _CMDR_SDMEM_MULTI;
00622 }
00623 break;
00624
00625 case SDMMC_CMD_RX:
00626 if (pCmd->cmdOp.bmBits.ioCmd) {
00627 cmdr |= HSMCI_CMDR_TRDIR_READ
00628 |((pCmd->wBlockSize == 1) ?
00629 _CMDR_SDIO_BYTE :
00630 _CMDR_SDIO_BLOCK) ;
00631 } else {
00632 cmdr |= HSMCI_CMDR_TRDIR_READ
00633 |((pCmd->wNbBlocks == 1) ?
00634 _CMDR_SDMEM_SINGLE :
00635 _CMDR_SDMEM_MULTI) ;
00636 }
00637 break;
00638
00639 case SDMMC_CMD_STOPXFR:
00640 cmdr |= HSMCI_CMDR_TRCMD_STOP_DATA;
00641 break;
00642 }
00643
00644 switch(pCmd->cmdOp.bmBits.respType) {
00645 case 3: case 4:
00646
00647 ier &= ~(uint32_t)HSMCI_IER_RCRCE;
00648 case 1: case 5: case 6: case 7:
00649 cmdr |= HSMCI_CMDR_RSPTYP_48_BIT;
00650 break;
00651 case 2:
00652 cmdr |= HSMCI_CMDR_RSPTYP_136_BIT;
00653 break;
00654
00655 default:
00656 ier &= ~(uint32_t)HSMCI_IER_RTOE;
00657 }
00658
00659 pHw->HSMCI_ARGR = pCmd->dwArg;
00660 pHw->HSMCI_CMDR = cmdr;
00661 }
00662
00663
00664 if (pCmd->cmdOp.bmBits.xfrData == SDMMC_CMD_STOPXFR) {
00665 ier &= ~STATUS_ERRORS_DATA;
00666 }
00667
00668 HSMCI_EnableIt(pHw, ier);
00669 return SDMMC_OK;
00670 }
00671
00672 static uint32_t dwMsk;
00673
00674
00675
00676 void MCID_Handler(sMcid *pMcid)
00677 {
00678 Hsmci *pHw = pMcid->pMciHw;
00679 sSdmmcCommand *pCmd = pMcid->pCmd;
00680
00681 uint32_t dwSr, dwMaskedSr;
00682 assert(pMcid);
00683 assert(pMcid->pMciHw);
00684
00685
00686 if (pCmd == NULL) {
00687 if (pMcid->bState >= MCID_CMD) {
00688 pMcid->bState = MCID_LOCKED;
00689 }
00690 return;
00691 }
00692
00693
00694 dwSr = HSMCI_GetStatus(pHw);
00695 dwMsk = HSMCI_GetItMask(pHw);
00696 dwMaskedSr = dwSr & dwMsk;
00697
00698 if (dwMaskedSr & STATUS_ERRORS) {
00699 if (dwMaskedSr & HSMCI_SR_RTOE) {
00700 pCmd->bStatus = SDMMC_ERROR_NORESPONSE;
00701 }
00702 if (pCmd->bCmd != 12) pMcid->bState = MCID_ERROR;
00703
00704 }
00705 dwMsk &= ~STATUS_ERRORS;
00706
00707
00708 if (dwMaskedSr & HSMCI_SR_CMDRDY) {
00709 TRACE_DEBUG("HSMCI_SR_CMDRDY \n\r");
00710 HSMCI_DisableIt(pHw, HSMCI_IDR_CMDRDY);
00711 dwMsk &= ~(uint32_t)HSMCI_IMR_CMDRDY;
00712 }
00713
00714
00715 if (dwMaskedSr & HSMCI_SR_NOTBUSY) {
00716 TRACE_DEBUG("NOTBUSY ");
00717 HSMCI_DisableIt(pHw, HSMCI_IDR_NOTBUSY);
00718 dwMsk &= ~(uint32_t)HSMCI_IMR_NOTBUSY;
00719 }
00720
00721 if (dwMaskedSr & HSMCI_SR_TXRDY) {
00722 TRACE_DEBUG("TXRDY ");
00723 dwMsk &= ~(uint32_t)HSMCI_IMR_TXRDY;
00724 }
00725
00726 if (dwMaskedSr & HSMCI_SR_FIFOEMPTY) {
00727
00728 HSMCI_DisableIt(pHw, HSMCI_IDR_FIFOEMPTY);
00729 dwMsk &= ~(uint32_t)HSMCI_IMR_FIFOEMPTY;
00730 TRACE_DEBUG("FIFOEMPTY %x \n\r",dwMsk);
00731 }
00732
00733
00734 if (dwMaskedSr & HSMCI_SR_XFRDONE) {
00735 HSMCI_DisableIt(pHw, HSMCI_IDR_XFRDONE);
00736 dwMsk &= ~(uint32_t)HSMCI_IMR_XFRDONE;
00737 TRACE_DEBUG("HSMCI_SR_XFRDONE %x \n\r",dwMsk);
00738 }
00739
00740
00741 if (0 == dwMsk || pMcid->bState == MCID_ERROR) {
00742
00743 if (pMcid->bState == MCID_ERROR) {
00744 MCI_Reset(pMcid, 1);
00745 } else {
00746 pCmd->bStatus = SDMMC_SUCCESS;
00747
00748 if (pCmd->pResp) {
00749 uint8_t bRspSize, i;
00750 switch(pCmd->cmdOp.bmBits.respType) {
00751 case 1: case 3: case 4: case 5: case 6: case 7:
00752 bRspSize = 1;
00753 break;
00754
00755 case 2:
00756 bRspSize = 4;
00757 break;
00758
00759 default:
00760 bRspSize = 0;
00761 }
00762 for (i = 0; i < bRspSize; i ++) {
00763 pCmd->pResp[i] = HSMCI_GetResponse(pHw);
00764 }
00765 }
00766 }
00767
00768 HSMCI_DisableIt(pHw, HSMCI_GetItMask(pHw));
00769
00770
00771
00772 _FinishCmd(pMcid, pCmd->bStatus);
00773 }
00774 }
00775
00776
00777
00778
00779 uint32_t MCID_CancelCmd(sMcid *pMcid)
00780 {
00781 if (pMcid->bState == MCID_IDLE) {
00782 return SDMMC_ERROR_STATE;
00783 }
00784 if (pMcid->bState == MCID_CMD) {
00785
00786 MCI_Reset(pMcid, 1);
00787
00788 _FinishCmd(pMcid, SDMMC_ERROR_USER_CANCEL);
00789 }
00790 return SDMMC_OK;
00791 }
00792
00793
00794
00795
00796 void MCID_Reset(sMcid * pMcid)
00797 {
00798 Hsmci *pHw = pMcid->pMciHw;
00799
00800 MCID_CancelCmd(pMcid);
00801
00802
00803
00804
00805 MCI_DISABLE(pHw);
00806
00807 HSMCI_ConfigureMode(pHw, HSMCI_GetMode(pHw) & (HSMCI_MR_CLKDIV_Msk
00808 | HSMCI_MR_PWSDIV_Msk));
00809
00810 HSMCI_ConfigureTransfer(pHw, 0, 0);
00811
00812
00813 MCI_Reset(pMcid, 1);
00814
00815
00816 if (pMcid->bState == MCID_CMD) {
00817
00818 _FinishCmd(pMcid, SDMMC_ERROR_USER_CANCEL);
00819 }
00820 }
00821
00822
00823
00824
00825 uint32_t MCID_IsCmdCompleted(sMcid *pMcid)
00826 {
00827 sSdmmcCommand *pCmd = pMcid->pCmd;
00828
00829 if (pMcid->bPolling) {
00830 MCID_Handler(pMcid);
00831 }
00832 if (pMcid->bState == MCID_CMD) {
00833 return 0;
00834 }
00835 if (pCmd) {
00836 return 0;
00837 }
00838 return 1;
00839 }
00840
00841
00842
00843
00844 uint32_t MCID_IOCtrl(sMcid *pMcid, uint32_t bCtl, uint32_t param)
00845 {
00846 Hsmci *pMciHw = pMcid->pMciHw;
00847 assert(pMcid);
00848 assert(pMcid->pMciHw);
00849
00850
00851
00852 switch (bCtl) {
00853 case SDMMC_IOCTL_BUSY_CHECK:
00854 *(uint32_t*)param = !MCID_IsCmdCompleted(pMcid);
00855 break;
00856
00857 case SDMMC_IOCTL_POWER:
00858 return SDMMC_ERROR_NOT_SUPPORT;
00859
00860 case SDMMC_IOCTL_RESET:
00861 MCID_Reset(pMcid);
00862 return SDMMC_SUCCESS;
00863
00864 case SDMMC_IOCTL_CANCEL_CMD:
00865 return MCID_CancelCmd(pMcid);
00866
00867 case SDMMC_IOCTL_SET_CLOCK:
00868 *(uint32_t*)param = MCI_SetSpeed(pMcid,
00869 *(uint32_t*)param,
00870 pMcid->dwMck);
00871 break;
00872
00873 case SDMMC_IOCTL_SET_HSMODE:
00874 HSMCI_HsEnable( pMciHw, *(uint32_t*)param );
00875 *(uint32_t*)param = HSMCI_IsHsEnabled( pMciHw );
00876
00877 break;
00878
00879 case SDMMC_IOCTL_SET_BUSMODE:
00880 HSMCI_SetBusWidth( pMciHw, *(uint32_t*)param );
00881 break;
00882
00883 case SDMMC_IOCTL_GET_BUSMODE:
00884
00885 break;
00886
00887 case SDMMC_IOCTL_GET_HSMODE:
00888 *(uint32_t*)param = 1;
00889 break;
00890
00891 default:
00892 return SDMMC_ERROR_NOT_SUPPORT;
00893 }
00894 return SDMMC_OK;
00895 }
00896
00897
00898
00899
00900
00901 void SDD_InitializeSdmmcMode(sSdCard * pSd,void * pDrv,uint8_t bSlot)
00902 {
00903 SDD_Initialize(pSd, pDrv, bSlot, &sdHal);
00904 }
00905
00906