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

📄 sd_driver.c

📁 文件包含了开发motorola mc9s12uf32单片机一些源码。  1、USB device 实现  2、CF卡读取  3、SD卡读取  4、ATA硬盘读取
💻 C
📖 第 1 页 / 共 2 页
字号:

		while(!(gSD_SDSATAT&0x0400)) ;					// wait for cmd end
		kSD_OCR_H = SD_SDRSP;
		kSD_OCR_M = SD_SDRSP;
		kSD_OCR_L = SD_SDRSP;
		kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
		kSD_OCR_M = ( kSD_OCR_M << 8);
		kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
		kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
		gSD_SDSATAT=0;		
	  kSD_OCR &= 0x00FF8000;			 // check the OCR range is within 2.7v~3.6V	
		if(kSD_OCR)				// response not 0, means the card has response. Must be a MMC card
		  goto InitMMCLoop;

InitLoop:

		//-------------------
		// card initializtion
		SD_SendCommand(0x0037, 0x0000, 0x0000, 0x0001);		// cmd55

		while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
//		SD_CheckResponse();		// to checking ACMD response to identify whether the plugged card is SD or MMC
				
		SD_SendCommand(0x0029, 0x00FF, 0x8000, 0x0003);		// cmd41, OCR

		UTL_Delay(6);
		while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
		kSD_OCR_H = SD_SDRSP;
		kSD_OCR_M = SD_SDRSP;
		kSD_OCR_L = SD_SDRSP;
		kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
		kSD_OCR_M = ( kSD_OCR_M << 8);
		kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
		kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
		gSD_SDSATAT=0;		

		for(i=0; i<70; i++)	
			asm NOP;					// delay 900us for next card init
		if((kSD_loop_counter == 10000) && (kSD_OCR == 0))
			goto InitMMCLoop;//			return(1);					// SD identification error

		else if((!(kSD_OCR & 0x80000000)) && (kSD_loop_counter<100000) )
		{
			kSD_loop_counter++;
			goto InitLoop;
		}

		else if( (kSD_OCR & 0x80000000) && (kSD_loop_counter<100000) )
			gSD_SDcard = 1;				// plugged flash card is SD
						
		goto EndInitLoop;
	
InitMMCLoop:
			SD_SendCommand(0x0001, 0x80FF, 0x8000, 0x0003);	// CMD1 SEND_OP_COND, for MMC initializtion
			while(!(gSD_SDSATAT&0x0400)) ;								// wait for cmd end
			kSD_OCR_H = SD_SDRSP;
			kSD_OCR_M = SD_SDRSP;
			kSD_OCR_L = SD_SDRSP;
			kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
			kSD_OCR_M = ( kSD_OCR_M << 8);
			kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
			kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
			gSD_SDSATAT=0;		

			for(i=0; i<70; i++)	
				asm NOP;			
	
			if((!(kSD_OCR & 0x80000000)) && (kSD_loop_counter<4000) )
			{
				kSD_loop_counter++;
				goto InitMMCLoop;
			}
			else if(kSD_loop_counter == 4000)
				return(1);					// SD identification error
			
			if( (kSD_OCR & 0x80000000) && (kSD_loop_counter<4000) )
				gSD_SDcard = 0;				// plugged flash card is MMC
				
EndInitLoop:	
			return(0);	
}

