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

📄 k9s1208.c

📁 USB_ON_s3c2410 USB_ON_s3c2410
💻 C
📖 第 1 页 / 共 2 页
字号:

#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 + -