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

📄 kw_nand.c

📁 对nanflash进行察除
💻 C
字号:
/************************************************************************************** 
 Copyright (C), 1988-1999, Xi'an Keyway Control & Measurement Technology Co., Ltd
 FileName: kw_nand.c 
 Description     :nandflash 接口模块。      
 Version         :1.0 
 Function List   :    
 History:         // 历史修改记录 
      <author>      <time>        <version >       <desc> 
      LigangWang    07/08/08       1.0             build this moudle   
*************************************************************************************/

#include "globals.h"

BYTE xdata gPageBuff[512];						//页缓冲区,用于临时备份数据

/************************************************************************************* 
  Function:       NM_ReadPage
  Description:    读取指定LBA地址数据到EP6的缓冲区中,并完成数据校验
  Called By:      
  Input:          rdLBA @ DWORD: LBA地址
  Output:         N/A
  Return:         void
  Others:         
*************************************************************************************/
void NM_ReadPage(DWORD rdLBA)
{ 
   dwLBA = rdLBA;								//LBA地址到全局LBA地址,Log2Phy函数用
  
   directionIn  =1;								//读写标志,Log2Phy函数用
   Log2Phy();									//将LBA地址转换成物理Flash地址

   Fifo6In();									//设置EP6的端点缓冲为输入方式
   NandSetAdd(cNAND_READ_DATA, dwLBA&3);		//设置读地址,地址由Log2Phy转换
   P_ECCRESET=0;								//复位ECC产生器

   P_GPIFTCB1=MSB(528),P_GPIFTCB0= LSB(528),	//设置GPIF读取数量
   GPIFTRIG = 0x04 | cEP6;						//启动GPIF

   AUTOPTR1H = MSB(cEP6FIFO);					//设置自动指针到EP6缓冲
   AUTOPTR1L = LSB(cEP6FIFO);
   while (P_GPIFTCB1);							//等待首256字节读取完成
   ecc0[0] = P_ECC1B0[0];       				//保存首256字节的ECC
   ecc0[1] = P_ECC1B0[1]; 
   ecc0[2] = P_ECC1B0[2]; 
   while (!gpifIdle());
   ecc0[3] = P_ECC1B0[3];    					//保存后256字节的ECC   
   ecc0[4] = P_ECC1B0[4];       
   ecc0[5] = P_ECC1B0[5];       

   ecc1[0] = P_XAUTODAT1;   					//保存ECC产生器中产生的ECC 
   ecc1[1] = P_XAUTODAT1;    
   ecc1[2] = P_XAUTODAT1;    
   ecc1[3] = P_XAUTODAT1;    
   ecc1[4] = P_XAUTODAT1;    
   ecc1[5] = P_XAUTODAT1;  

   bErr = 0;
   CheckECC();               					//检查ECC
   return;
}

/************************************************************************************* 
  Function:       NM_WritePages
  Description:    写EP6的缓冲区中的数据到指定LBA地址的扇区中
  Called By:      
  Input:          wrLBA @ DWORD: LBA地址
  Output:         N/A
  Return:         void
  Others:         
*************************************************************************************/
void NM_WritePages(DWORD wrLBA)
{
	WORD xdata i;

    dwLBA = wrLBA;								//LBA地址到全局LBA地址,Log2Phy函数用
	gSectorcount = 1;							//写扇区数量
	directionIn  =0;							//读写标志,Log2Phy函数用

	for(i = 0; i<512; i++)						//备份当前缓存区数据
		gPageBuff[i] = EP6FIFOBUF[i];
    
	Log2Phy();									//LBA地址转换物理地址

   	P_FIFORESET = 0x80;							//设置EP6缓冲区为输出方式
	P_FIFORESET = 6;
	P_EP6CFG = EP6CFG_OUT_DEFAULT;	
	
	for(i = 0; i<512; i++)						//读取数据
		EP6FIFOBUF[i] = gPageBuff[i];


	EP6BCH = MSB(512);							//设置缓冲区数据量
  	_nop_(); 
  	EP6BCL = LSB(512);
	_nop_();
	
    NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3));	//设置写地址
	
	P_ECCRESET =LSB(cNAND_DSIZE);
    FifoWr(cEP6, 512-1);             			//写数据
     
	WriteRedundant();							//写ECC码及LBA地址
    NandSendCmd(cNAND_PROGRAM_PAGE);			//编程,写入数据


	dwLBA++;									//因为写如数据为新块,故须复制当前块剩余页
	gPartialCpy = xLBA3;
	if((dwLBA & 3) == 0)
	{
		xPhyAdd++; xSrcAdd++;  	
	}
	if(gPartialCpy)
	{
		gPartialCpy = 0 - gPartialCpy;
		if(gPartialCpy)
		{
	         NAND_PCPY(gPartialCpy, xLBA3);
	         gPartialCpy = 0;  
	         nEraseBlock();
	         DISABLE_NAND();
	   	}
 	}
	else
	{
		nEraseBlock();
		DISABLE_NAND();
	}
}



/************************************************************************************* 
  Function:       NM_WritePagesFromBuff
  Description:    写pBuffer中的数据到指定地址,该地址扇区Start前字节保持不变
  Called By:      
  Input:          wrLBA @ DWORD: LBA地址
  				  pBuffer @ BYTE* : 数据指针
				  Start @ WORD: 扇区你偏移
				  Length @ WORD: 数据长度
  Output:         N/A
  Return:         void
  Others:         
*************************************************************************************/
void NM_WritePagesFromBuff(DWORD wrLBA,BYTE * pBuffer,WORD Start, WORD Length)
{
	WORD xdata i;

 	dwLBA = wrLBA;							//LBA地址到全局LBA地址,Log2Phy函数用
	gSectorcount = 1;						//写扇区数量
	directionIn  =0;						//读写标志,Log2Phy函数用

	for(i = 0; i<Start; i++)				//备份当前缓存区数据
		gPageBuff[i] = EP6FIFOBUF[i];

    Log2Phy();								//LBA地址转换物理地址

	P_FIFORESET = 0x80;						//设置EP6缓冲区为输出方式
	P_FIFORESET = 6;
	P_EP6CFG = EP6CFG_OUT_DEFAULT;


	for(i = 0; i<Start; i++)				//保持源Start个数据不变
		EP6FIFOBUF[i] = gPageBuff[i];		    


	for(i = Start;i<(Start+Length);i++)		//复制剩余length个数到EP6缓冲
	{
		EP6FIFOBUF[i] = *pBuffer;
		pBuffer ++;
	}

	EP6BCH = MSB(512);						//设置数据长度
  	_nop_(); 
  	EP6BCL = LSB(512);
	_nop_();

    NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3));	//设置写物理地址
	
	P_ECCRESET =LSB(cNAND_DSIZE);			//复位ECC产生器
    FifoWr(cEP6, 512-1);             		//写数据
     
	WriteRedundant();						//写ECC和LBA地址
    NandSendCmd(cNAND_PROGRAM_PAGE);		//编程,写入

	dwLBA++;								//因为写如数据为新块,故须复制当前块剩余页
	gPartialCpy = xLBA3;
	if((dwLBA & 3) == 0)
	{
		xPhyAdd++; xSrcAdd++;  	
	}
	if(gPartialCpy)
	{
		gPartialCpy = 0 - gPartialCpy;
		if(gPartialCpy)
		{
	         NAND_PCPY(gPartialCpy, xLBA3);
	         gPartialCpy = 0;  
	         nEraseBlock();
	         DISABLE_NAND();
	   	}
 	}
	else
	{
		nEraseBlock();
		DISABLE_NAND();
	}
}



⌨️ 快捷键说明

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