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

📄 nand.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
字号:
#include "init.h"
#include "hardware.h"
#include "hardware_reg.h"
#include "HA_typedef.h"

extern U32 para;


void HA_INIT_NANDFLASH(void)	
{
	U32	temp;
	
	//Gpio config...                    Ph5 set to "1"		
 	*(RP)PORTH_SEL 	= 0x20;
 	*(RP)PORTH_DATA	 = 0x020;
 	*(RP)PORTH_DIR = 0x00;
	
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
	*(RP)EMIADDR_NANDADDR = EMIADDR_NANDADDR_INIT; 
	*(RP)EMIADDR_NANDCOM = EMIADDR_NANDCOM_INIT; 			
	*(RP)EMIADDR_NANDSTATUS	= 0x0;   /* STATUS REGISTER IS READ-ONLY */
	*(RP)EMIADDR_NANDERRORADDR1 = EMIADDR_NANDERRORADDR1_INIT; 
	*(RP)EMIADDR_NANDERRORADDR2 = EMIADDR_NANDERRORADDR2_INIT; 
	*(RP)EMIADDR_NANDINTR = EMIADDR_NANDINTR_INIT; 		
	*(RP)EMIADDR_NANDINECC	= EMIADDR_NANDINECC_INIT; 		
 	*(RP)EMIADDR_NANDIDLE = EMIADDR_NANDIDLE_INIT; 	
 	
 	/* 读出所有寄存器的值,检验有无问题 */
	temp = *(RP)EMIADDR_NANDADDR;
	para = HA_EMI_WRIT(para,temp);
	
	
	temp = *(RP)EMIADDR_NANDSTATUS;
	para = HA_EMI_WRIT(para, temp);
	
	temp = *(RP)EMIADDR_NANDCOM;
	para = HA_EMI_WRIT(para, temp);
	
	temp = *(RP)EMIADDR_NANDERRORADDR1;
	para = HA_EMI_WRIT(para, temp);
	
	temp = *(RP)EMIADDR_NANDERRORADDR2;
	para = HA_EMI_WRIT(para, temp);
	
	temp = *(RP)EMIADDR_NANDCONF;
	para = HA_EMI_WRIT(para, temp);
	
	temp = *(RP)EMIADDR_NANDINTR;
	para = HA_EMI_WRIT(para, temp);
	
	
	temp = *(RP)EMIADDR_NANDINECC;
	para = HA_EMI_WRIT(para, temp);
	
	
	temp = *(RP)EMIADDR_NANDIDLE;
	para = HA_EMI_WRIT(para, temp);
	
}

 
/* esram to nand flash */
U32 Dma_Nand_Write(U32 block_number, U32 page_number, U32 Dma_src_Add, U32 channelnum)                  //just burst size = 4;
{        
	U32 	j,temp;						  //直接分配寄存器,编译器的智能化程度很高
    U32 	tempsrc,tempdest,tempcontrol,tempconfig;		//为什么直接分配寄存器
															//    of registers of channel which is used now 
	tempsrc = DMACbase + 0x1000 + channelnum * 0x100;					//replase registers of channel to be used;
	tempdest = DMACbase + 0x1004 + channelnum * 0x100;
	tempcontrol = DMACbase + 0x100c + channelnum * 0x100;
	tempconfig = DMACbase + 0x1010 + channelnum * 0x100;
                                                           //size:num of word,should be muiltpy of 16(words)
  	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
	*(RP)EMIADDR_NANDADDR = (U32)((page_number << 8) + (block_number << 13));
   	
	*(RP)tempsrc = Dma_src_Add; 
	*(RP)tempdest = EMI_NAND_DATA;  /* it is a buffer address */
	
	j = (U32)((0x80 << 14) + 0x149B);                                                         //suradd and desadd not add up
	*(RP)tempcontrol = j;
	*(RP)tempconfig =0x301B;						       //channel enable!
	
	*(RP)EMIADDR_NANDCOM = 0x80000080;					//write begin!
	
	
	#if 0
	do{ 
		temp = *(RP)tempconfig;
		temp &= 0x1;
	}while(temp != 0x1);
	#endif
	
	//judge Nand flash compish actions
	do{
		temp = *(RP)EMIADDR_NANDIDLE;
		temp &= 0x1;
	}while(temp != 0x1);

	return 0;
}

U32 Dma_Nand_Read(U32 block_number, U32 page_number, U32 Dma_des_Add, U32 channelnum)                  	//just burst size = 4;
{                         
 	U32 	j,temp;						
	U32 	tempsrc,tempdest,tempcontrol,tempconfig;		//These 4 temp regiser address rariable are used to replase registers
	
	tempsrc = DMACbase + 0x1000 + channelnum * 0x100;			        //replase registers of channel to be used;
	tempdest = DMACbase + 0x1004 + channelnum * 0x100;
	tempcontrol = DMACbase + 0x100c + channelnum * 0x100;
	tempconfig = DMACbase + 0x1010 + channelnum * 0x100;
	
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
	*(RP)EMIADDR_NANDADDR = (U32)((page_number << 8) + (block_number << 13));
   	
	*(RP)tempsrc = EMI_NAND_DATA;     /* it is a buffer address */
	*(RP)tempdest = Dma_des_Add ;
	
	j = (U32)((0x80 << 14) | 0x249B);                                                         //suradd and desadd not add up
	*(RP)tempcontrol = j;
	*(RP)tempconfig =0x031d;						//channel enable!
	
	*(RP)EMIADDR_NANDCOM = 0x80000000;					//write beg
	
		
	//judge Nand flash compish actions
	do{
		temp = *(RP)EMIADDR_NANDIDLE;
		temp &= 0x1;
	}while(temp != 0x1);
	
	return 0;
}

U32 Dma_Nand_Erase(U32 block_number)           //block_number:0x00--0xfff, 4096
{
	U32 temp;
	*(RP)EMIADDR_NANDCONF = 0x0f100aaa;                                   //3 addresss mode!!!!
	*(RP)EMIADDR_NANDADDR = (U32)(block_number<<5);
	*(RP)EMIADDR_NANDCOM = 0x80000060;
	
	//judge Nand flash compish actions
	do{
		temp = *(RP)EMIADDR_NANDIDLE;
		temp &= 0x1;
	}while(temp != 0x1);
	
	return 0;
}	



U32 Dma_Nand_StatusRead(void)
{
	U32	temp;
                                            
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;                    //re_config
	*(RP)EMIADDR_NANDCOM = 0x80000070;                               //read status command
		
	do{
		temp = *(RP)EMIADDR_NANDIDLE;
		temp &= 0x1;
	}while(temp != 0x1);
		
   	para = HA_EMI_WRIT(para, temp);
	return 0;
}


U32 Nand_Reset(void)               
{                                                                               
	U32	temp;  
    
    *(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
	*(RP)EMIADDR_NANDCOM = 0x800000ff;					
		
	do{
		temp = *(RP)EMIADDR_NANDIDLE;
		temp &= 0x1;
	}while(temp != 0x0);
		
	return 0;
    
}	


#if 0
U32 HA_NandFlash_IdRead(void)  
{
	
	U32	temp;
                                            
	*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;                    //re_config
	
	*(RP)EMIADDR_NANDCOM = 0x80000090;                               //read status command
		
	do{
   		temp = *(RP)EMIADDR_NANDIDLE;    //judge Nand flash compish actions
	}while((temp & 0x01) != 0x01);
	  
	temp = *(RP)EMI_NAND_DATA;
	para = HA_EMI_WRIT(para, temp);
	return 0;
}
#endif


ER NandFlash(void)
{
	U32 blocknum, pagenum, sdramaddr1 = 0x30000000, sdramaddr2 = 0x30100000;
	
	HA_INIT_NANDFLASH();
	
	/* write data from ESRAM to NandFlash */
	//HA_DMA_TRANS(0x11000200, para, 32, 32, 4, 0, 512); /* read nand flash */
	//HA_DMA_TRANS(para, 0x11000200, 32, 32, 4, 0, 512); /* write nand flash */
	//Dma_Nand_StatusRead();
	
	/* 在作用域的边界会有跳转指令 */
#if 0
	for(blocknum = 0; blocknum < 72; blocknum++){
		Dma_Nand_Erase(blocknum);
		for(pagenum = 0;pagenum < 32; pagenum++, sdramaddr1 += 0x200, sdramaddr2 += 0x200){
			Dma_Nand_Write(blocknum, pagenum, sdramaddr1, 4); 
			Dma_Nand_Read(blocknum, pagenum, sdramaddr2, 4);
		}             
    } 
#endif       
        
    //Dma_Nand_StatusRead();
    Dma_Nand_Erase(0x2);
    Dma_Nand_Read(0x2, 0x0, 0x1fff4000, 1);
    Dma_Nand_Erase(0x0);
    Dma_Nand_Write(0x0, 0x0, 0x1fff3800, 2); 
	Dma_Nand_Read(0x0, 0x0, 0x24005000, 3);
	compare(0x1fff3800, 0x24005000, 0x200, 32);
	
	return 0;
}

⌨️ 快捷键说明

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