// ==================================================================
//   SD_Init() -
//
//   Step 3, to initialize the flash card
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//  
//	Returned value list:
//						0: no error
//						1: An error happened while SD_AllSendCID
//						2: An error happened while SD_AllSendRCA
//						3: An error happened while SD_SendCSD
//						4: An error happened while SD_SelectSDcard
//						5: An error happened while SD_SetBlockLength
//						6: An error happened while SD_SetBusWidth
//
// ==================================================================
muint8	SD_Init(void)
{	
//	muint8	kSD_ReturnedValue;

	
	SD_AllSendCID();
	
	SD_AllSendRCA();		
	
	SD_SendCSD();
			
	SD_SelectSDcard((muint16)(gSD_RCA));
		
	SD_SetBlockLength(0x0200);				// set block length to 512 bytes


//	if(!gSD_SDcard)							// MMC card plugged
//		SD_SetBusWidth(0x01);				// 1 bit mode
//	else 
		if (gSD_SDcard)
			SD_SetBusWidth(0x04);				// SD card plugged, force to 4-bits mode

	SD_SDCLKCON = 0x000a;		// card clk enable, 1/2, 6MHz
	UTL_Delay(1);
		
	return(0);
}


// ==================================================================
//   SD_AllSendCID() -
//
//   Ask the card to send out it's CID (Card Identification)
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//	Returned value list:
//						0: no error
//						1: An error happened while SD_AllSendCID
//
// ==================================================================
void	SD_AllSendCID(void)
{
	muint16	i;

	gSD_SDSATAT=0;		
	SD_SDBLKLN = 0x0200;					// set block length to 512 bytes
	SD_SendCommand(0x0002, 0x0000, 0x0000, 0x0002);		
	while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
	
	for(i=0;i<8;i++)
		gSD_CID[i] = SD_SDRSP;
	gSD_SDSATAT=0;		

	for(i=0; i<100; i++)	
		asm NOP;							// delay 1ms for next card init		
	

}



// ==================================================================
//   SD_AllSendRCA() -
//
//   Ask the card to send out it's RCA (Card Relative Address)
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
//	Returned value list:
//						0: no error
//						1: An error happened while SD_AllSendRCA
//
// ==================================================================
void	SD_AllSendRCA(void)
{
	muint16	i;
	muint16 kSD_RCA_H, kSD_RCA_M, kSD_RCA_L;	
	
	gSD_SDSATAT=0;		
	//-----------------
	// all send RCA
	if(gSD_SDcard)
	{
		SD_SendCommand(0x0003, 0x0000, 0x0000, 0x0001);	

		while(!(gSD_SDSATAT&0x0400)) ;				// wait for cmd end
		kSD_RCA_H = SD_SDRSP;
		kSD_RCA_M = SD_SDRSP;
		kSD_RCA_L = SD_SDRSP;	
		gSD_SDSATAT=0;	
		kSD_RCA_H = (kSD_RCA_H & 0x00ff);			// RCA[31:16]
		kSD_RCA_M = ( kSD_RCA_M & 0xff00);
		gSD_RCA =( (kSD_RCA_H << 8) | (kSD_RCA_M >> 8));	
	}			
	else
	{
		gSD_RCA = 0x0102;			// for MMC card
		SD_SendCommand(0x0003, gSD_RCA, 0x0000, 0x0001);		// RCA=0xaaaa for MMC card

		while(!(gSD_SDSATAT&0x0400)) ;				// wait for cmd end
	}

	for(i=0; i<100; i++)	
		asm NOP;			// delay 1ms for next card init	
		
}


// ==================================================================
//   SD_SendCSD() -
//
//   Ask the card to send out it's CSD (Card Specific Data)
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
//	Returned value list:
//						0: no error
//						1: An error happened while SD_SendCSD
//
// ==================================================================
void	SD_SendCSD(void)
{
	muint16	i;

	gSD_SDSATAT=0;		
	SD_SendCommand(0x0009, (muint16)gSD_RCA, 0x0000, 0x0002);	// CMD9 SEND_CSD
	while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
	
	for(i=0; i<8; i++)
		gSD_CSD[i] = SD_SDRSP;
	for(i=0; i<100; i++)	
		asm NOP;			// delay 1ms for next card init				

//	gSD_MaxBlockNumber = ( ((gSD_CSD[3] & 0x3FF) << 2) | ( (gSD_CSD[4] & 0xC000) >> 14) ) * pow(2, ( (gSD_CSD[5] & 0x7000) >> 12 )+2 );
//	gSD_Capacity = (muint32)gSD_MaxBlockNumber * 0.5;

//	for(i=0; i<7; i++)
//		kSD_Temp |=	gSD_CSD[i];
//		
//	if(kSD_Temp == 0)
//		return(1);
//	else
//		return(0);			// no error
		
}


