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