📄 mmcoem.c.bak
字号:
* portAddress Base Address
* cmd Command index
* arg Argument
*
* Output:
* 6-byte command is sent to the card
*
* Return:
* Complete code
*
* Function: send the command to MMC card. CRC is not needed for
* the FPGA controller.
*
***************************************************************************/
SDVOID MMCSendCommand( UINT32 Arg, UINT16 Cmd, UINT16 crcDATA)
{
UINT16 dtmp;
dtmp = (UINT16)crcDATA;
/* Set up the argument. */
dtmp = (UINT16)(Arg >> 16);
v_pMMCReg->argh = dtmp;
dtmp = (UINT16)(Arg & 0xFFFF);
v_pMMCReg->argl = dtmp;
/* Set up the command. */
dtmp = (Cmd & 0x7F);
v_pMMCReg->cmd = dtmp;
}
/***************************************************************************
* 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 Error code
*
***************************************************************************/
MMC_CC getMMCResponseInfo(UCHAR *respBuff, UINT16 respLength, UINT16 respType)
{
UINT16 dtmp, dtimer;
UINT16 i;
i = respType; /* Make compiler happy! */
/* Timer count for an MMC response */
dtimer = 0x0FFF;
/* Clear the FIFO buffer */
dtmp = v_pMMCReg->rxfifo;
dtmp = v_pMMCReg->txfifo;
while ( dtimer )
{
/* Read status and wait for proper response */
dtmp = v_pMMCReg->stat;
dtimer--;
/* Check for TIME OUT on response */
if ( dtmp & TIME_OUT_RESPONSE )
{
return MMC_CARD_IS_NOT_RESPONDING;
}
/* Check for CRC on response */
else if ( dtmp & RESP_CRC_ERR)
{
return (MMC_CMD_CRC_ERROR );
}
else if ( dtmp & CRC_WR_ERR )
{
return MMC_DATA_STATUS_CRC_ERROR;
}
/* Check for CRC read error */
else if ( dtmp & CRC_RD_ERR )
{
return MMC_DATA_STATUS_CRC_ERROR;
}
/* Check for command response */
else if ( dtmp & END_CMD_RES )
{
/* Get the command response information */
dtmp = (respLength + 1) & 0xFE;
respLength = dtmp;
i = 0;
while ( i < respLength )
{
dtmp = v_pMMCReg->res;
respBuff[i] = (UCHAR)(dtmp >> 8);
i++;
respBuff[i] = (UCHAR)(dtmp & 0xFF);
i++;
}
/* No error return */
return MMC_NO_ERROR;
}
}
return (MMC_CARD_IS_NOT_RESPONDING);
}
/***************************************************************************
* Name: MMCTransmit - Handle data from host to device
*
* Description:
* Write data to the device. This routine handles single
* block (WRITE SINGLE BLOCK command) or multiple blocks
* (WRITE MULTIPLE BLOCK command) data transfer.
*
* Input:
* pc Device controller structure
* dataLength Data block length
* noBLocks Number of sectors to transfer
* xferMode Single or mulitiple mode transfer
*
* Output:
* Data is written to the device.
*
* Return:
* MMC Status code
*
***************************************************************************/
MMC_CC MMCTransmit(UCHAR *dBuf, UINT16 dataLength, UINT16 noBlocks, UINT16 xferMode)
{
UINT8 *dBufPtr;
UINT16 dLength;
UINT16 y;
// Set up the buffer
dBufPtr = (UINT8 *)dBuf;
dLength = dataLength;
data_trans_flag = 1;
v_pMMCReg->imask = MASK_ON_TXFIFO_WR_REQ;
while(dLength)
{
while(!(v_pMMCReg->ireg & 0x40))
{
//WaitForSingleObject(gSDMMCIntrEvent, 200);
InterruptDone(SYSINTR_SDMMC);
}
if(dLength%32==0)
{
for(y = 0; y<32; y++)
{
v_pMMCReg->txfifo = *dBufPtr;
// RETAILMSG(1, (TEXT("MMCTransmit -- get data dBufPtr[%d] = 0x%x\r\n"), y, *dBufPtr));
dBufPtr++;
dLength--;
}
}
else
{ v_pMMCReg->prtbu= BUFF_PARTIAL_FULL;
for(y = 0; y<dLength; y++)
{
v_pMMCReg->txfifo = *dBufPtr;
// RETAILMSG(1, (TEXT("MMCTransmit -- get data dBufPtr[%d] = 0x%x\r\n"), y, *dBufPtr));
dBufPtr++;
dLength--;
}
}
}
v_pMMCReg->imask = MASK_ON_DATA_TRAN_DONE; // Data Transfer Done
while(!(v_pMMCReg->stat & 0x00000800))
{
WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
InterruptDone(SYSINTR_SDMMC);
}
// MMC Prog Done
v_pMMCReg->imask = MASK_ON_PRG_DONE;
while((v_pMMCReg->stat & 0x00001000)==0x00000000)
{
WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
InterruptDone(SYSINTR_SDMMC);
}
v_pMMCReg->imask = MASK_OFF_ALL;
// RETAILMSG(1, (TEXT( "DATA_TRAN_DONE done!!! ireg is %x.\r\n"),v_pMMCReg->ireg ));
data_trans_flag = 0;
return MMC_NO_ERROR;
}
/***************************************************************************
* Name: MMCReceive - Handle data from target to host
*
* Description:
* Read data from the device. This routine handles single
* block (READ SINGLE BLOCK command) or multiple blocks (READ
* MULTIPLE BLOCK command) data transfer.
*
* Input:
* pc Controller structure
* dataLength Data block length
* noBLocks Number of sectors to transfer
* xferMode Single or mulitiple mode transfer
*
* Output:
* Data Buffer is filled
*
* Return:
* MMC status code
*
***************************************************************************/
MMC_CC MMCReceive(UCHAR *dBuf, UINT16 dataLength, UINT16 noBlocks, UINT16 xferMode)
{
UINT8 *dBufPtr;
// UINT16 dtmp, dtimer;
// UINT16 dStatus;
UINT16 dLength;
// UINT16 nLoops, x;
UINT16 y , z;
int i;
// Set up the buffer
// NKDbgPrintfW(1, (TEXT("MMCReceive -- dataLength =%d, noBlock = %d\r\n"), dataLength, noBlocks));
dBufPtr = (UINT8 *)dBuf;
z = 0;
v_pMMCReg->imask = MASK_ON_RXFIFO_RD_REQ;
data_trans_flag = 1;
// NKDbgPrintfW(TEXT("MMCReceive -- noBlocks %d, dLength = %d\r\n"), noBlocks,dLength);
for (i=0; i<noBlocks; i++)
{
dLength = dataLength;
// NKDbgPrintfW(TEXT("MMCReceive -- noBlocks %d\r\n"), i);
while(dLength)
{
if(dLength%32==0)
{
//wait for xmit_fifo_empty
while(!(v_pMMCReg->ireg & 0x20))
{
//WaitForSingleObject(gSDMMCIntrEvent, 200);
InterruptDone(SYSINTR_SDMMC);
}
for(y = 0; y<32; y++)
{
*dBufPtr = (v_pMMCReg->rxfifo & 0x00FF);
// NKDbgPrintfW(TEXT("MMCReceive -- get data dBufPtr[%d] = %x, dLength = %d\r\n"), y, *dBufPtr, dLength);
dBufPtr++;
dLength--;
}
}
else
{
v_pMMCReg->prtbu = BUFF_PARTIAL_FULL;
for(y = 0; y<dLength; y++)
{
*dBufPtr = (v_pMMCReg->rxfifo & 0x00FF);
// RETAILMSG(1, (TEXT("MMCReceive !!-- get data dBufPtr[%d] = %x, dLength = %d\r\n"), y, *dBufPtr, dLength));
dBufPtr++;
dLength--;
}
}
}
}
// NKDbgPrintfW(TEXT("MMCReceive -- Finishing data transfer\r\n"));
v_pMMCReg->imask = MASK_ON_DATA_TRAN_DONE; // Data Transfer Done
while(!(v_pMMCReg->stat & RD_DATA_AVAILABLE))
{
// v_pBLReg->hex_led=0xbbbbbbbb;
WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
InterruptDone(SYSINTR_SDMMC);
}
v_pMMCReg->imask = MASK_OFF_ALL;
// NKDbgPrintfW(TEXT("MMCReceive -- data transfer done interrupt\r\n"));
v_pMMCReg->strpc = STOP_CLOCK; // stop clock
while((v_pMMCReg->stat & CLOCK_ENABLE )); // wait for clock to stop
data_trans_flag = 0;
// v_pBLReg->hex_led=0xcccccccc;
// NKDbgPrintfW(TEXT("MMCReceive -- wait for STOP_CLOCK\r\n"));
return MMC_NO_ERROR;
}
/***************************************************************************
* Name: MMCSetupXfer
*
* Description:
* Set up information and configure the MMC controller
*
* Input:
* pc Device controller structure
* cmdIndex Command index
* noBlocks Number of blocks to transfer
* respType Type of response
*
* Output:
* All related Registers are update
*
* Return:
* None
*
***************************************************************************/
SDVOID MMCSetupXfer( UINT16 cmdIndex, UINT16 nBlocks, UINT16 respType)
{
UINT16 cmdDatContReg;
UINT16 blkLength;
UINT16 noBlocks = nBlocks;
cmdDatContReg = NO;
blkLength = 0;
setupMMcHostDataRegister(cmdIndex, &cmdDatContReg, &noBlocks, &blkLength);
if (cmdIndex != SSTOP_TRANSMISSION)
{
/* If None Data Transfer type, just skip */
if ( cmdDatContReg != NO )
{
/* BLOCK LENGTH */
v_pMMCReg->blkle = blkLength;
/* NUMBER OF BLOCK */
v_pMMCReg->nob = noBlocks;
}
}
/* COMMAND DATA */
cmdDatContReg |= respType;
/* Set up the hardware */
v_pMMCReg->cmdat = cmdDatContReg;
}
/***************************************************************************
* Name: MMCPrepareAndSetup
*
* Description:
* Set up information and Send the command to MMC card
*
* Input:
* pc Device controller structure
* Cmd Command index
* Arg Argument
* noBlocks Number of blocks to transfer
* respType Type of response
*
* Output:
* Command is written to the device
*
* Return:
* MMC status code
*
***************************************************************************/
SDBOOL MMCPrepareAndSetup(UINT32 Arg, UINT16 Cmd, UINT16 noBlocks, UINT16 Resp)
{
/* Stop the clock to set up the requested information */
if ( !stopMMCClock() )
return NO;
/*
Setup the command. CRC is not needed because the MMC controller
can generate the CRC.
*/
MMCSendCommand( Arg, Cmd, 0 );
/* Setup the transfer */
MMCSetupXfer( Cmd, noBlocks, Resp );
/* Start the clock to execute the request */
startMMCClock();
return YES;
}
/***************************************************************************
* Name: checkCardBusy
*
* Description:
* Test the READY/BUSY status of the MMC card.
*
* Input:
* UINT16 inData not used
*
* Output:
* None
*
* Return:
* True or False
*
***************************************************************************/
SDBOOL checkCardBusy(UINT16 inData)
{
UINT16 dStatus, dtimer;
dtimer = 0x200;
/*
Wait for BUSY to go off before the next transfer. The
device may very well be programmed data into the flash memory.
*/
while ( dtimer )
{
/* Get status */
dStatus = v_pMMCReg->stat;
/* Check for the availability of the device for next transfer */
if ((dStatus & DONE_PROG_RDWR) || (dStatus & DONE_WDATA_XFER) )
return YES;
dtimer--;
}
/* The device is busy ... */
return NO;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -