以前总是急着弄好,然后就懒得写笔记了,这次做点写点吧。
一、配置
- void NF_InitCfg(void)
- {
- rNFCONF=(1<<12)|(3<<8)|(0<<4)|(0<<0);
- // TACLS [14:12] CLE&ALE set time = HCLK*TACLS.
- // TWRPH0 [10:8] WE&RE pulse hold time = HCLK*(TWRPH0+1)
- // TWRPH1 [6:4] CLE&ALE hold time= HCLK*(TWRPH1+1)
- // AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048
- // PageSize(R) [2] NAND memory page size
- // when [3]==0, 0:256, 1:512 bytes/page.
- // when [3]==1, 0:1024, 1:2048 bytes/page.
- // AddrCycle(R) [1] NAND flash addr size
- // when [3]==0, 0:3-addr, 1:4-addr.
- // when [3]==1, 0:4-addr, 1:5-addr.
- // BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit.
- rNFCONT=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
- // Lock-tight [13] 0:Disable lock, 1:Enable lock.
- // Soft Lock [12] 0:Disable lock, 1:Enable lock.
- // EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable
- // EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable
- // RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low
- // SpareECCLock [6] 0:Unlock, 1:Lock
- // MainECCLock [5] 0:Unlock, 1:Lock
- // InitECC(W) [4] 1:Init ECC decoder/encoder.
- // Reg_nCE [1] 0:nFCE=0, 1:nFCE=1.
- // NANDC Enable [0] operating mode. 0:Disable, 1:Enable.
- }
复制代码 注意,这里片选为不选中状态,因为我们现在还不工作。
二、片选
- void NF_ENbit(void)
- {
- rNFCONT&=~(1<<1);
- }
复制代码 这简单,看手册就会了。
三、read id.
基本上,一般的设备第一步做的都是读id.
- void NF_ReadId(void)
- {
- U32 id;
- NF_InitCfg();
- NF_ENbit();
-
- rNFCMD=0x90;
- rNFADDR=0x00;
- while(!(rNFSTAT&1));
- id=rNFDATA;
- Uart_Printf("nand flash chip info:0x%x",id);
- }
-
复制代码 这里讲一下: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那一节的时序图上标的。
修改了一下函数名:
- static void NF_EnChip(void)
- {
- rNFCONT&=~(1<<1);
- }
- static void NF_DisChip(void)
- {
- rNFCONT|=(1<<1);
- }
复制代码 就是片选的函数,又加了片不选。
小试了一下读操作,没有想ecc.结果读出来的全是0xff
- void NF_ReadId(void)
- {
- U32 id;
- ;NF_InitCfg();
- NF_EnChip();
-
- rNFCMD=0x90;
- rNFADDR=0x00;
- while(!(rNFSTAT&1));
- id=rNFDATA;
- Uart_Printf("Nand flash chip info data:0x%x.\n",id);
- if(id==0xc0a576ec)
- Uart_Printf("Nand flash chip detected.\n");
- }
复制代码 再main函数里调用这个:
- void nftest(void)
- {
- NF_InitCfg();
- NF_ReadId();
- NF_EraseBlock(0x40);
-
- NF_ReadPage(0x40);
- }
复制代码 为什么用0x40呢?用再大些的也可以,但别用太大,超过空间大小,也别用小的,这个数刚刚好不是擦除第一个块。大家也知道,第一个块很金贵的。在一千次擦写下保证不会坏,这块如果坏了,就可能不能从nandflash启动了,主要是前4K,所以还是用后一点的做实验吧。
再试一下,我写的都是0x55,主要也为测一下读的好用不好用,还好,读出来的都是0x55.
- static void NF_WritePage(U32 pageaddr)
- {
- int i;
- U8 stat;
- NF_EnChip();
- rNFCMD=0x80; //write block cmd
- rNFADDR=(0);
- rNFADDR=(pageaddr);
- rNFADDR=(pageaddr>>8);
- rNFADDR=(pageaddr>>16);
- for(i=0;i<528;i++)
- rNFDATA8=0x55;
- rNFCMD=0x10;
- while(!(rNFSTAT&1));
- rNFCMD=0x70;
- stat=rNFDATA8;
- stat&=0x1;
- NF_DisChip();
- Uart_Printf("Write page 0x%x %s\n", pageaddr, stat?"fail":"ok");
- }
复制代码 调用函数如下:
- void nftest(void)
- {
- NF_InitCfg();
- NF_ReadId();
- NF_EraseBlock(0x40);
- NF_WritePage(0x40);
- NF_ReadPage(0x40);
- }
-
复制代码
下面讲讲吧,上面弄好了,但也有很多地方现在才想通。nand flash里面有528byte的寄存器,大吧!是这么说的。反正我们从rNFDATA中读数据时,就是从这些寄存器里面读写。前面busy等待ready那段时间,nand flash把存储单元的内容放到寄存器里,我们每data=rNFDATA一次就从里面读32位数据,指针(想必nand flash里面会有一个吧)就会向后移4个位置。data=rNFDATA8,则只读8bits,指针移动一个位置。
擦和写时,我们都会再写一次确让命令,如果写时,我们for循环后有一个,擦则没有循环,写完地址就直接有。
阅读(1682) | 评论(0) | 转发(0) |