S3C2440 Nand Flash驱动(分析MTD层并制作NAND驱动)(二十三)

http://www.cnblogs.com/lifexy/p/7701181.html

1、本节使用的nand flash型号为K9F2G08U0C,它的命令如下:

1.1 我们以上图的Read ID(读ID)为例,它的时序图如下:

首先需要使用CE片选

1)使能CLE

2)发出0x90命令,并发出WE写脉冲

3)复位CLE,然后使能ALE

4)发出0x00地址,并发出WE写脉冲

5)设置CLE和ALE为低电平

6)while判断nRE(读使能)是否为低电平

7)读出8个I/O的数据,并发出RE上升沿脉冲

(我们的nand flash为8个I/O口)

 

1.2 nand flash 控制器介绍

在2440中有个nand flash 控制器,它会自动控制CLE,ALE那些控制引脚,我们只需要配置控制器,就可以直接写命令,写地址,读写数据到它的寄存器中便能完成(读写数据之前需要判断RnB脚),如下图所示:

若在nand flash 控制器下,我们读ID就只需要如下几步(非常方便):

1)将寄存器NFCONT(0x4E000004)的bit1 = 0,来使能片选

2)写入寄存器NFCMMD(0x4E000008) = 0x90,发送命令

3)写入寄存器NFADDR(0x4E00000C) = 0x00,发送地址

4)while判断nRE(读使能)是否为低电平

5)读寄存器NFDATA(0x4E000010),来读取数据

 

1.3 我们在uboot中测试,通过md和mw命令来实现读id(x要小写)

刚好对用了我们nand flash手册里的数据(0xEC表示厂家ID,0xDA表示设备ID):

若我们要退出读ID命令时,只需要reset就行,同样地,要退出读数据/写数据时,也是reset。

 

1.4 reset的命令为0xff,它的时序图如下所示:

 

1.5 同样地,参考读地址时序图来看看:

其中Column Address 对应 列地址,表示某页里的2k地址

Row Address 对应 行地址,表示具体的某一页

5个地址的周期图,如下所示:

因为我们的nand flash = 256MB = (2k*128M)b

所以row Address = 128M = 2^17(A27~A11)

所以column Adress = 2k = 2^11(A10~A0)

 

1.7 我们现在读0地址的内容

使用命令 nand dump 0读出nand flash 0地址的内容

从这一节当中的第一张图,可以发现Read,先发出00h命令,再发出30h命令。

(md.b 后面的1表示读1次)

 

2、接下来我们来参考自带的nand flash,位于drivers/mtd/nand/s3c2410.c中

2.1 为什么nand在mtd目录下

因为mtd(memory technology device 存储技术设备)是用于访问memory设备(ROM、flash)的Linux子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口

2.2 首先来看s3c2440.c的入口函数

static int __init s3c2410_nand_init(void)
{
	printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");

	platform_driver_register(&s3c2412_nand_driver);
	platform_driver_register(&s3c2440_nand_driver);
	return platform_driver_register(&s3c2410_nand_driver);
}

在入口函数中,注册了一个platform平台设备驱动,也是说当与nand flash设备匹配时,就会调用s3c2440_nand_driver->probe()来初始化

我们进入probe函数中,看看是如何初始化

static int s3c24xx_nand_probe(struct platform_device *pdev,
			      enum s3c_cpu_type cpu_type)
{
	... ...
	err = s3c2410_nand_inithw(info, pdev);    //初始化硬件hardware,设置TACLS、TWRPH0、TWRPH1通信时序等
    ... ...
	s3c2410_nand_init_chip(info, nmtd, sets);    //初始化芯片
    ... ...
	nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);    //扫描nand flash
    ... ...
	s3c2410_nand_add_partition(info, nmtd, sets);    //来添加mtd分区
    ... ...
}

通过上面代码和注释,得出:驱动主要调用内核的nand_scan()函数,add_mtd_partitions()函数,来完成注册nand flash

 

3 上面probe()里的nand_scan()扫描函数 位于 drivers/mtd/nand/nand_base.c

它会调用nand_scan()->nand_scan_ident()->nand_get_flash_type()来获取flash存储器的类型

以及nand_scan()->nand_scan_ident()->nand_tail()来构造mtd设备的成员(实现对nand flash的读,写,擦除等)

3.1 其中nand_get_flash_type()函数如下所示:

static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, struct nand_chip *chip, int busw, int *maf_id)
{
	struct nand_flash_dev *type = NULL;
	int i, dev_id, maf_idx;
	chip->select_chip(mtd, 0);//调用nand_chip结构体的成员select_chip使能flash片选

	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);//3.2调用nand_chip结构体的成员cmdfunc,发送读id命令,最后数据保存在mtd结构体里

	*maf_id = chip->read_byte(mtd);//获取厂家ID
	d
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值