📄 sdmmc.c
字号:
Whatever that error is, just ignore it.
You can tell very much the card is an SD card because of this
error.
*/
else if (resErr == MMC_CARD_IS_NOT_RESPONDING)
{
#if (USE_SD)
/* Let's wait for awhile before testing for SD card. */
OS_WAIT(55);
SD_Card_In_Use = 1;
/* Try ACMD41 to poll for SD card. */
setupInfo = 0x00FF8000L;
resErr = mmcSDApplCmd(pc, SDNULL, setupInfo, 0, 0, R3, SD_SEND_OP_COND);
// RETAILMSG(, (TEXT("MMCmode, after mmcSDApplCmd\r\n")));
if (resErr != MMC_CARD_IS_NOT_RESPONDING)
{
/* The card is an SD card because it returns an error. */
sdFlag = YES;
SD_Card_In_Use = 1;
// RETAILMSG(, (TEXT("MMCmode, yes, it is SD card\r\n")));
}
#endif
/* If no card presents, the error should be MMC_CARD_IS_NOT_RESPONDING. */
if (resErr == MMC_CARD_IS_NOT_RESPONDING)
{
/* No card present, just return */
resErr = MMC_INTERFACE_ERROR;
goto END_OF_CARDS_SEARCH;
}
}
else
{
/* For other errors, just return. */
resErr = MMC_INTERFACE_ERROR;
goto END_OF_CARDS_SEARCH;
}
}
#if (USE_SD)
/* Check for SD card. */
if (sdFlag)
{
setupInfo = 0x00FF8000L;
/* Command CMD55 expects an RCA. At this point, the RCA
has not assigned to the card. Since SD card follows
the MMCA protocol, the RCA assignment is occured later.
*/
/* Make sure the card is ready */
resErr = mmcSDApplCmd(pc, SDNULL, setupInfo, 0, 0, R3, SD_SEND_OP_COND);
if (resErr == MMC_NO_ERROR)
{
/* The card responds kindly, we got an SD card. */
// RETAILMSG(1, (TEXT("we got SD card\r\n")));
cardType = SD_TYPE;
sdFlag = YES; /* It is an SD card */
/* Is the card ready? */
readyFlag = to_WORD((UCHAR *)&pc->LastResponse[0]);
// RETAILMSG(1, (TEXT("is the card ready? %x\r\n"), readyFlag));
}
}
#endif /* (USE_SD) */
/* Time out error on card response. There may be no card presented. */
if (resErr == MMC_CARD_IS_NOT_RESPONDING)
{
resErr = MMC_INTERFACE_ERROR;
goto END_OF_CARDS_SEARCH;
}
if ( resErr == MMC_NO_ERROR ) /* If no error */
{
/* Make sure all cards are ready */
if ( (readyFlag & CARD_READY_FLAG) )
{
// RETAILMSG(1, (TEXT("card is ready!\r\n")));
break;
}
pc->timer--;
OS_WAIT(1); /* Delay it for awhile */
if ( !pc->timer )
{
resErr = MMC_CARD_IS_NOT_READY;
goto END_OF_CARDS_SEARCH;
}
}
}
/* Assign IDs to all devices found */
i = NO;
for (;;)
{
// RETAILMSG(1, (TEXT("tr to asssign RCA with ID %d\r\n"), i));
pc->drive_active = i;
/* Get device information and assign an RCA to it. */
if ( mmcIdentify (pc, cardType, i) != MMC_NO_ERROR )
{
// RETAILMSG(1, (TEXT("asssign RCA is not sucessful! with ID %d\r\n"), i));
/* There isn't any more device found */
break;
}
// RETAILMSG(1, (TEXT("after successfully assign RCA, continue\r\n")));
/* Check for SD card */
if (cardType == SD_TYPE)
{
// RETAILMSG(1, (TEXT("mmcReset -- It entered SD Card area\r\n")));
/* The RCA is returned in pc->LastResponse[4] */
(pc->drive)->RCA = pc->LastResponse[4];
}
else
{
/* For MMC card in MMC mode, the RCA is the (drive number + 1) */
(pc->drive)->RCA = (UINT16)i + 1;
// RETAILMSG(1, (TEXT("MMCReset - pc->drive->RCA is %d\r\n"),1));
}
/* Save the card type */
(pc->drive)->drv_type = cardType;
i++; /* Next device */
// if (i >= (UINT16)drvs_per_controller[pc->controller_number])
// RETAILMSG(1, (TEXT("now, the number of i is %d\r\n"),i));
if(i>=1) //Yi added
break;
// MMCSelectController(pc->controller_number, i);
}
pc->drive_active = NO;
/* Make sure there is at least one card on the bus */
if ( i == NO )
{
/* No card found */
// RETAILMSG(1, (TEXT("No card is found\r\n")));
resErr = MMC_INTERFACE_ERROR;
}
devCount += i;
END_OF_CARDS_SEARCH:
#if (USE_SD)
if (sdFlag != YES)
{
if (bInterface < 1 )
{
bInterface++;
sdFlag = YES;
goto DO_ALL_BUS_INTERFACE;
}
}
#endif
// RETAILMSG(1, (TEXT("devCount is following %d\r\n"), devCount));
if ( devCount )
resErr = MMC_NO_ERROR;
#endif /* (USE_SPI || USE_SPI_EMULATION) */
pc->error_code = (UINT16)resErr;
// RETAILMSG(1, (TEXT("mmcReset ResErr is as follows %d\r\n"), resErr));
return resErr;
}
#if (USE_MMC || USE_MMC_EMULATION)
/***********************************************************************************
* Name: mmcIdentify
*
* Description:
* Available in MMC mode only. Identifiies and assigns an RCA
* for a selected MMC card on the bus.
*
* This function starts card identification cycle and (if a
* valid response is received) assigns the RCA of the identified
* card.
*
* Input:
* pc Device controller structure
* cardID Card number for the identified card.
* cardType Type of the card (MMC, SD, etc.)
*
* Output:
* The card is assigned with an RCA.
*
* Returns:
* Completion code
*
************************************************************************************/
MMC_CC mmcIdentify (PDEVICE_CONTROLLER pc, UINT32 cardType, UINT16 cardID)
{
MMC_CC resErr;
// RETAILMSG(1, (TEXT("mmcIdentify() is entered\r\n")));
/* Request any card to send the CID information */
resErr = mmcCommandAndResponse ( pc,
0L,
ALL_SEND_CID,
0,
R2 );
if ( resErr != MMC_NO_ERROR )
{
// RETAILMSG(1, (TEXT("ALL_SEND_CID command fails!\r\n")));
pc->error_code = (UINT16)resErr;
return resErr;
}
/* Check for SD card */
if (cardType == SD_TYPE)
{
/* For SD card, the relative address is sent back
in the response pc->LastResponse. If the command
is executed correctly, the RCA is at offset 4
from the starting address of the response.
*/
resErr = mmcCommandAndResponse ( pc,
0L,
SET_RELATIVE_ADDR,
0,
R6);
// RETAILMSG(1, (TEXT("SD, after sending SET_RELATIVE_ADDR command!\r\n")));
/* The RCA is returned in pc->LastResponse[4] */
}
else
{
// RETAILMSG(1, (TEXT("Before sending SET_RELATIVE_ADDR command!\r\n")));
/* Assgin an ID to the device. The assigned RCA can be choose
as any 16-bit integer number. To make this assignment as
simplest as possible, the RCA assignment is calculating
by adding an 1 to the given cardID. The formula is shown
below:
assigned RCA = cardId + 1
*/
resErr = mmcCommandAndResponse ( pc,
((((ULONG)cardID) + 1L) << 16),
SET_RELATIVE_ADDR,
0,
R1 );
}
pc->error_code = (UINT16)resErr;
// RETAILMSG(1, (TEXT("resErr is as follows %d\r\n"), resErr));
return resErr;
}
/*******************************************************************************
* Name: mmcSetStandbyState - Set the card in stand by state
*
* Description:
* In MMC mode, the deselect card command is sent to the card
* to put it in stand by state.
*
* Input:
* pc Device controller structure
* RCA The address of the card to be selected.
*
* Output:
* The card state is set to stand by state.
*
* Returns:
* Completion code.
*
********************************************************************************/
MMC_CC mmcSetStandbyState ( PDEVICE_CONTROLLER pc, UINT16 RCA)
{
MMC_CC resErr;
INT16 loopCnt;
UINT16 mmcRCA;
REASSURE_STANDBY_STATE:
mmcRCA = RCA;
// RETAILMSG(1, (TEXT("mmcSetStandbyState() is entered\r\n")));
for (loopCnt = 0; loopCnt < 100; loopCnt++)
{
/* Get the status from the card */
resErr = mmcCommandAndResponse ( pc,
(((ULONG)RCA) << 16),
SEND_STATUS,
0,
R1 );
if (resErr != MMC_NO_ERROR )
goto DONE_SET_TO_STANDBY_STATE;
if (pc->currentState == STANDBY)
goto DONE_SET_TO_STANDBY_STATE;
if (pc->currentState == TRANSFER)
{
/*
Toggles from Xfer to Standby state
when card is not addressed.
*/
mmcRCA = 0;
// RETAILMSG(1, (TEXT("mmcSetStandbyState() TRANSFER\r\n")));
break;
}
}
if (loopCnt == 100)
{
// RETAILMSG(1, (TEXT("mmcSetStandbyState() MMC_CARD_IS_BUSY\r\n")));
resErr = MMC_CARD_IS_BUSY;
goto DONE_SET_TO_STANDBY_STATE;
}
/* Check for the card current state */
/* The card needs to be in STANDBY state */
resErr = mmcCommandAndResponse ( pc,
(((ULONG)mmcRCA) << 16),
SELECT_DESELECT_CARD,
0,
R1 );
if ((resErr == MMC_NO_ERROR) || (resErr == MMC_CARD_IS_NOT_RESPONDING))
goto REASSURE_STANDBY_STATE;
DONE_SET_TO_STANDBY_STATE:
pc->error_code = (UINT16)resErr;
// RETAILMSG(1, (TEXT("mmcSetStandbyState with error %d\r\n"), resErr));
return (resErr);
}
/*******************************************************************************
* Name: mmcSetXferState - set the card in transfer state
*
* Description:
* In MMC mode, a select card command is sent to the card
* to put it in transfer state.
*
* Input:
* pc Device controller structure
* RCA The address of the card to be selected.
*
* Output:
* The card state is set to transfer state.
*
* Returns:
* Completion code.
*
********************************************************************************/
MMC_CC mmcSetXferState ( PDEVICE_CONTROLLER pc, UINT16 RCA)
{
MMC_CC resErr;
INT16 loopCnt;
REASSURE_XFER_STATE:
for (loopCnt = 0; loopCnt < 100; loopCnt++)
{
/* Get the status from the card */
resErr = mmcCommandAndResponse ( pc,
(((ULONG)RCA) << 16),
SEND_STATUS,
0,
R1 );
if (resErr != MMC_NO_ERROR )
goto DONE_SET_TO_XFER_STATE;
if (pc->currentState == TRANSFER)
goto DONE_SET_TO_XFER_STATE;
else if (pc->currentState == STANDBY)
break;
}
if (loopCnt == 100)
{
resErr = MMC_CARD_IS_BUSY;
goto DONE_SET_TO_XFER_STATE;
}
/* Check for the card current state */
/* The card needs to be in TRANSFER state */
resErr = mmcCommandAndResponse ( pc,
(((ULONG)RCA) << 16),
SELECT_DESELECT_CARD,
0,
R1 );
if (resErr == MMC_NO_ERROR)
goto REASSURE_XFER_STATE;
DONE_SET_TO_XFER_STATE:
pc->error_code = (UINT16)resErr;
// RETAILMSG(1, (TEXT("mmcSetXferState -- resErr %d\r\n"), resErr));
return resErr;
}
#endif /* (USE_MMC || USE_MMC_EMULATION) */
/*******************************************************************************
* Name: mmcGetCardIdentification - Card CID
*
* Description:
* Get the card Identification (reads the card CID reg.)
*
* Input:
* pc Device controller structure
* mmcIdent Pointer to CID buffer
* RCA Card address
*
* Output:
* mmcIdent Card Identification record.
*
* Returns:
* Completion code
*
********************************************************************************/
MMC_CC mmcGetCardIdentification ( PDEVICE_CONTROLLER pc,
UCHAR *mmcIdent,
UINT16 RCA )
{
#if (USE_MMC || USE_MMC_EMULATION)
UCHAR *resp_bytes;
#endif
MMC_CC resErr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -