• 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 }
  • 相关阅读:
    Git在AndroidStudio中的使用(一)
    自定义SiidingMenu简单实现
    圆形ImageView的简单实现
    使用PullToRefresh实现下拉刷新和上拉加载
    XMLpull解析使用
    Xutils简单使用
    友盟第三方登录和分享的使用
    ImageLoader简单使用
    Android中利用LinearLayout动态添加控件
    数据库两大神器【索引和锁】
  • 原文地址:https://www.cnblogs.com/losing-1216/p/4892028.html
Copyright © 2020-2023  润新知