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

📄 nand.c

📁 基于一款32位嵌入式微处理器的Nand Flash 接口的测试代码
💻 C
字号:
/*************************************************************************************
*	Copyright (c) 2005 by National ASIC System Engineering Research Center.
*	PROPRIETARY RIGHTS of ASIC are involved in the subject matter of this 
*	material.  All manufacturing, reproduction, use, and sales rights 
*	pertaining to this subject matter are governed by the license agreement.
*	The recipient of this software implicitly accepts the terms of the license.
*
*	File Name: uart.c
*
*	File Description:
*			The file consists of the function used to config uart
*
*	Function Description:



*	Created by Wuer
**************************************************************************************/

#include "garfield.h"
#include <string.h>
#include "nand.h"
extern print(char *string);


U32 g_NIN = 0x0L;										/* 读写过程出错次数 */
U32 SOURCE = 0x1fff3800;								/* 数据存放源地址 */							
U32 DEST = 0x1fff3c00;									/* 数据读出目标地址 */
U32 TESTNUM = 0x200;									/* 每次读写大小(512字节) */
char ch = 0xaa;											/* 数据内容 */

int PRINT(char *string)
{
   #ifndef USB_ICE
   printf(string);
   #else
   print(string);
   #endif
   return 0;
}


int main(void)
{
	char *s1,*s2;
	s1="Error in Nand Flash lab!!!\n";
	s2="Succeeded in Nand Flash lab!!!\n";
	if(E_OK != ModuleNand())
		//printf("Error in Nand Flash lab!!!\n");
		 PRINT(s1);
	else	//printf("Succeeded in Nand Flash lab!!!\n"); 
	     PRINT(s2);	
	while(1);

	return E_OK;
}


STATUS	ModuleNand(void)
{
	char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8;
	s1="____Error in erasing operation!\n";
	s2="Erasing operation ok!\n";
	s3="____Error in writing operation!\n";
	s4="Wrinting operation ok!\n";
	s5="____Error in Reading operation!\n";
	s6="Reading operation ok!\n";
	s7="____Some data is different from original data!\n";
	s8="ALL ok!\n";
	/* system initialized */
	system_init();
	
	/* open EMI interrrupt mask */	
	init_nand();
	unmask_irq(INT_EMI);
	
	
	DataDefine(SOURCE, ch, TESTNUM);						/* 初始化一块数据块 */			
	clear(DEST, TESTNUM);									/* 将需要读出数据存放地址清零 */
	
	if(E_OK != NandErase(0))								/* 需要写入的Nand Flash地址必须先擦除 */
	{
		//printf("____Error in erasing operation!\n");
		PRINT(s1);
		return ~E_OK;
	}else	PRINT(s2);//printf("Erasing operation ok!\n"); 
	
	if(E_OK != NandWrite(0, SOURCE))							/* 将预先定义的数据(512字节)块写入到Nand Flash中 */
	{
		PRINT(s3);
		//printf("____Error in writing operation!\n");
		return ~E_OK;
	}else	PRINT(s4); //printf("Wrinting operation ok!\n"); 
	
	if(E_OK != NandRead(0, DEST))								/* 将写入到Nand Flash的数据块读出到目标内存 */
	{
		PRINT(s5);
		//printf("____Error in Reading operation!\n");
		return ~E_OK;
	}else	PRINT(s6);  //printf("Reading operation ok!\n"); 
	
	if(E_OK != check(DEST, SOURCE, TESTNUM))					/* 检查目标内存中的数据是否与写入源数据相同 */
	{
		PRINT(s7);
		//printf("____Some data is different from original data!\n");
		return ~E_OK;
	}else	PRINT(s8); //printf("ALL ok!\n"); 
		
	return E_OK;
	
}


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

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

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

	for(i=0;i<0x1000;i++);									//must wait some time, waiting for the transmission's accomplish	
	
	i = *(RP)EMIADDR_NANDIDLE;                         		//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)EMIADDR_NANDIDLE; 
	}
	
	if(NTM == 0x5) return 0;								//still time out? then return error!
												
	return E_OK;											//OK! return happy!
}

STATUS NandWrite(U32 page, U32 bufferhead)
{
	U32 	i,j,NTM = 0x0L;	
             
  	
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;			//4 address mode for write
	*(RP)EMIADDR_NANDADDR = (U32)page >> 1;					//address right move 1 bit, set to nand address register

	*(RP)DMACC0SrcAddr = bufferhead; 						//DMA source is Sdram address	
	*(RP)DMACC0DestAddr = EMI_NAND_DATA;					//DMA destination is Nand data register
	
	i = (U32)(0x80 << 14);			
	j=i+0x149B; 											                                             
	*(RP)DMACC0Control = j;
	
	*(RP)DMACC0Configuration =0x301b;						 //channel enable!
	
	
	*(RP)EMIADDR_NANDCOM = 0x80000080;						//NAND_CMD_SEQIN;
															//write begin!	

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

STATUS NandRead(U32 page, U32 bufferhead)
{
	U32 	i,j,NTM = 0x0L;                                     
  
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;			//4 address mode for read
	*(RP)EMIADDR_NANDADDR = (U32)page >>1;					//address right move 1 bit, set to nand address register
	*(RP)DMACC0SrcAddr = EMI_NAND_DATA; 					//DMA source is Nand data register	
	*(RP)DMACC0DestAddr = bufferhead ;						//DMA destination is Sdram address 
		
	i = (U32)(0x80<<14);
	j=i+0x249B;                                             
	*(RP)DMACC0Control = j;	
	*(RP)DMACC0Configuration =0x31d;						//channel enable! 
	*(RP)EMIADDR_NANDCOM = NAND_CMD_READ0;					//read begin

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

}


STATUS check(U32 head1, U32 head2, U32 num)
{
	RP8 p1, p2;
	char data;
	char *s;
	s="the copyed data is not the orignal one!!\n";
	
	p1 = (RP8)head1;
	p2 = (RP8)head2;
	
	
	while(num-->0)
	{
		data = *((RP8)p1++);
		
		if(data!= *((RP8)p2++))
		{
			//printf("the copyed data is not the orignal one!!\n");
			PRINT(s);
			return ~E_OK;
		}
	}
	
	return E_OK;
}


void init_nand(void)										/* 配置GPIO口PH5为高电平,写使能 */
{
	U32	tempsel,tempdata,tempdir;
	#ifdef GE00
	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;
 	#endif
	#ifndef GE00
	
	tempsel = *(RP)GPIO_PB9_SEL;
	tempdata = *(RP)GPIO_PB9_DATA;
	tempdir = *(RP)GPIO_PB9_DIR;
	
	tempsel |= 0x200;
	tempdata |= 0x200;
	tempdir &= 0x1ff; 	
	
	*(RP)GPIO_PB9_SEL 	= tempsel;
 	*(RP)GPIO_PB9_DATA	 = tempdata;
 	*(RP)GPIO_PB9_DIR = tempdir;
 	#endif

}

void emi_handler(void)										/* 中断处理程序 */
{
	*(RP)EMIADDR_NANDINTR = 0x0UL;							/* 清除中断 */
	g_NIN++;											    /* 中断发生数累加 */
	
	return;													
}

void clear(U32 head, U32 num)								/* 清楚一块内存内容为全0 */
{
	U32 i = 0;
	for(i=0; i<num; i++)
	{
		*(RP8)head++ = (U8)0;
	}
	
	return;
}

void DataDefine(U32 head, char data, U32 num)				/* 定义一块内存内容为全data */
{
	U32 i = 0;
	for(i=0; i<num; i++)
	{
		*(RP8)head++ = data;
	}
	
	return;
}

⌨️ 快捷键说明

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