歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 嵌入式學習之Nand Flash控制器讀寫編程

嵌入式學習之Nand Flash控制器讀寫編程

日期:2017/3/1 9:55:51   编辑:Linux編程

S3C2440 NandFlash控制器介紹:

NAND Flash控制器提供幾個寄存器來簡化對NAND Flash的操作。比如要發出讀命令,只需往NFCMD寄存器寫入0即可,NAND FLash控制器會自動發出各種控制信號。

1、操作方法概述

訪問NAND Flash時需要先發出命令,然後發出地址序列,最後讀/寫數據;需要使用各種使能信號來分辨是命令、地址還是數據。S3C2410的NAND Flash控制器提供了NFCONF、NFCMD、NFADDR、NFDATA、NFSTAT和NFECC等6個寄存器來簡化這些操作。S3C2440的NAND Flash控制器則提供了NFCONF、NFCONT、NFCMMD、NFADDR、NFDATA、NFSTAT和其它與ECC有關的寄存器。對NAND Flash控制器的操作,S3C2410和S3C2440有一些小的差別:有些寄存器不一樣,有些寄存器內容不一樣,這在實例程序中會體現出來。

NAND Flash的讀寫操作次序如下:

(1)設置NFCONF(對於S3C2440,還要設置NFCONT)寄存器,配置NAND Flash。

(2)向NFCMD寄存器寫入命令,這些命令可以參考表8.2。

(3)向NFADDR寄存器寫入地址。

(4)讀/寫數據:通過寄存器NFSTAT檢測NAND Flash的狀態,在啟動某個操作後,應該檢測R/nB信號以確定該操作是否完成、是否成功。

2.下面講解這些寄存器的功能和用法:

1)NFCONF:NAND Flash配置寄存器

這個寄存器在S3C2410、S3C2440上功能有所不同。S3C2410的NFCONF寄存器被用來使能禁止NAND Flash控制器、使能禁止控制引腳信號nFCE、初始化ECC,設置NAND Flash的時序參數等。

(2)NFCONT:NAND Flash控制寄存器,S3C2410沒有這個寄存器。

被用來使能/禁止NAND Flash控制寄存器,使能/禁止控制引腳信號nFCE、初始化ECC。它還有其它功能,在一般的應用中用不到,比如鎖定NAND Flash。

(3)NFCMD:NAND Flash命令寄存器

對於不同型號的Flash,操作命令一般不一樣。對於本板使用的K9F1208U0M,可參考表8.2。

(4)NFADDR:NAND Flash地址寄存器。

當寫這個寄存器時,它將對Flash發出地址信號。

(5)NFDATA:NAND Flash數據寄存器。

只用到低8位,讀、寫此寄存器將啟動對NAND Flash的讀數據、寫數據操作。

(6)NFSTAT:NAND Flash狀態寄存器

只用到位0,0:busy,1:ready

讀NandFlash的步驟:

①設置NFCONF

在HCLK=100Mhz的情況下,TACLS=0,TWRPH0=3,TWRPH1=0,則

NFCONF = 0x300

使能NAND Flash控制器、禁止控制引腳信號nFCE,初始化ECC

NFCONT = (1<<4) | (1<<1) | (1<<0)

②操作NAND Flash前,復位

NFCONT &= ~(1<<1) 發出片選信號

NFCMD = 0xff reset命令

然後循環查詢NFSTAT位0,直到等於1,處於就緒態

最後禁止片選信號,在實際使用時再使能

NFCONT |= 0x2 禁止NAND Flash

③發出讀命令

NFCONT &= ~(1<<1) 發出片選信號

NFCMD = 0 讀命令

④發出地址信號

⑤循環查詢NFSTAT,直到等於1

⑥連續讀NFDATA寄存器,得到一頁數據

⑦最後禁止NAND Flash片選信號

NFCONT |= (1<<1)

介紹幾個Nand Flash初期化的函數:

/* 初始化NAND Flash */
void nand_init(void)
{
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0

/* 判斷是S3C2410還是S3C2440 */
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
{
nand_chip.nand_reset = s3c2410_nand_reset;
nand_chip.wait_idle = s3c2410_wait_idle;
nand_chip.nand_select_chip = s3c2410_nand_select_chip;
nand_chip.nand_deselect_chip = s3c2410_nand_deselect_chip;
nand_chip.write_cmd = s3c2410_write_cmd;
nand_chip.write_addr = s3c2410_write_addr;
nand_chip.read_data = s3c2410_read_data;

/* 使能NAND Flash控制器, 初始化ECC, 禁止片選, 設置時序 */
s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
}
else
{
nand_chip.nand_reset = s3c2440_nand_reset;
nand_chip.wait_idle = s3c2440_wait_idle;
nand_chip.nand_select_chip = s3c2440_nand_select_chip;
nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip;
nand_chip.write_cmd = s3c2440_write_cmd;
#ifdef LARGER_NAND_PAGE
nand_chip.write_addr = s3c2440_write_addr_lp;
#else
nand_chip.write_addr = s3c2440_write_addr;
#endif
nand_chip.read_data = s3c2440_read_data;

/* 設置時序 */
s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片選 */
s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);
}

/* 復位NAND Flash */
nand_reset();
}

Copyright © Linux教程網 All Rights Reserved