NAND Flash驱动

发布时间:2024-07-31  

硬件原理及分析

管脚说明

   

   

Pin Name

Pin Function

R/B(RnB)

The R/B output indicates the status of the device operation. When low, it indicates that a program, erase or random read

operation is in process and returns to high state upon completion. It is an open drain output and does not float to high-z condition when the chip is deselected or when outputs are disabled.

CLE(CLE)

The CLE input controls the activating path for commands sent to the command register. When active high, commands are

latched into the command register through the I/O ports on the rising edge of the WE signal.

CE(nFCE)

The CE input is the device selection control. When the device is in the Busy state, CE high is ignored, and the device does

not return to standby mode in program or erase operation.

ALE(ALE)

The ALE input controls the activating path for address to the internal address registers. Addresses are latched on the rising

edge of WE with ALE high.

WE(nFWE)

The WE input controls writes to the I/O port. Commands, address and data are latched on the rising edge of the WE pulse.

RE(nFRE)

The RE input is the serial data-out control, and when active drives the data onto the I/O bus. Data is valid tREA after the falling

edge of RE which also increments the internal column address counter by one.

I/O(LDATA0-LDATA7)

The I/O pins are used to input command, address and data, and to output data during read operations. The I/O pins float to

high-z when the chip is deselected or when the outputs are disabled.

   

在U-BOOT上操作Nand Flash

NAND FLASH S3C2440

发命令 选中芯片

CLE设为高电平 NFCMMD=命令值

在DATA0~DATA7上输出命令值

发出一个写脉冲

 

发地址 选中芯片 NFADDR=地址值

ALE设为高电平

在DATA0~DATA7上输出地址值

发出一个写脉冲

   

发数据 选中芯片 NFDATA=数据值

ALE,CLE设为低电平

在DATA0~DATA7上输出数据值

发出一个写脉冲

   

读数据 选中芯片 val=NFDATA

发出读脉冲

读DATA0~DATA7的数据

   

 

OpenJTAG> help md

md [.b, .w, .l] address [# of objects]

- memory display

   

OpenJTAG> help mw

mw [.b, .w, .l] address value [count]

- write memory

•b        1字节

•W        2字节

•l        4字节

 

   

1. 读ID

S3C2440

u-boot

选中 NFCONT的bit1设为0

md.l 0x4E000004 1; mw.l 0x4E000004 1

发出命令0x90 NFCMMD=0x90

mw.b 0x4E000008 0x90

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

读数据得到0xEC val=NFDATA

md.b 0x4E000010 1

读数据得到device code val=NFDATA

md.b 0x4E000010 1

退出读ID的状态 NFCMMD=0xff

mw.b 0x4E000008 0xff

 

2. 读内容: 读0地址的数据

使用UBOOT命令:

nand dump 0

Page 00000000 dump:

17 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5

   

S3C2440

u-boot

选中 NFCONT的bit1设为0

md.l 0x4E000004 1; mw.l 0x4E000004 1

发出命令0x00 NFCMMD=0x00

mw.b 0x4E000008 0x00

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

发出地址0x00 NFADDR=0x00

mw.b 0x4E00000C 0x00

发出命令0x30 NFCMMD=0x30

mw.b 0x4E000008 0x30

读数据得到0x17 val=NFDATA

md.b 0x4E000010 1

读数据得到0x00 val=NFDATA

md.b 0x4E000010 1

读数据得到0x00 val=NFDATA

md.b 0x4E000010 1

读数据得到0xea val=NFDATA

md.b 0x4E000010 1

退出读状态 NFCMMD=0xff

mw.b 0x4E000008 0xff

   

ECC的作用

 

 

 

S3C2440-Nand Flash Controller Register

 

   

S3C2440-Nand Flash Memory Timing

   

K9F2G08U0C-Key Characteristic

   

K9F2G08U0C-Operation Timing

   

   

驱动程序

driver.c

1 /*
2 * SAMSUNG: K9F2G08U0C
3 * 参考:
4 * .linux-2.6.22.6driversmtdnands3c2410.c
5 * .linux-2.6.22.6driversmtdnandat91_nand.c
6 */
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18         
19 #include
20 #include
21 #include
22 #include
23         
24 #include
25         
26 #include
27 #include
28
29 struct regs_nand {
30         unsigned long         NFCONF;                
31         unsigned long        NFCONT;                 
32         unsigned long        NFCMMD;                 
33         unsigned long        NFADDR;                 
34         unsigned long        NFDATA;
35         unsigned long        NFMECCD0;
36         unsigned long        NFMECCD1;
37         unsigned long        NFSECCD;
38         unsigned long        NFSTAT;
39         unsigned long        NFESTAT0;         
40         unsigned long        NFESTAT1;
41         unsigned long        NFMECC0;                
42         unsigned long        NFMECC1;                        
43         unsigned long        NFSECC;                 
44         unsigned long        NFSBLK;                 
45         unsigned long        NFEBLK;
46 };
47
48 static struct nand_chip *nand;
49 static struct mtd_info *mtd;
50 static struct regs_nand *regs_nand;
51
52 //分区信息
53 static struct mtd_partition nand_parts[] = {
54         [0] = {
55                 .name         = "bootloader",                        
56                 .size         = 0x00040000,                        
57                 .offset = 0,                                        /* offset within the master MTD space */
58         },
59
60         [1] = {
61                 .name         = "params",                        
62                 .offset = MTDPART_OFS_APPEND,        //紧跟着上一个分区的大小
63                 .size         = 0x00020000,                        
64         },
65
66         [2] = {
67                 .name         = "kernel",                                
68                 .offset = MTDPART_OFS_APPEND,        //紧跟着上一个分区的大小
69                 .size         = 0x00200000,                        
70         },
71
72         [3] = {
73                 .name         = "root",                                
74                 .offset = MTDPART_OFS_APPEND,        //紧跟着上一个分区的大小
75                 .size         = MTDPART_SIZ_FULL,                
76         },
77 };
78
79 static void nand_select_chip(struct mtd_info *mtd, int chipnr)
80 {
81         if (chipnr == -1)
82         {
83                 //取消选中:NFCONT[1]:0
84                 regs_nand->NFCONT |= (1<<1);
85         }
86         else {
87                 //选中:NFCONT[1]:1
88                 regs_nand->NFCONT &= ~(1<<1);
89         }
90         return;
91 }
92
93 static void nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
94 {
95         if (ctrl & NAND_CLE)
96         {
97                 //发命令:NFCMMD=dat
98                 regs_nand->NFCMMD = dat;
99         }
100         else
101         {
102                 //发地址:NFADDR=dat
103                 regs_nand->NFADDR = dat;
104         }
105         return;
106 }
107
108 static int nand_dev_ready(struct mtd_info *mtd)
109 {
110         return (regs_nand->NFSTAT & (1<<0));
111 }
112
113
114 /* 1 出、入口函数 */
115 static int __init nand_init(void)
116 {
117         struct clk *clk;
118
119         /* 2 分配一个nand_chip结构体 */
120         nand = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
121         /******** 2 end ********/
122
123         regs_nand = ioremap(0x4E000000, sizeof(struct regs_nand));
124
125         /* 3 设置:nand_chip */
126         //提供:选中、发命令、发地址、发数据、读数据、判断状态的功能
127         nand->select_chip         = nand_select_chip;                //片选
128         nand->cmd_ctrl                = nand_cmd_ctrl;                //发命令
129         nand->IO_ADDR_R                = ®s_nand->NFDATA;        //读
130         nand->IO_ADDR_W                = ®s_nand->NFDATA;        //写
131         nand->dev_ready                = nand_dev_ready;                //Flash 状态(忙/空闲)
132         nand->ecc.mode                = NAND_ECC_SOFT;                //ecc软件校验
133         /******** 3 end ********/
134
135         /* 4 硬件相关的操作:时序 */
136         //使能时钟
137         clk = clk_get(NULL, "nand");
138         clk_enable(clk);
139         
140 #define TACLS        0
141 #define TWRPH0        1
142 #define TWRPH1        0
143         //时间参数设置
144         regs_nand->NFCONF        = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
145
146         //控制---使能nand flash控制器,取消片选
147         regs_nand->NFCONT        = (1<<0) | (1<<1);
148         /******** 4 end ********/
149         
150
151         /* 5 使用:nand_scan */
152         mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
153         mtd->owner        = THIS_MODULE;
154         mtd->priv        = nand;                //私有数据
155         
156         nand_scan(mtd, 1);                //识别nand_flash,构造mtd_info结构体
157         /******** 5 end ********/
158
159
160         /* 6 添加分区:add_mtd_partitions */
161         add_mtd_partitions(mtd, nand_parts, 4);
162
163         //不分区的情形
164         //add_mtd_device(mtd);
165         /******** 6 end ********/
166
167         return 0;
168 }
169
170 static void __exit nand_exit(void)
171 {
172         del_mtd_partitions(mtd);
173         kfree(nand);
174         kfree(mtd);
175         iounmap(regs_nand);
176         return;
177 }
178
179 module_init(nand_init);
180 module_exit(nand_exit);
181 MODULE_LICENSE("GPL");
182 /******** 1 end ********/

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    戴尔科技做到了:• 公布[ii]设备驱动程序和下载发布时间表,使IT管理员可以按照预期的时间表对整个机群进行设备更新。• 对每次更新中的所有驱动程序和BIOS模块实施[iii]集成验证。戴尔科技的商用PC系统......
    戴尔科技做到了: 公布[ii]设备驱动程序和下载发布时间表,使IT管理员可以按照预期的时间表对整个机群进行设备更新。 对每次更新中的所有驱动程序和BIOS模块实施[iii]集成验证。 戴尔科技的商用PC系统......
    制作一个STM32下载器的过程;本文介绍制作一个STM32下载器的过程。 原理图 STLINK-V2下载器电路原理图如下。 上图中,H5接口是固件下载口。H4接口是STLINK-V2下载口(实现下载......
    ,需先将下方固件下载到本地电脑端,若使用在线工具Web BDT(https://debug.telink-semi.cn/web_bdt/index.html),则可在线下载固件。(两个bin......
    部分是需要进行替换的。默认的SBSFU 用户固件只是一个示例,不符合用户的场景。同时例子固件仅支持从UART 传输固件。实际中的固件则是需要支持从网络接受固件。这一点在改动时,可以修改固件下载部分。STM32......
    合用户的场景。同时例子固件仅支持从UART传输固件。实际中的固件则是需要支持从网络接受固件。这一点在改动时,可以修改固件下载部分。STM32 SBSFU的固件下载部分和固件解密部分是分开的。固件下载可以在用户固件......
    MaxWit及其中的g-bios 在mini2440的初次使用;前段时间上网的时候无意中看到了国内的一个开源项目maxwit,看了其中的介绍感觉还不错,所以就下载了相关的文档和源码试着用了用。经过......
    数单片机都支持两种升级模式:ISP模式和IAP模式。ISP模式是通过串口将固件下载到芯片内部进行升级,而IAP模式则是将固件下载到芯片外部的存储器中,然后通过程序控制将固件写入到芯片内部进行升级。 4. 连接......
    低功耗、手机应用软件“ST BLE Sensor” 实验1:STM32固件下载和演示测试 连接B-L475-IOT01A 用Micro USB线连接到B-L475-IOT01A 连接之后,驱动......
    前获得对新处理器的支持,华硕官方网站相关产品支持页面已有最新的UEFI BIOS可供下载。 率先全面支持英特尔新一代处理器 支持USB BIOS Flashback功能的华硕100系主......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>