• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : mini2440 128M nand(K9F1G08U0B)读写的疑问 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
楼主  发表于: 2009-11-28 19:42

 mini2440 128M nand(K9F1G08U0B)读写的疑问

管理提醒: 本帖被 qq2440 从 Linux技术交流专区 移动到本区(2010-02-08)
(Update: 关于这一问题的进一步讨论,看http://www.aiothome.net/read.php?tid-5088.html
K9F1G08U0B这个手册上地址时序是四个周期(第6页),不太明白mini2440为什么用五个周期?

参考Tekkaman的移植uboot代码中int nand_read_llb(unsigned char *buf, unsigned long start_addr, int size) 函数 
(此函数在 ……/u-boot-2009.08/board/tekkamanninja/mini2440/nand_read.c中)
  (http://www.aiothome.net/read.php?tid-3539.html
  
        NFADDR = 0;
        NFADDR = 0;
        NFADDR = (i >> 11) & 0xff;
        NFADDR = (i >> 19) & 0xff;
        NFADDR = (i >> 27) & 0xff;

确实是五个周期,但是也不太明白。为什么不是这样呢:
                    
        NFADDR = 0;
        NFADDR = 0;
        NFADDR = (i >> 12) & 0xff;
        NFADDR = (i >> 20) & 0xff;
四个周期不就结束了?        
[ 此帖被kasim在2010-03-11 13:52重新编辑 ]
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2009-11-29 17:56
事实上我觉得datasheet上的写法是不对的,对于2048字节的NAND Flash来说,column地址对应的是A0~A10 (0 ~ 7ff), 而row地址对应A12~A26.
因此代码中的写法是正确的,只是最后一句 NFADDR = (i >> 27) & 0xff;看起来应该是不需要的,那只对大于128M的NAND Flash才有意义。
也许u-boot的MTD中NAND驱动部分的写法更容易让人理解:
复制代码
  1. /**
  2. * nand_command_lp - [DEFAULT] Send command to NAND large page device
  3. * @mtd:    MTD device structure
  4. * @command:    the command to be sent
  5. * @column:    the column address for this command, -1 if none
  6. * @page_addr:    the page address for this command, -1 if none
  7. *
  8. * Send command to NAND device. This is the version for the new large page
  9. * devices We dont have the separate regions as we have in the small page
  10. * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
  11. */
  12. static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
  13.                 int column, int page_addr)
  14. {
  15.     register struct nand_chip *chip = mtd->priv;
  16.     uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
  17.         .......
  18.     /* Command latch cycle */
  19.     chip->cmd_ctrl(mtd, command & 0xff,
  20.                NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
  21.     if (column != -1 || page_addr != -1) {
  22.         int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
  23.         /* Serially input address */
  24.         if (column != -1) {
  25.             /* Adjust columns for 16 bit buswidth */
  26.             if (chip->options & NAND_BUSWIDTH_16)
  27.                 column >>= 1;
  28.             chip->cmd_ctrl(mtd, column, ctrl);
  29.             ctrl &= ~NAND_CTRL_CHANGE;
  30.             chip->cmd_ctrl(mtd, column >> 8, ctrl);
  31.         }
  32.         if (page_addr != -1) {
  33.             chip->cmd_ctrl(mtd, page_addr, ctrl);
  34.             chip->cmd_ctrl(mtd, page_addr >> 8,
  35.                        NAND_NCE | NAND_ALE);
  36.             /* One more address cycle for devices > 128MiB */
  37.             if (chip->chipsize > (128 << 20))
  38.                 chip->cmd_ctrl(mtd, page_addr >> 16,
  39.                            NAND_NCE | NAND_ALE);
  40.         }
  41.     }
  42.     chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
2楼  发表于: 2009-11-29 20:47
非常感谢版主的悉心教导!

还有点疑问:那个row地址版主是不是想写:A11~A26,这样刚好就是65536。也就是说datasheet第六页上最后那个图A12和A20的起始地址写错了?而且A27应该再开一个周期?

那个27是做什么用的?应该有用吧,不然直接4个周期结束不是更省事了?
级别: 新手上路
UID: 11180
精华: 0
发帖: 7
金钱: 70 两
威望: 35 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2009-11-29
最后登录: 2010-04-09
3楼  发表于: 2009-11-29 22:24
我也刚好遇见这个问题,按照nand的芯片手册,应该是
nfaddr=i&0xff
nfaddr=(i>>8)&0x0f
nfaddr=(i>>12)&0xff
nfaddr=(i>>20)>>0xff
四个周期,但是很明显页大小是2k,如果第三个周期右移12的话就会造成2-4k这个地址和0-2k一样了,也就是说页大小成了4k.所以右移11是对的,这样刚好是2k,我读取的时候也发现右移12的话,2k内数据一样,2k到4k就不一样了,因为实际上2-4k还是读取的0-2k数据
至于5个周期是s3c2440芯片手册上根据gcon,gpg13,14,15这个接的情况决定的,可以看到原理图上接的是gcon=1所以后面需要5个地址周期。
我的问题是,即使右移了11位,2-4k数据也是不对,原因不明,因为发布的uboot那个用0x400内的数据比较,而0x400只是1k大小,对于512byte的这样就可以验证了,但是2k的应该用0x1000才可以吧,这才是4k大小,0x400属于2k内无法检验是否正确。(同时有个疑问为何0x400后面写的注释是4*1024=4k?这明明是2^10=1k阿,奇怪)希望得到解答
                                                                                            
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
4楼  发表于: 2009-11-30 09:38

 回 2楼(azfa) 的帖子

是的,抱歉那是笔误,row地址应该是A11~A26. 第五个周期(也就是第三个row地址周期)只有在NAND Flash大小超过128M的时候才有意义。
beggar提到的是boot from NAND的特殊情况,因为硬件Boot ROM代码(实现将NAND Flash前4K数据复制到SRAM中的那部分代码)根据GPG13,14,15的配置来配置NAND Flash Controller,因此,这时候会输入5个地址周期,但这不影响NAND Flash的操作,因为K9F1G08会忽略所有超过4个周期的地址周期(手册第6页注释)。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 11180
精华: 0
发帖: 7
金钱: 70 两
威望: 35 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2009-11-29
最后登录: 2010-04-09
5楼  发表于: 2009-11-30 10:29
ldr r0,=_TEXT_BASE
      ldr r1,=0x0
      mov r2,#0x20000
      bl read_nand_ll
      tst r0,#0x0
      beq testequ
lll:  b lll
testequ:
     ldr r0,=_TEXT_BASE
     ldr r1,=0x0
    mov r2,#0x800
testp:ldr r3,[r1],#4
     ldr r4,[r0],#4
     teq r3,r4
     bne notmatch
     subs r2,r2,#4
     beq done    
     bne testp
notmatch:
     ldr r0,=LEDCON
     mov r1,#0x15400
     str r1,[r0]
     ldr r0,=LEDDAT
     mov r1,#0xef
     str r1,[r0]
here: b here
done:ldr r0,=LEDCON
     mov r1,#0x15400
     str r1,[r0]
     ldr r0,=LEDDAT
     mov r1,#0x0
     str r1,[r0]
abc: b abc
版主我的意思是这个,当我把0x20000这么大128k代码拷到sdram中的时候,用来比较0x800内(2k大小)这样的话数据是没错的,led灯也全亮了(证明进入了done里面)。而当我比较0x1000(4k大小)的时候灯亮了一个,进入了notmatch里面,说明2k到4k的数据有不相同的,只有0-2k的数据是相同的。在read_nand_ll里面我是按照128m的那种操作来的,和大家用的一样。因为大家用的是0x400比较,这个在0-2k里面没有超过一页,所以验证不出来问题。不知道版主有没有验证过2k之后的数据是不是一样?
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
6楼  发表于: 2009-11-30 11:16

 回 5楼(beggar) 的帖子

我没有追踪过这段代码,我想你可以在AXD里把这两部分memory dump出来比较一下4K大小的内容是否一致。(应该是一样的,否则uboot不可能正常启动)
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 11180
精华: 0
发帖: 7
金钱: 70 两
威望: 35 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2009-11-29
最后登录: 2010-04-09
7楼  发表于: 2009-11-30 18:24
谢谢版主,是我自己写错了
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
8楼  发表于: 2009-12-01 09:21
恩,我也试过了,4K也没什么问题。
级别: 骑士
UID: 11942
精华: 1
发帖: 144
金钱: 775 两
威望: 155 点
贡献值: 1 点
综合积分: 308 分
注册时间: 2009-12-25
最后登录: 2022-01-16
9楼  发表于: 2010-01-12 09:54

 回 6楼(kasim) 的帖子

我也在这个问题上困扰了很久,看到kasim的解释,真是豁然开朗,但还有一事不明:
SpareField不计入地址吗?若计入的话每页是2112个字节,那么11位地址就不够了啊
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go