一、数据手册相关内容

1.地址传输周期

2.命令表

3.在寄存器中,会涉及TACLS,TWRPH0,TWRPH1的设定

这里我们就去看nandflash的数据手册

在这里我们可以清楚的看到,TACLS=TCLS-TWP,TWRPH0=TWP,TWRPH1=TCLH,从下表可以查到时间,并根据主频转换成CPU周期数

二、寄存器

1.NFCONF

这个寄存器的0-3位是硬件控制的,TACLS,TWRPH0,TWRPH1的值也可以怎么设定上面有讲

2.NFCONT

这个寄存器我们先只关心这两位,一个是使能nandflash控制器,一个是使能chip

3.NFCMMD,NFADDR,NFDATA

命令寄存器,地址寄存器,数据寄存器,往里面读取值就行了

4.NFSTAT

这个寄存器第0位表示nandflash是否在忙,1表示不忙可以操作

第2位表示往里面写1就是清除RnB标识位

三、裸机驱动

这个驱动主要实现简单的往nandflash里面进行初始化,擦除,写,读操作,其中第0块是保证不是坏块的,所以我们以此来测试,因为我没有JTAG线,在中间要监测某些值得话我是改成了Linux下面的驱动,用ioremap来操作nandflash,用printk来监测调试的,没有JLINK线确实挺蛋疼的,下面是在ADS下的代码

init.s

     AREA init, CODE, READONLY
ENTRY
IMPORT rNF_init
IMPORT rNF_ReadID
IMPORT rNF_Erase
IMPORT rNF_WritePage
IMPORT rNF_ReadPage
start
bl rNF_init
bl rNF_ReadID
mov r0,#
bl rNF_Erase  //擦除第0块
mov r0,#
bl rNF_WritePage  //写
mov r0,#
bl rNF_ReadPage  //读
loop    
b loop
END

nandflash.c

 #define rNFCONF  (*(volatile unsigned long *)0x4e000000)
#define rNFCONT (*(volatile unsigned long *)0x4e000004)
#define rNFCMMD (*(volatile unsigned long *)0x4e000008)
#define rNFADDR (*(volatile unsigned long *)0x4e00000c)
#define rNFDATA (*(volatile unsigned long *)0x4e000010)
#define rNFDATA8 (*(volatile unsigned char *)0x4e000010)
#define rNFSTAT (*(volatile unsigned long *)0x4e000020) #define CMD_READ_CYCLE1 0x00
#define CMD_READ_CYCLE2 0x30
#define CMD_READID 0x90
#define CMD_WRITE_CYCLE1 0x80
#define CMD_WRITE_CYCLE2 0x10
#define CMD_ERASE_CYCLE1 0x60
#define CMD_ERASE_CYCLE2 0xd0
#define CMD_STATUS 0x70
#define CMD_RESET 0xff  //这些命令都可以查表得到 #define NF_Chip_En() {rNFCONT &= ~(1<<1);} //Enable chip select
#define NF_Chip_Ds() {rNFCONT |= (1<<1);} //Disable chip select #define Wr_NF_Cmd(cmd) {rNFCMMD = (cmd);}  
#define Wr_NF_Addr(addr) {rNFADDR = (addr);} #define Wait_NF_Busy() {while(!(rNFSTAT & 1));} //等待系统不忙
#define DETECT_RB() {while(!(rNFSTAT & (1<<2)))} //RB位被检测到
#define NF_Clear_RB() {rNFSTAT |= (1<<2);} //清除RB位 #define NF_READ_DATA() (rNFDATA)  
#define NF_READ_DATA8() (rNFDATA8)  //读取一字节的数据 #define NF_WRITE_DATA(data) {rNFDATA = data;}
#define NF_WRITE_DATA8(data) {rNFDATA8 = data;} #define TACLS 1
#define TWRPH0 3
#define TWRPH1 0 #define U32 unsigned int
#define U16 unsigned short
#define U8 unsigned char

初始化:

 static void rNF_Reset()
{
NF_Chip_En();
NF_Clear_RB();
Wr_NF_Cmd(CMD_RESET);
Wait_NF_Busy();
NF_Chip_Ds();
} void rNF_init(void)
{
rNFCONF = (TACLS<<)|(TWRPH0<<)|(TWRPH1<<);
rNFCONT = (<<)|(<<)|(<<)|(<<)|(<<);
rNF_Reset();
}

ReadID:

 void delay(int num)
{
int i;
for(i=;i<num;i++);
} U8 rNF_ReadID()
{
U8 PMID,PDID,CYCLE3,CYCLE4,CYCLE5; NF_Chip_En();
NF_Clear_RB();
Wr_NF_Cmd(CMD_READID);
Wr_NF_Addr(0x0);
delay();
PMID = NF_READ_DATA8();
PDID = NF_READ_DATA8();
CYCLE3 = NF_READ_DATA8();
CYCLE4 = NF_READ_DATA8();
CYCLE5 = NF_READ_DATA8();
NF_Chip_Ds(); return PDID;
}

我们关心的是PDID,如果返回的PDID和数据手册一致,就表示nandflash设置没有什么问题了

擦除操作:

 U8 rNF_Erase(U32 block_num)
{
char state; NF_Chip_En();
NF_Clear_RB();
Wr_NF_Cmd(CMD_ERASE_CYCLE1);
Wr_NF_Addr((block_num<<) & 0xff);
Wr_NF_Addr((block_num>>) & 0xff);
Wr_NF_Addr((block_num>>) & 0xff);  //A18到A25,一次读取8位,注意移位
Wr_NF_Cmd(CMD_ERASE_CYCLE2);
delay();
Wr_NF_Cmd(CMD_STATUS); do
{
state = NF_READ_DATA8();
}while(!(state & 0x40)); NF_Chip_Ds();
return 0x66;  //0x66表示擦除成功了
}

