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

📄 mmc_drv.c

📁 给予mx21处理器的嵌入式系统的mmc卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * *//****************************************************************************** *  * Copyright (C) 2001, Motorola All Rights Reserved *  * File Name:   mmcsd.c *  * Progammers:  Yiwei Zhao  * * Date of Creations:   30  DEC,2001 * * Synopsis: * * Modification History: * 30 DEC, 2001 * *****************************************************************************///#include "dbmx1_type.h"#include "mmc_def.h"#include "mmc_main.h"/* Functions List:	 * *///Karen add for write protect#define _reg_I2C_IADR           (*((volatile unsigned long*)(0xf0217000))) #define _reg_I2C_IFDR           (*((volatile unsigned long*)(0xf0217004)))#define _reg_I2C_I2CR           (*((volatile unsigned long*)(0xf0217008)))     #define _reg_I2C_I2SR           (*((volatile unsigned long*)(0xf021700c)))     #define _reg_I2C_I2DR           (*((volatile unsigned long*)(0xf0217010)))     #define _reg_PTA_GIUS           (*((volatile unsigned long*)(0xf021C020)))                   #define _reg_PTA_PUEN           (*((volatile unsigned long*)(0xf021C040)))unsigned long* pI2CReadData;unsigned short nI2CReadData;//number of dataunsigned short nI2CData; // index of dataunsigned long  dI2CReadData[2];unsigned char  bTransferDone;unsigned char  bTransferCurMode;unsigned char  gSDWriteProtect;#define KAREN_DEBUG/*  * Implementation of the MMCSD Driver. *//****************************************************************************** * Function Name: _MMCSD_InitCard * * Input:               None. * * Value Returned:      * * 		MMCSD_STATUS * * Description:  * * 	this routine will initialize the cards. * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/MMCSD_STATUS _MMCSD_InitSDHC(int port){	MMCSD_STATUS	ret;   	#ifdef CONFIG_ARCH_MX2ADS	if(port == 0)//sdhc1	{//set i/o driving strength		_reg_SYS_DSCR1 &= ~0x07;//		_reg_SYS_DSCR1 |= 0x01;//4mA		_reg_SYS_DSCR1 |= 0x03;//6mA			//check hardware revision		ret=_MMCSD_ChectHardwareRevision(port);		if(ret)			return ret;	//softreset		ret=_MMCSD_SoftReset(port);		if(ret)			return ret;			_MMCSD_SetClk(MMCSD_LOW_SPEED,port);		_MMCSD_ReadTimeOut(0x2DB4,port);						}	else if(port == 1)	{		_reg_SYS_DSCR1 &= ~0x00380000;//		_reg_SYS_DSCR1 |= 0x00080000;//4mA		_reg_SYS_DSCR1 |= 0x00180000;//6mA	//check hardware revision		ret=_MMCSD_ChectHardwareRevision(port);		if(ret)			return ret;	//softreset		ret=_MMCSD_SoftReset(port);		if(ret)			return ret;		_MMCSD_SetClk(MMCSD_LOW_SPEED,port);		_MMCSD_ReadTimeOut(0x2DB4,port);	}	#else		ret=_MMCSD_ChectHardwareRevision(0);	if(ret)		return ret;	ret=_MMCSD_SoftReset(0);	if(ret)		return ret;		_MMCSD_SetClk(MMCSD_LOW_SPEED,0);	_MMCSD_ReadTimeOut(0x2DB4,0);	#endif	return 0;}MMCSD_STATUS _MMCSD_InitMMC(int port){    u16  i,  count;    MMCSD_STATUS  ret;	u8   Cid_buff[20];	u16 card_type = 0xFFFF;   	count = 0;   	ret = 0;       	//TRACE("Card Identify\n");    /*------------------------------------------------------------------*/    /*  CMD0 CALL PROCEDURE (PLACES CARDS IN IDLE STATE)                */    /*------------------------------------------------------------------*/    	   	ret =_MMCSD_GoIdleState(port);              	if(ret != 0 )   	{	/*--------- WHEN NO ERROR OCCURS (= FINISH INIT)*/		FAILED("Place Cards into Idle State Failed(%ld)",(unsigned long)ret);       	return ret;    }       /*------------------------------------------------------------------*/    /*  CMD1						                 */    /*------------------------------------------------------------------*/	i = MMCSD_ADP_REPEATNUM;	while(i--)	{        ret = _MMCSD_SendOpCond(MMCSD_MMC_CARD_VOLTAGE,port);// MMC         if (ret == 0)        {/*--------- WHEN NO ERROR OCCURS (= FINISH INIT)*/			card_type = MMCSD_TYPE_MMC;			INFO("IT'S MMC CARD");        	break;        }             	if(ret!=MMCSD_CARD_BUSY)		{			//FAILED("Command SendOpCond Failed");       		return ret; 		//CMD send ERROR		}	}    /*------------------------------------------------------------------*/    /* Registe CARDS					                */    /*------------------------------------------------------------------*/	if(card_type == MMCSD_TYPE_MMC)	{           g_mmcsd_devices[port].card_type = MMCSD_TYPE_MMC;		/*		TRACE("Set Op Condition..");		ret = _MMCSD_Set_SendOpCond(MMCSD_MMC_CARD_VOLTAGE,				            MMCSD_CARD_SET_VOLTAGE);		if(ret)		{			FAILED("MMCSD_SendOpCond(SET_VOLTAGE) error with 0x%x",ret);			return ret;		}		*/		while(1)		{            ret = _MMCSD_AllSendCID(Cid_buff,port);//CMD2            if(ret&MMCSD_CMD_TIMEOUT)                                 {				FAILED("_MMCSD_AllSendCID failed with 0x%lx",(unsigned long)ret);            	g_mmcsd_devices[port].card_state = MMCSD_NOTREADY;				return ret;            }       		ret = _MMCSD_SetRelativeAddr(g_mmcsd_devices[port].card_rca,port); //CMD3       		if(ret&MMCSD_CMD_TIMEOUT)       		{				FAILED("_MMCSD_SetRelativeAddr failed with 0x%lx",ret);            	g_mmcsd_devices[0].card_state = MMCSD_NOTREADY;				return ret;            }			else			{				break;			}			g_mmcsd_devices[port].card_rca++;		}        g_mmcsd_devices[port].card_state = MMCSD_STANDBY;		count++;	}	else	{		FAILED("UNKNOWN CARD TYPE");		return MMCSD_ERROR;	// ISSUE	}        /*----------------------------------------------------------------------*/    /*  CHECK IF EFFECTIVE CARDS EXIST                                      */    /*----------------------------------------------------------------------*/    if ( count )    {	/*------------------------- IF THERE IS AN EFFECTIVE CARD  */       	g_mmcsd_num = count;                  /* ACQUIRE THE NUMBER  */       	//TRACE("Finish Init Card. %d Cards have beed detected\n",count);       	return MMCSD_OK;    }    else    {      /*--------------------- WHEN NO EFFECTIVE CARD IS IDENTIFIED */       	INFO("No Card is detected\n");       	return( MMCSD_NO_CARD );    }    return( ret );}/****************************************************************************** * Function Name: _MMCSD_InitCard * * Input:             * 		device:	 pointer to MMCSD_Dev structure. * * Value Returned:      * * 		MMCSD_STATUS * * Description:  * *	Check and aqquire CSD/CID register data * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/MMCSD_STATUS _MMCSD_GetInfo(MMCSD_Dev *device){    MMCSD_STATUS  ret;	u8   Csd_buff[20];                /* BUFFER FOR RECEIVING CSD           */	u8   Cid_buff[20];                /* BUFFER FOR RECEIVING CID           */	u32 port;	TRACE("Get Card Info\n");    ret = 0;	port = device->port;	_MMCSD_SetBlockLenReg(0x10,port);		// Why????    ret = _MMCSD_SendCSD( device->card_rca,Csd_buff,port); //CMD9    if (ret)    {		FAILED("_MMCSD_SendCSD() error with 0x%lx",(unsigned long)ret);		return ret;	}    else    {         ret = _MMCSD_CSDCheck(Csd_buff);         if ( ret )         {			FAILED("_MMCSD_CSDCheck error, ret=0x%lx",ret);			return ret;          }          else          {				_MMCSD_SetCSD(device,Csd_buff);          }    }    ret = _MMCSD_SendCID( device->card_rca,Cid_buff,port); //CMD10    if ( ret )    { 		FAILED("_MMCSD_SendCID() error with 0x%lx",(unsigned long)ret);        device->card_state = MMCSD_NOTREADY;    }    else    {         ret = _MMCSD_CIDCheck(Cid_buff);         if ( ret )         {			FAILED("_MMCSD_CIDCheck() error with 0x%lx",ret);			return ret;          }          else          {               	_MMCSD_SetCID(device, Cid_buff);           }	}    return( ret );}/****************************************************************************** * Function Name: _MMCSD_SetSectLen * * Input:               None. * * Value Returned:      * * 		MMCSD_STATUS * * Description:  * * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *      Why??? this function must be here, otherwise CRC-WRITE-ERROR while polling write. *****************************************************************************/MMCSD_STATUS _MMCSD_SetSectLen(MMCSD_Dev *device){    	u8   type;    	MMCSD_STATUS  ret;    /*----------------------------------------------------------------------*/    /*  INITIALIZE LOCAL VARIABLES                                          */    /*----------------------------------------------------------------------*/    	type     = 0;                         /* CMD TYPE = NO DATA TRANSFER    */    	ret      = 0;                                   /* SEND/RECEIVE ERROR   */          /*--------------------------------------------------------------*/          /*  CARD SELECT                                                 */          /*--------------------------------------------------------------*/                      ret = _MMCSD_SelectDeselectCard(device->card_rca,device->port);          if ( ret )          {              device->card_state = MMCSD_NOTREADY;	      return ret;          }/*          ret = _MMCSD_SetBlockLen(MMCSD_MINIMUM_BLK_SIZE,1); //          if ( ret )          {               device->card_state = MMCSD_NOTREADY;	       return ret;           }           device->blksize = MMCSD_MINIMUM_BLK_SIZE;*/           ret = _MMCSD_SelectDeselectCard(0,device->port);           if ( ret )	   	   {                device->card_state = MMCSD_NOTREADY;                return ret;           }            device->card_state = MMCSD_STANDBY;    return( ret );}/****************************************************************************** * Function Name: _MMCSD_GetStatus  * * Input:               None. * * Value Returned:      * * 		MMCSD_STATUS * * Description:  * * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/u32 _MMCSD_GetStatus(MMCSD_Dev *device){	u32 state;	MMCSD_STATUS ret=_MMCSD_SendStatus(device->card_rca,&state,device->port);    	ret&=MMCSD_STATUS_NOERROR|0xFFFF;

⌨️ 快捷键说明

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