备注:K9F2G08U0A.pdf

如何计算出我们要传入的行地址和列地址

以K9K8G08U0A为例,此Nand Flash,一共有8192个块,每个块内有64页,每个页是2K+64 Bytes
假设,我们要访问其中的第7000个块中的第25页中的1208字节处的地址,此时,我们就要先把具体的地址算出来
0x36B204B8 = 11 0110 1011 0010 00000100 1011 1000

1st周期,A7~A0 :1011 1000 = 0x B8
2nd周期,A10~A8 :100 = 0x04
3rd周期,A19~A12 :010 0000 0 = 0x40
4th周期,A27~A20 :110 1011 0 = 0xD6
5th周期,A30~A28 :11 0 = 0x06

要访问第7000个块中的第25页中的1208字节处,对应着:
页内地址 = 1208 = 0x4B8
页号 = 块数 × 页数/块 + 块内的页号 = 7000×(128K/2K)+ 25 = 7000×64 + 25 = 448025 = 0x6D619
0x6D619页内的0x4B8地址

对应的:
页内地址=0x4B8,分成两个对应的列地址,就变成:
0x4B8 :列地址1=0xB8,列地址2=0x04
页号=0x6D619,分成三个行号就是:
0x6D619:行号1=0x19,行号2=0xD6,行号3=0x06

