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

📄 mmcoem.c

📁 intel xscale pxa270的完整wince4.2 BSP包
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef NMD_DEBUG 
    RETAILMSG(1, (TEXT("getMMCResponseInfo> %x\r\n"),v_pMMCReg->MMC_STAT));
#endif	

    /* Timer count for an MMC response */
    dtimer = 0x0FFF;

    /* Clear the FIFO buffer */
    

    while ( dtimer )
    {
        /* Read status and wait for proper response */
		dtmp = v_pMMCReg->MMC_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 = dtmp = v_pMMCReg->MMC_RES;
                respBuff[i] = (UCHAR)(dtmp >> 8);
                i++;
                respBuff[i] = (UCHAR)(dtmp & 0xFF);
                i++;
            }

			msWait(5);   
            /* No error return */
            return MMC_NO_ERROR;
        }
    }
#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("getMMCResponseInfo %x\r\n"), dtmp));
#endif	

#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("getMMCResponseInfo<-\r\n")));
#endif	
    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)
{
    UINT32  *dBufPtr;
    UINT16  dLength;
    UINT16  y;
	UINT16  i;
	UINT32  starttime=0, endtime=0, diff=0;
#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("MMCTransmit>\r\n")));
#endif	

//	starttime = v_pOSTReg->oscr0;
    // Set up the buffer 
    dBufPtr = (UINT32 *)dBuf;
	//dLength = dataLength;
        data_trans_flag = 1;
	v_pMMCReg->MMC_I_MASK &= ~0x40;

  for (i=0; i<noBlocks; i++)
  {
	  dLength = dataLength;
	while(dLength)
	{
	//	RETAILMSG(1, (TEXT("1Before enter write FIFO\r\n")));
	//	while(!(v_pMMCReg->MMC_I_REG & 0x40))
	//	{
			WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
			
	//	}
      //  RETAILMSG(1, (TEXT("after enter write FIFO\r\n")));
		if(dLength%32==0)
		{
			for(y = 0; y<8; y++)
			{
				v_pMMCReg->MB_TXFIFO = *dBufPtr;
//				RETAILMSG(1, (TEXT("MMCTransmit -- get data dBufPtr[%d] = 0x%x\r\n"), y, *dBufPtr)); 
				dBufPtr++;
				dLength-=4;
			}
			InterruptDone(SYSINTR_SDMMC);
		}
		else
		{	v_pMMCReg->MMC_PRTBUF= BUFF_PARTIAL_FULL;
			for(y = 0; y<dLength; y++)
			{
				v_pMMCReg->MB_TXFIFO = *dBufPtr;
#ifdef NMD_DEBUG1 
				RETAILMSG(1, (TEXT("MMCTransmit!! -- get data dBufPtr[%d] = 0x%x\r\n"), y, *dBufPtr)); 
#endif
				dBufPtr++;
				dLength-=4;
			}

		}
	}
  } //for
    v_pMMCReg->MMC_I_MASK |= 0x40;  //disable this tranmit request interrupt
	v_pMMCReg->MMC_I_MASK &=~0x1;		// Data Transfer Done

	WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
    v_pMMCReg->MMC_I_MASK |=0x1;
	InterruptDone(SYSINTR_SDMMC);
	
    
													// MMC Prog Done
	v_pMMCReg->MMC_I_MASK &=~0x2;

	WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
	v_pMMCReg->MMC_I_MASK = 0xFF;
	InterruptDone(SYSINTR_SDMMC);
	
	

//	RETAILMSG(1, (TEXT( "DATA_TRAN_DONE done!!!\r\n")));
        data_trans_flag = 0;
#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("MMCTransmit<\r\n")));
#endif	
	   //endtime = v_pOSTReg->oscr0;
/*
   if(endtime<starttime)
	   diff = (0xffffffff - starttime) + endtime;
   else
	   diff = endtime-starttime;
   total += diff;
   NKDbgPrintfW(TEXT("total is %d\r\n"),total); 
*/
	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)
{
	volatile UCHAR *pBuf;
	UINT16  dLength;
	int i;
	int alignment;

	pBuf	= (UCHAR *)dBuf;
    
	v_pMMCReg->MMC_I_MASK &= ~0x20;
    data_trans_flag = 1;

	for (i=0; i<noBlocks; i++)
	{
		dLength = dataLength;
		while (dLength)
		{
			alignment = (DWORD)pBuf & 0x3;

			// If the buffer not 32-bit aligned, we need to align the buffers, then continue with 32-bit copies
			if ((alignment == 1) || (alignment == 5))
			{

				if (dLength >= 32)
				{

					WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
					
					*pBuf					= *pMMC_RX_Fifo;			// 1 BYTE
					*(UINT16 *)(pBuf + 1)	= *(UINT16 *)pMMC_RX_Fifo;	// 2 BYTES
					*(UINT32 *)(pBuf + 3)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 7)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0xb)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0xf) = *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x13)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x17)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x1b)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(pBuf + 0x1f)			= *pMMC_RX_Fifo;			// 1 BYTE
	
					pBuf += 32;
										
					dLength-= 32;

					InterruptDone(SYSINTR_SDMMC);
				} else 
				{
					while (dLength > 0)
					{
						*pBuf++ = *pMMC_RX_Fifo;
						dLength--;
					}
				}
			} else 	if ((alignment == 3) || (alignment == 7))
			{
				if (dLength >= 32)
				{

					WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
					
					*pBuf					= *pMMC_RX_Fifo;			// 1 BYTE
					*(UINT32 *)(pBuf + 1)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 5)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 9)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0xd)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x11)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x15)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x19)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT16 *)(pBuf + 0x1d)= *(UINT16 *)pMMC_RX_Fifo;	// 2 BYTES
					*(pBuf + 0x1f)			= *pMMC_RX_Fifo;			// 1 BYTE
				
					pBuf += 32;
										
					dLength-= 32;

					InterruptDone(SYSINTR_SDMMC);
				} else 
				{
					while (dLength > 0)
					{
						*pBuf++ = *pMMC_RX_Fifo;
						dLength--;
					}
				}
			}else if ((alignment == 2) || (alignment == 6))
			{
				if (dLength >= 32)
				{

					WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
					
					*(UINT16 *)pBuf			= *(UINT16 *)pMMC_RX_Fifo;	// 2 BYTES
					*(UINT32 *)(pBuf + 2)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 6)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0xa)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0xe)	= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x12)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x16)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT32 *)(pBuf + 0x1a)= *(UINT32 *)pMMC_RX_Fifo;	// 4 BYTES
					*(UINT16 *)(pBuf + 0x1e)= *(UINT16 *)pMMC_RX_Fifo;	// 2 BYTES
				
					pBuf += 32;
										
					dLength-= 32;

					InterruptDone(SYSINTR_SDMMC);
				} else 
				{
					while (dLength > 0)
					{
						*pBuf++ = *pMMC_RX_Fifo;
						dLength--;
					}
				}
			}
			else 
			{
				if (dLength >= 32)
				{

					WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
					
					*(UINT32 *) pBuf		= *(UINT32 *)pMMC_RX_Fifo;
					*(UINT32 *)(pBuf + 4)	= *(UINT32 *)pMMC_RX_Fifo;
					*(UINT32 *)(pBuf + 8)	= *(UINT32 *)pMMC_RX_Fifo;				
					*(UINT32 *)(pBuf + 0xc) = *(UINT32 *)pMMC_RX_Fifo;
					*(UINT32 *)(pBuf + 0x10)= *(UINT32 *)pMMC_RX_Fifo;
					*(UINT32 *)(pBuf + 0x14)= *(UINT32 *)pMMC_RX_Fifo;
					*(UINT32 *)(pBuf + 0x18)= *(UINT32 *)pMMC_RX_Fifo;				
					*(UINT32 *)(pBuf + 0x1C)= *(UINT32 *)pMMC_RX_Fifo;				

					pBuf += 32;
	
					dLength -= 32;				

					InterruptDone(SYSINTR_SDMMC);
				} else 
				{
					while (dLength > 0)
					{
						*pBuf++ = *pMMC_RX_Fifo;
						dLength--;
					}
				}
			}
		}
	}

	v_pMMCReg->MMC_I_MASK |= 0x20;
	v_pMMCReg->MMC_I_MASK &= ~0x1;		// Data Transfer Done

	WaitForSingleObject(gSDMMCIntrEvent, INFINITE);
	v_pMMCReg->MMC_I_MASK = 0xFF;
	InterruptDone(SYSINTR_SDMMC);
	
