📄 mmcoem.c
字号:
* 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 + -