// ==================================================================
//   SD_SelectSDcard() -
//
//   Select the card
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//	Returned value list:
//						0: no error, the card is ready
//						1: the card is not ready
//
// ==================================================================
void	SD_SelectSDcard(muint16 kSD_RCA)
{
	muint16	i;
//	muint32 kSD_Temp;
	
	gSD_SDSATAT=0;		
	SD_SendCommand(0x0007, kSD_RCA, 0x0000, 0x0001);	// 0xbb0b: Toshiba SD card

	UTL_Delay(6);

	while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
	
	SD_SDBLKLN = 0x0200;		// set block length to 512 bytes
	SD_SDNOBLK = 2;				// test, Number of block in block mode transmission					

	for(i=0; i<100; i++)	
		asm NOP;			// delay 1ms for next card init		
//		
//	kSD_Temp =SD_CheckResponse();
//	if((kSD_Temp & 0x0100) == 0x0100)	// bit8=1 means the card is ready
//		return(0);			// no error
//	else
//		return(1);			// not ready
	
}



// ==================================================================
//   SD_SetBlockLength() -
//
//   Set block length fixed to 512 bytes
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
//	Returned value list:
//						0: no error, the card is ready
//						1: the card is not ready
//
// ==================================================================
void	SD_SetBlockLength(muint16 SD_BlockLength)
{
	muint16	i;
	
	gSD_SDSATAT=0;		
	SD_SendCommand(0x0010, 0x0000, SD_BlockLength, 0x0001);	

	while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
	for(i=0; i<100; i++)	
		asm NOP;			// delay 1ms for next card init	

//	kSD_Temp =SD_CheckResponse();
//	if((kSD_Temp & 0x0100) == 0x0100)	// bit8=1 means the card is ready
//		return(0);			// no error
//	else
//		return(1);			// not ready	
	
}



// ==================================================================
//   SD_SetBusWidth() -
//
//   Set bus width to 1 or 4 bits mode
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
//	Returned value list:
//						0: no error, the card is ready
//						1: the card is not ready
//
// ==================================================================
void	SD_SetBusWidth(muint16 SD_BusWidth)
{
	muint16	i;

	gSD_SDSATAT=0;		
	if(gSD_SDcard)
	{
		SD_SendCommand(0x0037, (muint16)gSD_RCA, 0x0000, 0x0001);	// cmd55, RCA, stuff bits
		UTL_Delay(6);

		while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
		if(SD_BusWidth == 1)
			SD_SendCommand(0x0006, 0x0000, 0x0000, 0x0001);		// cmd6 SET_BUS_WIDTH, [31:2]stuff bits, [1:0] bus width, 00=1bit, 0x200=1bit

		else
			SD_SendCommand(0x0006, 0x0000, 0x0002, 0x0201);		// 4 bits

		while(!(gSD_SDSATAT&0x0400)) ;			// wait for cmd end
		
		UTL_Delay(6);
		for(i=0; i<100; i++)	
			asm NOP;			// delay 1ms for next card init	

//		kSD_Temp =SD_CheckResponse();
//
//	if((kSD_Temp & 0x0100) == 0x0100)	// bit8=1 means the card is ready
//		return(0);			// no error
//	else
//		return(1);			// not ready
	
	}
	
}



