⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdmmc.c

📁 基于RM9200主芯片
💻 C
📖 第 1 页 / 共 5 页
字号:
                                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 + -