声明:下面我们均以16位宽的Nor Flash芯片MX29LV160DBTI为例讲解。涉及的程序见最后面附录。
本文章为个人学习心得记录,如有错误,还望多多指正!
其实驱动Nor Flash比较简单,方法就是在Nor Flash芯片手册里,厂家已经给我们定义了各种的命令,用以实现对Nor Flash芯片的复位reset操作、进入CFI模式、擦除指定扇区、写入数据操作等。
我们只需要查看表格,往指定的地址(相对于Nor Flash来说)写入命令或写入数据即可。
其芯片手册中的命令部分截图:
比如:
使Nor Flash进入CFI模式:我们只需要往地址0x55写入98H即可(此地址0x55是相对于Nor Flash的地址总线来看的,是该16位宽Nor Flash芯片一个存储单元(2字节大小)的地址,CPU直接发出0x55地址,是不行的)。
又因为我们的JZ2440 开发板上所用的Nor Flash芯片为16位宽。所以CPU与其的地址连线有着特殊的对应连接,CPU的A1地址线连的是Nor Flash芯片的A0。
需要错位连接的原因是:ARM处理器的每个地址对应的是一个Byte的数据单元,而16-bit的FLASH的每个地址对应的是一个16bit大小的数据单元。为了将CPU地址转换为Nor Flash存储单元的地址,所以必须错位连接。
两者之间这样的地址连线,使CPU的系统总线地址cpu_addr与Nor Flash的设备总线地址device_addr(即Nor中数据单元的地址)之间存在如下关系:
系统总线地址cpu_addr = Nor Flash的设备总线地址device_addr <<1。
上表中的地址0x55是设备总线地址device_addr,即该16位宽Nor Flash芯片一个存储单元(2字节大小)的地址,所以0x55<<1=0xaa,变成地址0x55对应的系统总线地址cpu_addr。
这样CPU发出向地址0xaa写入数据98h的命令,Nor Flash地址线收到的地址就是0x55,这样就完成了Nor Flash认为的向0x55写入98h操作。这里的0x55为offset。
/*jz2440,nor---bank0,片选信号nGCS0*/
/*base addr = 0*/
#define NOR_FLASH_BASE 0
/*函数功能:向nor flash内指定地址写入一个字*/
/*比如:原意是往地址0x55写入0x98--->往(0+(0x55<<1))写入0x98*/
void nor_write_word(unsigned int base,unsigned int offset,unsigned int v