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

📄 sdmmc.c

📁 SD卡的其本操作函数
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	XBYTE[REG_CMDBUF1] = ComBuff[0];
	XBYTE[REG_CMDBUF2] = ComBuff[1];
	XBYTE[REG_CMDBUF3] = ComBuff[2];
	XBYTE[REG_CMDBUF4] = ComBuff[3];
	XBYTE[REG_CMDBUF5] = ComBuff[4];
	// trigger to TX command 转换命令
	XBYTE[REG_SD_TRIGGER] = C_bit_TxCmd;	//0x01;  
	{
		U16 tw_TimeOut;

		tw_TimeOut = K_CARD_TIMEOUTSECONDS;
		
		while ((XBYTE[REG_SD_STATE1] & 0x0F) != 0x00)
		{
			tw_TimeOut --;
			
			if (gc_SysCardInsert)
     		{//if CD pin is HIGH,the C 	 
		 		tw_TimeOut = 0;
     		}

			if (!tw_TimeOut)
			{
				XBYTE[0xB450] = 0x03;//reset SD interface
				gc_ReadWriteTimeOut = 1;
				break; 
			} 
  		}
  	} 
}


void SdTxDummy(void) //USING_0
{	
	U8 i;
	XBYTE[REG_SD_TRIGGER] = 0x20;      
	for(i=0;i<10;i++);
}


void SDWaitIdle(void) //USING_0
{
	{
		U16 tw_TimeOut;
		
		tw_TimeOut = K_CARD_TIMEOUTSECONDS;

		while ((XBYTE[REG_SD_STATE1] & 0x0F) != 0x00)	//wait the card into idle 
		{

			tw_TimeOut --;
			
			if (gc_SysCardInsert)
     		{
		 		tw_TimeOut = 0;
     		}

			if (!tw_TimeOut)
			{
				XBYTE[0xB450] = 0x03;//reset SD interface
				gc_ReadWriteTimeOut = 1;
				break; 
			} 
		
  		}
  	}
}


U8 SDCheckDat0(void)
{
	//data0 is high, not busy state
	if(XBYTE[REG_SD_STATE0]&0x20)
	{
	 	return 1;	 	
	}
	return 0;	
}


U8 SD_SetBusWidth(U8 tc_BusMode)
{
	U8 tc_ComBuff[5],tc_RespBuff[17];
	U8 tc_Ture;
//	SD_SetClock(0);
	if(tc_BusMode==C_1BITBUS)
	{
		XBYTE[REG_SD_TIMER]&=0xfb;   
	}
	//four data bus 
	else
	{		 
		XBYTE[REG_SD_TIMER]|=0x04;   	
	}
	//发送CMD55命令和ACMD42命令
	tc_ComBuff[0] =	0x77;
	tc_ComBuff[1] =	gc_SD_RCA[0];
	tc_ComBuff[2] =	gc_SD_RCA[1];
	tc_ComBuff[3] =	0x00;
	tc_ComBuff[4] =	0x00;
	CommandToSd(tc_ComBuff); 
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	
	// check the response number
	if((tc_Ture)||(tc_RespBuff[0]!=0x37))
	{
		//error happen
	   	return 0x01;	   
	}
	//发送ACMD42命令
	tc_ComBuff[0] =	0x6A;
	tc_ComBuff[1] =	0x00;
	tc_ComBuff[2] =	0x00;
	tc_ComBuff[3] =	0x00;
	
	// TX "ACMD42" to connect the pull-up resistor on line 'data3'
	if(tc_BusMode==C_1BITBUS)
	{
		tc_ComBuff[4] =	0x01;                                
	}
	// TX "ACMD42" to disconnect the pull-up resistor on line 'data3'
	else
	{ 
		tc_ComBuff[4] =	0x00;                                 
	}
	CommandToSd(tc_ComBuff);  
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	
	// check the response number
	if((tc_Ture)||(tc_RespBuff[0]!=0x2a))
	{
		//error happen
	  	 return 0x01;	                       	             
	}		 

	//发送CMD55命令和ACMD6命令
	tc_ComBuff[0] =	0x77;
	tc_ComBuff[1] =	gc_SD_RCA[0];
	tc_ComBuff[2] =	gc_SD_RCA[1];
	tc_ComBuff[3] =	0x00;
	tc_ComBuff[4] =	0x00;
	CommandToSd(tc_ComBuff); 
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	
	// check the response number
	if((tc_Ture)||(tc_RespBuff[0]!=0x37))
	{
		//error happen	
	   	return 0x01;	                       	             
	}
	//发送ACMD6命令
	tc_ComBuff[0] =	0x46;
	tc_ComBuff[1] =	0x00;
	tc_ComBuff[2] =	0x00;
	tc_ComBuff[3] =	0x00;
	if(tc_BusMode==0)
	{
		//设置bus的宽度为1bit
	   	tc_ComBuff[4] = 0x00;
	}
	else
	{
		//设置bus的宽度为4bit
	   	tc_ComBuff[4] = 0x02;
	}
	CommandToSd(tc_ComBuff);  
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	
	// check the response number
	if((tc_Ture)||(tc_RespBuff[0]!=0x06))
	{
	   	return 0x01;	                       	           
	}				 
	return 0x00;
}


U8 SD_Initializes(U8 tc_CurrCard)
{
	if(SD_SetInterface(tc_CurrCard))
	{ 
		return 0;
	}

	SdDetect();	

	//将SD卡的状态由standy-by改为transfer状态
	if(SD_StandByToTrans())
	{
		return	1;
	}
	
	//如果当前卡是SD卡
	if(tc_CurrCard==CURRENT_MEDIA_SD)
	{
		if(SD_SetBusWidth(C_4BITBUS))
		{
			return	1;	
		}
	}
	SD_SetClock(1);	//set SD interface clock is 12MHz

	return	0;
}


U8 SD_StandByToTrans(void)
{
	U8 tc_ComBuff[5],tc_RespBuff[17];
	U8 tc_Ture;

	// CMD13
	tc_ComBuff[0] =	0x4D;
	tc_ComBuff[1] =	gc_SD_RCA[0];
	tc_ComBuff[2] =	gc_SD_RCA[1];
	tc_ComBuff[3] =	0x00;
	tc_ComBuff[4] =	0x00;
	CommandToSd(tc_ComBuff);
    tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
    	
	if((tc_Ture)||(tc_RespBuff[0]!=0x0d))
	{
	   return 0x01;	
	}
	
	if((tc_RespBuff[3] &0x1e)==C_State_Stby)
	{	
		// CMD7
		tc_ComBuff[0] =	0x47;
		tc_ComBuff[1] =	gc_SD_RCA[0];
		tc_ComBuff[2] =	gc_SD_RCA[1];
		tc_ComBuff[3] =	0x00;
		tc_ComBuff[4] =	0x00;
		CommandToSd(tc_ComBuff);  
		tc_Ture=SDToRespond(tc_RespBuff,0,1);
		
		if((tc_Ture)||(tc_RespBuff[0]!=0x07))
		{		 
		   return 0x01;
		}
	}
	else
	{
		//是否已经处于transfer状态
		if((tc_RespBuff[3] &0x1e)!= C_State_Tran)
		{ 
			return 0x01;
		}
	}

	//发送"CMD13"得到卡的状态,检查卡的状态是否转化为transfer状态
	tc_ComBuff[0] =	0x4D;
	tc_ComBuff[1] =	gc_SD_RCA[0];
	tc_ComBuff[2] =	gc_SD_RCA[1];
	tc_ComBuff[3] =	0x00;
	tc_ComBuff[4] =	0x00;
	CommandToSd(tc_ComBuff);  
	tc_Ture=SDToRespond(tc_RespBuff,0,1);
	
	//检查回应是否出错
	if((tc_Ture)||(tc_RespBuff[0]!=0x0d))
	{
	   return 0x01;
	}
	
	//检查卡的状态是否为transfer状态
	if((tc_RespBuff[3] &0x1e)!= C_State_Tran)
	{	
		return 0x01;
	}
	return 0x00;		
}	


