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

📄 sdmmc.c

📁 SD卡的其本操作函数
💻 C
📖 第 1 页 / 共 3 页
字号:
	
			XBYTE[REG_DMASIZE7_0] = 0xff;//REG_DMASIZE7_0 = 0xB302
			XBYTE[REG_DMASIZE10_8] = 0x01;//actual size = DMAsize+1;//REG_DMASIZE10_8 = 0xB303
	
			XBYTE[REG_DMA_STATE] = 0x09;//REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] = 0x08;//Set Inernal buffer 4 Byte,and Reset DMA
	
			XBYTE[REG_DMACMP] = 0x00;	//clear DMA interrupt//REG_DMACMP = 0xB3C0
		   	XBYTE[REG_DMASTART] = 0x01;	//Start DMA from Bank1 To SD//REG_DMASTART = 0xB3B0
	
			tdw_WriteSectorNumber--;

			if(tdw_WriteSectorNumber == 0)
			{
				if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank1 To SD
				{
					gc_ReadWriteTimeOut = 1;
					tc_WriteError = 1;
				}
				break;
			}
	
			XBYTE[REG_BULK_EN0] = 0x02;//start USB to Bank0;//REG_BULK_EN0 = 0xB5A1
		}while(1);
	
		XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xdd;//clear Bank0 Bulkout ACK//REG_BULK_ACK = 0xB5C2
			
		XBYTE[REG_BULKOUTAUTO] = 0x00;  //disable usb auto //REG_BULKOUTAUTO = 0xB511
			
		if(tc_WriteError)
		{
			XBYTE[0xB519] = 0x00;  //512B  (default)      

			//Clean Bulk IN/OUT Buffer pointer and Data linker setting
			XBYTE[0xb5E9] = 0xff;
			XBYTE[0xb5EA] = 0xff;
			XBYTE[0xb5A0] &= 0xfc;  
			XBYTE[0xb5A1] = 0x02;
			XBYTE[0xb5A2] = 0x00;
			
			XBYTE[0xB5eb] = K_USB_CLASS_OUT_ACK_MASK;//0x01;
			gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;   //lizhn add for fail
			while (XBYTE[0xB5ee] == 0)
			{
				if(gw_WaitTimeOut == 0)
				{
					XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
					gc_ReadWriteTimeOut = 1;//Set timeout flag
					break;
				}
				gw_WaitTimeOut--;	
			}		
			XBYTE[0xB5e8] = K_USB_CLASS_OUT_STALL; //OUT STALL
		}
	}
	// CMD12
	tc_ComBuff[0] = 0x4C;
	tc_ComBuff[1] = 0;
	tc_ComBuff[2] = 0;
	tc_ComBuff[3] = 0;
	tc_ComBuff[4] = 0;
	CommandToSd(tc_ComBuff);
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	
	//检查传送命令是否成功
	if((tc_Ture)||(tc_RespBuff[0]!=0x0C))
	{
		gc_ReadWriteTimeOut = 1;
	   	return 1;
	}
	//等待not busy信号
	gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
	do{								            
		SdTxDummy();
		tc_Ture=SDCheckDat0();
		if(gw_WaitTimeOut == 0)
		{
			XBYTE[0xB450] = 0x03;
			gc_ReadWriteTimeOut = 1;
			return 0xff;
		}
		gw_WaitTimeOut--;
	 } while(tc_Ture == 0); 

	SdTxDummy();     
	SDWaitIdle();
	return tc_WriteError;
}


U8 SD_Read_LogicSector(U32 tdw_LogicSectorAddr,U32 tdw_ReadSectorNumber)
{
	U8 	tc_ComBuff[5],tc_RespBuff[17];
	U8 	tc_Ture;
	U16	TmpAddr;
	U8 tc_ReadError;
	U8 tc_FirstEnterLoopFlag;
	U8 	tc_ET0;
	tc_ReadError = 0;

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

	// CMD18
	tc_ComBuff[0] = 0x52;
	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) >> 0;
	
	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]!=0x12))
	{
		gc_ReadWriteTimeOut = 1;
	   	return 1;
	}
	if(gc_ReadWriteDataArea < 2)//if MCU Read SD
	{
		while(tdw_ReadSectorNumber)//
		{
			//设置DMA送数据的方向为 sd to sramm    
			if(gc_ReadWriteDataArea == 0)
			{
				TmpAddr = &gc_PlayRecordDataBuf;
			}
			else
			{
				TmpAddr = &gc_UserDataBuf;
			}
	
			XBYTE[REG_DMA_STATE] |= 0x01; //REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] &= 0xfe; //reset DMA
			
			XBYTE[REG_DMA_SEL]  = 0x02;//set the DMA from Flash memory to Sram
			XBYTE[REG_SRAMDMADSTIDX7_0] = (unsigned char)(TmpAddr & 0xff);//set DMA Sram Address //REG_SRAMDMADSTIDX7_0 = 0xB114
			XBYTE[REG_SRAMDMADSTIDX15_8] = (unsigned char)((TmpAddr>>8) & 0xff);//REG_SRAMDMADSTIDX15_8 = 0xB115

			XBYTE[REG_DMASIZE7_0] = 0xFF;//set dma size //REG_DMASIZE7_0 = 0xB302
			XBYTE[REG_DMASIZE10_8] = 0x01;//the transfer number is the size + 1 //REG_DMASIZE10_8 = 0xB303

			XBYTE[REG_DMACMP] = 0;////clear DMA interrupt //REG_DMACMP = 0xB3C0
	
			XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] = 0x08;//set four bytes internal buffer and reset DMA
			
			XBYTE[REG_DMASTART] = 0x01;//start DMA //REG_DMASTART = 0xB3B0
	
			if(UsbReadWaitSD(K_READ_CARD))//wait Read DMA Over
			{
				tc_ReadError = 1;
				gc_ReadWriteTimeOut = 1;
				break;
			}

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

		tc_FirstEnterLoopFlag = 1;
	

		XBYTE[REG_BINLASTEN]=0x00;//Set Not auto turn on BulkIn when DMA over

		XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xee; //clear transfer ack //REG_BULK_ACK = 0xB5C2
		
		XBYTE[REG_BULK_BUF_CLR] = 0x11;//clear Bulk in Buffer //REG_BULK_BUF_CLR = 0xB5E9
		XBYTE[REG_BULKINAUTO] = 0x1;//Set Bulkin Auto //REG_BULKINAUTO = 0xB510
	
		XBYTE[REG_DMA_STATE] |= 0x01; //REG_DMA_STATE = 0xB304
		XBYTE[REG_DMA_STATE] &= 0xfe; //reset DMA
	
		XBYTE[REG_DMA_SEL]  = 0x02;//Set DMA from FM to Sram // REG_DMA_SEL = 0xB301
	
		XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK0_LOW_ADDR;
		XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK0_HIGH_ADDR;//set Sram Address for DMA(USB Bank0)

		XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size low Byte //REG_DMASIZE7_0 = 0xB302
		XBYTE[REG_DMASIZE10_8] = 0x01;//dma size high Byte //REG_DMASIZE10_8 = 0xB303

		XBYTE[REG_DMACMP] = 0x00;////clear DMA interrupt //REG_DMACMP = 0xB3C0
	
		XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
		XBYTE[REG_DMA_STATE] = 0x08;//sent four Bytes internal buffer and Reset DMA
	
		XBYTE[REG_DMASTART] = 0x01;//start DMA(SD Card -> Bank0) // REG_DMASTART = 0xB3B0
		
		do{
			if(!tc_FirstEnterLoopFlag)//If It is not the first time enter the transfering loop,
			{							//there will be useful data in Bank1 to be transfered
				if(UsbReadWaitBank1USB(K_READ_CARD))//wait Bank1 to USB
				{
					tc_ReadError = 1;
					gc_ReadWriteTimeOut = 1;
					break;
				}
			}
	
			tc_FirstEnterLoopFlag = 0;
			if(UsbReadWaitSD(K_READ_CARD))//wait SD to Bank0 DMA
			{
				tc_ReadError = 1;
				gc_ReadWriteTimeOut = 1;
				break;
		}
		tdw_ReadSectorNumber--;
	
			XBYTE[REG_USBBANK0WRIDX7_0] = 0x00;//REG_USBBANK0WRIDX7_0 = 0xB515
			XBYTE[REG_USBBANK0WRIDX11_8] = 0x02; //REG_USBBANK0WRIDX11_8 = 0xB516
			//set how many bytes will transfer to USB while command mode
			XBYTE[REG_BULK_EN0] = 0x1;//Trigger Bank0 To USB DMA //REG_BULK_EN0 = 0xB5A1
	
			if(tdw_ReadSectorNumber == 0)
			{
				break;
			}
			XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK1_LOW_ADDR; //REG_SRAMDMADSTIDX7_0 = 0xB114
			XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK1_HIGH_ADDR;//REG_SRAMDMADSTIDX15_8 = 0xB115
	
			//set Sram address for DMA (USB Bank1)
			XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size//REG_DMASIZE7_0 = 0xB302
			XBYTE[REG_DMASIZE10_8] = 0x01;//REG_DMASIZE10_8 = 0xB303
	
			XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] = 0x08;//set internal buffer four bytes ,and reset DMA
	
			XBYTE[REG_DMASTART] = 0x01;//Start DMA from SD ->Bank1 //REG_DMASTART = 0xB3B0
			
			if(UsbReadWaitSD(K_READ_CARD))//wait SD to Bank1
			{
				tc_ReadError = 1;
				gc_ReadWriteTimeOut =1;
				break;
			}

			tdw_ReadSectorNumber-- ;
			
			XBYTE[REG_USBBANK1WRIDX7_0] = 0x00;  //REG_USBBANK1WRIDX7_0 = 0xB517
			XBYTE[REG_USBBANK1WRIDX11_8] = 0x02; //REG_USBBANK1WRIDX11_8 = 0xB518
			//set how many bytes will transfer to USB while command mode
	
			XBYTE[REG_BULK_EN1] = 0x01;//启动Bank1 To USB //REG_BULK_EN1 = 0xB5A2
	
			if(tdw_ReadSectorNumber == 0)
			{//判断是否读完
				if(UsbReadWaitBank1USB(K_READ_CARD))
				{
					tc_ReadError = 1;
					gc_ReadWriteTimeOut = 1;
				}
				break;
			}
			XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK0_LOW_ADDR;//REG_SRAMDMADSTIDX7_0 = 0xB114;
			XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK0_HIGH_ADDR;//set sram address for DMA(USB Bank0)//REG_SRAMDMADSTIDX15_8 = 0xB115

			XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size //REG_DMASIZE7_0 = 0xB302
			XBYTE[REG_DMASIZE10_8] = 0x01;//设置传输字节数 //REG_DMASIZE10_8 = 0xB303
	
			XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
			XBYTE[REG_DMA_STATE] = 0x08; //set internal buffer 4 bytes,and reset DMA
	
			XBYTE[0xB3B0] = 0x01;//start SD To Bank0;
	
		}while(1);
	
		//clear bulk in transaction ACK.
		XBYTE[REG_BULKINAUTO] =0x00;//disable Bulk in auto // REG_BULKINAUTO = 0xB510
		XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xee; //clear usb ACK //REG_BULK_ACK = 0xB5C2

		if(tc_ReadError) //Read Error
		{
			//Clean Bulk IN/OUT Buffer pointer and Data linker setting
			XBYTE[0xb5E9] = 0xff;
			XBYTE[0xb5EA] = 0xff;
			XBYTE[0xb5A0] &= 0xfc;  
			XBYTE[0xb5A1] = 0x02;
			XBYTE[0xb5A2] = 0x00;

			XBYTE[0xB5eb] = K_USB_CLASS_IN_ACK_MASK;//0x01;
			gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;   //lizhn add for fail
			while (XBYTE[0xB5ee] == 0)
			{
				if(gw_WaitTimeOut == 0)
				{
					XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
					gc_ReadWriteTimeOut = 1;//Set timeout flag
					break;								
				}
				gw_WaitTimeOut--;				
			}
	
			XBYTE[0xB5e8] = K_USB_CLASS_IN_STALL;//IN STALL	//
		}
	}
	//TX "CMD12" to stop read Multi block data 
	tc_ComBuff[0] = 0x4C;
	tc_ComBuff[1] = 0;
	tc_ComBuff[2] = 0;
	tc_ComBuff[3] = 0;
	tc_ComBuff[4] = 0;
	CommandToSd(tc_ComBuff);
	tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
	//检查传送命令是否成功
	if((tc_Ture)||(tc_RespBuff[0]!=0x0C))
	{
		gc_ReadWriteTimeOut = 1;
	   	return 1;
	}
	SdTxDummy();
	SDWaitIdle();
	return tc_ReadError;
}


U8 SD_STORAGE_Initialize(void)
{
	U8 tc_InitSts = 1;

	gc_SectorUnit=1;

	if (!gc_SysCardInsert)
	{//if have card insert
		if (!SD_SetInterface(CURRENT_MEDIA_SD))
		{			
			gc_CurrentCard = CURRENT_MEDIA_SD;
			gc_CurrentExistMedia |= 0x40;
 			tc_InitSts = 0;
		}
		else if (!SD_SetInterface(CURRENT_MEDIA_MMC))
		{
			gc_CurrentCard = CURRENT_MEDIA_MMC;
			gc_CurrentExistMedia |= 0x40;
			tc_InitSts = 0;
		}
	}		
	if (tc_InitSts == 0)
	{
		tc_InitSts = SD_Initializes(gc_CurrentCard);
	}

	if(tc_InitSts == 0)
	{
		tc_InitSts = DOS_Initialize();
	}
	else
	{
		tc_InitSts = 0xff;          //dos error
	}
	
	gc_DOS_Status = tc_InitSts;//record DOS status
	gc_ReadWriteTimeOut = 0;
	return tc_InitSts;	
}


U8 UsbReadWaitSD(U8 tc_ReadOrWrite)
{
	gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
	while(XBYTE[REG_DMACMP]==0)//wait DMA complete //REG_DMACMP = 0xB3C0
	{
		if(gw_WaitTimeOut == 0)
		{
			XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
			gc_ReadWriteTimeOut = 1;//Set timeout flag
			return 0xff;
		}
		gw_WaitTimeOut--;
	}
	XBYTE[REG_DMACMP] = 0x00;	//clear DMA interrupt //REG_DMACMP = 0xB3C0

	if(tc_ReadOrWrite)//if Read SD Card,Only Check the CRC
	{
		if(!XBYTE[REG_CRC16COR]) //REG_CRC16COR = 0xB46F;
		{//检查CRC16是否正确
			gc_ReadWriteTimeOut = 1;
			return 1;	
		}
		XBYTE[REG_SRAMDMADSTIDX15_8] = 0xff;//When DMA Over,must Set this Register 0xff to release the SRAM Buffer
	}else{//if write sd card

		U8 tc_Ture;
		XBYTE[REG_SD_TRIGGER] = 0x10;//trigger CRC 
		if(((XBYTE[REG_SD_STATE1])&0x70)!=0x20)//check crc Right or Error 
		{
			gc_ReadWriteTimeOut = 1;
			return 1;
		}		
		//wait Card to idle
		gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
		do{
			SdTxDummy();
			tc_Ture=SDCheckDat0();//
			if(gw_WaitTimeOut == 0)
			{
				XBYTE[REG_SDRST] = 0x03; //reset sd interface //REG_SDRST = 0xB450
				gc_ReadWriteTimeOut = 1;//set time out flag
				return 0xff;
			}
			gw_WaitTimeOut--;
		} while(tc_Ture == 0);
		XBYTE[REG_SRAMDMASRCIDX15_8] = 0xff;//When DMA Over,must Set this Register 0xff to release the SRAM Buffer
	}
	SDWaitIdle();//wait sd interface to idle

	return 0;
}


U8 UsbReadWaitBank1USB(U8 tc_ReadOrWrite)
{
	gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
	if(tc_ReadOrWrite)//if read
	{
		while(XBYTE[REG_BULK_EN1])//wait Bulk in over
		{//REG_BULK_EN1 = 0xB5A2
			if(gw_WaitTimeOut == 0)
			{
				XBYTE[REG_SDRST] = 0x03;//reset sd interface //REG_SDRST = 0xB450
				gc_ReadWriteTimeOut = 1;
				return 0xff;
			}
			gw_WaitTimeOut--;
		}
	}
	else
	{
		while(XBYTE[REG_BULK_EN1])
		{//REG_BULK_ACK = 0x25c2
			if(gw_WaitTimeOut == 0)
			{
				XBYTE[REG_SDRST] = 0x03;//reset sd interface //REG_SDRST = 0xB450
				gc_ReadWriteTimeOut = 1;
				return 0xff;
			}
			gw_WaitTimeOut--;
		};  //wait pc ack
		XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xdf;//Clear ACK ;REG_BULK_ACK = 0x25c2
	}
	return 0;
}

⌨️ 快捷键说明

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