#define NFCONF           ( *((volatile unsigned long *)0xB0E00000) )
#define NFCONT          ( *((volatile unsigned long *)0xB0E00004) )
#define NFCMMD          ( *((volatile unsigned long *)0xB0E00008) )
#define NFADDR          ( *((volatile unsigned long *)0xB0E0000C) )
#define NFDATA          ( *((volatile unsigned long *)0xB0E00010) )
#define NFSTAT          ( *((volatile unsigned long *)0xB0E00028) )
#define MP0_1CON        ( *((volatile unsigned long *)0xE02002E0) )
#define MP0_2CON        ( *((volatile unsigned long *)0xE0200300) )
#define MP0_3CON        ( *((volatile unsigned long *)0xE0200320) )
#define MAX_NAND_BLOCK                8192          /*定义nand最大块数:8192块   */
#define NAND_PAGE_SIZE                2048          /*定义一页的容量:2048 byte     */
#define NAND_BLOCK_SIZE               64            /*定义block大小:64页      */
#define TACLS                         1             /* 时序相关的设置          */
#define TWRPH0                        4
#define TWRPH1                        1
#define NAND_CMD_READ_1st             0x00          /* 命令                       */
#define NAND_CMD_READ_2st             0x30
#define NAND_CMD_RANDOM_WRITE         0x85
#define NAND_CMD_RANDOM_READ_1st      0x05
#define NAND_CMD_RANDOM_READ_2st      0xe0
#define NAND_CMD_READ_CB_1st          0x00
#define NAND_CMD_READ_CB_2st          0x35
#define NAND_CMD_READ_ID              0x90
#define NAND_CMD_RES                  0xff
#define NAND_CMD_WRITE_PAGE_1st       0x80
#define NAND_CMD_WRITE_PAGE_2st       0x10
#define NAND_CMD_BLOCK_ERASE_1st      0x60
#define NAND_CMD_BLOCK_ERASE_2st      0xd0
#define NAND_CMD_READ_STATUS          0x70
#define BUSY                          1
#define ECC_EN                        (1<<4)
#define CHIP_SELECTED                 (~(1<<1))
#define CHIP_DESELECTED               (1<<1)
#define CONTROL_EN                    (1<<0)static void nand_reset(void);
static void nand_wait_idle(void);
static void nand_select_chip(void);
static void nand_deselect_chip(void);
static void nand_send_cmd(unsigned long cmd);
static void nand_send_addr(unsigned long addr);
static unsigned char nand_read(void);
static void nand_write(unsigned char data);typedef struct nand_id_info {//marker codeunsigned char IDm; //device codeunsigned char IDd; unsigned char ID3rd;unsigned char ID4th;unsigned char ID5th;
}nand_id_info;// 复位
static void nand_reset(void) {nand_select_chip();nand_send_cmd(NAND_CMD_RES);nand_wait_idle();nand_deselect_chip();
}// 等待就绪
static void nand_wait_idle(void) {unsigned long i;while( !(NFSTAT & (BUSY<<4)) )for(i=0; i<10; i++);
}// 发片选
static void nand_select_chip(void) {unsigned long i;NFCONT &= ~(1<<1);for(i=0; i<10; i++);
}// 取消片选
static void nand_deselect_chip(void) {NFCONT |= (1<<1);
}// 发命令
static void nand_send_cmd(unsigned long cmd)
{NFCMMD = cmd;
}// 发地址
static void nand_send_addr(unsigned long addr) {unsigned long i;unsigned long col, row;// 列地址,即页内地址  col = addr % NAND_PAGE_SIZE;       // 行地址,即页地址              row = addr / NAND_PAGE_SIZE;// Column Address A0~A7  NFADDR = col & 0xff;         for(i=0; i<10; i++);      // Column Address A8~A11  NFADDR = (col >> 8) & 0x0f;        for(i=0; i<10; i++);// Row Address A12~A19    NFADDR = row & 0xff;           for(i=0; i<10; i++);// Row Address A20~A27    NFADDR = (row >> 8) & 0xff;for(i=0; i<10; i++);// Row Address A28~A30  NFADDR = (row >> 16) & 0xff;for(i=0; i<10; i++);
}// 读一个字节的数据
static unsigned char nand_read(void) {return NFDATA;
}// 写一个字节的数据
static void nand_write(unsigned char data) {NFDATA = data;
}// nandflash 初始化
void nand_init(void)
{// 1. 配置nandflash  NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0);NFCONT = (0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x3<<1)|(1<<0);// 2. 配置引脚  MP0_1CON = 0x22333322;MP0_2CON = 0x00002222;MP0_3CON = 0x22222222;// 3. 复位  nand_reset();
}// 读芯片ID
void nand_read_id(void)
{nand_id_info nand_id;// 1. 发片选  nand_select_chip();// 2. 读ID  nand_send_cmd(NAND_CMD_READ_ID);nand_send_addr(0x00);nand_wait_idle();nand_id.IDm =     nand_read();nand_id.IDd =  nand_read();nand_id.ID3rd = nand_read();nand_id.ID4th = nand_read();nand_id.ID5th = nand_read();nand_deselect_chip();
}// 擦除块
unsigned char nand_erase(unsigned long block_num)
{unsigned long i = 0;// 获得row地址,即页地址  unsigned long row = block_num * NAND_BLOCK_SIZE;// 1. 发出片选信号  nand_select_chip();// 2. 擦除:第一个周期发命令0x60,第二个周期发块地址,第三个周期发命令0xd0  nand_send_cmd(NAND_CMD_BLOCK_ERASE_1st);for(i=0; i<10; i++);// Row Address A12~A19 NFADDR = row & 0xff;                           for(i=0; i<10; i++);// Row Address A20~A27  NFADDR = (row >> 8) & 0xff;for(i=0; i<10; i++);// Row Address A28~A30  NFADDR = (row >> 16) & 0xff;           NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_BLOCK_ERASE_2st);for(i=0; i<10; i++);// 3. 等待就绪  nand_wait_idle();// 4. 读状态  unsigned char status = read_nand_status();if (status & 1 ) {// 取消片选信号  nand_deselect_chip();                     printf("masking bad block %d\r\n", block_num);return -1;} else {nand_deselect_chip();return 0;}
}// 从nand中读数据到sdram
int copy_nand_to_sdram(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length)
{unsigned long i = 0;// 1. 发出片选信号  nand_select_chip();// 2. 从nand读数据到sdram,第一周期发命令0x00,第二周期发地址nand_addr,第三个周期发命令0x30,可读一页(2k)的数据  while(length) {nand_send_cmd(NAND_CMD_READ_1st);nand_send_addr(nand_addr);NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_READ_2st);nand_wait_idle();// 列地址,即页内地址  unsigned long col = nand_addr % NAND_PAGE_SIZE;i = col;// 读一页数据,每次拷1byte,共拷2048次(2k),直到长度为length的数据拷贝完毕 for(; i<NAND_PAGE_SIZE && length!=0; i++,length--) {*sdram_addr = nand_read();sdram_addr++;nand_addr++;}}// 3. 读状态  unsigned char status = read_nand_status();if (status & 1 ) {// 取消片选信号  nand_deselect_chip();printf("copy nand to sdram fail\r\n");return -1;} else {nand_deselect_chip();return 0;}
}// 从sdram中写数据到nand
int copy_sdram_to_nand(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length)
{unsigned long i = 0;// 1. 发出片选信号  nand_select_chip();// 2. 从sdram读数据到nand,第一周期发命令0x80,第二周期发地址nand_addr,第三个周期写一页(2k)数据,第四周期发0x10  while(length) {nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);nand_send_addr(nand_addr);// 列地址,即页内地址  unsigned long col = nand_addr % NAND_PAGE_SIZE;i = col;// 写一页数据,每次拷1byte,共拷2048次(2k),直到长度为length的数据拷贝完毕 for(; i<NAND_PAGE_SIZE && length!=0; i++,length--) {nand_write(*sdram_addr);sdram_addr++;nand_addr++;}NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);nand_wait_idle();}// 3. 读状态  unsigned char status = read_nand_status();if (status & 1) {// 取消片选信号  nand_deselect_chip();printf("copy sdram to nand fail\r\n");return -1;} else {nand_deselect_chip();return 0;}
}// 随机读数据 paddr页地址,offset页内偏移地址
unsigned char nand_random_read(unsigned long paddr,unsigned short offset)
{unsigned char readdata;// 1. 发出片选信号  nand_select_chip();// 2. 随机读页内某个地址的值  nand_send_cmd(NAND_CMD_READ_1st);//写入页地址NFADDR = 0;                                        NFADDR = 0;NFADDR = paddr&0xff;NFADDR = (paddr>>8)&0xff;NFADDR = (paddr>>16)&0xff;NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_READ_2st);nand_wait_idle();nand_send_cmd(NAND_CMD_RANDOM_READ_1st);//写入页内偏移地址NFADDR = offset&0xff;                            NFADDR = (offset>>8)&0xff;NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_RANDOM_READ_2st);readdata = nand_read();// 3. 读状态  unsigned char status = read_nand_status();if (status & 1 ) {// 取消片选信号  nand_deselect_chip();printf("nand random read fail\r\n");return -1;} else {nand_deselect_chip();return readdata;}
}// 随机写数据 paddr页地址,offset页内偏移地址
unsigned char nand_random_write(unsigned long paddr,unsigned short offset,unsigned char wrdata)
{// 1. 发出片选信号  nand_select_chip();// 2. 随机写页内某个地址的值  nand_send_cmd(NAND_CMD_WRITE_PAGE_1st);NFADDR = 0;NFADDR = 0;NFADDR = paddr&0xff;NFADDR = (paddr>>8)&0xff;//NFADDR = (paddr>>16)&0xff;nand_send_cmd(NAND_CMD_RANDOM_WRITE);//写入页内偏移地址NFADDR = offset&0xff;                   NFADDR = (offset>>8)&0xff;nand_write(wrdata);NFSTAT = (NFSTAT)|(1<<4);nand_send_cmd(NAND_CMD_WRITE_PAGE_2st);nand_wait_idle();// 3. 读状态  unsigned char status = read_nand_status();if (status & 1 ) {// 取消片选信号  nand_deselect_chip();printf("nand random write fail\r\n");return -1;} else {nand_deselect_chip();return 0;}
}unsigned char read_nand_status(void)
{unsigned char ch;int i;// 1. 发出片选信号  nand_select_chip();// 2. 读状态  nand_send_cmd(NAND_CMD_READ_STATUS);for(i=0; i<10; i++);ch = nand_read();// 3. 取消片选  nand_deselect_chip();return ch;
}

