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

📄 sdmmc.c

📁 PXA27X_CAYMAN BSP from CAYMAN board
💻 C
📖 第 1 页 / 共 5 页
字号:
                        /* CMD1 failed.  There are two ways to explain this:
                           1. SD card seems not to respond to CMD1 at all (MMC mode).
                              Therefore, based on the error, this could be an SD card.
                              Try ACMD41 command to verify this claim.
                           2. There is no card in the slot.
                        */
                        /* Try SD application command. This application command should
                           return an error. It is unclear why the card returns an error
                           after CMD1. Is it a firmware bug? or...
                           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;

        //SD Card: SDType=1  MMC Card: SDType=0
        if(cardType == SD_TYPE)
        {
            v_pDrvGlob->ac97.SDType=1;   //SD Card

//            resErr = mmcSDApplCmd(pc, (UCHAR *)buf, 0L, 0, pc->drive[phys_drive].RCA, R1, SD_STATUS);
            resErr = mmcSDApplCmd(pc, SDNULL, 0x02, 0, (pc->drive)->RCA, R1, SET_BUS_WIDTH);

            v_pDrvGlob->ac97.SDConFig = 1;
            
            NKDbgPrintfW(TEXT("SD resErr:%d\r\n"),resErr);
        }
        else
        {
            v_pDrvGlob->ac97.SDType=0;    //MMC Card
            resErr = mmcSDApplCmd(pc, SDNULL, 0x00, 0, (pc->drive)->RCA, R1, SET_BUS_WIDTH);
            NKDbgPrintfW(TEXT("Mmc resErr:%d\r\n"),resErr);
        }
        //NKDbgPrintfW(TEXT("(pc->drive)->drv_type:%x cardType:%x\r\n"),(pc->drive)->drv_type,cardType);
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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -