📄 nand.c
字号:
#include <stdlib.h>
#include <string.h>
#include "option.h"
#include "2460addr.h"
#include "2460lib.h"
#include "2460slib.h"
#include "nand.h"
#include "mmu.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_Page_Write, "Page Write ",
(void *)K9S1208_Erase, "Block Erase ",
(void *)K9S1208_Program, "Nand program ",
(void *)K9S1208_AutoLoad, "AutoLoad ",
(void *)K9S1208_AutoStore, "AutoStore ",
(void *)K9S1208_Lock, "Lock ",
(void *)K9S1208_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_Page_Write, "Page Write ",
(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)
{
unsigned char ch;
printf("[NAND Flash Controller Test start]\n\n");
printf("Select Nand flash device, K9S1208(1)/K9K2G16(2) : ");
ch=getchar();
printf("\n\n");
switch(ch) {
case '1':
Test_K9S1208(); // in K9S1208.c
break;
case '2':
Test_K9K2G16(); // in K9K2h16.c
break;
default:
break;
}
printf("[NAND Flash Controller Test end]\n");
}
void Test_K9S1208(void)
{
int i,id;
printf("====== K9S1208 Test ======\n");
NF_Init();
id=NF_CheckId();
if(id ==0x76)
printf("ID=%x(0x76)\n\n",id);
else {
printf("Selection fail : ID=%x\n",id);
return;
}
while(1)
{
i=0;
while(1)
{ //display menu
printf("%2d:%s",i,func_k9s1208_test[i][1]);
i++;
if((int)(func_k9s1208_test[i][0])==0)
{
printf("\n");
break;
}
if((i%4)==0)
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = 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_K9K2G16(void)
{
int i,id;
printf("====== K9K2G16 Test ======\n");
while(1)
{
i=0;
//printf("\n\n");
NF16_Init();
id=NF16_CheckId();
if(id==0xca)
printf("ID=%x(0xca)\n",id);
else {
printf("Selection fail : ID=%x\n",id);
return;
}
while(1)
{ //display menu
printf("%2d:%s",i,func_k9k2g16_test[i][1]);
i++;
if((int)(func_k9k2g16_test[i][0])==0)
{
printf("\n");
break;
}
if((i%4)==0)
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = 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 unsigned char NF_CheckId(void)
{
int i;
unsigned char id1, id2,id3,id4;
printf(" Check the ID of the Nand flash memory\n");
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();
//printf("\n%x,%x,%x,%x\n ",id1,id2,id3,id4);
return id2;
}
static unsigned char NF16_CheckId(void)
{
int i;
unsigned char 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)
{
rPRIORITY0|=(1<<4); // CS2 is used for nand flash controller
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)|(0<<2)|(3<<0);
// LdStrAddr illegalAccINT LoadINT StoreINT RnBINT TransMode SpareECCLock MainECCLock
// initECC Reg_nCE PageSie Lock-tight UnLock Software mode
// NF_Reset();
}
static void NF16_Init(void)
{
rPRIORITY0|=(1<<4); // CS2 is used for nand flash controller
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)|(0<<2)|(3<<0);
// LdStrAddr illegalAccINT LoadINT StoreINT RnBINT TransMode SpareECCLock MainECCLock
// initECC Reg_nCE PageSie Lock-tight Unlock Software mode
// NF16_Reset();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -