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

📄 mmcoem.c

📁 基于RM9200主芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
*       INT16   power_state
*                       1 - Turn on.                                                                                                            |
*                       0 - Turn OFF.                                                                                                           |
*                                                                                                                                                                       |
* Output:
*       None.                                                                                                                           |
*                                                                                                                                                                       |
* Returns:
*       Completion code                                                                                                         |
*
************************************************************************************/
SDVOID mmcPowerOnOff(INT16 controllerno, INT16 power_state) /*__fn__*/
{
    /* Select the base address */
        MMCSelectController(controllerno, 0);

    SDWRITE_DATA08( (portIO+PPCTRL_REG), (UINT16)(power_state ? 0x1 : 0x08) );
}


SDVOID mmc_hw_init(INT16 controllerno) /*__fn__*/
{
    lastTransByte = 0x03;

        resetMMCController(controllerno);
}



SDVOID resetMMCController(UINT16 ctrlno)
{
        mmcPowerOnOff(ctrlno, 0);         /* Power off the reader */
    OS_WAIT(1);
    /* Make sure the power is set */
    mmcPowerOnOff(ctrlno, 1);         /* Power on the reader */
    OS_WAIT(3);
}


/**************************************************************************
* Name: startMMCClock - Start the MMC Host Controller clock
*
* Description:
*       The MMC clock is started by the.       
*
* Input:
*       portAddress     Controller bas address
*
* Output:
*       Starting the clock.
*
* Return:
*       None
*
**************************************************************************/
SDVOID startMMCClock( SDVOID )
{
}


/* This routine is not used for this implementation */
SDBOOL setMMCClockRate(UINT16 clkRate)
{
    clkRate = clkRate;

    return YES;
}


SDVOID startMMC80Clocks(INT16 controller_no)
{
    INT16   i;
    UCHAR   iData;


    /* Select the base address */
        MMCSelectController(controller_no, 0);


    /* Send 80 clocks */
    for (i = 0; i < 80; i++)
    {
        MMCExchangeData(0x0F, &iData);
    }
}


/***********************************************************************************
* Name: MMCDataExchange
*
* Description:
*       Performs one clock-tick MMC transaction using the PC parallel port.
*       The clock bit is toggled. Data and command bits are read and written
*       on the rising and falling edges of the clock, respectively.                                                                                     |
*
* Input:
*       oByte   A control byte for output.
*               Bit0    Command bit.
*               Bit1    Data bit.
* Note: Clock bit is superimposed on bit 7.
*
* Output:
*       iByte   Data read from the bus.
*               Bit4 - Response bit.
*               Bit5 - Data in bit.
*
* Returns:
*       None
*
************************************************************************************/
SDLOCAL MMC_CC MMCExchangeData(UCHAR odata, UCHAR *idata)
{
    UCHAR tvalue;
    UCHAR retval;

    tvalue = (UCHAR)~(lastTransByte | (UCHAR)WRITE_CLK1_PATTERN);
    SDWRITE_DATA08((portIO+PPDATA_REG), (UINT16)tvalue);

    retval = (UCHAR)(~SDREAD_DATA08(portIO+PPSTAT_REG));

    lastTransByte = (UCHAR)(odata | (UCHAR)WRITE_CLK0_PATTERN);

    tvalue = (UCHAR)~(odata | (UCHAR)WRITE_CLK0_PATTERN);
    SDWRITE_DATA08((portIO+PPDATA_REG), (UINT16)tvalue);

    *idata = retval;

        lastTransByte_drv[driveSave] = lastTransByte;

    return (MMC_NO_ERROR);
}



/***********************************************************************************
* Read or Write a byte of data to the MMC device
*
***********************************************************************************/
UCHAR MMCGetData(SDVOID)
{
    INT16   nbit;
    UCHAR   iByte, iData;

    iByte = 0;
    iData = 0;
    for (nbit = 7; nbit >= 0; nbit--)
    {
        MMCExchangeData(0x0F, &iByte);
        iByte &= 0x20;
        iByte >>= 5;
        iData |= (UCHAR)(iByte << nbit);
    }
    return (iData);
}


SDVOID MMCSendData(UCHAR odata)
{
    INT16   nBit;
    UCHAR   oByte, iByte;

    for (nBit = 0; nBit < 8; nBit++)
    {
        oByte = (UCHAR)((odata << nBit) >> 6);
        oByte &= (UCHAR)0x2;
        oByte |= (UCHAR)0x0D;
        /* Transmitting DATA */
        MMCExchangeData(oByte, &iByte);
    }
}


