nand flash 地址问题

prettyboybaoxiaopeng 2011-02-07 09:08:54

谁能解释一下,这款nand flash的column address为什么是A0-A11呀?

按理应该2K=2^11,用11根地址线,所以从A0-A10就可以了呀?
...全文
508 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
tczhangyan120 2012-07-27
  • 打赏
  • 举报
回复
这张表是错的,
一、a0-a7;
二、a8-a10;
三、a11-a18;
四、a19-a26;
五、a27-a28;

一~二为列地址即页地址(2k);
三~五为行地址,即一块地址(128k);
embeddedstudy 2011-02-13
  • 打赏
  • 举报
回复
你可以看下这个帖子,和你的问题差不多,里面有更详细的讨论
http://www.100ask.net/showtopic-3179.aspx
  • 打赏
  • 举报
回复




结贴



回复内容太短了!
  • 打赏
  • 举报
回复
花自飘零水自流,一种相思两处闲愁
embeddedstudy 2011-02-11
  • 打赏
  • 举报
回复
关于64bytes的附加信息的操作,楼上的博文写的不错,受教了。
而对于普通数据,楼主用的2g08的系列,也就是page里2048bytes的寻址[Quote=引用 9 楼 prettyboybaoxiaopeng 的回复:]
第3周期发送的是(addr>>11)&0xff
[/Quote]
按照一般的做法,应该是把地址和2047逻辑与,得到的结果是column的数目,然后按照周期写入开发板相应的寄存器里,第一个周期是a0~a7,也就是低8位的地址,第二个周期是a8~a11的地址,但因为是寻址普通数据,这里应该是col>>8&0x0f,这样才符合芯片手册上的周期图。
你说的第3个周期是寻址row addr的地址了,和page里的地址无关。row addr寻址的是page的数目。具体到哪一个page里的地址,再用column addr寻址。
这两天正好在学nandflash的知识,不知道我说的对不对。
loongembedded 2011-02-11
  • 打赏
  • 举报
回复
这和我想的没错呀,是不是数据手册错了?????
---》数据手册错的概率很低,一般是我们的理解出错了
访问你们说的spare area即OOB,是不是有特别的指令,不需要寻址的呀?
---》不需要特别的,楼主可以参考我的博文:
http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx
blancell 2011-02-11
  • 打赏
  • 举报
回复
数据手册应该没问题的,你把这段代码贴出来看看.
embeddedstudy 2011-02-11
  • 打赏
  • 举报
回复
汗,我被你带过去了,自己也说错了。不是a11为0,而是寻不到那个spare area的地址,就是
2048~2111这个范围。
embeddedstudy 2011-02-11
  • 打赏
  • 举报
回复
因为是普通数据,不涉及spare area,范围从0~2047,2048~2111,所以a11是永远为0的,是用不到的。你自己随便找个地址换成二进制算算就知道了。。。我确实不会想到你是问这个问题。。。
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 embeddedstudy 的回复:]

你问出那样的问题来不正是说明了没有搞懂结构吗?
start_addr和A0 A1 A2。。。。。A25的每一位对应起来,这个完全正确。
而i是start_addr>>11的值,和A0 A1 A2....A11已经无关了。说的这么清楚了,你再把顶楼贴的那张图好好对照的理解一下吧。
[/Quote]
“而i是start_addr>>11的值,和A0 A1 A2....A11已经无关了。”呵呵,A0-A11共12位呀,要是无关,就应该是start_addr>>12了啦,这才是我问的问题?明白?
embeddedstudy 2011-02-11
  • 打赏
  • 举报
回复
你问出那样的问题来不正是说明了没有搞懂结构吗?
start_addr和A0 A1 A2。。。。。A25的每一位对应起来,这个完全正确。
而i是start_addr>>11的值,和A0 A1 A2....A11已经无关了。说的这么清楚了,你再把顶楼贴的那张图好好对照的理解一下吧。
Ejack79 2011-02-11
  • 打赏
  • 举报
回复
11L的博文里以及NAND Flash的数据手册里面已经写的再清楚不过了:
main field的列地址是0~2047,spare field的列地址是2048~2111。

而且rLB_ReadPage这个函数根本就没有操作到spare field。

简单来说LZ通过rLB_ReadPage多操作一些字节,超过页大小(例如到2060),然后再试验体会体会。
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 embeddedstudy 的回复:]

引用 13 楼 prettyboybaoxiaopeng 的回复:
引用 11 楼 loongembedded 的回复:
楼主可以参考我的博文:
http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx


确实,这里NewSpareAddr=2048时,用到了A11,(2048>>8)&0x……
[/Quote]

老兄,回帖前,先看清问题好不好
embeddedstudy 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 prettyboybaoxiaopeng 的回复:]
引用 11 楼 loongembedded 的回复:
楼主可以参考我的博文:
http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx


确实,这里NewSpareAddr=2048时,用到了A11,(2048>>8)&0xff =1000b A11=1,且在第二周期时给出。
但是这里是NewSect……
[/Quote]
看了你的代码,关键你没有看清rLB_ReadPage()这个函数传的形参是什么。
第一个形参是i,i = (start_addr >> 11)这个i已经是右移11位以后的数字了,那就是row addr,就是行地址,然后在这一块页里再从0-2047一个个读出来复制到内存中去。这个>>11和你所说的column addr没有任何关系,这个是row addr。你没有理解行和列在nandflash的结构是怎么分布的,先理解这一点再去看程序,一看就明白了。
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 loongembedded 的回复:]
楼主可以参考我的博文:
http://blog.csdn.net/LoongEmbedded/archive/2010/11/17/6015302.aspx
[/Quote]

确实,这里NewSpareAddr=2048时,用到了A11,(2048>>8)&0xff =1000b A11=1,且在第二周期时给出。
但是这里是NewSectorAddr却是直接给出的,具体是右移11还是12位来的无法知道。
下面看一段TQ2440开发板的程序

static void rLB_ReadPage(U32 addr, unsigned char * to)
{
U32 i;

rNF_Reset();

// Enable the chip
NF_nFCE_L();
NF_CLEAR_RB();

// Issue Read command
NF_CMD(CMD_READ);

// Set up address
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR((addr) & 0xff);
NF_ADDR((addr >> 8) & 0xff);
NF_ADDR((addr >> 16) & 0xff);

NF_CMD(CMD_READ3);

NF_DETECT_RB(); // wait tR(max 12us)

for (i = 0; i < 2048; i++)
{
to[i] = NF_RDDATA8();
}

NF_nFCE_H();

}


void RdNF2SDRAM( )
{
U32 i;
U32 start_addr = 0x6400000;
unsigned char * to = (unsigned char *)0x30000000;
U32 size = 0x100000;
void (* app)(void);
app = (void(*)(void))to;
rNF_Init();
for(i = (start_addr >> 11); size > 0; )
{
rLB_ReadPage(i, to);
size -= 2048;
to += 2048;
i ++;
}

(*app)();
}


位了验证这段程序的正确性,我对它稍稍加工了一点,当从nand flash启动时RdNF2SDRAM()函数会被调用,会从0x6400000(100M)的地方复制0x100000(1M)大小的东西到内存0x30000000开始运行,我用u-boot在0x6400000出写入特定的代码,然后执行这段程序,运行正确,说明这段程序确完成了它的功能

关键是看RdNF2SDRAM()函数中调用rLB_ReadPage()时传递的addr参数

// Set up address
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR((addr) & 0xff);
NF_ADDR((addr >> 8) & 0xff);
NF_ADDR((addr >> 16) & 0xff);

可以看出addr就是第三周期传出的页地址,而在for(i = (start_addr >> 11); size > 0; )这句看出它是由start_addr>>11位得到的。

总上所述,将start_addr>>11得到页地址是不会错的了,但是

这图也应该没错,开始也用到了A11,找一个折中的解释,就是我们犯了一个错误,我们错误的将start_addr(读写地址)的每一位与上图中A0 A1 A2。。。。。A25的每一位对应起来,如果认为start_addr的第一位是A1的,那么start_addr>>11不就从A12开始了么,问题就顺利解决了。
这是我想法,大家有想法也可以说出来讨论讨论。。。。。。



  • 打赏
  • 举报
回复
[Quote=引用 7 楼 loongembedded 的回复:]

引用 4 楼 blancell 的回复:
我认为还要加上spare的,那就等于2112了,所以是A0-A11.

是的,我们对nandflash的一页寻址的范围包括main area和spare area,其中你的使用的nandflash一页的main area大小是2k,spare area的大小是64bytes,所以需要12个数据线才能完全寻址到2k+64
[/Quote]

刚从U-boot的源码中和开发板的配套程序中都发现:
寻址时在第3周期发送了(addr>>11)//第三周期发送的页地址,右移了11位,说明,A0到A10这11位是
column address,即页内偏移,从A11开始就是page address了,这和我想的没错呀,是不是数据手册错了?????
访问你们说的spare area即OOB,是不是有特别的指令,不需要寻址的呀?
loongembedded 2011-02-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 blancell 的回复:]
我认为还要加上spare的,那就等于2112了,所以是A0-A11.
[/Quote]
是的,我们对nandflash的一页寻址的范围包括main area和spare area,其中你的使用的nandflash一页的main area大小是2k,spare area的大小是64bytes,所以需要12个数据线才能完全寻址到2k+64
Ejack79 2011-02-10
  • 打赏
  • 举报
回复
LZ看下正文描述就会明白的。例如:
引用
The K9XXGXXXXM is a 4224Mbit (4,429,185,024 bit) memory organized as 262,144 rows(pages) by 2112x8(X8 device) or
1056x16(X16 device) columns.

每行都有若干备用列,例如对于8位器件来说,是2048+64列。因此列地址多1位。
诚如4L所言。
  • 打赏
  • 举报
回复
第3周期发送的是(addr>>11)&0xff
blancell 2011-02-09
  • 打赏
  • 举报
回复
我认为还要加上spare的,那就等于2112了,所以是A0-A11.
加载更多回复(2)

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