TQ2440--nandflash(K9F2G08U0A)驱动编写

一、数据手册相关内容

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 }

 

posted @ 2015-10-19 15:21  L_free  阅读(399)  评论(0编辑  收藏  举报