zoukankan      html  css  js  c++  java
  • 9.NandFlash的驱动_读操作2440

    9.NandFlash的驱动_读操作

    在Makefile里添加nand.o,然后新建一个nand.c来实现NandFlash的读操作。

    对NandFlash的读方式有两种:

    1. 按页读(需要提供页地址,也就是行地址)。
    2. 随机读(就是读取页里的某一列,需要提供页地址,也就是行地址和列地址)。

    实现页读需要两个操作,一个是页地址,另一个是存放读出的数据的变量。所以定义的函数的原型:

    void NF_PageRead(unsigned long addr,unsigned char* buff)

    该函数根据NandFlash的手册:K9F2G08U0A.pdf中读的操作流程:

    上面是TQ2440NandFlash读的操作流程,最下面的I/Ox是I/O pin角的输入输出信号。首先是发送命令:00h。接着是发送5个周期的地址Address(5Cycle):三个周期的行地址和两个周期的列地址。

    发送完地址后,紧接着就是发送命令30h。接着就是等待R/B信号变为高电平。从上图可以看到,当我们发送完30h命令后,信号从高电平变成低电平,进入忙的状态。这是CPU开始处理前面发送的命令和地址。等待完后就可以读取数据了。

        上面是页读的流程,但是这里需要补充一些公共的步骤:

        首先你要操作NandFlash,必须要先选中。接着是清除R/B信号。接着才是上面的操作。操作完,最后还得加上:取消选中NandFlash芯片。操作步骤如下:

    从上面的步骤可以看到,首先是要选中NandFlash芯片,是通过NFCONT这个寄存器的[1]位来操作的:

    从上面的说明看到,如果要Enable chip select,就是把[1]位置为0即可。然后习惯在操作NandFlash前要使能片选,操作完会禁止片选。一般写入0是采用与操作,写入1是采用或操作。所以代码实现:

    选中NandFlash芯片:

    上面,我们把[1]位先置为1,再取反变为0,最后与NFCONT相与,是NFCONT的[1]位为0.实现片选NandFlash。

    上面是取消片选,情况跟使能片选相反。

    接着是R/B信号的处理,它是在NFSTAT寄存器里的:

    之所以需要先清除R/B信号,这是因为在进行一次NandFlash的操作前要确保上一次的操作已经被清除了,不会影响到这一次的操作。就是要先把这一位变为0,即是清除。然后后面我们只要检查这一位如果是1即可认为NandFlash处于可读写状态。然后注意到跟前面的中断一样,要把某一位变为0,就是往对应的位写入1.

    实现代码:

    清除完后就是发送命令00h了。

    命令00h作为参数,通过send_cmd传递给NFCMD寄存器。

    发送完命令就是发送地址了。

    首先是发送列地址,但是这里采用按页读的,所以列地址都是0,由于每一次发送0位,所以是0x00,由下面的时序图知道,需要发送两次列地址。

    实现代码:

    发送完列地址,接着就是发送行地址。行地址是按照从低位到高位的顺序来发送,每次发送8位。三个周期的行地址的方式如下:

    按照时序图,接下来是发送0x30命令,

    发送完命令后进入等待,等待前面的操作完成。完成的标识是R/B信号变为高电平:

    等待完R/B信号后,根据时序图,我们就可以实现信号的读取了。

    读取是从NFDATA寄存器里面读取的。

    每个页的大小在2440里是2K,根据型号不同,值可能不同。最后按页读的操作:

    这里实现了NandFlash读的基本操作,但是在前面的学习知道,在操作一个硬件之前必须对该硬件进行初始化操作。

    NandFlash初始化的操作流程:

    NandFlash初始化要配置NandFlash的配置寄存器NFCONF和寄存器NFCONT

    三个时序图的关系:

    上面三个参数的取值运算:

    我们的nandflash使用的HCLK,频率是100MHz的。那么他每震动一次对应的时间是10ns(1/100MHz).

    上面有算TACLS>0ns

    TWFPH0>12ns

    TWFPH1>5ns的公式。

    要实现duration=HCLK*TACLS=10ns*TACLS>0,只需要取TACLS=1,即可。

    要实现duration=HCLK*(TWRPH0+1)=10ns*(TWRPH0+1)>12ns,只需要TWRPH0=2即可

    要实现duration=HCLK*(TWRPH1+1)=10ns*(TWRPH1+1)>5ns,只需要TWRPH1=1,即可。

    上面就是配置NandFlash配置寄存器的参数。

    下面是NandFlash的控制寄存器

    接下来是初始化我们的NFCONT。

    先使能控制器,然后让取消片选:

    操作完成还需要第三步是复位操作:

    可以看到复位的操作很简单,就是发送FFh命令,然后等待R/B信号,等待从低变高表示完成了。

    上面的学习知道,要操作NandFlash,首先要选中NandFlash,然后清除R/B信号。接着才是发送ffh命令来复位NandFlash,等待R/B信号复位完成。最后要取消选中NandFlash。

    实现:

    最后的NandFlash的初始化流程代码:

    到这里我们才完成了NandFlash读的全部操作。

    前面的学习知道:

    从上面知道,当系统上电后,会拷贝NandFlash里的4KB代码到Stepping Stone去运行。而实际运行stepping stone里代码的是拷贝到内存里去运行的,最大是4KB。所以如果当我们的uboot的代码大于4KB的时候,就会拷贝不全,导致运行出错。

    前面之所以要这样做是因为当初没有学习NandFlash的知识,不会直接从NandFlash拷贝代码到内存去运行,而是通过垫脚石。所以下面就直接从NandFlash拷贝代码到内存去运行,这样的程序就完整了。

    要实现按页拷贝NandFlash里的内容,首先需要知道页的首地址。

    这里地址的0-11位是列地址,即是页内偏移量。我们要的是页地址,所以需要把低12位去掉。按页拷贝的代码:

    最后是修改start.S文件:

    在内存初始化:

    完成之后,由于我们的NandFlash的初始化是用C实现的,所以在调用NandFlash初始化的函数前需要对堆栈进行初始化。所以跳转如下:

    最后是跳转到copy_to_ram,即是从iRam拷贝到内存运行的,此时我们是直接把NandFlash的代码拷贝到内存去运行了,所以此处的代码也需要修改。

    上面就完成了所有的操作,make编译。

    上面是2440和6410的操作步骤,但是210的还需要修改一个寄存器MPLLCON.

  • 相关阅读:
    转!!MySQL中的存储引擎讲解(InnoDB,MyISAM,Memory等各存储引擎对比)
    转!!left join on and 与 left join on where的区别
    swoole WebSocket 消息推送
    基于swoole搭建聊天室程序
    使用php+swoole对client数据实时更新(下)
    使用php+swoole对client数据实时更新(上)
    swoole实现websocket推送
    PHP只显示姓名首尾字符,隐藏中间字符并用*替换
    微信小程序 tp5上传图片
    thinkphp 调用wsdl接口实例化SoapClient抛出异常
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188808.html
Copyright © 2011-2022 走看看