📄 nand.c
字号:
#include <string.h>
#include "def.h"
#include "option.h"
#include "24a0addr.h"
#include "24a0lib.h"
#include "24a0slib.h"
#include "nand.h"
//** H/W dependent functions **
// 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 ECC3 FF FF ....
// 1block=(512+16)bytes x 32pages
// 4096block
// A[23:14][13:9]
// block page
//*******************************************************
// K9D1G08 H/W dependent functions
// block0: reserved for boot strap
// block1~8191: used for OS image
// badblock SE: xx xx xx xx xx 00 ....
// good block SE: ECC0 ECC1 ECC2 ECC3 FF FF ....
// 1block=(512+16)bytes x 32pages
// 8192block
// A[26:14][13:9]
// block page
//*******************************************************
// K9K2G16 H/W dependent functions
// block0: reserved for boot strap
// block1~2047: used for OS image
// badblock SE: xxxx xxxx xxxx xxxx xxxx 0000 ....
// good block SE: ECC0 ECC1 ECC2 ECC3 xx FFFF ....
// 1block=(1024+32)Words x 64pages
// 2048block
// A[27:17][16:11]
// block page
//*******************************************************
#define NF_CMD(cmd) {rNFCMMD=cmd;}
#define NF_ADV_CMD(cmd2,cmd1) {rNFCMMD=(cmd1|(cmd2<<8));}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_nFCE_L() {rNFCONT&=~(1<<7);}
#define NF_nFCE_H() {rNFCONT|=(1<<7);}
#define NF_RSTECC() {rNFCONT|=(1<<8);}
#define NF_RDDATA() (rNFDATA)
#define NF_WRDATA(data) {rNFDATA=data;}
#define NF_TRANSRnB() {while(!(rNFSTAT&(1<<13)));}
#define NF_CLRRnB() {(rNFSTAT|=(1<<13));}
#define NF_MECC_Lock() { rNFCONT|=(1<<9);}
#define NF_MECC_UnLock() { rNFCONT&=~(1<<9);}
#if 1
// HCLK=100Mhz
#define TECH 0x3f
#define TACLS 7//0 //1clk(0ns)
#define TWRPH0 7
#define TWRPH1 7//0 //1clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
#else
// HCLK=50Mhz
#define TECH 0x3f
#define TACLS 0 //1clk(0ns)
#define TWRPH0 1 //2clk(25ns)
#define TWRPH1 0 //1clk(10ns)
#endif
void * func_k9s1208_test[][2]=
{
//NAND x8,normal
(void *)K9S1208_PrintBadBlockNum, "View Bad Block ",
(void *)K9S1208_PrintBlock, "Page Read ",
(void *)K9S1208_Erase, "Block Erase ",
(void *)K9S1208_Program, "Write ",
(void *)K9S1208_AutoLoad, "AutoLoad ",
(void *)K9S1208_AutoStore, "AutoStore ",
//(void *)K9S1208_Lock, "Lock ",
//(void *)K9S1208_SoftUnLock, "SoftUnlock ",
0,0
};
void * func_k9d1g08_test[][2]=
{
//NAND x8,normal
(void *)K9D1G08_PrintBadBlockNum, "View Bad Block ",
(void *)K9D1G08_PrintBlock, "Page Read ",
(void *)K9D1G08_Erase, "Block Erase ",
(void *)K9D1G08_Program, "Write ",
(void *)K9D1G08_AutoLoad, "AutoLoad ",
(void *)K9D1G08_AutoStore, "AutoStore ",
//(void *)K9D1G08_Lock, "Lock ",
//(void *)K9D1G08_SoftUnLock, "SoftUnlock ",
0,0
};
void * func_k9k2g16_test[][2]=
{
//NAND x16,advance
(void *)K9k2g16_PrintBadBlockNum, "View Bad Block ",
(void *)K9k2g16_PrintBlock, "Page Read ",
(void *)K9k2g16_Erase, "Block Erase ",
(void *)K9k2g16_Program, "Write ",
(void *)K9k2g16_AutoLoad, "AutoLoad ",
(void *)K9k2g16_AutoStore, "AutoStore ",
//(void *)K9k2g16_Lock, "Lock ",
//(void *)K9k2g16_SoftUnLock, "SoftUnlock ",
0,0
};
void Ch4_NAND_FLASH_CONTROLLER(void)
{
U8 ch;
Uart_Printf("[NAND Flash Controller Test start]\n\n");
Uart_Printf("Select Nand flash device, K9S1208(1)/K9D1G08(2)/K9K2G16(3) : ");
ch=Uart_Getch();
Uart_Printf("%c\n\n", ch);
switch(ch) {
case '1':
Test_K9S1208(); // in K9S1208.c
break;
case '2':
Test_K9D1G08(); // in K9D1G08.c
break;
case '3':
Test_K9K2G16(); // in K9K2h16.c
break;
default:
break;
}
Uart_Printf("[NAND Flash Controller Test end]\n");
}
void Test_K9S1208(void)
{
int i,id;
Uart_Printf("====== K9S1208 Test ======\n");
while(1)
{
i=0;
//Uart_Printf("\n\n");
NF_Init();
id=NF_CheckId();
if(id ==0x76)
Uart_Printf("ID=%x(0x76)\n",id);
else {
Uart_Printf("Selection fail : ID=%x\n",id);
return;
}
while(1)
{ //display menu
Uart_Printf("%2d:%s",i,func_k9s1208_test[i][1]);
i++;
if((int)(func_k9s1208_test[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nPress Enter key to exit : ");
i = Uart_GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_k9s1208_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_k9s1208_test[i][0]) )();
}
}
void Test_K9D1G08(void)
{
int i,id;
Uart_Printf("====== K9D1G08 Test ======\n");
while(1)
{
i=0;
//Uart_Printf("\n\n");
NF_Init();
id=NF_CheckId();
if(id==0x79)
Uart_Printf("ID=%x(0x79)\n",id);
else {
Uart_Printf("Selection fail : ID=%x\n",id);
return;
}
while(1)
{ //display menu
Uart_Printf("%2d:%s",i,func_k9d1g08_test[i][1]);
i++;
if((int)(func_k9d1g08_test[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nPress Enter key to exit : ");
i = Uart_GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_k9d1g08_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_k9d1g08_test[i][0]) )();
}
}
void Test_K9K2G16(void)
{
int i,id;
Uart_Printf("====== K9K2G16 Test ======\n");
while(1)
{
i=0;
//Uart_Printf("\n\n");
NF16_Init();
id=NF16_CheckId();
if(id==0xca)
Uart_Printf("ID=%x(0xca)\n",id);
else {
Uart_Printf("Selection fail : ID=%x\n",id);
return;
}
while(1)
{ //display menu
Uart_Printf("%2d:%s",i,func_k9k2g16_test[i][1]);
i++;
if((int)(func_k9k2g16_test[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nPress Enter key to exit : ");
i = Uart_GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_k9k2g16_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_k9k2g16_test[i][0]) )();
}
}
static U8 NF_CheckId(void)
{
int i;
U8 id,id1, id2,id3,id4;
NF_nFCE_L();
NF_CMD(0x90);
NF_ADDR(0x0);
for(i=0;i<10;i++); //wait tWB(100ns)////?????
// id=NF_RDDATA()<<8; // Maker code(K9S1208V:0xec)
// id|=NF_RDDATA(); // Devide code(K9S1208V:0x76)
id1=NF_RDDATA(); // Maker code(K9S1208V:0xec)
id2=NF_RDDATA(); // Devide code(K9S1208V:0x76)
id3=NF_RDDATA();
id4=NF_RDDATA();
NF_nFCE_H();
//Uart_Printf("\n%x,%x,%x,%x\n ",id1,id2,id3,id4);
return id2;
}
static U8 NF16_CheckId(void)
{
int i;
U8 id1, id2,id3,id4;
NF_nFCE_L();
NF_CMD(0x90);
NF_ADDR(0x0);
for(i=0;i<10;i++); //wait tWB(100ns)////?????
id1=NF_RDDATA(); // Maker code(K9S1208V:0xec)
id2=NF_RDDATA(); // Devide code(K9S1208V:0x76)
id3=NF_RDDATA();
id4=NF_RDDATA();
NF_nFCE_H();
return id2;
}
void NF_Reset(void)
{
int i;
rNFCONT|=(3<<0); //software mode
NF_nFCE_L();
NF_CLRRnB();
NF_CMD(0xFF); //reset command
for(i=0;i<10;i++); //tWB = 100ns. //??????
NF_TRANSRnB(); //wait 200~500us;
NF_nFCE_H();
}
void NF16_Reset(void)
{
int i;
rNFCONT|=(3<<0); //software mode
NF_nFCE_L();
NF_CLRRnB();
NF_CMD(0xFF); //reset command
for(i=0;i<10;i++); //tWB = 100ns. //??????
NF_TRANSRnB(); //wait 200~500us;
NF_nFCE_H();
}
static void NF_Init(void)
{
rSROM_BW|=(1<<9);
rNFCONF=(0<<22)|(TECH<<16)|(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0);
// AdvFlash(R) [22] Advanced NAND, 0:256/512, 1:1024/2048
// TCEH [21:16] nCE High hold time
// TACLS [14:12] CLE&ALE duration = HCLK*TACLS.
// TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1)
// TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1)
// HW_nCE [3] H/W nCE control
// BusWidth(H/W set) [2] NAND bus width. 0:8-bit, 1:16-bit.
// PageSize(H/W set) [1] NAND memory page size
// when [22]==0, 0:256, 1:512 bytes/page.
// when [22]==1, 0:1024, 1:2048 bytes/page.
// AddrCycle(H/W set) [0] NAND flash addr size
// when [22]==0, 0:3-addr, 1:4-addr.
// when [22]==1, 0:4-addr, 1:5-addr.
// Advance off,Not support nCE ctl, 8bit, 512B, 4step
rNFCONT=(0<<16)|(0<<15)|(0<<14)|(0<<13)|(0<<12)|(0<<11)|(1<<10)|(1<<9)|(0<<8)|(1<<7)|(0<<4)|(0<<3)|(1<<2)|(0<<0);
// LdStrAddr illegalAccINT LoadINT StoreINT RnBINT TransMode SpareECCLock MainECCLock
// initECC Reg_nCE PageSie Lock-tight Lock Software mode
// NF_Reset();
}
static void NF16_Init(void)
{
rSROM_BW|=(1<<9);
rNFCONF=(1<<22)|(TECH<<16)|(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<3)|(1<<2)|(0<<1)|(1<<0);
// Advanced, Not support nCE ctl, 16bit, 1KHWord, 5step
rNFCONT=(0<<16)|(0<<15)|(0<<14)|(0<<13)|(0<<12)|(0<<11)|(1<<10)|(1<<9)|(0<<8)|(1<<7)|(0<<4)|(0<<3)|(1<<2)|(0<<0);
// LdStrAddr illegalAccINT LoadINT StoreINT RnBINT TransMode SpareECCLock MainECCLock
// initECC Reg_nCE PageSie Lock-tight Lock Disable all mode
NF16_Reset();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -