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

📄 mmcdrv.c

📁 intel xscale pxa270的完整wince4.2 BSP包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
* FileName: MMCDRV.C
*
* SanDisk Host Developer's Toolkit
*
* Copyright (c) 1997 - 2000 SanDisk Corporation
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*
* Description:
*       MMC driver
*
******************************************************************************/

#include "sdconfig.h"
#include <bvd1.h>

extern MMC_REGS	*v_pMMCReg;

#if (USE_MMC || USE_MMC_EMULATION)
#include "sdmmc.h"

;


/***********************************************************************************
*                                  Public Functions
*                                  ----------------
************************************************************************************/

/***********************************************************************************
* Name: mmcBusStart
*
* Description:
*       Starts the MMC bus by sending 80 clock cycles.
*       Reset the MMC devices. Put them in IDLE mode and configure all
*       devices with proper OCR and wait for ready.
*
* Input:
*       INT16   controller_no           Controller Number
*
* Output:
*       None.
*
* Returns:
*       None.
*
************************************************************************************/
SDBOOL mmcBusStart( INT16 ctrlNo )
{
    /* Reset the MMC host controller */
//    resetMMCController(ctrlNo);

    /* IDENTIFICATION STATE process in OPEN-DRAIN mode. */
    /* This process is operated at low clock rate 250KHz */
        if ( !setMMCClockRate(6) )
		{
//			RETAILMSG(1, (TEXT("fail to set setMMCClockRate()\r\n")));
			return NO;
		}

    /* Enable MMC interface in open drain mode and turn on the clock. */
    startMMC80Clocks(ctrlNo);
    
    return YES;
}

/*****************************************************************************
* Name: mmc_init_setup
*
* Description:
*       Initialize MMC devices. The MMC controller is operated in
*       OPEN-DRAIN mode.
*               - 80 clocks
*               - IDLE STATE
*               - OPERATIING VOLTAGE CONDITION
*
* Input:
*       None
*
* Output:
*       All devices should be ready
*
* Returns:
*       YES if successful
*       NO if failure
*       
*****************************************************************************/
SDBOOL mmc_init_setup(SDVOID) /*__fn__*/
{
    PDEVICE_CONTROLLER pc;
    INT16   ctrlNo;
    INT16   nFailures;

    nFailures = 0;
//    RETAILMSG(1, (TEXT("mmc_init_setup() \r\n")));
    /* This is a starting point in the IDENTIFICATION STATE process. */
    /* Apply to all MMC controllers */

    for (ctrlNo = 0; ctrlNo < N_INTERFACES; ctrlNo++)
    {
//		RETAILMSG(1, (TEXT("mmc_init_setup() enter loop %d\r\n"), ctrlNo));
        pc = &controller_s[ctrlNo];
        pc->controller_number = ctrlNo;

       //  Send 80 clocks to start the bus 
        if ( mmcBusStart(ctrlNo) )   // Put all device in idle mode 
        {
//			RETAILMSG(1, (TEXT("mmcBusStart successful\r\n")));
            // Reset all devices on the bus and wait for ready. 
            
            //Make sure all devices are READY.
            //- IDLE STATE
            //- OPERATIING VOLTAGE CONDITION
            
            if ( MMC_NO_ERROR == mmcReset ( pc, 0x00020000 ) )  //made change here by Yi, actually, originally value is 0xFFC000
            {
                // Set max. clock rate 
//				RETAILMSG(1, (TEXT("mmcReset() no error \r\n")));
                setMMCClockRate(0);
            }
            else
            {
                nFailures++;
            }
        }
        pc->controller_number = -1;
    }

    if ( nFailures >= N_INTERFACES )
        return NO;
//    RETAILMSG(1, (TEXT("mmc_init_setup() end, return value is YES \r\n")));
    return (YES);
}

/****************************************************************************
* Name: mmcConfigDevice
*
* Description:
*       Configure MMC devices and assign device ID.
*
* Input:
*       pc              Device Controller structure
*       driveno         Drive Number
*
* Output:
*       None.
*
* Returns:
*       Complete code.
*
****************************************************************************/
MMC_CC mmcConfigDevice( INT16 driveno )
{
    PDEVICE_CONTROLLER pc;
    INT16   phys_drive;

    /* THIS IS A INDENTIFICATION STATE phase */

#if (N_INTERFACES > 1)
    pc = drno_to_controller(driveno);
    phys_drive = drno_to_phys(driveno);
#else
    pc = &controller_s[0];
    phys_drive = driveno;
#endif

        /* Allow all card to identify itself and Assign ID to the device. */
        return (mmcIdentify( pc, pc->drive[phys_drive].drv_type, phys_drive ));
}


