TQ2440--nandflash(K9F2G08U0A)驱动编写

发布者:JoyfulExplorer最新更新时间:2024-08-21 来源: elecfans关键字: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 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 }


关键字:TQ2440  nandflash  K9F2G08U0A  驱动编写 引用地址:TQ2440--nandflash(K9F2G08U0A)驱动编写

上一篇:S3C2440存储系统-SDRAM驱动
下一篇:S3C2440内核蜂鸣器驱动解读

小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved