Chinaunix首页 | 论坛 | 博客
  • 博客访问: 566107
  • 博文数量: 169
  • 博客积分: 2656
  • 博客等级: 少校
  • 技术积分: 1685
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-30 13:03
文章分类

全部博文(169)

文章存档

2011年(1)

2010年(135)

2009年(33)

我的朋友

分类: 嵌入式

2010-06-23 23:04:39

以前总是急着弄好,然后就懒得写笔记了,这次做点写点吧。
一、配置
  1. void NF_InitCfg(void)
  2. {
  3.     rNFCONF=(1<<12)|(3<<8)|(0<<4)|(0<<0);
  4.     // TACLS        [14:12]    CLE&ALE set time = HCLK*TACLS.
  5.     // TWRPH0        [10:8]    WE&RE pulse hold time = HCLK*(TWRPH0+1)
  6.     // TWRPH1        [6:4]    CLE&ALE hold time= HCLK*(TWRPH1+1)
  7.     // AdvFlash(R)    [3]        Advanced NAND, 0:256/512, 1:1024/2048
  8.     // PageSize(R)    [2]        NAND memory page size
  9.     //                        when [3]==0, 0:256, 1:512 bytes/page.
  10.     //                        when [3]==1, 0:1024, 1:2048 bytes/page.
  11.     // AddrCycle(R)    [1]        NAND flash addr size
  12.     //                        when [3]==0, 0:3-addr, 1:4-addr.
  13.     //                        when [3]==1, 0:4-addr, 1:5-addr.
  14.     // BusWidth(R/W) [0]    NAND bus width. 0:8-bit, 1:16-bit.
  15.     rNFCONT=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
  16.     // Lock-tight    [13]    0:Disable lock, 1:Enable lock.
  17.     // Soft Lock    [12]    0:Disable lock, 1:Enable lock.
  18.     // EnablillegalAcINT[10]    Illegal access interupt control. 0:Disable, 1:Enable
  19.     // EnbRnBINT    [9]        RnB interrupt. 0:Disable, 1:Enable
  20.     // RnB_TrandMode[8]        RnB transition detection config. 0:Low to High, 1:High to Low
  21.     // SpareECCLock    [6]        0:Unlock, 1:Lock
  22.     // MainECCLock    [5]        0:Unlock, 1:Lock
  23.     // InitECC(W)    [4]        1:Init ECC decoder/encoder.
  24.     // Reg_nCE        [1]        0:nFCE=0, 1:nFCE=1.
  25.     // NANDC Enable    [0]        operating mode. 0:Disable, 1:Enable.
  26. }
复制代码

注意,这里片选为不选中状态,因为我们现在还不工作。
 
 
二、片选
  1. void NF_ENbit(void)
  2. {
  3.         rNFCONT&=~(1<<1);
  4. }
复制代码
这简单,看手册就会了。
 
 
三、read id.
基本上,一般的设备第一步做的都是读id.
  1. void NF_ReadId(void)
  2. {        
  3.         U32 id;
  4.         NF_InitCfg();
  5.         NF_ENbit();
  6.         
  7.         rNFCMD=0x90;
  8.         rNFADDR=0x00;
  9.         while(!(rNFSTAT&1));
  10.         id=rNFDATA;
  11.         Uart_Printf("nand flash chip info:0x%x",id);
  12. }
  13.         
复制代码
这里讲一下:void NF_ReadId(void)
{        
        U32 id;//用来保留id的。
        NF_InitCfg();//初始化配置。这里准备好工作了,只差片选。
        NF_ENbit();//这里片选,工作。
        
        rNFCMD=0x90;//发送命令,为读id.请见数据手册。
        rNFADDR=0x00;//发送地址,这里是id存放的地址吧,可能是,这里没仔细看呢,有懂的说下。
        while(!(rNFSTAT&1));//等ready信号,发送cmd信号后,nand就处于busy,直到发送完id.
        id=rNFDATA;//读id.
        Uart_Printf("nand flash chip info:0x%x",id);
}
在main时加入函数。我读到的结果是:0xc0a576ec.
手册上讲,先发的是maker code,生产厂家吧:ec.第二个byte是76.为device code.第三个:oa,我的手册上讲是don't care bits,
1st Byte
2nd Byte
3rd Byte
4th Byte
Maker Code
Device Code
Must be don’t -cared
Supports Multi Plane Operation
但别人说法还不一样,可能手册也有不同吧。但这里固定是a5.下一个也固定是c0.总之,这个值每次读都是一样的才对。
关于这四个数,有人说他的手册上有表格,有人说没找到,我的是在时序图上写着的,是read id operation那一节的时序图上标的。
 
修改了一下函数名:
  1. static void NF_EnChip(void)
  2. {
  3.         rNFCONT&=~(1<<1);
  4. }
  5. static void NF_DisChip(void)
  6. {
  7.         rNFCONT|=(1<<1);
  8. }
复制代码
就是片选的函数,又加了片不选。
 
 
 
小试了一下读操作,没有想ecc.结果读出来的全是0xff
  1. void NF_ReadId(void)
  2. {        
  3.         U32 id;
  4.         ;NF_InitCfg();
  5.         NF_EnChip();
  6.         
  7.         rNFCMD=0x90;
  8.         rNFADDR=0x00;
  9.         while(!(rNFSTAT&1));
  10.         id=rNFDATA;
  11.         Uart_Printf("Nand flash chip info data:0x%x.\n",id);
  12.         if(id==0xc0a576ec)
  13.         Uart_Printf("Nand flash chip detected.\n");
  14. }
复制代码

再main函数里调用这个:
  1. void nftest(void)
  2. {
  3.         NF_InitCfg();
  4.         NF_ReadId();
  5.         NF_EraseBlock(0x40);
  6.        
  7.         NF_ReadPage(0x40);
  8. }
复制代码

为什么用0x40呢?用再大些的也可以,但别用太大,超过空间大小,也别用小的,这个数刚刚好不是擦除第一个块。大家也知道,第一个块很金贵的。在一千次擦写下保证不会坏,这块如果坏了,就可能不能从nandflash启动了,主要是前4K,所以还是用后一点的做实验吧。
 
再试一下,我写的都是0x55,主要也为测一下读的好用不好用,还好,读出来的都是0x55.
  1. static void NF_WritePage(U32 pageaddr)
  2. {
  3.         int i;
  4.         U8 stat;
  5.         NF_EnChip();
  6.         rNFCMD=0x80;                //write block cmd
  7.         rNFADDR=(0);
  8.         rNFADDR=(pageaddr);
  9.         rNFADDR=(pageaddr>>8);
  10.         rNFADDR=(pageaddr>>16);
  11.         for(i=0;i<528;i++)
  12.                 rNFDATA8=0x55;
  13.         rNFCMD=0x10;
  14.         while(!(rNFSTAT&1));
  15.         rNFCMD=0x70;
  16.         stat=rNFDATA8;
  17.         stat&=0x1;
  18.         NF_DisChip();
  19.         Uart_Printf("Write page 0x%x %s\n", pageaddr, stat?"fail":"ok");
  20. }
复制代码
调用函数如下:
  1. void nftest(void)
  2. {
  3.         NF_InitCfg();
  4.         NF_ReadId();
  5.         NF_EraseBlock(0x40);
  6.         NF_WritePage(0x40);
  7.         NF_ReadPage(0x40);
  8. }
  9.        
复制代码
 
下面讲讲吧,上面弄好了,但也有很多地方现在才想通。nand flash里面有528byte的寄存器,大吧!是这么说的。反正我们从rNFDATA中读数据时,就是从这些寄存器里面读写。前面busy等待ready那段时间,nand flash把存储单元的内容放到寄存器里,我们每data=rNFDATA一次就从里面读32位数据,指针(想必nand flash里面会有一个吧)就会向后移4个位置。data=rNFDATA8,则只读8bits,指针移动一个位置。

擦和写时,我们都会再写一次确让命令,如果写时,我们for循环后有一个,擦则没有循环,写完地址就直接有。
阅读(1604) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~