void SD_SetBlockLen(U16 BlockSize)
{
	//ECC mode bytes/page
	XBYTE[REG_ECCMODE] = 0x01;
	XBYTE[REG_DATALEN7_0] = (U8)(BlockSize);
    XBYTE[REG_DATALEN9_8] = (U8)(BlockSize>>8);	
}	



bit STORAGE_Detect()
{ 
	U8 tc_BattValue;

 	tc_BattValue=USER_READSAR(1);
	if(tc_BattValue<0x50)
	{
		// SD exist
		gc_SysCardInsert = 0;
		return 0;	
	}
	gc_SysCardInsert = 1;
	
	return	1;	 	
}


U8 SD_Write_LogicSector(U32 tdw_LogicSectorAddr,U32 tdw_WriteSectorNumber)
{
	U8 	tc_ComBuff[5],tc_RespBuff[17];
	U8 	tc_Ture;
	U16	TmpAddr;
	U8 tc_WriteError;
	U8 tc_FirstEnterLoopFlag;
	U8 tc_ET0;
	tc_WriteError = 0;

	if(SDHC==0)
	{
		tdw_LogicSectorAddr=tdw_LogicSectorAddr<<9;
	}

	// CMD25
	tc_ComBuff[0] = 0x59;
	tc_ComBuff[1] = (tdw_LogicSectorAddr & 0xFF000000) >> 24;
	tc_ComBuff[2] = (tdw_LogicSectorAddr & 0x00FF0000) >> 16;
	tc_ComBuff[3] = (tdw_LogicSectorAddr & 0x0000FF00) >> 8;
	tc_ComBuff[4] = (tdw_LogicSectorAddr & 0x000000FF);

	tc_ET0 = ET0;
	ET0 = 0;//必须关闭中断,否则会影响数据读写
	CommandToSd(tc_ComBuff);
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	ET0 = tc_ET0;//必须打开中断

	if((tc_Ture)||(tc_RespBuff[0]!=0x19))
	{
		gc_ReadWriteTimeOut = 1;
	   	return 1;
	}

	if(gc_ReadWriteDataArea < 2)
	{
		while(tdw_WriteSectorNumber)
		{
			if(gc_ReadWriteDataArea == 0)
			{
				TmpAddr = &gc_PlayRecordDataBuf;
			}
			else
			{
				TmpAddr = &gc_UserDataBuf;
			}

			SdTxDummy();          //lizhn
			SDWaitIdle();         //lizhn
	        XBYTE[0xB304] |= 0x01; //Reset DMA
			XBYTE[0xB304] &= 0xfe; //this bit will not auto clear by HW, so must clear it by firmwire
			XBYTE[0xB301]  = 0x20;//set the DMA Direction from Sram to Flash Memory
	
			XBYTE[0xB112]  =(unsigned char)(TmpAddr & 0xff);//set DMA scr Address
			XBYTE[0xB113] =(unsigned char)((TmpAddr>>8) & 0xff); 

			XBYTE[0xB3C0] = 0x00;	//clear DMA interrupt
			
			XBYTE[0xB302] = 0xff;//(UCHAR)nByte;
			XBYTE[0xB303] = 0x01;//(UCHAR)(nByte>>8);//actual size = DMAsize+1;注意是字节数减一;
				
			XBYTE[0xB304] = 0x09;
			XBYTE[0xB304] = 0x08;//set internal buffer is four byte and reset the DMA

		   	XBYTE[0xB3B0] = 0x01;	//start DMA	
			
			if(UsbReadWaitSD(K_WRITE_CARD))
		{
				tc_WriteError = 1;
				gc_ReadWriteTimeOut = 1;
				break;
		}

			tdw_WriteSectorNumber-- ;
		}
	}
	else
	{
		XBYTE[REG_SRAMDMASRCIDX15_8] = 0xff;
		XBYTE[REG_SRAMDMADSTIDX15_8] = 0xff;

		tc_FirstEnterLoopFlag = 1;

		XBYTE[REG_BULKOUTACKCTR] = 0x00;//set got Bulkout ACK when USB Device acceptd 512 byte
		XBYTE[REG_BULKOUTAUTO]=0x01;//set bulk auto //REG_BULKOUTAUTO = 0xB511
	    XBYTE[REG_BULK_BUF_CLR]=0x22; //REG_BULK_BUF_CLR = 0xB5E9 
		XBYTE[REG_DMA_STATE] |= 0x01; //Reset DMA //REG_DMA_STATE = 0xB304
		XBYTE[REG_DMA_STATE] &= 0xfe; //该位不能硬件清除,所以必须将其清掉,不然DMA不能正常传输
	
		XBYTE[REG_DMA_SEL]  = 0x20;//Set DMA transfer from Sram to FM //REG_DMA_SEL = 0xB301
	
		XBYTE[REG_BULK_EN0] = 0x02;// star DMA from USB to Bank0 //REG_BULK_EN0 = 0xB5A1
	
		do{
				if(!tc_FirstEnterLoopFlag)
				{
					if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank1 To SD Card;
					{
						tc_WriteError = 1;
						gc_ReadWriteTimeOut = 1;
						break;
					}
				}  //wait pc ack
				SdTxDummy();          //lizhn
				SDWaitIdle();         //lizhn	
				tc_FirstEnterLoopFlag = 0;	

			XBYTE[REG_SRAMDMASRCIDX7_0] = K_USB_BANK0_LOW_ADDR;//set DMA transfer Size //REG_SRAMDMASRCIDX7_0 = 0xB112
			XBYTE[REG_SRAMDMASRCIDX15_8] = K_USB_BANK0_HIGH_ADDR;//actual size = DMAsize+1;//REG_SRAMDMASRCIDX15_8 = 0xB113
	
			XBYTE[REG_DMASIZE7_0] = 0xff; // REG_DMASIZE7_0 = 0xB302
			XBYTE[REG_DMASIZE10_8] = 0x01; //REG_DMASIZE10_8 = 0xB303//set DMA Size
	
			XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] = 0x08;//set Inernal buffer four bytes,and reset DMA
	
			XBYTE[REG_DMACMP] = 0x00;	//clear DMA interrupt //REG_DMACMP = 0xB3C0
	
		   	XBYTE[REG_DMASTART] = 0x01;//start DMA from Bank0 to SD Card //REG_DMASTART = 0xB3B0
	
			tdw_WriteSectorNumber -- ;

			if(tdw_WriteSectorNumber == 0)
			{
				if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank0 To SD Card
				{
					tc_WriteError = 1;
					gc_ReadWriteTimeOut = 1;
				}	
				break;
  			}
	
			XBYTE[REG_BULK_EN1] = 0x02;//start DMA from USB to Bank1;//REG_BULK_EN1 = 0xB5A2
	
			if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank0 to SD Card
			{
				tc_WriteError = 1;
				gc_ReadWriteTimeOut = 1;
				break;
			}
			SdTxDummy();          //lizhn
			SDWaitIdle();         //lizhn		
			if(UsbReadWaitBank1USB(K_WRITE_CARD))//wait USB to Bank1
			{
				tc_WriteError = 1;
				gc_ReadWriteTimeOut = 1;
				break;
			}
			XBYTE[REG_SRAMDMASRCIDX7_0] = K_USB_BANK1_LOW_ADDR;//REG_SRAMDMASRCIDX7_0 = 0xB112
			XBYTE[REG_SRAMDMASRCIDX15_8] = K_USB_BANK1_HIGH_ADDR; //REG_SRAMDMASRCIDX15_8 = 0xB113

⌨️ 快捷键说明

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