SDVOID MMCSendCommand( UINT32 Arg, UINT16 Cmd, UINT16 crcDATA )
{
    UINT16  i;
    UINT08  cmd_bytes[BYTE_LENGTH];
    UCHAR   iByte;
    UCHAR   nByte;
    UCHAR   tranByte;
    INT16   nBit;

    for (i = 0; i < 2; i++)
        MMCExchangeData(0xF, &iByte);

    cmd_bytes[0] = (UCHAR)(Cmd);

    /* MSB first */
    for (i = 4; i > 0; i--)
    {
        cmd_bytes[i] = (UCHAR)(Arg & 0xFFL);
        Arg >>= 8;
    }

    cmd_bytes[5] = (UINT08)crcDATA;
    /* Send the command */
    for (i = 0; i < BYTE_LENGTH; i++)
    {
        tranByte = cmd_bytes[i];

        for (nBit = 7; nBit >= 0; nBit--)
        {       /* Transmit Command */
            nByte = (UCHAR)(((tranByte >> nBit) & 0x1) | 0xE);
            MMCExchangeData(nByte, &iByte);
        }
    }
}


/***********************************************************************
* Name: MMCReceive - Handle data from target to host
*
* Description:
*       Read data from Receive FIFO
*
* Input:
*       portAddress     I/O address
*
* Output:
*
*
* Return:
*
***********************************************************************/
MMC_CC MMCReceive(UCHAR *dBuf, UINT16 dataLength, UINT16 noBlocks, UINT16 xferMode)
{
        UCHAR   *dPtr;
    UINT16  i, rCRC;
        UINT16  count;
    UCHAR   iByte;

        dPtr = dBuf;

        for (count = 0; count < noBlocks; count++)
        {
                /* Wait for data token */
                if ( !checkCardBusy(DATA_TOKEN) )
                {
                        return MMC_CARD_READ_FAILURE;
                }

                /* Get data */
                rCRC = 0;
                for (i = 0; i < dataLength; i++)
                {
                        dPtr[i] = MMCGetData();
                }

                /* Get CRC */
                iByte = MMCGetData();
                rCRC = ((UINT16)iByte) << 8;
                iByte = MMCGetData();
                rCRC |= ((UINT16)iByte);

                if (rCRC != calculateDataCRC16( dPtr, dataLength ))
                        return MMC_DATA_CRC_ERROR;

                dPtr += dataLength;
        }

         return MMC_NO_ERROR;

}


/***************************************************************************
* Name: MMCTransmit - Handle data from host to device
*
* Description:
*       Write data to transmit FIFO
*
* Input:
*
* Output:
*
* Return:
*
*
***************************************************************************/
MMC_CC MMCTransmit(UCHAR *dBuf, UINT16 dataLength, UINT16 noBlocks, UINT16 xferMode)
{
        UCHAR   *dPtr;
    UINT16  i;
    UINT16  wCRC;
        UINT16  count;
    UCHAR   oByte;
    UCHAR   CRCstatus;

        dPtr = dBuf;

        for (count=0; count < noBlocks; count++)
        {
                /* 2 clk - delay before transmitting DATA */
                for (i = 0; i < 2; i++)       /* MMC_Nwr_MIN == 2 */
                        MMCExchangeData(0x0F, &oByte);

                /* Calculate CRC */
                wCRC = calculateDataCRC16( dPtr, dataLength );

                /* Start Bit of DATA */
                MMCExchangeData(0x0D, &oByte);

                /* Send data */
                for (i = 0; i < dataLength; i++)
                {
                        oByte = (UCHAR)dPtr[i];
                        MMCSendData(oByte);
                }

                /* Send CRC */
                oByte = (UCHAR)(wCRC >> 8);
                MMCSendData(oByte);
                oByte = (UCHAR)(wCRC);
                MMCSendData(oByte);
    
                /* End bit + 2 Z_bit */
                for (i = 0; i < 4; i++)
                        MMCExchangeData(0x0F, &oByte);

                /* Get the start bit */
                MMCExchangeData(0x0F, &oByte);

                if (oByte & 0x20)               /* if NO Start Bit */
                        return MMC_NO_CRC_STATUS;
                else            /* if Start Bit of CRC_status detected */
                {
                        /* Get CRC status bits and END bit */
                        for (i = 0, CRCstatus = 0; i < 4 ; i++)
                        {
                                CRCstatus <<= 1;
                                MMCExchangeData(0x0F, &oByte);
                                CRCstatus |= ((oByte & 0x20) >> 5);
                        }

                        CRCstatus &= 0x0F;
                        if (CRCstatus == 0x5)   /* Including the END bit */
                        {
                                /* Look at the DAT signal for READY */
                                if ( !checkCardBusy(DUMMY_DATA) )
                                {
                                        /* Time out before finishing program data.  Sheeee... it happens */
                                        return MMC_TIME_OUT_RCVD;
                                }

                                dPtr += dataLength;
                                continue;
                        }
    
                        return MMC_DATA_STATUS_CRC_ERROR;
                }

        }

        return MMC_NO_ERROR;
}


