天嵌 ARM开发社区

 找回密码
 注册
查看: 5286|回复: 13

关于突破nand flash 4K的疑惑???

[复制链接]
albert 发表于 2010-12-29 15:18:58 | 显示全部楼层 |阅读模式
我参考韦山东的第8章关于把nand flash 4k外的程序拷到sdram上执行的代码,因为韦山东使用开发板的nand flash是64M的,是K9F1208U0M,每一页是512Byte,而天嵌2440开发板用的是256M的nand flash ,是K9F2G08R0B,每一页的大小是2048Byte,在读nand flash数据时,K9F2G08R0B需要二个命令字,分别是00h,30h,而K9F1208U0M的需要一个命令字 00H.
其次还有就是地址序列的不同, K9F1208U0M 是4个地址序列,而K9F2G08R0B 是5个地址序列

我根据他们的不同,修改了一下程序,下载到天嵌2440开发板上,没有流水灯现象出现(程序是流水灯),不知道那里出了问题了,

以前没操作过nand flash的读取,对时序不是很了解, 那位帮忙看看

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
吕氏春秋8266 发表于 2010-12-29 15:44:12 | 显示全部楼层
兄弟,你这玩意还扣钱,太狠了吧!!!
 楼主| albert 发表于 2010-12-29 16:13:24 | 显示全部楼层
不对啊,我添加附件是时,那个阅读权限是为0的啊,可能是论坛默认设置的吧,我要这钱干嘛?难道大于0的时候下载才不用钱?
问问版主才知道了
天嵌_support1 发表于 2010-12-29 17:31:11 | 显示全部楼层
2# 吕氏春秋8266


是论坛的规矩的
不是那位网友的定制了。
要有劳动才能有了收获
吕氏春秋8266 发表于 2010-12-29 17:59:14 | 显示全部楼层

NAND操作体会

本帖最后由 吕氏春秋8266 于 2010-12-29 18:23 编辑

这几天我也在学习NAND/LCD操作,说说我这几天学习的体会,大家共同进步
    地址序列要正确,A11是用来对space区域进行操作,故传送行地址时应为[A11~A27]
     当使用DWN下载程序到NAND时,如果NAND未擦除或有坏块时,感觉DWN将跳过坏块或未擦除,而我们程序中没有坏块管理,读取相应块时数据显然不正确。故建议用9/2命令对NAND进行擦除后再下载,不要用1命令。
   个人在编写LCD驱动程序时,打算显示4张图像(4.3屏),程序近1M,用DWN下载到SDRAM中执行能正确显示前2张,后2张就不行,个人感觉DWN没有完全下载数据。没办法,这个问题没法解决,只好下载到NAND中并编程读取NAND中数据,每一次图片就只显示半张,下面为白屏,后3张能显示,但都错开了(第1张下半部和第2张上半部显示在一起,最后一张只显示上半部)。只好用JLINK连接硬件调试,发放读取的数据有近128K全为FF(即第1张图片下半部为白色),明显不正确,这时明白,DWN下载时自动跳过该坏块,由于我们读取NAND程序没有坏块管理,将读取坏块数据,故后3张图片因坏块而错开,第1张只显示上半部。
    明白原因后,用9/2命令擦除NAND后,再下载NAND中,程序运行完全正常。
   个人建议,当程序运行不正确时,多用JLINK硬件调试查找原因,在调试过程中,会发觉很多细节,让你对硬件的操作有更深的了解。
   我曾经在JLINK硬调试中读页操作命令后,读取4096个字节,看看后2048个字节是什么,也曾经
在未擦除页的情况下再写入数据,最后读出看看结果,通过这类测试,对NAND的操作有了更深入的了解。
天嵌_support1 发表于 2010-12-29 18:22:52 | 显示全部楼层
:)
 楼主| albert 发表于 2010-12-29 18:43:51 | 显示全部楼层
本帖最后由 albert 于 2010-12-29 18:47 编辑

地址序列要正确,A11是用来对space区域进行操作,故传送行地址时应为[A11~A27]?
其他的地址不需要?
K9F2G08R0B的地址序列是下面的:
          I/O 0 I/O 1 I/O 2 I/O 3 I/O 4 I/O 5 I/O 6 I/O 7
1st Cycle  A0 A1 A2 A3 A4 A5 A6 A7
2nd Cycle A8 A9 A10 A11 *L *L *L *L
3rd Cycle A12 A13 A14 A15 A16 A17 A18 A19
4th Cycle A20 A21 A22 A23 A24 A25 A26 A27
5th Cycle A28 *L *L *L *L *L *L *L
与K9F1208U0M的地址序列是不同的。。

我尝试格式化nand flash后再下载程序,还是没流水灯现象,该不会是程序没写对吧?
吕氏春秋8266 发表于 2010-12-29 20:43:31 | 显示全部楼层
本帖最后由 吕氏春秋8266 于 2010-12-29 20:45 编辑

如果我们传送地址用addr[31~0]表示,注意不是用行和页地址表示
则列地址为addr[10~0]共11位寻址空间为2048
行地址为addr [27~11]共17位建地空间为131072行
列地址1st addr[7~0】
      2st addr[10~8]  A11(I/0)3 位必须置0读取space区域置1根据情况设置
行地址3st addr[18~11]
         4st addr[26~19]
         5st addr[27]
吕氏春秋8266 发表于 2010-12-29 21:00:58 | 显示全部楼层
如果读取整页数据,列地址设置为0即可
吕氏春秋8266 发表于 2010-12-29 21:51:06 | 显示全部楼层
本帖最后由 吕氏春秋8266 于 2010-12-29 21:54 编辑

static void s3c2440_write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
   
    *p = addr & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 8) & 0x07;a11 0   
for(i=0; i<10; i++);
    *p = (addr >> 11) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 19 & 0xff;
    for(i=0; i<10; i++);
   *p = (addr >> 27 & 0x01;
    for(i=0; i<10; i++);

}
machoe 发表于 2010-12-30 13:01:34 | 显示全部楼层
:lol
 楼主| albert 发表于 2010-12-30 15:04:58 | 显示全部楼层
本帖最后由 albert 于 2010-12-30 15:06 编辑

*p = (addr >> 8) & 0x07;a11 0   
for(i=0; i<10; i++);
    *p = (addr >> 11) & 0xff;
这个传送地址的话,   *p = (addr >> 8) & 0x07把A11置为0,而*p = (addr >> 11) & 0xff;
保持A11的原值,如果刚好地址是1的话,那不是要出错了吗?A11好像传了2次?  
还有 *p = (addr >> 27 & 0x01  这个A28不要了?
还是很糊涂....

static void s3c2440_write_addr(unsigned int addr)

{

    int i;

    volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;



    int col,page;

    col=addr & NAND_BLOCK_MASK ;

    page=addr / NAND_SECTOR_SIZE;

   

    *p = col & 0xff;

    for(i=0; i<10; i++);

    *p = (col >> 8) & 0x0f;

    for(i=0; i<10; i++);



    *p=page & 0xff;

    for(i=0; i<10; i++);

    *p = (page >> 8) & 0xff;

    for(i=0; i<10; i++);

    *p = (addr >> 16) & 0x03;

    for(i=0; i<10; i++);
}

这个代码也可以实现,但也不明白。。。。。。。
吕氏春秋8266 发表于 2010-12-30 15:26:11 | 显示全部楼层
最根本在于读取256M空间需要的28位地址,也就是说,addr[27~0].其中addr[10~0]11位2^11=2048表示列地址(不考虑space)addr[27~11]=17位表示2^17=131072行表示行地址。所以传送列地址为0~10
行地址为11~27.后一种函数将地址转换为列,行,前一种函数实现是传送整个地址,其实质是一样的。  
   col=addr & NAND_BLOCK_MASK ;
    page=addr / NAND_SECTOR_SIZE;
将地址转换为列,行地址,你自己可以看看,列地址col取addr中第几位到几位,同理,行地址将addr移位,你也可以看年它取addr中的第几位到第几位,一看就明白了。
wbche 发表于 2011-3-14 11:27:12 | 显示全部楼层
5# 吕氏春秋8266


谢谢,学习了,终于明白为什么了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-22 11:28 , Processed in 1.031250 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表