一、数据手册相关内容
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
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 }