// ==================================================================
//   SD_CheckStatus() -
//
//     Check the response from SD card
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
//	Returned value list:
//			0: RDY
//			1: Not RDY
//
// ==================================================================
muint8	SD_CheckStatus(void)
{	
	muint32 kSD_ResponseCheck;
	muint16	i;

	gSD_SDSATAT=0;		
	SD_SendCommand(0x000d, gSD_RCA, 0x0000, 0x0001);	// CMD13 SEND_STATUS,

	while(!(gSD_SDSATAT&0x0400)) ;								// wait for cmd end

	kSD_ResponseCheck = SD_CheckResponse();

	for(i=0; i<100; i++)	
		asm NOP;			// delay 1ms for next card init	
	if( (kSD_ResponseCheck&0x0100)==0x0100 )			// bit8=1=RDY
		return(1);	// the card is ready

	else
		return(0);	// the card is not ready
}


// ==================================================================
//   SD_CheckResponse() -
//
//     Check the response from SD card
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
muint32	SD_CheckResponse(void)
{
	muint32 kSD_Resp;
	muint8 	*cptr;

	cptr=(muint8*)&kSD_Resp;
	*cptr++=0;
	*cptr++ = (muint8)SD_SDRSP;
	*cptr++ = (muint8)SD_SDRSP; 
	*cptr++ = (muint8)SD_SDRSP;
	
	return(kSD_Resp);
}


// ==================================================================
//   SD_SendCommand() -
//
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
void	SD_SendCommand(muint16 SD_CMDNo, muint16 SD_argh, muint16 SD_argl, muint16 SD_RespNo)
{
//	muint16 i;

	SD_SDCMDNO 		= SD_CMDNo;		
	SD_SDARGH 		= SD_argh;			
	SD_SDARGL 		= SD_argl;	
	SD_SDCMDATCON = SD_RespNo;		

	while (!(gSD_SDSATAT &  0x0400));
}


// ==================================================================
//   SD_LBACommand1() -
//
//     To set command to SM device
//
//	Input -		=	3 command parameters
//				
//	Output - 	=	
//
//	Function returns error code
//
// ==================================================================
muint8 SD_LBACommand1(muint8 Block, muint8 *pLBA, muint8 QueBuffer)
{
	muint32				*lptr;
	volatile muint32 SD_LBA;
	muint16 status;

	lptr=(muint32*)pLBA;	
	gSD_LBA=*lptr;
	
	gSD_DSCR_B = Block;
	
	mClearBit(QnEN,QC1CR);				// disable QC1
	QC1REQ	= 0xff;						// remap QC1 to mon-existing resources
	QC2REQ	= 0xff;						// remap QC1 to mon-existing resources
	mSetBit(DBRST,QC34DCR);				// reset QC34
	mSetBit(QnPRST, QC3CR);				// reset QC3

	SD_LBA=gSD_LBA;
		    
	IQUECR = (1<<CH34DBE)+(1<<IQUEEN);	// Enable double buffer
    QC34DTR = 0;							// Enable force handshake
	mClearBit(SBTE,QC34DCR);				// clear single buffer mode

    QC3CR=0x17;							// Q1SML = 0, large buffer 16-bit transfer
    QC3SZB=0x10+QueBuffer<<1;			// 512 bytes block, starting from $x000+QueBuffer
    QC3REQ=0x08;						// SD Rx channel		
 	
  	status = SD_QUE_ReadMultipleBlock(SD_LBA, gSD_DSCR_B);		  

	IQUECR = (1<<CH34DBE)+(1<<IQUEEN);	// Enable double buffer
	QC34DTR = (1<<DTHE)+(1<<DRHE);		// Enable force handshake
  	QC3CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);	
	QC3SZB = 0x12;						// 2 block 0f 256 bytes (HS), base 0x2000
	QC3REQ = 0x01;						// Channel 3 set to USB TX
 	
 	QC1CR  = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
	QC1SZB = 0x10;						// 2 block of 256 bytes (HS)	  
	QC1REQ = 0x00;						// Channel 1 set to USB RX

	return(0);	
}


//
// The end of file sd_driver.c 
// *********************************************************************************

⌨️ 快捷键说明

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