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

📄 mmc_main.c

📁 给予mx21处理器的嵌入式系统的mmc卡驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if(counter == 0)	{		ret = MMCSD_ERROR;		FAILED("TIME OUT..");		goto dma_write_end;	}	/*******************************************************	 * Write Done	 *******************************************************/	if(ret==MMCSD_OK)	{		counter = 0xFFFF;		while(counter--)		{			if(device->port == 1)				g_mmcsd_status = mmcsdr_status_2;			else					g_mmcsd_status = mmcsdr_status;			TRACE("g_mmcsd_status is 0x%0lX (for Write-DONE)",(unsigned long)g_mmcsd_status);			if(g_mmcsd_status&0x0004)			{				TRACE("8)ERROR!");				ret = MMCSD_ERROR;				break;			}			else if((g_mmcsd_status&0x1000)!=0)			{				ret = MMCSD_OK;				break;			}			mmcsd_delay(0xFFFF);		}		if(counter==0)		{			ret = MMCSD_ERROR;			FAILED("Time Out for Write-DONE.");			goto dma_write_end;					}	}dma_write_end:	g_mmcsd_cmd[device->port] = 0;	if((ret == MMCSD_OK)&&(device->cur_num>1))	{		MMCSD_Responses rp;//		TRACE("CMD12 -- Last Block.");		ret2=_MMCSD_NoDataCommand(MMCSD_CMD12,0,MMCSDB_R1,device->port);		_MMCSD_GetResponses(&rp,MMCSDB_R1,device->port);	}//	INFO("Check Status.....(after cmd12)");	state =MMCSD_TRANSFER;	mmcsd_check_status(device,&state);	if(int_mask != 0xFFFFFFFF)	{//		TRACE("Enable Interrupt.");		_MMCSD_Restore_Mask(int_mask,device->port);	}	mmcsd_free_buffer(device);//	TRACE("15)return with ret = %lx,ret2 = %lx",ret,ret2);	return(ret|ret2);}void mmcsd_free_buffer(MMCSD_Dev *device){		device->cur_num = 0;	device->addr = 0;}/****************************************************************************** * Function Name: mmcsd_sector_erase * * Input:	 * 		device: the related device * 		blks:	the blocks that will be erased. * * Value Returned:  * 		0:	success. * 		1:	failure. * * Description:  * 	this routine will erase indicated group.	 * * Modification History: * 	30 DEC,2001, Initial version.  			Yiwei Zhao  *****************************************************************************/static int mmcsd_sector_erase(MMCSD_Dev *device, MMCSD_Blks *blks) {	int ret;	u32 state;	TRACE("Erase the sector  %ld ", (long int)(blks->start));	/********************************************************************	 * Lock the device. 	 *******************************************************************/#ifndef MMCSD_TEST	down_interruptible(&(device->sema));	g_selected_lock[device->port].device = device;#endif	/********************************************************************	 * Identify the Card State ( Process only for Stand By State)	 *******************************************************************/	state =MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);	if(ret)	{		FAILED(" Check Status failed.");		goto sector_erase_ret;	}	/********************************************************************	 * Erase 	 *******************************************************************/	ret = _MMCSD_TagSectorStart(blks->start);	if(ret)	{		TRACE("TagSectorStart error");		goto sector_erase_ret;	}	//ret = _MMCSD_TagSectorEnd(blks->start);	ret = _MMCSD_TagSectorEnd(blks->start+device->phy_sectorsize-1);	if(ret)	{		TRACE("TagSectorEnd error");		goto sector_erase_ret;	}	ret = _MMCSD_Erase();	if(ret)	{		TRACE("Erase error");		goto sector_erase_ret;	}sector_erase_ret:	/********************************************************************	 * Unlock the selected device structure. 	 *******************************************************************/	state =MMCSD_TRANSFER;	mmcsd_check_status(device,&state);#ifndef MMCSD_TEST	up(&(device->sema));#endif	return ret;}/****************************************************************************** * Function Name: mmcsd_ReadBlock * * Input:               None. * * Value Returned:      * * 		MMCSD_STATUS * * Description:  * * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/MMCSD_STATUS mmcsd_ReadBlock(MMCSD_Dev *device,u32 start_addr,u16 nsects, u8 *buff ){	u16  i;    u32  read_addr;    MMCSD_STATUS ret;	u8	*cur_buf;    /************************************************************************    *  Initialize local variables                                              *************************************************************************/    ret = read_addr = 0;                            /* SEND/RECEIVE ERROR   */    for ( i = 0 ; i < nsects ; i++ )    {    	/************************************************************       	*  Set the first address of read sector        	**************************************************************/       	read_addr = ( start_addr + (MMCSD_MINIMUM_BLK_SIZE*i) );    	/************************************************************       	*  Create cmd                                    	**************************************************************/		cur_buf = buff+(MMCSD_MINIMUM_BLK_SIZE*i);#ifdef MMCSD_READ_DMA        	ret=mmcsd_DMA_ReadSingleBlock(device,read_addr, cur_buf); 		if(ret==MMCSD_OK)	// Only for DMA		{			// Endian processing#ifdef MMCSD_DMA_ENDIAN_ERR			_mmcsd_16_big_2_little(cur_buf,MMCSD_MINIMUM_BLK_SIZE);#endif		}#else        ret=mmcsd_ReadSingleBlock(device,read_addr, cur_buf); #endif        if (ret)        {        	break;        }    }    return( ret );}/****************************************************************************** * Function Name: mmcsd_ReadSingleBlock * * Input:               None. * * Value Returned:      * * 	MMCSD_STATUS * * Description:  * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/MMCSD_STATUS mmcsd_DMA_ReadSingleBlock(MMCSD_Dev *device,u32 addr,u8 * buff){	MMCSD_STATUS ret;	u32 channel,status,int_mask,state;	int timeleft;	device->result = MMCSD_OK;	channel = device->dma_channel;	ret = mmcsd_DmaStartTransfer( device,				      buff,				      MMCSD_MINIMUM_BLK_SIZE,				      MMCSD_READ,				      device->bit_width);	if(ret != MMCSD_OK)	{		FAILED("mmcsd_DmaStartTransfer failed !");		return ret;	}	state = MMCSD_TRANSFER;	ret = mmcsd_check_status(device,&state);		_MMCSD_Mask_interrupt(0x7F,&int_mask,device->port);	_MMCSD_StopClk(device->port);		if(device->bit_width)	{		_MMCSD_SetCmd(MMCSD_CMD17,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1,device->port);	// Read Single BLK	}	else	{		_MMCSD_SetCmd(MMCSD_CMD17,addr,MMCSDB_DATEN|MMCSDB_R1,device->port);	// Read Single BLK	}	g_mmcsd_cmd[device->port] = MMCSD_CMD17;		_MMCSD_StartClk(device->port);	if((ret=_MMCSD_WaitUntil(MMCSD_CMD_DONE,device->port))!=0)	{		FAILED("WaitCMDDone ret 0x%lx",(unsigned long)ret);		goto dma_read_end;	}	TRACE("Enable DMA..");#ifdef CONFIG_ARCH_MX1ADS	enable_dma(channel);#endif#ifdef CONFIG_ARCH_MX2ADS	mx_dma_start(channel);#endif	timeleft = interruptible_sleep_on_timeout(&(device->select_wait),100);	if(!timeleft)	{		TRACE("read failed, Timeout!");		ret = MMCSD_ERROR;		goto dma_read_end;	}	status = device->result; 	TRACE("waked up! status = %x", status);	if(status&0x800)	{		ret = MMCSD_OK;		goto dma_read_end;	}	else if(status&0x3)	{		TRACE("g_mmcsd_status 0x%lx",(unsigned long)status);		ret = MMCSD_ERROR;		goto dma_read_end;	}	// in fact, although status&0x800 ==0, read succeed.dma_read_end:#ifdef CONFIG_ARCH_MX1ADS	disable_dma(channel);#endif	#ifdef CONFIG_ARCH_MX2ADS	//disable dma	_reg_DMA_CCR(channel) &= 0xFFFFFFFE;#endif	_MMCSD_Restore_Mask(int_mask,device->port);	g_mmcsd_cmd[device->port] = 0;	return ret;}MMCSD_STATUS mmcsd_ReadSingleBlock(MMCSD_Dev *device,u32 addr,u8 * buff){	MMCSD_STATUS ret;	u32 temp32,j,int_mask,total;	u16 temp16; 	u8 *pbuff;	int i;	pbuff=buff;	_MMCSD_Mask_interrupt(0x7F,&int_mask,device->port);	total = 0;	_MMCSD_StopClk(device->port); 	//Ricky		if(device->bit_width)	{		_MMCSD_SetCmd(MMCSD_CMD17,addr,MMCSD_BUS_4BIT|MMCSDB_DATEN|MMCSDB_R1,device->port);	// Read Single BLK	}	else	{		_MMCSD_SetCmd(MMCSD_CMD17,addr,MMCSDB_DATEN|MMCSDB_R1,device->port);	// Read Single BLK	}	g_mmcsd_cmd[device->port] = MMCSD_CMD17;	_MMCSD_StartClk(device->port);	while(1)	{		if(device->port == 1)			g_mmcsd_status = (mmcsdr_status_2);		else			g_mmcsd_status = (mmcsdr_status);		if((g_mmcsd_status&0x088B) == 0) 		{			continue;		}				j = 0xFF;		while(j--);		if(g_mmcsd_status&0x000B)		{			FAILED("Read Error (status = 0x%lx",(unsigned long)g_mmcsd_status);			ret = MMCSD_ERROR;			goto signle_read_end;		}/*		if(g_mmcsd_status&0x0008)		{			goto single_read_try_again;		}*/		if((g_mmcsd_status&0x0080)!=0)		// Buffer is FULL 		{			//TRACE("FIFO is full");			if(device->bit_width == 0)					{				for(i = 0;i < 8; i++)				{					if(device->port == 1)						temp32 = mmcsdr_buffer_access_2;					else						temp32 = mmcsdr_buffer_access;											temp16 = (u16)temp32;#ifdef MMCSD_DMA_ENDIAN_ERR					*pbuff = (temp16&0xFF00)>>8;					pbuff++;					*pbuff = (temp16&0x00FF);					pbuff++;#else					*pbuff = (temp16&0x00FF);					pbuff++;					*pbuff = (temp16&0xFF00)>>8;					pbuff++;				#endif				}				total += 16;			}			else			{				for(i = 0;i < 32; i++)				{					if(device->port == 1)						temp32 = mmcsdr_buffer_access_2;					else						temp32 = mmcsdr_buffer_access;					temp16 = (u16)temp32;#ifdef MMCSD_DMA_ENDIAN_ERR					*pbuff = (temp16&0xFF00)>>8;					pbuff++;					*pbuff = (temp16&0x00FF);					pbuff++;#else					*pbuff = (temp16&0x00FF);					pbuff++;					*pbuff = (temp16&0xFF00)>>8;					pbuff++;#endif				}				total += 64;			}		}		if((g_mmcsd_status&0x0800) != 0)	// TRANS Done		{			//TRACE("Transfer done! g_mmcsd_status = 0x%x",g_mmcsd_status);			ret = MMCSD_OK;			goto signle_read_end;					}//		TRACE("Sleep on.. status=%x",g_mmcsd_status);//		interruptible_sleep_on(&(device->select_wait));//		TRACE("Waked up ! status = 0x%x",g_mmcsd_status);//	}signle_read_end:	_MMCSD_StopClk(device->port);	//Karen need more consideration how to implement this!!!!!!!!!!!!!!!!	_MMCSD_Restore_Mask(int_mask,device->port);//Karen need more consideration how to implement this!!!!!!!!!!!!!!!!	g_mmcsd_cmd[device->port] = 0;	return ret;}/****************************************************************************** * Function Name: mmcsd_DmaStartTransfer * * Input:    * * Value Returned:      * * Description:  * 	 * * Modification History: *      30 DEC,2001, Initial version.                   Yiwei Zhao  *****************************************************************************/int mmcsd_DmaStartTransfer(MMCSD_Dev *device,u8 * buff,u32 counter, u8 mode,u8 is_4_bit){	int channel;	channel = device->dma_channel;	if(mode == MMCSD_READ)	{#ifdef CONFIG_ARCH_MX1ADS		_reg_DMA_DAR(channel) = (u32)__virt_to_phys(buff);		_reg_DMA_SAR(channel) = (MMCSDR_BUFFER_ACCESS&0x0FFFFFFF);		_reg_DMA_CNTR(channel) = counter; 		_reg_DMA_CCR(channel) = 0x00000828;	// Source Size = 16,Des Len = 32 		_reg_DMA_RSSR(channel) = 0xD;		if(is_4_bit)		{			_reg_DMA_BLR(channel) = 0x0;			// Burst Len 64;			//_reg_DMA_BLR(channel) = 0x20;			// Burst Len 32;		}		else		{			_reg_DMA_BLR(channel) = 0x10;			// Burst Len 16;		}#endif#ifdef CONFIG_ARCH_MX2ADS		(device->dma).sourceType = DMA_TYPE_FIFO;		(device->dma).sourcePort = DMA_MEM_SIZE_16;		(device->dma).destType = DMA_TYPE_LINEAR;		(device->dma).destAddr = (u32)__virt_to_phys(buff);		(device->dma).destPort = DMA_MEM_SIZE_32;		(device->dma).count = counter;		if(device->port == 0)		{			(device->dma).sourceAddr = 0x10013038;//sdhc1, 			(device->dma).request = 0x7;//sdhc1 				}		else		{			(device->dma).sourceAddr = 0x10014038;// for sdhc2 is 0x10014038			(device->dma).request = 0x6;// sdhc2 is 0x6;				}				if(is_4_bit)		{			(device->dma).burstLength = 0x0; //burst length 64		}		else		{			(device->dma).burstLength = 0x10; //burst len 16		}		mx_dma_set_config(device->dma_channel,&(device->dma));//		mx_dump_dma_register(device->dma_channel);#endif	}	else 	{#ifdef CONFIG_ARCH_MX1ADS	//	_reg_DMA_SAR(channel) = (u32)_MMCSD_get_phy_addr(buff);		_reg_DMA_SAR(channel) = (u32)__virt_to_phys(buff);		_reg_DMA_DAR(channel) = (MMCSDR_BUFFER_ACCESS&0x0FFFFFFF);		_reg_DMA_CNTR(channel) = counter; 		//_reg_DMA_CCR(channel) = 0x00002088;	// Source Size = 32,Des Len = 16 		_reg_DMA_CCR(channel) = 0x2088;	// Source Size = 32,Des Len = 16 		_reg_DMA_RSSR(channel) = 0xD;		if(is_4_bit)		{			_reg_DMA_BLR(channel) = 0x0;		// Burst Len 64;			//_reg_DMA_BLR(channel) = 0x20;		// Burst Len 32;		}		else		{			_reg_DMA_BLR(channel) = 0x10;		// Burst Len 16;		//	_reg_DMA_BLR(channel) = 0x8;		// Burst Len 8;		}#endif#ifdef CONFIG_ARCH_MX2ADS		(device->dma).sourceType = DMA_TYPE_LINEAR;		(device->dma).sourceAddr = (u32)__virt_to_phys(buff);		(device->dma).sourcePort = DMA_MEM_SIZE_32;		(device->dma).destType = DMA_TYPE_FIFO;		(device->dma).destPort = DMA_MEM_SIZE_16;				(device->dma).count = counter;

⌨️ 快捷键说明

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