www.pudn.com > nand_flash_arithmetic.rar > NandFlash.c


/*************************************************************************/ 
/*                                                                       */ 
/* FILE NAME                                      VERSION                */ 
/*                                                                       */ 
/* source\flash.c                                  1.0                   */ 
/*                                                                       */ 
/* DESCRIPTION                                                           */ 
/*                                                                       */ 
/*                                                                       */ 
/*                                                                       */ 
/* DATA STRUCTURES                                                       */ 
/*                                                                       */ 
/* FUNCTIONS : Flash Fujitsu program code                            */ 
/*                                                                       */ 
/* DEPENDENCIES                                                          */ 
/*                                                                       */ 
/*                                                                       */ 
/*                                                                       */ 
/*                                Copyrigth (C) 2001 AIJISYSTEM CO.,LTD  */ 
/*************************************************************************/ 
 
#include  
#include  
#include "common.h" 
 
#define PAGE_CNT 32 
#define PAGE_SIZE 512 
#define BLOCK_COUNT 2048  
#define BLOCK_SIZE 0x4000 
 
#define BASE_ADDR	(ulong)0x64000000 
 
volatile ulong *data_reg = (ulong *)0x64000000; 
volatile ulong *spare_data_reg = (ulong *)0x64000320; 
volatile ulong *cle_reg = (ulong *)0x64000300; 
volatile ulong *ale_reg = (ulong *)0x64000304; 
volatile ulong *status_reg = (ulong *)0x64000308; 
volatile ulong *ecc_read_reg = (ulong *)0x6400030c; 
volatile ushort *flash_cfg_reg = (ushort *)0x6400031c; 
volatile ulong *clear_status_reg = (ulong *)0x80000c84; 
 
// WatchDog resetÀ» ¹æÁöÇϱâ À§ÇÑ register 
//volatile ushort *AutoKick_reg = (ushort *)0x3000600;  //MSM3000, 3100, 5000, 5105 
//volatile ushort *AutoKick_reg = (ushort *)0x3000700;  //MSM5100 watch dog address 
//volatile ushort *AutoKick_reg = (ushort *)0x30006d0;  //MSM6050 
//volatile ushort *AutoKick_reg = (ushort *)0x3001080;  //MSM5500 
//volatile ushort *AutoKick_reg = (ushort *)0x80000700;  //MSM6100 
volatile ushort *AutoKick_reg = (ushort *)0x80003404;  //MSM6250 
//volatile ushort *AutoKick_reg = (ushort *)0x80001b40;  //MSM6500 
 
// Host program°ú data & command¸¦ ÁÖ°í¹Þ±â À§ÇÑ structure 
extern FLASH_INFO Flash_Info; 
 
uchar TempBuf[BLOCK_SIZE]; 
ulong Current_Block_No = 0; 
ulong Current_Page_No = 0; 
 
 
void Main(void) 
{ 
	switch(Flash_Info.Command) 
	{ 
		case FPROGRAM: Program(); 
				break; 
		case FERASEALL:  
				Flash_Info.Result = 1; 
				//EraseAll(); 
				break; 
		case FERASESEC:  
				Flash_Info.Result = 1; 
				//EraseSector(); 
				break; 
		case FREADID: ReadChipID(); 
				break; 
		case FREADMEM: ReadMem(); 
				break; 
		case FWRITE_BIB:  
			Flash_Info.Result = 1; 
				break; 
		case FINIT: InitFlash(); 
				break; 
		default : 
			Flash_Info.Result = 0; 
	} 
} 
 
// Flash program function 
void  Program(void) 
{ 
	ulong len, flen, i; 
	volatile ulong status; 
	uchar *srcP, *bsrcP; 
 
    Flash_Info.Result = 0; 
	Flash_Info.TargetAddr &= 0x3FFF; 
 
	AutoKick(); 
	 
	srcP = (uchar *)Flash_Info.Buf; 
	len = Flash_Info.Length; 
     
    while(len) 
    { 
    	if(!(Current_Page_No%PAGE_CNT)) { 
    		if(!OneBlockErase(Current_Block_No)) 
    			return; 
    	} 
    	 
		if(len > PAGE_SIZE) 
			flen = PAGE_SIZE; 
		else { 
			flen = len; 
			bsrcP = srcP+len; 
			for(i=len; i> 1; 
		no_of_shifts++; 
	} 
 
	/* Set the block address in Nand_Flash_Addr */ 
	nand_cntlr_block_addr = block << (9 + no_of_shifts); 
	*ale_reg = nand_cntlr_block_addr; 
 
	/* Issue the block erase command */ 
	*cle_reg = ERASE_CMD; 
 
	/* Wait for erase command to be executed */ 
	while(*status_reg & ERASE_CMD) 
	; 
 
	/* Check status after erase */ 
	status = *status_reg; 
	if( (status & FS_NAND_OP_ERR_MASK != 0) || 
		(status & FS_NAND_OP_RESULT_MASK != 0) ) 
	{ 
		return 0; 
	} 
 
	return 1; 
} 
 
// Read Manufacturer & Device ID 
void ReadChipID(void) 
{ 
    ulong manId,devId; 
 
	*cle_reg = RESET_CMD; 
 
	*cle_reg = ID_CMD; 
 
	/* Wait for completion. */ 
	while(*status_reg & ID_CMD) 
	{ 
		*AutoKick_reg = 1; 
		*AutoKick_reg = 0; 
	}	 
	 
	manId = *status_reg; 
	 
	 
	devId = (manId >> 15) & 0xff; 
	manId = (manId >> 23) & 0xff; 
 
	Flash_Info.Result = (devId << 8) + manId; 
} 
 
 
int BlankCheck(ulong *targetP,ulong targetSize)  
{ 
	ulong i; 
	 
	for(i=0; i PAGE_SIZE) 
			flen = PAGE_SIZE; 
		else 
			flen = len;	 
 
		*ale_reg = targetAddr & 0x01FFFE00; 
		*cle_reg = READ_DATA; 
 
		while(*status_reg & READ_DATA) { 
			*AutoKick_reg = 1; 
			*AutoKick_reg = 0; 
		} 
			 
		status = *status_reg; 
		 
		if( (status & FS_NAND_OP_ERR_MASK != 0) ||  
			(status & FS_NAND_ECC_SELF_ERR_MASK != 0) ||  
			(status & FS_NAND_READ_ECC_ERR_MASK != 0) ) 
				return 0;		 
		 
//		for(j=0; j