TQ2440--nandflash(K9F2G08U0A)驱动编写
一、数据手册相关内容
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)驱动编写的更多相关文章
- liunx中字符驱动编写的简单模板
下面是关于字符驱动两个程序,主要是说明驱动编写的思想,理解驱动是怎么一步一步被实现的. 驱动的第一个实现程序,是相对于裸机编程的,主要是体会一下驱动编程思想: cdev.h: 所包含的头文件 #ifn ...
- AM335x(TQ335x)学习笔记——触摸屏驱动编写
前面几篇文章已经通过配置DTS的方式完成了多个驱动的移植,接下来我们解决TQ335x的触摸驱动问题.由于种种原因,TQ335x的触摸屏驱动是以模块方式提供的,且Linux官方内核中也没有带该触摸屏的驱 ...
- Tiny4412之串口(Uart)驱动编写
一:tiny4412串口驱动编写 1.串口通信简介 串口通信指串口按位(bit)发送和接收字节,串口通信的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口 ...
- Linux驱动之按键驱动编写(中断方式)
在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...
- Linux驱动之按键驱动编写(查询方式)
在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...
- Linux驱动:I2C驱动编写要点
继续上一篇博文没讲完的内容“针对 RepStart 型i2c设备的驱动模型”,其中涉及的内容有:i2c_client 的注册.i2c_driver 的注册.驱动程序的编写. 一.i2c 设备的注册分析 ...
- Linux驱动:SPI驱动编写要点
题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这 ...
- ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程
ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程 原文地址:http://www.cnblogs.com/NickQ/p/9026545.html 一.开发板与ds18b20的入门 ...
- v4l2驱动编写篇【转】
转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...
- nand flash详解及驱动编写
https://www.crifan.com/files/doc/docbook/linux_nand_driver/release/html/linux_nand_driver.html#nand_ ...
随机推荐
- Java 第九周总结
1. 本周学习总结 2. 书面作业 1.常用异常 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避免? 以前的代码经常出现空指针的,需 ...
- 201521123062《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synch ...
- 201521123009 《Java程序设计》第10周学习总结
1. 本周学习总结 2. 书面作业 本次PTA作业题集异常.多线程 Q1:finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? tr ...
- 201521123029《Java程序设计》第十二周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...
- 小巧玲珑:机器学习届快刀XGBoost的介绍和使用
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:张萌 序言 XGBoost效率很高,在Kaggle等诸多比赛中使用广泛,并且取得了不少好成绩.为了让公司的算法工程师,可以更加方便的 ...
- org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method test() on null context object
前言 本文中提到的解决方案,源码地址在:springboot-thymeleaf,希望可以帮你解决问题. 至于为什么已经写了一篇文章thymeleaf模板引擎调用java类中的方法,又多此一举的单独整 ...
- mybatis-basedao的实现
package com.yangwei.shop.dao; import java.util.HashMap; import java.util.List; import java.util.Map; ...
- 分享一个图片上传插件(TP5.0)
效果预览图: 该插件主要功能是:可预览裁剪图片和保存原图片,执行裁剪图片后会删除 裁剪的原图片目录,以便减少空间.一.下载附件 地址:https://pan.baidu.com/s/1bpxZhM3 ...
- js如何获取客户端IP
1.在HTML页面里面引入<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> 2.获取 ...
- BZOJ2748_音量调节_KEY
[HAOI2012]音量调节 Time Limit: 3 Sec Memory Limit: 128 MB Description 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以 ...