📄 sdmmc.c
字号:
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. */
cardType = SD_TYPE;
sdFlag = YES; /* It is an SD card */
/* Is the card ready? */
readyFlag = to_WORD((UCHAR *)&pc->LastResponse[0]);
}
}
#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) )
{
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 (;;)
{
pc->drive_active = i;
/* Get device information and assign an RCA to it. */
if ( mmcIdentify (pc, cardType, i) != MMC_NO_ERROR )
{
/* There isn't any more device found */
break;
}
/* Check for SD card */
if (cardType == SD_TYPE)
{
/* The RCA is returned in pc->LastResponse[4] */
pc->drive[i].RCA = pc->LastResponse[4];
}
else
{
/* For MMC card in MMC mode, the RCA is the (drive number + 1) */
pc->drive[i].RCA = (UINT16)i + 1;
}
/* Save the card type */
pc->drive[i].drv_type = cardType;
i++; /* Next device */
if (i >= (UINT16)drvs_per_controller[pc->controller_number])
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 */
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
if ( devCount )
resErr = MMC_NO_ERROR;
#endif /* (USE_SPI || USE_SPI_EMULATION) */
pc->error_code = (UINT16)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;
/* Request any card to send the CID information */
resErr = mmcCommandAndResponse ( pc,
0L,
ALL_SEND_CID,
0,
R2 );
if ( resErr != MMC_NO_ERROR )
{
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);
/* The RCA is returned in pc->LastResponse[4] */
}
else
{
/* 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;
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;
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;
break;
}
}
if (loopCnt == 100)
{
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;
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;
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;
# if (USE_SPI || USE_SPI_EMULATION)
pc->user_address = (USERADDRESS)mmcIdent;
selectChip( RCA );
resErr = mmcCommandAndResponse ( pc,
0L,
SEND_CID,
0,
R1 );
if ( resErr == MMC_NO_ERROR )
resErr = receive_data( pc, (CID_BYTE_LENGTH - 1), 1, NO );
/* De-select the card */
deSelectChip ( RCA );
#else /* This is for MMC */
INT16 ij;
resp_bytes = (UCHAR *)pc->LastResponse;
/* Set the card to stanby state */
resErr = mmcSetStandbyState( pc, RCA );
resErr = mmcCommandAndResponse ( pc,
(((ULONG)RCA) << 16),
SEND_CID,
0,
R2 );
if ( resErr == MMC_NO_ERROR )
{
for (ij = 0; ij < (CID_BYTE_LENGTH-1); ij++)
{
mmcIdent[ij] = resp_bytes[ij+1];
}
}
#endif
pc->error_code = (UINT16)resErr;
return resErr;
}
/*******************************************************************************
* Name: mmcGetConfiguration - Card CSD
*
* Description:
* Get the card configuration parameters (reads the card CSD reg.)
*
* Input:
* pc Device Controller structure
* UINT16 RCA Card address.
* UCHAR respCSD Pointer to CSD information
*
* Output:
* respCSD Card configuration record.
*
* Returns:
* Completion code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -