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

📄 nandflash.c

📁 基于ARM9的NAND FLASH(large page)的驱动
💻 C
字号:
#include"ZV1050_NandCtr.h"
#include"NandFlash.h"

#define pod(a,d)	(*(volatile unsigned  *)a = (unsigned int )d)
#define pid(a)		(*(volatile unsigned  *)a)

#define NUM_PAGE_BLOCK        64          /* Number of pages for block*/
#define FLASH_WIDTH           8           /* Flash data width */
#define FLASH_SIZE            0x10000000  /* Flash size in byte */
#define PAGE_SIZE             2112        /* Page size in byte */ 
#define PAGE_DATA_SIZE     	  2048        /* Page data size in byte */
#define PAGE_SPARE_SIZE		  64		  /* Page spare size in bytes*/
#define NUM_BLOCKS			  0x800 	  /* Number of blocks*/
#define SHIFT_A8			  1
unsigned char dataWidth;                   /*Flash data type*/

typedef struct Device_Identfier{
	unsigned char ManufacturerCode;
	unsigned char DeviceIdentifier;
	unsigned char InternalChipNum;
	unsigned char CellType;
	unsigned char Num_SimProPages;
	unsigned char PageSize;
	unsigned char SpareSize;
	unsigned char BlockSize;
	unsigned char Organization;
	unsigned char Num_Plane;
	unsigned char PlaneSize;
}DeviceID;

typedef struct StructPageInfo{
	unsigned long dwReserved1;//Reserved-used by FAL
	unsigned char bOEMReserved;//For use by OEM
	unsigned char bBadBlock;   //Indicates if block is bad
	          int wReserved2;  //Reserved -used by FAL
}*PPageInfo;     
	
void Delay(unsigned int i)
{
	unsigned int j,k;
	for(j=0;j<200;j++)
	{
		for(k=0;k<i;k++);
	}
}

void NF_Reset(void)
{
	pod(NFC_CMD_REG,0xff);//disable read status and wait for READY
	pod(NFC_CMD_START_REG,0x01);
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
}

void NF_Init(void)
{
	pod(NFC_CONFIG_REG,0x0e);//enable CS0,ECC size=512 bytes,Page size=2048 bytes,NAND width=8 bits
	pod(NFC_WR_PROT_REG,0x01);//disable Write Protect
	NF_Reset();//reset the NandFlash
}

unsigned char NF_RdStatus(void)//IO0:Pass:'0',Fail:'1';IO5:Active:'0',Idle:'1';IO6:Busy:'0',Ready:'1';IO7:Protect:'0',Not Protect:'1'
{
	pod(NFC_CMD_REG,0x600070);//enable read status and wait for READY
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles before the first READ STATUS command
	pod(NFC_CMD_START_REG,0x01);
	
	return(pid(NFC_STATUS_REG));
	
}


unsigned char NF_DataRd(unsigned int BlkAddr,unsigned int PageAddr,int size,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,size);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

unsigned char NF_DataRd_FirstChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

unsigned char NF_DataRd_SecondChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x02);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

unsigned char NF_DataRd_ThirdChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x04);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

unsigned char NF_DataRd_ForthChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x06);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)==0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

unsigned char NF_BlkErase(unsigned int BlkAddr)
{
	pod(NFC_CMD_REG,0x3d0360);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,((BlkAddr&0x03)<<6));
	pod(NFC_ADDR_1_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_2_REG,((BlkAddr>>10)&0x01));
	pod(NFC_CMD_START_REG,0x01);//开始执行擦除操作
	pod(NFC_WAIT_1_REG,0xba00);//wait 47616 clock cycles(about 2ms)
	
	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
	

unsigned char NF_DataWr(unsigned int BlkAddr,unsigned int PageAddr,int size,unsigned char *WrBuff)
{
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	
	pod(NFC_TX_SIZE_REG,size);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行写入数据
	pod(NFC_WAIT_1_REG,0x50f);//wait 1295 clock cycles(about 200us)
	
	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
	
unsigned char NF_DataWr_FirstChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *WrBuff)
{
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}


unsigned char NF_DataWr_SecondChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *WrBuff)
{
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x02);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
	
unsigned char NF_DataWr_ThirdChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *WrBuff)
{
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x04);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
unsigned char NF_DataWr_ForthChunk(unsigned int BlkAddr,unsigned int PageAddr,unsigned char *WrBuff)
{
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x06);
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,512);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据
	pod(NFC_WAIT_1_REG,0x100);//wait 256 clock cycles
	while((NF_RdStatus()&0x40)!=0x40);//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
unsigned char NF_RdID(unsigned char *IDBuff)
{
  pod(NFC_CMD_REG, 0x600190);//enable read status and wait for READY
  pod(NFC_ADDR_0_REG, 0);
  pod(NFC_TX_SIZE_REG, 5);
  pod(NFC_SYS_ADDR_REG, IDBuff);
  pod(NFC_CMD_START_REG, 0x01);
 
  while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
  return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}

void ClearGCC(int n)
{
  switch (n)
    {
    case 0 : pod(NFC_ECC_0_REG, 0x0); break;
    case 1 : pod(NFC_ECC_1_REG, 0x0); break;
    case 2 : pod(NFC_ECC_2_REG, 0x0); break;
    case 3 : pod(NFC_ECC_3_REG, 0x0); break;
    case -1 : 
      pod(NFC_ECC_0_REG, 0x0); 
      pod(NFC_ECC_1_REG, 0x0); 
      pod(NFC_ECC_2_REG, 0x0); 
      pod(NFC_ECC_3_REG, 0x0); 
      break;
    }
}

unsigned int GetGCC(int n)
{
  switch (n)
    {
    case 0 : return pid(NFC_ECC_0_REG); break;
    case 1 : return pid(NFC_ECC_1_REG); break;
    case 2 : return pid(NFC_ECC_2_REG); break;
    case 3 : return pid(NFC_ECC_3_REG); break;
    default : return 0xffffffff; break;
    }
}
/***********************************************************
*each time copy-back a page(consist spare area),
*the value A28 from second to the last page address must be same as the value
*given to A28 in first address
*only within the same memory plane (all plane number is 2)
*copy-back program is permitted just between odd address pages or even address pages
**************************************************************/
unsigned char CopyBack_Wr(unsigned int S_BlkAddr,unsigned int S_PageAddr,unsigned int D_BlkAddr,unsigned int D_PageAddr)	
{
	pod(NFC_CMD_REG,0x535500);//disable read status and wait for READY 
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((S_BlkAddr&0x03)<<6) | S_PageAddr));
	pod(NFC_ADDR_3_REG,((S_BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((S_BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,2111);//read one page include spare area
	pod(NFC_CMD_START_REG,0x01);
	pod(NFC_WAIT_1_REG,0x400);//wait 1024 clock cycles
	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending of read
	
	pod(NFC_CMD_REG,0x310d85);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x00);
	pod(NFC_ADDR_2_REG,(((D_BlkAddr&0x03)<<6) | D_PageAddr));
	pod(NFC_ADDR_3_REG,((D_BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((D_BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,2111);
	pod(NFC_CMD_START_REG,0x01);
	pod(NFC_WAIT_2_REG,0x400);//wait 1024 clock cycles
	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
	
/*******************************************************************************
*Any block where the 1st Byte/1st Word in the spare area of the 1st or 2nd page
*(if the 1st page is Bad)does not contain FFh is a Bad Block
******************************************************************************/
void NF_BadBlkTab(unsigned char *BadBlkTab)
{	
	int i;
	unsigned char buff_1[64],buff_2[64];
	for(i=0;i<2048;i++)//all of the block number
	{
		//bad block info in the spare area of 1st or 2nd page 
	   NF_SpareRd(i,0,63,buff_1);
	   NF_SpareRd(i,1,63,buff_2);
	   if((buff_1[0]!=0xff)&&(buff_2[0]!=0xff))//find the bad block
	   {
			*(BadBlkTab++) = i;
	   }
	}
}
	
unsigned char NF_SpareRd(unsigned int BlkAddr,unsigned int PageAddr,int size,unsigned char *RdBuff)
{
	pod(NFC_CMD_REG,0x730500);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x08);//A11=1
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,size);
	pod(NFC_SYS_ADDR_REG,RdBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据

	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
	
}

unsigned char NF_SpareWr(unsigned int BlkAddr,unsigned int PageAddr,int size,unsigned char *WrBuff)
{
	
	pod(NFC_CMD_REG,0x310d80);//enable read status and wait for READY
	pod(NFC_ADDR_0_REG,0x00);
	pod(NFC_ADDR_1_REG,0x08);//A11=1
	pod(NFC_ADDR_2_REG,(((BlkAddr&0x03)<<6) | PageAddr));
	pod(NFC_ADDR_3_REG,((BlkAddr>>2)&0xff));
	pod(NFC_ADDR_4_REG,((BlkAddr>>10)&0x01));
	pod(NFC_TX_SIZE_REG,size);
	pod(NFC_SYS_ADDR_REG,WrBuff);
	pod(NFC_CMD_START_REG,0x01);//开始执行读取数据

	while(((NF_RdStatus()&0x40)!=0x40));//wait for ending
	return(NF_RdStatus()&0x01);//IO0:Pass:'0',Fail:'1'
}
	

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

⌨️ 快捷键说明

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