nandflash驱动相关推荐

  1. MTD NANDFLASH驱动相关知识介绍

    转:http://blog.csdn.net/zhouzhuan2008/article/details/11053877 目录 MTD总概述 MTD数据结构 MTD相关层实现 MTD,Memory ...

  2. Nandflash 驱动移植

    前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...

  3. 基于WINCE6.0的nandflash驱动(基于K9F1G08U0B)

    *******************************LoongEmbedded******************************** 作者:LoongEmbedded 时间:201 ...

  4. NandFlash驱动移植基础知识

    NandFlash驱动移植基础知识 文章借鉴博文:http://blog.csdn.net/leibniz_zsu/article/details/4977842 博文写的不错,谢谢分享 MTD 驱动 ...

  5. MTD系统架构和yaffs2使用、Nandflash驱动设计

    一.MTD系统架构 1.MTD设备体验 FLASH在嵌入式系统中是必不可少的,它是bootloader.linux内核和文件系统的最佳载体. 在Linux内核中引入了MTD子系统为NORFLASH和N ...

  6. 驱动专题:第五章MTD及Flash驱动 2.Nandflash驱动

    一.MTD体系结构:Linux内核提供MTD子系统来建立FLASH针对Linux的统一.抽象接口.MTD将文件系统与底层的FLASH存储器进行隔离. 引入MTD后Linux系统中对FLASH的设备驱动 ...

  7. 第十二章 NandFlash驱动移植

    12.1 NandFlash介绍         对Nandflash存储芯片操作,必须通过NandFlash控制器完成,不能通过对NandFlash进行总线操作         对NandFlash ...

  8. FatFs文件系统Nandflash驱动函数详解

    FatFs文件系统Nandflash驱动函数详解 转载 2015-08-06 14:43:27 标签:nandflash驱动函数详fatfs文件系统nandfla 本文讲解FatFs文件系统 下需要的 ...

  9. 20150311 NandFlash驱动分析

    20150311 NandFlash驱动分析 2015-03-11 李海沿 一.结构体详解 MTD体系结构: 在linux中提供了MTD(Memory Technology Device,内存技术设备 ...

  10. NandFlash 驱动分析与基础功能实现

    NandFlash 一.写作目的及参考来源说明 二.NandFlash的简介 三.引脚功能 四.Array Organization(组织阵列) 1 . 最小读写单元 2 . 最小擦除单元 3 . N ...

最新文章

  1. HTML基础部分(1)字体,照片,链接
  2. Django 无法添加新字段,django.db.utils.OperationalError: (1050, Table app already exists)
  3. webpack4.x加vue模板文件简单还原vue-cli
  4. 记录一个相当好用的反编译工具下载地址
  5. Navicat连接mysql8.0.1版本出现1251--Client
  6. redis 计数器 java_Redis 的 8 大应用场景!
  7. win7桌面便签。自带的
  8. .net core精彩实例分享 -- 基础篇
  9. 手机通话记录重复显示怎么处理_手机通话记录怎么找回
  10. IDEA 常用快捷键 常用插件 1
  11. 2021-03-23梦笔记
  12. SpringBoot上传文件类型检测
  13. 关于hive分区,你知道多少呢?
  14. fl_studio-声卡设置、1
  15. 淘宝原数据商品详情API调用示例
  16. PW系列 | palette 体验
  17. itpt_TCPL 第三章:控制流
  18. 局域网访问提示无法访问检查拼写_windows无法访问请检查名称的拼写… 错误代码:0x80070035 | 吴文辉博客...
  19. c语言剧透,破镜重圆 ·《C语言修仙》by 十四洲
  20. 关于xxl-job终止任务但程序没有停止的问题

热门文章

  1. BUAA Object Oriented Unit 1 Summary
  2. JGit获取当前分支的所有提交请求
  3. linux发送rarp协议,通过源码理解Rarp协议
  4. 启动tomcat 报错java.lang.UnsatisfiedLinkError
  5. 北京社保服务平台Android版(CSDN技术专区)
  6. java线上流量复制工具_tcpcopy复制线上流量
  7. python ocr安装_详解Python安装tesserocr遇到的各种问题及解决办法
  8. 甘孜州2021高考 康定中学宴冬梅成绩查询,康定中学
  9. phpmyadmin 连接数据库报错 HY000/1045 HY000 / 2002
  10. 敏捷实践之Stand-UP Meetting早会