写操作:

 U8 rNF_WritePage(U32 page_num)
{
int i;
char state; NF_Chip_En();
NF_Clear_RB();
Wr_NF_Cmd(CMD_WRITE_CYCLE1);
Wr_NF_Addr(0x00);
Wr_NF_Addr(0x00);          
Wr_NF_Addr(page_num & 0xff);
Wr_NF_Addr((page_num>>) & 0xff);
Wr_NF_Addr((page_num>>) & 0xff); for(i=;i<;i++)  //一页大小2KB
{
NF_WRITE_DATA8((char)(i+));
} Wr_NF_Cmd(CMD_WRITE_CYCLE2);
delay();
Wr_NF_Cmd(CMD_STATUS); do
{
state = NF_READ_DATA8();
}while(!(state & 0x40)); NF_Chip_Ds();
return 0x66;
}

读操作:

 void rNF_ReadPage(U32 page_num)
{
int i;
U8 buf[]; NF_Chip_En();
NF_Clear_RB();
Wr_NF_Cmd(CMD_READ_CYCLE1);
Wr_NF_Addr(0x00);
Wr_NF_Addr(0x00);
Wr_NF_Addr(page_num & 0xff);
Wr_NF_Addr((page_num>>) & 0xff);
Wr_NF_Addr((page_num>>) & 0xff);
Wr_NF_Cmd(CMD_READ_CYCLE2);
Wait_NF_Busy(); for(i=;i<;i++)
{
buf[i] = NF_READ_DATA8();
} NF_Chip_Ds();
}

TQ2440--nandflash(K9F2G08U0A)驱动编写的更多相关文章

  1. liunx中字符驱动编写的简单模板

    下面是关于字符驱动两个程序,主要是说明驱动编写的思想,理解驱动是怎么一步一步被实现的. 驱动的第一个实现程序,是相对于裸机编程的,主要是体会一下驱动编程思想: cdev.h: 所包含的头文件 #ifn ...

  2. AM335x(TQ335x)学习笔记——触摸屏驱动编写

    前面几篇文章已经通过配置DTS的方式完成了多个驱动的移植,接下来我们解决TQ335x的触摸驱动问题.由于种种原因,TQ335x的触摸屏驱动是以模块方式提供的,且Linux官方内核中也没有带该触摸屏的驱 ...

  3. Tiny4412之串口(Uart)驱动编写

    一:tiny4412串口驱动编写 1.串口通信简介 串口通信指串口按位(bit)发送和接收字节,串口通信的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口 ...

  4. Linux驱动之按键驱动编写(中断方式)

    在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...

  5. Linux驱动之按键驱动编写(查询方式)

    在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...

  6. Linux驱动:I2C驱动编写要点

    继续上一篇博文没讲完的内容“针对 RepStart 型i2c设备的驱动模型”,其中涉及的内容有:i2c_client 的注册.i2c_driver 的注册.驱动程序的编写. 一.i2c 设备的注册分析 ...

  7. Linux驱动:SPI驱动编写要点

    题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这 ...

  8. ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程

    ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程 原文地址:http://www.cnblogs.com/NickQ/p/9026545.html 一.开发板与ds18b20的入门 ...

  9. v4l2驱动编写篇【转】

    转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...

  10. nand flash详解及驱动编写

    https://www.crifan.com/files/doc/docbook/linux_nand_driver/release/html/linux_nand_driver.html#nand_ ...

随机推荐

  1. sublime主题安装

    网上发现与之前最相近的两款皮肤分别是Theme – Soda与Flatland.这里就记录一下安装与使用方法. 方法一:手动下载安装: 1.下载安装SublimeText2,这个我就不说了.网上的版本 ...

  2. 201521123104 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 1.1 建立数据库,将自己的姓名.学号作为一条记录插入.(截图, ...

  3. oracle11g 体系结构详解

    1.oracle内存由SGA+PGA所构成 2.oracle数据库体系结构数据库的体系结构是指数据库的组成.工作过程与原理,以及数据在数据库中的组织与管理机制. oracle工作原理: 1).在数据库 ...

  4. [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)

    接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...

  5. Dom4J生成xml和包含CDATA问题

    在 java注解生成xml和包含CDATA问题里面做了介绍,这里直接贴代码. 1:生成xml的java文件 package com.dufy.test.xml; import java.io.File ...

  6. Windows 编程中恼人的各种字符以及字符指针类型

    在Windows编程中,很容易见到这些数据类型:LPSTR,LPTSTR,LPCTSTR... 像很多童鞋一样,当初在学Windows编程的时候,对着些数据类型真的是丈二和尚,摸不着头脑,长时间不用就 ...

  7. MySQL数据备份之mysqldump使用(转)

    mysqldump常用于MySQL数据库逻辑备份. 1.各种用法说明 A. 最简单的用法: mysqldump -uroot -pPassword [database name] > [dump ...

  8. Jenkins 在声明式 pipeline 中并行执行任务

    在持续集成的过程中,并行的执行那些没有依赖关系的任务可以缩短整个执行过程.Jenkins 的 pipeline 功能支持我们用代码来配置持续集成的过程.本文将介绍在 Jenkins 中使用声明式 pi ...

  9. 【笔记】php常用函数

    phpusleep() 函数延迟代码执行若干微秒.unpack() 函数从二进制字符串对数据进行解包.uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID.time_sleep_unti ...

  10. Android打包版本号设置

    之前没有设置过打包的命名,每次打包都是默认的"app-realease.apk",之后手动修改名字来显示出它是一个新版本. 晚上学习了如何配置打包名称,很简单,修改build.gr ...