📄 k9s1208.c
字号:
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "2410slib.h"
#include "../k9s1208_fif.h"
#define BAD_CHECK (0)
#define ECC_CHECK (0)
//*************** H/W dependent functions ***************
void __RdPage528(U8 *pPage);
void __WrPage528(U8 *pPage);
static U16 NF_CheckId(void);
int NF_EraseBlock(U32 blockNum);
int NF_ReadPage(U32 block,U32 page,U8 *buffer);
int NF_WritePage(U32 block,U32 page,U8 *buffer);
//buffer size is 512 bytes
static int NF_IsBadBlock(U32 block);
static int NF_MarkBadBlock(U32 block);
static void NF_Reset(void);
void NF_Init(void);
//*******************************************************
void K9S1208_PrintBlock(void)// Printf one page
{
int i,j;
U16 id;
U32 block,page;
U8 buffer[512];
Uart_Printf("\n[SMC(K9S1208V0M) NAND Flash block read]\n");
block=13,page=2;
NF_Init();
id=NF_CheckId();
Uart_Printf("ID=%x(0xec76)\n",id);
if(id!=0xec76)
return;
Uart_Printf("Input target block number:");
// block=Uart_GetIntNum();
Uart_Printf("Input target page number:");
// page=Uart_GetIntNum();
NF_ReadPage(block,page,buffer);
Uart_Printf("block=%d,page=%d:",block,page);
for(j=0;j<512;j++)
{
if(j%16==0)
Uart_Printf("\n%3xh:",j);
Uart_Printf("%02x ",buffer[j]);
}
Uart_Printf("\n");
}
//*************************************************
//*************************************************
//** H/W dependent functions **
//*************************************************
//*************************************************
//The code is made for bi-endian mode
// block0: reserved for boot strap
// block1~4095: used for OS image
// badblock SE: xx xx xx xx xx 00 ....
// good block SE: ECC0 ECC1 ECC2 FF FF FF ....
#define WRITEVERIFY (0) //verifing is enable at writing.
/*
#define FC_CMD() {rPDATA|=CLE;rPDATA&=~(ALE|CE);}
#define FC_ADDR() {rPDATA|=ALE;rPDATA&=~(CLE|CE);}
#define FC_DATA() {rPDATA&=~(ALE|CLE|CE);}
#define FC_INACTIVE() {rPDATA|=CE;rPDATA&=~(ALE|CLE);}
*/
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_nFCE_L() {rNFCONF&=~(1<<11);}
#define NF_nFCE_H() {rNFCONF|=(1<<11);}
#define NF_RSTECC() {rNFCONF|=(1<<12);}
#define NF_RDDATA() (rNFDATA)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_WAITRB() {while(!(rNFSTAT&(1<<0)));}
//wait tWB and check F_RNB pin.
#define ID_K9S1208V0M 0xec76
#if 1
// HCLK=100Mhz
#define TACLS 0 //1clk(0ns)
#define TWRPH0 3 //3clk(25ns)
#define TWRPH1 0 //1clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
#else
// HCLK=50Mhz
#define TACLS 0 //1clk(0ns)
#define TWRPH0 1 //2clk(25ns)
#define TWRPH1 0 //1clk(10ns)
#endif
static U8 seBuf[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
// 1block=(512+16)bytes x 32pages
// 4096block
// A[23:14][13:9]
// block page
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//*******************//
//为YAFFS而实现的函数
//*******************//
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//块擦除
int k9_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
{
U32 blockPage=(blockNumber<<5);
int i;
NF_Reset();/////////
NF_nFCE_L();
NF_CMD(0x60); // Erase one block 1st command
NF_ADDR(blockPage&0xff); // Page number=0
NF_ADDR((blockPage>>8)&0xff);
NF_ADDR((blockPage>>16)&0xff);
NF_CMD(0xd0); // Erase one blcok 2nd command
for(i=0;i<10;i++); //wait tWB(100ns)//??????
NF_WAITRB(); // Wait tBERS max 3ms.
NF_CMD(0x70); // Read status command
if (NF_RDDATA()&0x1) // Erase error
{
NF_nFCE_H();
NF_MarkBadBlock((U32)blockNumber);//???需不需要呢????
return YAFFS_FAIL;
}
else
{
NF_nFCE_H();
return YAFFS_OK;
}
}
//块编程
int k9_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare)
{
int i;
__u8 * cp;
//NF_RSTECC(); // Initialize ECC
NF_Reset();/////////
NF_nFCE_L();
if (data)
{
NF_CMD(0x0); //从A区开始528字节
}else{
NF_CMD(0x50); //从C区开始16字节
}
NF_CMD(0x80); // Write 1st command
NF_ADDR(0); // Column 0
NF_ADDR(chunkInNAND&0xff); //
NF_ADDR((chunkInNAND>>8)&0xff); // Block & page num.
NF_ADDR((chunkInNAND>>16)&0xff); //
if (data) //写入主数据
{
for(i=0;i<512;i++)
{
NF_WRDATA(data[i]); // Write one page to NFM from buffer
}
}
//seBuf[0]=rNFECC0;
//seBuf[1]=rNFECC1;
//seBuf[2]=rNFECC2;
//seBuf[5]=0xff; // Marking good block
if (spare) //写入spare数据
{
cp=(__u8 * )spare;
for(i=0;i<16;i++)
{
NF_WRDATA(cp[i]); // Write spare array
}
}
NF_CMD(0x10); // Write 2nd command
for(i=0;i<10;i++); //tWB = 100ns. ////??????
NF_WAITRB(); //wait tPROG 200~500us;
NF_CMD(0x70); // Read status command
for(i=0;i<3;i++); //twhr=60ns
if (NF_RDDATA()&0x1) // Page write error
{
NF_nFCE_H();
//NF_MarkBadBlock(block); //???需不需要呢????
return YAFFS_FAIL;
}else {
NF_nFCE_H();
return YAFFS_OK;
}
}
//块读取
int k9_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
{
int i;
__u8 * cp;
//NF_RSTECC(); // Initialize ECC
NF_Reset();/////////
NF_nFCE_L();
if (data)
{
NF_CMD(0x00); // Read1 command
}else{
NF_CMD(0x50); //Read2 command 仅仅读取spare部分
}
NF_ADDR(0); // Column = 0
NF_ADDR(chunkInNAND&0xff); //
NF_ADDR((chunkInNAND>>8)&0xff); // Block & Page num.
NF_ADDR((chunkInNAND>>16)&0xff); //
for(i=0;i<10;i++); //wait tWB(100ns)/////??????
NF_WAITRB(); // Wait tR(max 12us)
if (data) //读入数据
{
for(i=0;i<512;i++)
{
data[i]=NF_RDDATA(); // Read one page
}
}
//ecc0=rNFECC0;
//ecc1=rNFECC1;
//ecc2=rNFECC2;
if(spare) //读入spare
{
cp=(__u8 *)spare;
for(i=0;i<16;i++)
{
cp[i]=NF_RDDATA(); // Read spare array
}
}
NF_nFCE_H();
/*if(ecc0==se[0] && ecc1==se[1] && ecc2==se[2])
{
Uart_Printf("[ECC OK:%x,%x,%x]\n",se[0],se[1],se[2]);
return 1;
}else{
Uart_Printf("[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n",
se[0],se[1],se[2],ecc0,ecc1,ecc2);
return 0;
}
*/
return YAFFS_OK;
}
//设备初始化
int k9_InitialiseNAND(yaffs_Device *dev)
{
NF_Init();
return YAFFS_OK;
}
//flash初始化函数 擦除指定范围内的块
int k9_flash_init(int startBlk,int endBlk)
{
yaffs_Device dev;
int i;
for(i=startBlk;i<=endBlk;i++)
{
k9_EraseBlockInNAND(&dev,i);
}
return YAFFS_OK;
}
//设备支持测试函数
//可以随意修改
int k9_test()
{
yaffs_Device dev;//暂时的支持函数并不需要对设备进行判断,所以在测试中不需要初始化该结构
int i;
int retVal;
__u8 buf[512];
yaffs_Spare spare;
int page;
char * sp=(char *)&spare;
k9_InitialiseNAND(&dev);
for(i=0;i<4096;i++)
{
k9_ReadChunkFromNAND(&dev,i*32,NULL,&spare);
if(!(i%16))Uart_Printf("\n%3xh",i);
if(sp[5]<0xff)
{
Uart_Printf("*");
}else{
Uart_Printf("O");
}
}
return 0;
//Erase test
for(i=0;i<100;i++)
{
retVal=k9_EraseBlockInNAND(&dev, i);
if(retVal!=YAFFS_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -