分类: 嵌入式
2014-02-22 21:34:45
为什么要支持nand启动?这是面试的时候问的一个问题,结果我说是就是多一种支持,事后想想回答的太笨了啊,最起码也得回答个nand便宜啊,至于从sd卡驱动,以后再说。。
nand启动原理很简单,就是用nand的读方法从当前地址拷贝到链接地址,其中的难点是写地址。
以K9F2G08 (256M*8bit) 为例,其地址周期如下图:
其中列地址A0-A10也称为页内地址;行地址A12-A28也成为页号,即页的号码,第五周期的A28也成为块号。而A11是给OOB用的对OOB没有研究,先略过。。。
所以对于向页内的某个地址读写,其实际的地址排布是A28、A27、A26、... ...A13、A12、A10、A9、A8、... ...A2、A1、A0 (没有A11)。
另一个难点(也说不上难点,我掌握的不好而已)是关于内存的步长。开始我是这么写的:
#define NFDATA (*((volatile unsigned long *)0x4E000010))
。。。。。。
static unsigned long nand_read_data(void)
{
return NFDATA;
}
。。。。。。
static void nand_read_to_buf(unsigned char *buf, unsigned long addr, unsigned long count)
{
volatile int i = 0;
unsigned long col = addr & 0x7ff;
nand_select();
while (i < count)
{
nand_write_cmmd(0x00);
nand_write_addr(addr);
nand_write_cmmd(0x30);
nand_wait_ready();
for (; (col < 2048) && (i < count); i++, addr++, col++)
{
buf[i] = nand_read_data();
}
col = 0;
}
nand_deselect();
}
但是启动不起来,原因是nand_read_to_buf()的第一个参数buf是char *类型的,而nand_read_data()的返回值类型是unsigned long,肯定不对了,所以应该把nand_read_data()的返回值类型改为unsigned char,#define NFDATA (*((volatile unsigned char*)0x4E000010))。
另一种改法就是步长为四字节的处理,但这样的话要求判断是否对齐,而且大小端的问题也要注意到,等系统学习完一遍了在研究。