/****************************************************************************
* Name: receive_data
*
* Description:
*       While monitoring the MMC bus for data start bit condition, waits for
*       certain time before issue CARD NOT RESPONSE condition.
*       The data is read and stored after the start bit is detected. MMC timeouts
*       are observed and the received CRC number is validated.
*
* Input:
*       buffDATA   -   pointer to the data buffer.
*       length     -   Expected length of data block.
*
* Output:
*       buffData[] -   Received data.
*
* Returns:
*       Completion code
*
****************************************************************************/
MMC_CC receive_data( PDEVICE_CONTROLLER pc, UINT16 dLength, UINT16 noBlocks, UINT16 xferMode )
{
    /* Data is ready.  Get it from the MMC BUFFER */
//	RETAILMSG(1, (TEXT("receive_data is entered\r\n")));
        return (MMCReceive((UCHAR *)pc->user_address, dLength, noBlocks, xferMode));
}


/****************************************************************************
* Name: send_data
*
* Description:
*       Writes data block to the card.
*
* Input:
*       pc              Controller structure pointer.
*       dataLength      Length of data block.
*
* Output:
*       Data are sent to the device.
*
* Returns:
*       Completion code
*
****************************************************************************/
MMC_CC send_data( PDEVICE_CONTROLLER pc, UINT16 dLength, UINT16 noBlocks, UINT16 xferMode )
{
    /* Write data to the device */
        return (MMCTransmit((UCHAR *)pc->user_address, dLength, noBlocks, xferMode));
}


/*****************************************************************************
* Name: MMCReceivedResponse - Get the response from MMC card
*
* Description:
*       Get the response from MMC card
*
* Input:
*       pc      Device information structure
*       Resp    Response Type
*
* Output:
*
* Return:
*
*****************************************************************************/
MMC_CC MMCReceivedResponse(PDEVICE_CONTROLLER pc, RESP_TYPE Resp)
{
    UINT08  *respBuff;
    UINT16  respLength;


    if ( Resp == R0 )
        return (MMC_NO_ERROR);

        respLength = BYTE_LENGTH;               /* 6 bytes R1, R3 or R6 response */
    if ( Resp == R2 )
        respLength = CID_BYTE_LENGTH -1;/* (17-1) bytes R2 response */

    respBuff = (UINT08 *)pc->LastResponse;

    /* Read status and wait for response. */
    return (getMMCResponseInfo(respBuff, respLength, (UINT16)Resp));
}


/***************************************************************************
* Name: MMCAnalysisResponse - Analyze the MMC response
*
* Description:
*       Analyze the response from MMC card and convert the RAW
*       information to the known status
*
* Input:
*       pc      Device information structure
*
* Output:
*       None
*
* Return:
*       MMC completion code
*
***************************************************************************/
MMC_CC MMCAnalysisResponse( PDEVICE_CONTROLLER pc, RESP_TYPE respType )
{
    UINT32  statusInfo;
    UINT08  *respBuff;
    UINT16  ij, tt;

    respBuff = (UINT08 *)pc->LastResponse;
    if (respType == R6)
    {
                ij = (UINT16)respBuff[1];
                ij <<= 8;
                ij |= (UINT16)respBuff[2];
                pc->LastResponse[4] = ij;
#if (LITTLE_ENDIAN)
                /* Clear bits 31-24 of Status register */
                pc->LastResponse[0] &= 0x00FF;

                 /* Extract bits 23, 22 and clear bits 23-16 */
                ij = (pc->LastResponse[1] & 0xC000);
                 /* Extract bit 19 */
                tt = (pc->LastResponse[1] & 0x0800) << 2;
                ij |= tt;
                /* Pack bits 23,22 and 19 to bits 15-13 of Status register */
                pc->LastResponse[1] = ij;

                ij = pc->LastResponse[2] & 0x001F;
                 /* Extract bits 12-8 then pack to bits 12-8 */
                pc->LastResponse[1] |= (ij << 8);

                ij = pc->LastResponse[2] >> 8;
                 /* Extract bit 7-0 then pack to bit 7-0 */
                pc->LastResponse[2] = ij;
#else
                /* Clear bits 31-24 of Status register */
                pc->LastResponse[0] &= 0xFF00;

                 /* Extract bits 23, 22 */
                ij = pc->LastResponse[1] & 0x00C0;
                 /* Extract bit 19  */
                tt = (pc->LastResponse[1] & 0x0008) << 2;
                ij |= tt;
                /* Pack bits 23,22 and 19 to bits 15-13 */
                pc->LastResponse[1] = ij;

                 /* Extract bits 12-8 */
                ij = (pc->LastResponse[2] >> 8) & 0x1F;
                 /* Pack to bits 12-8 of Status register */
                pc->LastResponse[1] |= ij;

                ij = pc->LastResponse[2] & 0x00FF;
                 /* Extract bit 7-0 then pack to bit 7-0 */
                pc->LastResponse[2] = (ij << 8);
#endif
        }

    /* Get the RAW MMC status */
    statusInfo = (UINT32)(respBuff[1] & 0xFF);
    statusInfo <<= 8;
    statusInfo |= (UINT32)(respBuff[2] & 0xFF);
    statusInfo <<= 8;
    statusInfo |= (UINT32)(respBuff[3] & 0xE0);
    statusInfo <<= 8;

    /* Get the MMC state */

⌨️ 快捷键说明

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