一、数据手册相关内容
1.地址传输周期
2.命令表
3.在寄存器中,会涉及TACLS,TWRPH0,TWRPH1的设定
这里我们就去看nandflash的数据手册
在这里我们可以清楚的看到,TACLS=TCLS-TWP,TWRPH0=TWP,TWRPH1=TCLH,从下表可以查到时间,并根据主频转换成CPU周期数
二、寄存器
1.NFCONF
这个寄存器的0-3位是硬件控制的,TACLS,TWRPH0,TWRPH1的值也可以怎么设定上面有讲
2.NFCONT
这个寄存器我们先只关心这两位,一个是使能nandflash控制器,一个是使能chip
3.NFCMMD,NFADDR,NFDATA
命令寄存器,地址寄存器,数据寄存器,往里面读取值就行了
4.NFSTAT
这个寄存器第0位表示nandflash是否在忙,1表示不忙可以操作
第2位表示往里面写1就是清除RnB标识位
三、裸机驱动
这个驱动主要实现简单的往nandflash里面进行初始化,擦除,写,读操作,其中第0块是保证不是坏块的,所以我们以此来测试,因为我没有JTAG线,在中间要监测某些值得话我是改成了Linux下面的驱动,用ioremap来操作nandflash,用printk来监测调试的,没有JLINK线确实挺蛋疼的,下面是在ADS下的代码
init.s
1 AREA init, CODE, READONLY 2 ENTRY 3 IMPORT rNF_init 4 IMPORT rNF_ReadID 5 IMPORT rNF_Erase 6 IMPORT rNF_WritePage 7 IMPORT rNF_ReadPage 8 start 9 bl rNF_init 10 bl rNF_ReadID 11 mov r0,#0 12 bl rNF_Erase //擦除第0块 13 mov r0,#0 14 bl rNF_WritePage //写 15 mov r0,#0 16 bl rNF_ReadPage //读 17 loop 18 b loop 19 END
nandflash.c
1 #define rNFCONF (*(volatile unsigned long *)0x4e000000) 2 #define rNFCONT (*(volatile unsigned long *)0x4e000004) 3 #define rNFCMMD (*(volatile unsigned long *)0x4e000008) 4 #define rNFADDR (*(volatile unsigned long *)0x4e00000c) 5 #define rNFDATA (*(volatile unsigned long *)0x4e000010) 6 #define rNFDATA8 (*(volatile unsigned char *)0x4e000010) 7 #define rNFSTAT (*(volatile unsigned long *)0x4e000020) 8 9 #define CMD_READ_CYCLE1 0x00 10 #define CMD_READ_CYCLE2 0x30 11 #define CMD_READID 0x90 12 #define CMD_WRITE_CYCLE1 0x80 13 #define CMD_WRITE_CYCLE2 0x10 14 #define CMD_ERASE_CYCLE1 0x60 15 #define CMD_ERASE_CYCLE2 0xd0 16 #define CMD_STATUS 0x70 17 #define CMD_RESET 0xff //这些命令都可以查表得到 18 19 #define NF_Chip_En() {rNFCONT &= ~(1<<1);} //Enable chip select 20 #define NF_Chip_Ds() {rNFCONT |= (1<<1);} //Disable chip select 21 22 #define Wr_NF_Cmd(cmd) {rNFCMMD = (cmd);} 23 #define Wr_NF_Addr(addr) {rNFADDR = (addr);} 24 25 #define Wait_NF_Busy() {while(!(rNFSTAT & 1));} //等待系统不忙 26 #define DETECT_RB() {while(!(rNFSTAT & (1<<2)))} //RB位被检测到 27 #define NF_Clear_RB() {rNFSTAT |= (1<<2);} //清除RB位 28 29 #define NF_READ_DATA() (rNFDATA) 30 #define NF_READ_DATA8() (rNFDATA8) //读取一字节的数据 31 32 #define NF_WRITE_DATA(data) {rNFDATA = data;} 33 #define NF_WRITE_DATA8(data) {rNFDATA8 = data;} 34 35 #define TACLS 1 36 #define TWRPH0 3 37 #define TWRPH1 0 38 39 #define U32 unsigned int 40 #define U16 unsigned short 41 #define U8 unsigned char
初始化:
1 static void rNF_Reset() 2 { 3 NF_Chip_En(); 4 NF_Clear_RB(); 5 Wr_NF_Cmd(CMD_RESET); 6 Wait_NF_Busy(); 7 NF_Chip_Ds(); 8 } 9 10 void rNF_init(void) 11 { 12 rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); 13 rNFCONT = (1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0); 14 rNF_Reset(); 15 }
ReadID:
1 void delay(int num) 2 { 3 int i; 4 for(i=0;i<num;i++); 5 } 6 7 U8 rNF_ReadID() 8 { 9 U8 PMID,PDID,CYCLE3,CYCLE4,CYCLE5; 10 11 NF_Chip_En(); 12 NF_Clear_RB(); 13 Wr_NF_Cmd(CMD_READID); 14 Wr_NF_Addr(0x0); 15 delay(1000); 16 PMID = NF_READ_DATA8(); 17 PDID = NF_READ_DATA8(); 18 CYCLE3 = NF_READ_DATA8(); 19 CYCLE4 = NF_READ_DATA8(); 20 CYCLE5 = NF_READ_DATA8(); 21 NF_Chip_Ds(); 22 23 return PDID; 24 }
我们关心的是PDID,如果返回的PDID和数据手册一致,就表示nandflash设置没有什么问题了
擦除操作:
1 U8 rNF_Erase(U32 block_num) 2 { 3 char state; 4 5 NF_Chip_En(); 6 NF_Clear_RB(); 7 Wr_NF_Cmd(CMD_ERASE_CYCLE1); 8 Wr_NF_Addr((block_num<<6) & 0xff); 9 Wr_NF_Addr((block_num>>2) & 0xff); 10 Wr_NF_Addr((block_num>>10) & 0xff); //A18到A25,一次读取8位,注意移位 11 Wr_NF_Cmd(CMD_ERASE_CYCLE2); 12 delay(1000); 13 Wr_NF_Cmd(CMD_STATUS); 14 15 do 16 { 17 state = NF_READ_DATA8(); 18 }while(!(state & 0x40)); 19 20 NF_Chip_Ds(); 21 return 0x66; //0x66表示擦除成功了 22 }
写操作:
1 U8 rNF_WritePage(U32 page_num) 2 { 3 int i; 4 char state; 5 6 NF_Chip_En(); 7 NF_Clear_RB(); 8 Wr_NF_Cmd(CMD_WRITE_CYCLE1); 9 Wr_NF_Addr(0x00); 10 Wr_NF_Addr(0x00); 11 Wr_NF_Addr(page_num & 0xff); 12 Wr_NF_Addr((page_num>>8) & 0xff); 13 Wr_NF_Addr((page_num>>16) & 0xff); 14 15 for(i=0;i<2048;i++) //一页大小2KB 16 { 17 NF_WRITE_DATA8((char)(i+6)); 18 } 19 20 Wr_NF_Cmd(CMD_WRITE_CYCLE2); 21 delay(1000); 22 Wr_NF_Cmd(CMD_STATUS); 23 24 do 25 { 26 state = NF_READ_DATA8(); 27 }while(!(state & 0x40)); 28 29 NF_Chip_Ds(); 30 return 0x66; 31 }
读操作:
1 void rNF_ReadPage(U32 page_num) 2 { 3 int i; 4 U8 buf[2048]; 5 6 NF_Chip_En(); 7 NF_Clear_RB(); 8 Wr_NF_Cmd(CMD_READ_CYCLE1); 9 Wr_NF_Addr(0x00); 10 Wr_NF_Addr(0x00); 11 Wr_NF_Addr(page_num & 0xff); 12 Wr_NF_Addr((page_num>>8) & 0xff); 13 Wr_NF_Addr((page_num>>16) & 0xff); 14 Wr_NF_Cmd(CMD_READ_CYCLE2); 15 Wait_NF_Busy(); 16 17 for(i=0;i<2048;i++) 18 { 19 buf[i] = NF_READ_DATA8(); 20 } 21 22 NF_Chip_Ds(); 23 }