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

📄 nanddriver.c

📁 对nand flash的读写
💻 C
字号:
/*
**************************************************************************************************************************
*filename:			NandDriver.C		
*author:			wuer 
*create date:		2005.5                                                                     
*description:	    		                                           
*modify history:	                                                                      
*misc:           
*****************************************************************************************************************************
*/



#include "HA_TypeDef.h"
#include "hardware.h"
#include "hardware_reg.h"
#include "stdio.h" 


U32 g_NIN = 0x0L;
U32 g_NTN = 0x0L;
U32 *g_flash_pagebuf=(U32 *)0x1fff3400;
U32 *g_flash_esrambuf = (U32 *)0x1fff3800;


void init_nand(void)										/* 配置GPIO口PH5为高电平,写使能 */
{
	U32	tempsel,tempdata,tempdir;
	
	tempsel = *(RP)GPIO_PH5_SEL;
	tempdata = *(RP)GPIO_PH5_DATA;
	tempdir = *(RP)GPIO_PH5_DIR;
	
	tempsel |= 0x20;
	tempdata |= 0x20;
	tempdir &= 0xffffffdf; 	
	
	*(RP)GPIO_PH5_SEL 	= tempsel;
 	*(RP)GPIO_PH5_DATA	 = tempdata;
 	*(RP)GPIO_PH5_DIR = tempdir;

	return;
}



 void int_serv_emi(void)
{
	*(RP)GFD_NAND_INTR = 0x0UL;			//clear interrupt bit
	g_NIN++;
}


int nand_rd_page(U32 page, U32*buffer,  U32 do_read)
{
	U32 status,i;
	U32 tempg_NIN,tempg_NTN;
	U32 nand_addr = page<<9;	
	
	g_NIN = 0x0;
	g_NTN = 0x0;

	//printf("\tpage [%08d] [0x%08x] [%s]\n",page, (U32)buffer, do_read?"R":"Write");
							
	while((g_NIN < 2) & (g_NTN < 3))
	{
		if(do_read&1)
			nand_read_page_com(nand_addr,(U32*)g_flash_esrambuf);
		else 
		{
			for(i=0;i<128;i++)
			{
				g_flash_esrambuf[i] = buffer[i];
			}
			nand_write_page_com(nand_addr,(U32*)g_flash_esrambuf);
		}
		for(i=0;i<0x1000;i++);
		if(g_NIN >= 2) 
			return NO;
		
		status = *(RP)GFD_NAND_IDLE;
		if((status&0x1) == 0x1)
		{
			if(do_read&1)	
			{		
				for(i=0;i<128;i++)
				{
					buffer[i] = g_flash_esrambuf[i];
				}
				return YES;						//read  success!
			}
			else 
			{	
				tempg_NIN = g_NIN; //aviod g_var be changed!
				tempg_NTN = g_NTN;
				//for(i=0;i<128;i++) g_flash_pagebuf[i] = 0;
				status = nand_rd_page(page,g_flash_pagebuf,0x1);
				g_NIN = tempg_NIN;
				g_NTN = tempg_NTN;
				if( status == 1 )
				{
					#ifdef READOUT_CHECK			
					for(i=0; i<128; i++)
					{
						if(g_flash_pagebuf[i] !=buffer[i]) 
						{
							printf("error address is NO 0x%x word in page 0x%x!\n",i,page);
							printf("Value at g_flash_pagebuf[0x%08x] is 0x%x \n and at buffer[0x%08x] is 0x%x\n",i,g_flash_pagebuf[i],i,buffer[i]);
							return NO;
						}
					}
					#endif
					
					return YES;	 //write  success!
				
				}
				else 
					return NO;	 //write Ok, but reread fail!										
			}
			
		}
		else
		{	
			for(i=0;i<0x1000;i++);
	 		g_NTN ++;
		}	
		
	}
	
	if(g_NTN >= 3) 
		return NO;
	
	return NO;
	
}


int nand_erase_block(U32 page)
{
	U32 i,j,NTM = 0x0L;
	
	*(RP)GFD_NAND_CONF = 0x0100aaa;          	 		//3 addresss mode!!!!(refer to Garfield IV user manual)

	
	*(RP)GFD_NAND_ADDR = (page );     		 			//just that way(refer to Garfield IV user manual)

	*(RP)GFD_NAND_COM = NAND_CMD_ERASE1;				 	//nand flash erase

	for(i=0;i<0x1000;i++);									//must wait some time, waiting for the transmission's accomplish	
	
	i = *(RP)GFD_NAND_IDLE;                         		//judge Nand flash compish actions by IDLE register
	while((i&0x1) != 0x1)
	{  
		for(j = 0x0; j < 0x1000; j++);						//not yet, then wait another period of time
		NTM++;
		if(NTM == 0x5) break;
		i = *(RP)GFD_NAND_IDLE; 
	}
	
	if(NTM == 0x5) return NO;								//still time out? then return error!
												
	return YES;											//OK! return happy!
}




int nand_read_page_com (U32 from,  U32 *buf)
{
	*(RP)GFD_NAND_CONF = 0x2200aaa;	                    // Nand 4 address mode config 
	*(RP)GFD_NAND_ADDR = ((U32)from) >> 1;		//address config according to EMI refference	
	*(RP)DMACC0SrcAddr = GFD_NAND_DATA;			//Nand data register is the source address of DMA
	*(RP)DMACC0DestAddr = (U32)buf;				//data buffer is the target address of DMA
	*(RP)DMACC0Control = 0x20249b;				//word-word burst=4  size=128words
	*(RP)DMACC0Configuration = 0x31d;				//enable DMA channel                   		

	*(RP)GFD_NAND_COM = (NAND_CMD_READ0 );		//send the read command, transportation begin now!!

	return YES;
	
}


int nand_write_page_com(U32 to, U32 *buf)
{
	*(RP)GFD_NAND_CONF = 0x02200aaa;			// Nand 4 address mode config 
	*(RP)GFD_NAND_ADDR = ((U32)to) >> 1;			//address config according to EMI refference	
	*(RP)DMACC0SrcAddr = (U32)buf ;				//data buffer is the source address of DMA
	*(RP)DMACC0DestAddr = GFD_NAND_DATA;		//Nand data register is the target address of DMA
	*(RP)DMACC0Control = 0x0020149B;				//word-word burst=4  size=128words
	*(RP)DMACC0Configuration = 0x301b;				//enable DMA channel 
	
	*(RP)GFD_NAND_COM = (NAND_CMD_SEQIN);		//send the write command, transportation begin now!!
	
	return YES;
	
}


void pmc_init(U32 sysclk, U32 module)
{
	U32 i;
	U32	n,m;

	*(RP)(PMU_PCSR) |= module;	//open all module
	
	*(RP)(PMU_PMDR)	= 0X01;
	*(RP)(PMU_PLTR) = 0x00d200cd;	//MLTV=210,ULTV=205
	
	for(i=0;i<100;i++);
		
	n = 2;
	m = 8*sysclk/10000000;
	*(RP)(PMU_PMCR) = (n << 8) | m;
	*(RP)(PMU_PMCR) = (1 << 12) | (n << 8) | m;
		
	*(RP)(PMU_PUCR)=0x1530;		//parameter PD=5,D=48

	return ;
}

void system_init(void)
{
	/* PLL initialized */
	pmc_init(70000000, 0x17fff);

	/* Interrupt initialize */
	INT_INIT();
	
	/* set GPIO PH5 to "1" */
	init_nand();

	return ;
}

⌨️ 快捷键说明

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