SDBOOL MMCPrepareAndSetup(UINT32 Arg, UINT16 Cmd, UINT16 noBlocks, UINT16 Resp)
{
    UINT16 crcDATA;

    crcDATA = calculateCmdCRC(Arg, Cmd);
    
    /* Setup the command */
    MMCSendCommand( Arg, Cmd, crcDATA );

    return YES;
}


MMC_CC mmc_get_response( UCHAR *resp_bytes, UINT16 respBitLength)
{
    UINT16 i, maxTime;
    UCHAR iByte;

    iByte = 0;
    maxTime = 0xFFFF;        

    for (i = 0; i < maxTime; i++)
    {       /* Waiting of response  */
        MMCExchangeData(0x0F, &iByte);

        if ( !(iByte & 0x10) )  /* start bit of cmd's response detected */
            break;
        if (i == (maxTime-1))   /* The card isn't responding */
            return MMC_CARD_IS_NOT_RESPONDING;
    }

    for (i = 0; i < respBitLength; i++)
    {       /* Receiving & storing CMD_response */
        iByte &= 0x10;
        iByte >>= 4;
        resp_bytes[(i>>3)] |= (iByte << (7-(i&7)));
        MMCExchangeData(0x0F, &iByte);
    }

    return MMC_NO_ERROR;
}


/***************************************************************************
* Name: getMMCResponseInfo - Get the response from MMC card
*
* Description:
*       Get the response from MMC card
*
* Input:
*       RespBuff        Response buffer
*       RespLength      Length of the response
*
* Output:
*       Response information
*
* Return:
*
***************************************************************************/
MMC_CC getMMCResponseInfo(UCHAR *pRespBuff, UINT16 respLength, UINT16 respType)
{
    /* The response length can be 6 or 16 bytes long */
    if (respLength > BYTE_LENGTH)
    {
        if (mmc_get_response( pRespBuff, R2_BIT_LENGTH ))
            return MMC_CARD_IS_NOT_RESPONDING;      /* The card isn't responding */
            
        if (checkResponseCRC( pRespBuff,
                1,
                R2_BYTE_LENGTH))
            return MMC_CMD_CRC_ERROR;       /* Detected CRC-error */
    }        
    else
    {
        if (mmc_get_response( pRespBuff, R1R3_BIT_LENGTH ))
            return MMC_CARD_IS_NOT_RESPONDING;      /* The card isn't responding */

        if (respType == 3)
            return (MMC_NO_ERROR);

        if (checkResponseCRC(pRespBuff,
                0,
                R1R3_BYTE_LENGTH))
            return MMC_CMD_CRC_ERROR;       /* Detected CRC-error */
    }

    return MMC_NO_ERROR;
}



/***********************************************************************************
* Name: checkCardBusy
*
* Description:
*       Test the READY/BUSY status of the MMC card.
*
* Input:
*       UINT16   inData         used for switch case of returned data expected.
*
* Output:
*       None.
*
* Returns:
*       Completion code
*
************************************************************************************/
SDBOOL checkCardBusy(UINT16 inData)
{
        UINT16  ii;
        UCHAR   datState = 0;

        ii = 0xFFFF;
        while (ii)
    {
                /* Look at the DAT signal for READY */
                MMCExchangeData(0x0F, &datState);

                switch (inData)
                {
                        case DATA_TOKEN:        /* wait for data token */
                                if ((datState & 0x20) == 0)
                                        return YES;
                                break;
                        case DUMMY_DATA:        /* wait for DATA line high  */
                                if (datState & 0x20)
                                        return YES;      /* The card is ready */
                                break;
                }

                ii--;

        datState = 0;
    }
        
    /* The card is busy.  TOO BAD... */
        return NO;
}

#endif /* (USE_MMC) */

#endif  /* (USE_MMC || USE_MMC_EMULATION) */

⌨️ 快捷键说明

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