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

📄 mmccmd.c

📁 How to control MMC interface under SZ platform
💻 C
📖 第 1 页 / 共 3 页
字号:
	
	if(ret)
		return ret;
		
	_MMCGetResponses(&rp,MMCB_R2);
	for(i=0;i<16;i++)
	{
		pBuff[i]=rp.CID[i];
	}
	
	return 0;
}

/******************************************************************************

 Function Name    : _MMCStopTransmission()

 Input Parameters : VOID
 
 Output Parameters: VOID

 Value returned   : int    0: Sucessful operation, others: meet Error

 Description      : CMD12:		Forces the card to stop transmission
 
 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
MMC_STATUS _MMCStopTransmission()
{
	MMC_RESPONSES rp;
	MMC_STATUS ret;
	
	ret=_MMCNoDataCommand(MMC_CMD12,0,MMCB_R1);
	
	if(ret)
		return ret;
	
	_MMCGetResponses(&rp,MMCB_R1);
	
	return rp.status&MMC_STATUS_NOERROR;

}
/******************************************************************************

 Function Name    : _MMCSendStatus(U32 addr,P_U32 pStatus)

 Input Parameters : U32 addr       relative address
 
 Output Parameters: VOID

 Value returned   : U32    Card Status

 Description      : CMD13	addressed card sends its status register

 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
U32 _MMCSendStatus(U32 addr,P_U32 pStatus)
{
	MMC_RESPONSES rp;
	MMC_STATUS ret;
	
	ret=_MMCNoDataCommand(MMC_CMD13,addr<<16,MMCB_R1);
	
	if(ret)
		return ret;
	
	_MMCGetResponses(&rp,MMCB_R1);
	
	*pStatus=rp.status;
	
	return rp.status&MMC_STATUS_NOERROR;

}
/******************************************************************************

 Function Name    : _MMCSendSCR()

 Input Parameters : VOID
  
 Output Parameters: VOID

 Value returned   : int    0: Sucessful operation, others: meet Error

 Description      : ACMD51  Read the SD Configuration Register(SCR)
 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
MMC_STATUS _SDSendStatus(P_U8 pBuff)
{
	MMC_RESPONSES rp;
	MMC_STATUS ret;
	int i=0;
	U16 status;
	P_U16 pbuff;
	pbuff=(P_U16)pBuff;
	
	while(_MMCIsRun())
		_MMCStopClk(); 
	
	_MMCSetCmd(MMC_CMD13,_gCardInfo.card_adr,MMCB_DATEN|MMCB_R1);
	
   
    *(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF;
	_gMMCIsIrpt=1;
	
	_MMCStartClk();
	
	while(_gMMCIsIrpt)i++; //wait for CMD_DONE interrupt
		
	TRACE("	CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i);												//TEST omit response CRC Error 
	ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT;           //Time Out Error  
	
	if(ret)
	{	_MMCStopClk();	
		return ret;
	}
	
	while((*((P_U16)MMCR_STATUS)&0x800)==0)
	{	//If Fifo is empty
		ret=(*((P_U16)MMCR_STATUS))&0x1;
		if(	ret )
			return ret;
	}
	
	for(i=0;i<MMC_BLOCK_SIZE/(sizeof(U16));i++)
	{	
						
		//If MMC meet Time-Out of Response or CRC Read Error. 
		if(	ret )
		{	
			TRACE("	Read SCR Time Out\n");
			break;
		}	
																	
		*pbuff=*((P_U16)(MMCR_BUFFER_ACCESS)); //data tranferring
		pbuff++;
	
	}
	
	_MMCStopClk();
	return ret;
}

/******************************************************************************

 Function Name    : _MMCSetBlockLen(U32 size)

 Input Parameters : U32 size       block size
 
 Output Parameters: VOID

 Value returned   : int    0: Sucessful operation, others: meet Error

 Description      : CMD16    sets the block length (in bytes) for all following 
 						  block commands(read and write). Default block length 
 						  is specified in the CSD.
 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
MMC_STATUS _MMCSetBlockLen(U32 size)
{
	MMC_RESPONSES rp;
	MMC_STATUS ret;
	
	_MMCSetBlockLenReg(size);
	_MMCSetNumberOfBlockReg(1);

	ret=_MMCNoDataCommand(MMC_CMD16,size,MMCB_R1);

	if(ret)
		return ret;
	
	_MMCGetResponses(&rp,MMCB_R1);

	
	return rp.status&MMC_STATUS_NOERROR;

}

/******************************************************************************

 Function Name    :MMC_STATUS _MMCReadBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 start_addr,U16 nsects, P_U8 buff );


 Input Parameters : U32  addr       address
 					P_U8 buff  		data buff
 
 Output Parameters: VOID

 Value returned   : int    0: Sucessful operation, others: meet Error

 Description      : CMD17  or CMD18    reads a block of the size selected by the Set_Block 
 							command
 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
MMC_STATUS _MMCReadBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 addr,U16 nsects, P_U8 buff )

{
	MMC_RESPONSES rp;
	MMC_STATUS ret;
	int i=0;
	U16 status;
	P_U16 pbuff;
	U8 cmd;
	U32 length;
	
	pbuff=(P_U16)buff;
	
	while(_MMCIsRun())
		_MMCStopClk(); 
		
	if(nsects==1)
		cmd=MMC_CMD17;
	else
		cmd=MMC_CMD18;
		
	_MMCSetNumberOfBlockReg(nsects);	
	
	if(pCurrentCardInfo->buswidth&SD_BUS_WIDTH4)
		_MMCSetCmd(cmd,addr,MMCB_BUSW|MMCB_DATEN|MMCB_R1);
	else
		_MMCSetCmd(cmd,addr,MMCB_DATEN|MMCB_R1);
	
    
   // *(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF;
    *(P_U16)MMCR_INT_MASK=0xF;
	_gMMCIsIrpt=1;
	
	*(P_U16)MMCR_STR_STP_CLK=0x06; //start clk
	
	//while(_gMMCIsIrpt)i++; //wait for CMD_DONE interrupt
	while(!((*(P_U16)MMCR_STATUS)&0x2000))i++;
	
	TRACE("	CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i);												//TEST omit response CRC Error 
	ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT;           //Time Out Error  

	
	if(ret)
	{	_MMCStopClk();	
		return ret;
	}
	
	/*because block size is always larger than FIFO Size, after command done,there are not anthor interrupt
	before start transfer. */
	_gMMCIsIrpt=1;
	*(P_U16)MMCR_INT_MASK=~MMC_DATA_TRANS_DONE;
	
	
	if(_gMMCDMAChannel!=0xFF) //Use DMA
	{
		// Start DMA
		_gMMCIsTransferDone=0;
		if(_DmaStartTransfer(_gMMCDMAChannel,((P_VOID)MMCR_BUFFER_ACCESS),buff,MMC_BLOCK_SIZE*nsects,DMA_IOTOMEM)
			==SYS_OK)
		{	ret=_MMCWaitDataTransDone(); //wait DMA tranferring over
			
			ret|= (*(P_U16)MMCR_STATUS)&0xF;
			_MMCStopClk();
			return ret;
		}
	}
		
	TRACE("Don't Use DMA Transfer Data\n");
	length=nsects*MMC_BLOCK_SIZE/sizeof(U16);
	for(i=0;i<length;i++)
	{	
		if(i>0&&((i&0xFF)==0)) //if(i>0 && i%256==0)
			_MMCStartClk();
		if((*((P_U16)MMCR_STATUS)&0x40)!=0)//If Fifo is empty
			while((*((P_U16)MMCR_STATUS)&0x80)==0) //wait for buff full
			{	
				ret=(*((P_U16)MMCR_STATUS))&0x1;
				if(	ret )
					break;
			}
		
		//If MMC meet Time-Out of Response or CRC Read Error. 
		if(	ret )
		{	
			TRACE("	Read Data Time Out\n");
			break;
		}	
																
		*pbuff=*((P_U16)(MMCR_BUFFER_ACCESS)); //data tranferring
		pbuff++;
	}	
	
	i=0;
	while(!((*(P_U16)MMCR_STATUS)&0x800))i++; //wait data transfer done
	
	ret|= (*(P_U16)MMCR_STATUS)&0xF;
	_MMCStopClk();
	return ret;


}
/******************************************************************************

 Function Name    : MMC_STATUS _MMCWriteBlock(P_MMC_CARD_INFO,U32 start_addr,U16 nsects, P_U8 buff );


 Input Parameters : U32  addr       address
 					P_U8 buff  		data buff
 
 Output Parameters: VOID

 Value returned   : int    0: Sucessful operation, others: meet Error

 Description      : CMD24 :   		Write a block of the size selected by the 
 							Set_Block command
 Cautions         : 
 
 Prev Condition   : VOID

 Post Condition   : VOID

******************************************************************************/
MMC_STATUS _MMCWriteBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 addr,U16 nsects, P_U8 buff )
{
	MMC_RESPONSES rp;
	int i=0;
	U16 status;
	U8 cmd;
	U32 length;
	
	MMC_STATUS ret;
	
	if(nsects==1)
		cmd=MMC_CMD24;
	else
		cmd=MMC_CMD25;
		
	while(_MMCIsRun())
		_MMCStopClk(); 
		
	_MMCSetNumberOfBlockReg(nsects);	
	
	if(pCurrentCardInfo->buswidth&SD_BUS_WIDTH4)
		_MMCSetCmd(cmd,addr,MMCB_BUSW|MMCB_DATEN|MMCB_R1|MMCB_WRRD);//bus width is 4 only for SD Card
	else		
		_MMCSetCmd(cmd,addr,MMCB_DATEN|MMCB_R1|MMCB_WRRD);
    
    //*(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF; //set irpt mask register, only for CMD DONE
	*(P_U16)MMCR_INT_MASK=0xF;
	
	
	*(P_U16)MMCR_STR_STP_CLK=0x06; //start clk
		
	while(!((*(P_U16)MMCR_STATUS)&0x2000))i++;
		
	TRACE("	CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i);//TEST omit response CRC Error 
	ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT;           //Time Out Error  

	
	if(ret)
	{	_MMCStopClk();	
		return ret;
	}
	
	/*because block size is always larger than FIFO Size, after command done,there are not anthor interrupt
	before start transfer. */
	_gMMCIsIrpt=1;
	*(P_U16)MMCR_INT_MASK=~MMC_DATA_TRANS_DONE;
	
	if(_gMMCDMAChannel!=0xFF) //Use DMA
	{	//Start DMA
		_gMMCIsTransferDone=0;
		if(_DmaStartTransfer(_gMMCDMAChannel,buff,(P_VOID)MMCR_BUFFER_ACCESS,MMC_BLOCK_SIZE*nsects,DMA_MEMTOIO)
		   ==SYS_OK);
		{	ret=_MMCWaitDataTransDone(); //wait DMA data tranferring over
			
			ret|= (*(P_U16)MMCR_STATUS)&0x4;
			_MMCStopClk();
			return ret;
		}
	}
	
	//don't use DMA
	TRACE("Don't use DMA Transfer Data\n");
	length=nsects*MMC_BLOCK_SIZE/sizeof(U16);
	for(i=0;i<length;i++)
	{	
		//if(i>0&&((i&0xFF)==0)) //if(i>0 && i%256==0)
			//_MMCStartClk();
	
			//if FIFO full 
		if(((*(P_U16)MMCR_STATUS)&0x80)!=0)
			while(((*(P_U16)MMCR_STATUS)&0x40)==0); //wait till FIFO empty
																
		*(P_U16)MMCR_BUFFER_ACCESS=*((P_U16)buff+i); //data tranferring
	}
	
	i=0;
	while(!((*(P_U16)MMCR_STATUS)&0x800))i++; //wait data transfer done
	i=0;

⌨️ 快捷键说明

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