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

📄 sd_driver.c

📁 文件包含了开发motorola mc9s12uf32单片机一些源码。  1、USB device 实现  2、CF卡读取  3、SD卡读取  4、ATA硬盘读取
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*                                                  
*  (c) copyright Freescale Semiconductor Hong Kong Ltd 2004
*  ALL RIGHTS RESERVED
*                                                                       
*******************************************************************************  
** THIS  CODE IS ONLY INTENDED AS AN EXAMPLE FOR DEMONSTRATING THE FREESCALE **
** MICROCONTROLLERS.  IT  HAS ONLY BEEN GIVEN A MIMIMUM LEVEL OF TEST. IT IS **
** PROVIDED  'AS  SEEN'  WITH  NO  GUARANTEES  AND  NO  PROMISE  OF SUPPORT. **
*******************************************************************************  
*                                                                           
* FILE:        sd_driver.c	 REVISION 0.1
*  
* DESCRIPTION: This module handles the major part of SD Driver module,
*              (APIs & Functions) applicaton tasks for the system
*
* NOTES:       All modules remain at their reset addresses
*                                                  
* UPDATED HISTORY:
*
* REV   YYYY.MM.DD  AUTHOR        DESCRIPTION OF CHANGE
* ---   ----------  ------        --------------------- 
* 0.0   2004.03.01  Taine Chang   Initial version
* 0.1   2004.04.12  Derek Lau
*                   Kenny Lam     Demo version
*
******************************************************************************/                                                                        
/* Freescale  is  not  obligated  to  provide  any  support, upgrades or new */
/* releases  of  the Software. Freescale may make changes to the Software at */
/* any time, without any obligation to notify or provide updated versions of */
/* the  Software  to you. Freescale expressly disclaims any warranty for the */
/* Software.  The  Software is provided as is, without warranty of any kind, */
/* either  express  or  implied,  including, without limitation, the implied */
/* warranties  of  merchantability,  fitness  for  a  particular purpose, or */
/* non-infringement.  You  assume  the entire risk arising out of the use or */
/* performance of the Software, or any systems you design using the software */
/* (if  any).  Nothing  may  be construed as a warranty or representation by */
/* Freescale  that  the  Software  or  any derivative work developed with or */
/* incorporating  the  Software  will  be  free  from  infringement  of  the */
/* intellectual property rights of third parties. In no event will Freescale */
/* be  liable,  whether in contract, tort, or otherwise, for any incidental, */
/* special,  indirect, consequential or punitive damages, including, but not */
/* limited  to,  damages  for  any loss of use, loss of time, inconvenience, */
/* commercial loss, or lost profits, savings, or revenues to the full extent */
/* such  may be disclaimed by law. The Software is not fault tolerant and is */
/* not  designed,  manufactured  or  intended by Freescale for incorporation */
/* into  products intended for use or resale in on-line control equipment in */
/* hazardous, dangerous to life or potentially life-threatening environments */
/* requiring  fail-safe  performance,  such  as  in the operation of nuclear */
/* facilities,  aircraft  navigation  or  communication systems, air traffic */
/* control,  direct  life  support machines or weapons systems, in which the */
/* failure  of  products  could  lead  directly to death, personal injury or */
/* severe  physical  or  environmental  damage  (High  Risk Activities). You */
/* specifically  represent and warrant that you will not use the Software or */
/* any  derivative  work of the Software for High Risk Activities.           */
/* Freescale  and the Freescale logos are registered trademarks of Freescale */
/* Semiconductor Inc.                                                        */ 
/*****************************************************************************/

#include	"FreescaleDef.h"			// Get my definitions (Constants & Macros)
#include	"mk_extern.h"		// Get Mini-Kernel global prototypes
#include	"sd_includes.h"	// Get ATA Driver Configuration
#include	"usbms_includes.h"	// Get ATA Driver Configuration
#include	"sd_extern.h"
#include	"UF32reg.h"
#include	"utl_includes.h"
// code is placed in the main code area.
#pragma CODE_SEG	DEFAULT
// ==================================================================
//   SD_QUE_ReadMultipleBlock() -
//
//     Read single block from SD card
//
//	Input -		32-bits block addres (byte)
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
mErrorCode SD_QUE_ReadMultipleBlock(muint32 SD_BlockAddress, muint16 SD_NoOfBlocks)
{
	muint16 SD_BlockAdrs_H, SD_BlockAdrs_L,/* j,*/ k, kSD_NoOfBlocksCounter;
	muint16 kSD_Temp;
//	mint16 *kSD_RxData1;
	muint32 i;
	
	gSD_SDSATAT=0;		
	for(i=0; i<SD_TimeOut; i++)
	{
		kSD_Temp = SD_CheckStatus();
		if(kSD_Temp == 1)				// device is ready
			break;
	}
	if((i==SD_TimeOut) && (kSD_Temp == 0) )
		return(2);
	SD_SDINTREN = 0x001c;	// disable CD int
	SD_SDBLKLN = 0x0200;		// set block length to 512 bytes
	SD_SDNOBLK = SD_NoOfBlocks;				// Number of blocks
	kSD_NoOfBlocksCounter = 0;
	SD_BlockAddress *= 512;
	SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
	SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);

	k=0;	
	if(!gSD_SDcard)
	   	SD_SendCommand(0x0012, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0425);	//CMD18 READ_MULTIPLE_BLOCK, data adrs	

	else
	   	SD_SendCommand(0x0012, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0625);	//CMD18 READ_MULTIPLE_BLOCK, data adrs, WBUS

	i = 0;
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		i++;
		if(i==SD_TimeOut) 
			return(2);
	}
    SD_QIEN = 1;	

//	while (QCDCT34);

	i = 0;
	while(!(gSD_SDSATAT&0x0100))		// wait for DTDN=1
	{
		i++;
		if(i==SD_TimeOut) 
			return(2);
	}


	gSD_SDSATAT=0;		
	k=0;
	SD_SendCommand(0x000C, 0, 0, 0x0061);	//CMD12, STOP_TRANSMISSION,

	i = 0;
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		i++;
		if(i==SD_TimeOut) 
			return(2);
	}


    SD_QIEN=0;		

			   
	return(kSDNoError);
}

// ==================================================================
//   SD_QUE_ReadSingleBlock() -
//
//     Read single block from SD card via QUE
//
//	Input -		32-bits block addres (byte)
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
mErrorCode	SD_QUE_ReadSingleBlock(muint32 SD_BlockAddress)
{
	muint16 SD_BlockAdrs_H, SD_BlockAdrs_L;
//	muint32  i,
	muint32	 k=0;

	gSD_SDSATAT=0;		
	SD_BlockAddress *=512;
	SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
	SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
	if(gSD_SDcard)							// Plugged flash card is SD
	   	SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0205);	//CMD17 READ_SINGLE_BLOCK, data adrs, WBUS for SD card	
	else
	   	SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0005);	//CMD17 READ_SINGLE_BLOCK, data adrs, 1-bit mode for MMC	
   	
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		k++;
		if(k>100000)
			return(1);
	}
	SD_SDINTREN = 0x001c;					// disable CD int
    SD_QIEN=1;	
	k=0;
	while(!(gSD_SDSATAT&0x0100)) 			// wait for DTDN=1
	{
		k++;
		if(k>100000)
			return(2);
	}	
    SD_QIEN=0;	

	return(0);
 
}

//   SD_QUE_ReadSingleBlock() -
//
//     Read single block from SD card via QUE
//
//	Input -		32-bits block addres (byte)
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
mErrorCode	SD_QUE_ReadSingleBlock_FS(muint32 SD_BlockAddress)
{
	muint16 SD_BlockAdrs_H, SD_BlockAdrs_L;
//	muint32  i,
	muint32	 k=0;

	gSD_SDSATAT=0;		
    // QUE initialization for  SD Rx                           
    IQUECR = (1<<CH34DBE)+(1<<IQUEEN);	// Enable double buffer
    mSetBit(QnPRST, QC3CR);					// reset QC3
    QC3CR=0x1f;	//0x1d;								//
    QC3SZB=0x3f;
    QC3REQ=0x01;							// USB Tx channel
    QC4REQ=0x08;							// SD Rx channel		
	mSetBit(DBRST,QC34DCR);					// reset QC34
    QC34DTR = 0;					// Enable force handshake	
	
	SD_BlockAddress *=512;
	SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
	SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
	if(gSD_SDcard)							// Plugged flash card is SD
	   	SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0205);	//CMD17 READ_SINGLE_BLOCK, data adrs, WBUS for SD card	
	else
	   	SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0005);	//CMD17 READ_SINGLE_BLOCK, data adrs, 1-bit mode for MMC	
   	
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		k++;
		if(k>100000)
			return(1);
	}
	SD_SDINTREN = 0x001c;					// disable CD int
    SD_QIEN=1;	

    mUSBClearBit(USBTCIE,UEPCSR5A);			// disable PhyEP5 Xfer complete int      
    USBMS_SetPhyEP5(64);								

	k=0;
	while(!(gSD_SDSATAT&0x0100)) 			// wait for DTDN=1
	{
		k++;
		if(k>100000)
			return(2);
	}	
    SD_QIEN=0;	

	return(0);
 
}


// ==================================================================
//   SD_QUE_WriteSingleBlockFromQram2Card() -
//
//   Read out single block from Qram
//
//	Input -		32-bits block addres (byte)
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
/*mErrorCode	SD_QUE_WriteSingleBlockFromQram2Card(muint32 SD_BlockAddress)
{
	muint16 SD_BlockAdrs_H, SD_BlockAdrs_L, k=0;
	muint16 kSD_Temp;
	muint32 kSD_BlockAddress, i, j;

	for(i=0; i<SD_TimeOut; i++)
	{
		kSD_Temp = SD_CheckStatus();
		if(kSD_Temp == 1)				// device is ready
			break;
	}
	if((i==SD_TimeOut) && (kSD_Temp == 0) )	
		return(1);
	
//	SD_BlockAddressInWritePage = SD_BlockAddress;
//	kSD_BlockAddress = SD_BlockAddressInWritePage*512;
	
	kSD_BlockAddress = kSD_BlockAddress*512;

	SD_BlockAdrs_H = (muint16)((kSD_BlockAddress & 0xFFFF0000) >>16);
	SD_BlockAdrs_L = (muint16)(kSD_BlockAddress & 0x0000FFFF);
	
	if(!gSD_SDcard)
		SD_SendCommand(0x0018, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x004D);	//CMD24, WRITE_BLOCK, data adrs, WRD=DATAEN=1 R1
	else
		SD_SendCommand(0x0018, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x020D);	//CMD24, WRITE_BLOCK, data adrs, WRD=DATAEN=1 R1
	i = 0;
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		i++;
		if(i==SD_TimeOut) 
			return(2);
		
	}
	SD_QIEN=1;	

	i = 0;
	while(!(gSD_SDSATAT&0x0100))		// wait for DTDN=1
	{
		i++;
		if(i==SD_TimeOut) 
			return(3);
	}


	j = 0;	
	while(!(gSD_SDSATAT&0x0200))		// wait for WRDN=1
	{
		j++;
		if(j==SD_TimeOut) 
			return(4);
		
	}	


    SD_QIEN=0;	
//	kSD_errorCheck =SD_CheckResponse();
 	return(0);							// command passed

}

*/

// ==================================================================
//   SD_QUE_WriteMultipleBlock() -
//
//     Write single block with 0 ~ 255 to SD card 
//
//	Input -		32-bits block addres (byte)
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
mErrorCode	SD_QUE_WriteMultipleBlock(muint32 SD_BlockAddress, muint16 SD_NoOfBlocks)
{
	muint16 SD_BlockAdrs_H, SD_BlockAdrs_L, k=0, kSD_Temp;
//	muint8 kSD_CheckWriteProtect;
//	muint32 kSD_BlockAddress, 
	muint32 i, j;
	muint8	error;

	error = 0;
	gSD_SDSATAT=0;		

//	kSD_CheckWriteProtect = SD_CheckWriteProtect();
//	if(kSD_CheckWriteProtect)
//		return(1);				// Write Protect is enabled

	for(i=0; i<SD_TimeOut; i++)
	{
		kSD_Temp = SD_CheckStatus();
		if(kSD_Temp == 1)				// device is ready
			break;
	}
	if((i==SD_TimeOut) && (kSD_Temp == 0) )
		return(1);


	SD_BlockAddress *= 512;
	SD_SDNOBLK = SD_NoOfBlocks;				// Number of blocks
	SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
	SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);

	if(!gSD_SDcard)			// for 1-bit mode
		SD_SendCommand(0x0019, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x042D);	//CMD25, WRITE_MULTUPLE_BLOCK, data adrs, WRD=DATAEN=1 R1
	else					// for 4-bits mode
		SD_SendCommand(0x0019, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x062D);	//CMD25, WRITE_MULTUPLE_BLOCK, data adrs, WRD=DATAEN=1 R1, WBUS

	i = 0;
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		i++;
		if(i==SD_TimeOut) 
			return(2);
	}	

 	DisableInterrupts;
	SD_QIEN=1;						
 	while(QCDCT12>0);					// wait for the last block is sent
	SD_LBUF = 1;
	EnableInterrupts;


	i = 0;
	while(!(gSD_SDSATAT&0x0100))		// wait for DTDN=1
	{
		i++;
		if (i == 0x2000)
	//	if(i==SD_TimeOut) 
	//		return(3);
		{
			error = 3;
			break;
		}	
	}
	
	j = 0;	
	while(!(gSD_SDSATAT&0x0200))		// wait for WRDN=1
	{
		j++;
		if(j==SD_TimeOut)
		{
			error = 4;
			break; 
		}
	}

	SD_LBUF = 0;						// reset last buffer in SDCON			
	SD_QIEN=0;						

	gSD_SDSATAT=0;		
	SD_SendCommand(0x000C, 0, 0, 0x0001);	//CMD12, STOP_TRANSMISSION,
	i = 0;
	while(!(gSD_SDSATAT&0x0400)) 			// wait for cmd end
	{
		i++;
		if(i==SD_TimeOut) 
			return(5);
	}	

		
	for(i=0; i<1000; i++)
	{
		kSD_Temp =(muint16)SD_CheckStatus();
		if(kSD_Temp)	// return=0, bit8=1 means the card is ready
			return(0);			// no error
	}
  	return(error);
  	
}

// ==================================================================
//   SD_PreInit() -
//
//   Step 1. Pre-initialize the flash card
//
//	Input -		nil
//
//	Output - 	nil
//
//	Function -	nil.
//
// ==================================================================
void	SD_PreInit(void)
{
	muint16	i;
	
//	VREG_U = 0x02;				// turn on the 3.3V regulator for MPW2	
	for(i=0;i<9000;i++)		// Waiting for 9 ms after power-on
		asm nop;

//	SD_SDEN = 0;				// make sure the SDEN is off before starting
	
//	SD_SDCON = 0x0009;			// SDEN, PUEN = 1, for MMC testing
//	for(i=0; i<1000; i++)		// wait 1ms for start-up
//		asm NOP;

/*		
	SD_IRST = 1;			// reset SDHC
	for(i=0;i<9000;i++)		// Waiting for 9 ms 
		asm nop;
			
	SD_IRST = 0;			// disable reset
	for(i=0;i<900;i++)		// Waiting for 9 ms 
		asm nop;
	*/
	
	SD_SDCON = 0x0009;			// SDEN, PUEN = 1, for MMC testing
	for(i=0; i<1000; i++)		// wait 1ms for start-up
		asm NOP;
		
	UTL_Delay(10);	
		
	SD_SDCLKCON = 0x000f;		// card clk enable, 1/10, 1.2MHz
	SD_SDRDTOUT = 0x5B68;		// Set read timeout 	
//	SD_SDRDTOUT = 0x2DB4;		// Set read timeout 	
//	SD_CDIE = 1;				// enable CD interrupt, remarked for MMC
//	while(!SD_CD);				// wait for card inserted

	//-----------------
	// enable all interrupts except timeout error
//	SD_SDINTREN = 0x003c;		// enable all interrupt, except CRCIE & TOIE
	SD_SDINTREN = 0x001c;		// enable all interrupt, except SDIE, CRCIE & TOIE

	//-----------------
	// reset SD card
	SD_SendCommand(0, 0, 0, 0);		// cmd0


//	for(i=0; i<100; i++)		// delay 500us for next card init
//	for(i=0; i<200; i++)		// delay 1ms for next card init, same as CR
	for(i=0; i<2000; i++)		  // delay 8ms for next card init
			asm NOP;	


	SD_SendCommand(55, 0, 0, 1);		// APP_CMD, for release all app_cmd
	for(i=0; i<2000; i++)		        // delay 8ms for next card init
			asm NOP;	
			
}




// ==================================================================
//   SD_Identification() -
//
//   Step 2, to idientify whether the card is SD or MMC
//
//	Input -		nil
//
//	Output - 	nil
//
//		If the card is MMC: gSD_SDcard=0, 1 bit mode
//		If the card is SD : gSD_SDcard=1, switch to 4-bits mode
//
// ==================================================================
muint8	SD_Identification(void)
{
	muint16 i;
	muint32 kSD_OCR_H=0, kSD_OCR_M=0, kSD_OCR_L=0, kSD_OCR=0;
	muint32 kSD_loop_counter=0;

	gSD_SDSATAT	= 0;
	//-------------
	// Send cmd1 to check is it a MMC
		SD_SendCommand(0x0001, 0x80FF, 0x8000, 0x0003);	// CMD1 SEND_OP_COND, for MMC initializtion

⌨️ 快捷键说明

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