//   NKDbgPrintfW(TEXT("MMCReceive -- data transfer done interrupt\r\n"));

 //	v_pMMCReg->MMC_STRPCL  = STOP_CLOCK;					// stop clock
 //	while((v_pMMCReg->MMC_STAT & CLOCK_ENABLE ));		// wait for clock to stop
        data_trans_flag = 0;
//    NKDbgPrintfW(TEXT("MMCReceive -- wait for STOP_CLOCK %x\r\n"), v_pMMCReg->MMC_STAT);
	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->MMC_BLKLEN = blkLength;

            /* NUMBER OF BLOCK */
			v_pMMCReg->MMC_NUMBLK = noBlocks;
        }
    }

    /* COMMAND DATA */
    cmdDatContReg |= respType;

    /* Set up the hardware */
	v_pMMCReg->MMC_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;

#ifdef NMD_DEBUG 
    RETAILMSG(1, (TEXT("MMCPrepareAndSetup>cmd %x arg %x HW_PWRUP %x\r\n"), Cmd, Arg,HW_PWRUP ));
#endif	
	if (HW_PWRUP == TRUE)
	{
	   HW_PWRUP= FALSE;
	   mmc_init_setup();
	}   	
	if( (Cmd == XLLP_MMC_CMD11) ||
		(Cmd == XLLP_MMC_SPICMD17) ||
		(Cmd == XLLP_MMC_CMD18) ||
		(Cmd == XLLP_SD_ACMD13 ) || 
		(Cmd == XLLP_SD_ACMD51) ||
  		(Cmd == XLLP_MMC_CMD20) ||
		(Cmd == XLLP_MMC_SPICMD24) ||
		(Cmd == XLLP_MMC_CMD25) ) 
	{
	if(Cmd == XLLP_SD_ACMD13)
	 	 XllpMmcSdSetupXCmd(v_pMMCReg, (XLLP_INT32_T)(DEFAULT_BLK_LENGTH >> 3), (XLLP_INT32_T)(DEFAULT_BLK_LENGTH >> 3), 0xFFFF);
   	else 
   		if(Cmd == XLLP_SD_ACMD51)
   			 XllpMmcSdSetupXCmd(v_pMMCReg, (XLLP_INT32_T)8, (XLLP_INT32_T)8, 0xFFFF);
   		else
  			 XllpMmcSdSetupXCmd(v_pMMCReg, (XLLP_INT32_T)(noBlocks * 512), (XLLP_INT32_T)512, 0xFFFF);
	}
    XllpMmcSdSetupCmd(v_pMMCReg, Cmd, Arg, 64, FALSE);
#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("MMCPrepareAndSetup<\r\n")));
#endif	
	   
    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)
{
    UINT32  dStatus, dtimer;
#ifdef NMD_DEBUG 
    RETAILMSG(1, (TEXT("checkCardBusy>\r\n")));
#endif	

    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->MMC_STAT;

        /* Check for the availability of the device for next transfer */
        if ((dStatus & DONE_PROG_RDWR) || (dStatus & DONE_WDATA_XFER) ) 
            return YES;

        dtimer--;
    }
#ifdef NMD_DEBUG1 
    RETAILMSG(1, (TEXT("checkCardBusy<\r\n")));
#endif	

    /* The device is busy ... */
        return NO;
}


⌨️ 快捷键说明

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