OK6410裸機(jī)簡(jiǎn)單的NAND?FLASH驅(qū)動(dòng),只寫了個(gè)簡(jiǎn)單的函數(shù),讀取一頁(yè)
/*************************************************************************************************************
?*?文件名: NandFlash.c
?*?功能: S3C6410?NandFlash底層驅(qū)動(dòng)函數(shù)
?*?作者: 陳鵬
?*?創(chuàng)建時(shí)間: 2012年3月31日21:34
?*?最后修改時(shí)間:2012年3月31日
?*?詳細(xì): NandFlash底層驅(qū)動(dòng)函數(shù),
? 板載NAND?FLASH信息:2GB,MLC?K9G4G08(K9GAG08U0D,頁(yè)大小4KB,4bit糾正)
*************************************************************************************************************/
#include?"s3c6410_system.h"
#include?"NandFlash.h"
#include?"s3c6410_map.h"
//配置
//CONF
#define?ECCType 1 //ECC類型選擇,0:SLC(1位修正);1:MLC(4位修正)
#define?TACLS 5 //CLE?&?ALE持續(xù)時(shí)間(0-7)(=?HCLK?*?TACLS)
#define?TWRPH0 5 //TWRPH0持續(xù)時(shí)間(0-7)(=?HCLK?*?(TWRPH0?+?1))
#define?TWRPH1 5 //TWRPH1持續(xù)時(shí)間(0-7)(=?HCLK?*?(TWRPH1?+?1))
#define?AdvFlash 1 //預(yù)先NAND?flash?存儲(chǔ)器啟動(dòng);0:支持512字節(jié)/頁(yè);1:支持2KB/頁(yè)
#define?AddrCycle 1 //NAND?Flash存儲(chǔ)器地址周期,0:?0:3地址周期,1:4地址周期;1:?0:4地址周期,1:5地址周期
//CONT
#define?SoftLock 0 //軟件鎖配置,0:禁用鎖,1:使能鎖
#define?MainECCLock 1 //鎖存主區(qū)ECC生成:0:開啟主區(qū)ECC;1:鎖存主區(qū)ECC
#define?SpareECCLock 1 //鎖存?zhèn)溆脜^(qū)ECC生成;0:開啟備用區(qū)ECC,1:鎖存?zhèn)溆脜^(qū)ECC,備用區(qū)ECC?狀態(tài)寄存器是NFSECC(0x7020003C)
#define?RegNCE1 1 //NAND?Flash?存儲(chǔ)器nGCS[3]信號(hào)控制:0:強(qiáng)制nGCS[3]為低(使能片選);1:強(qiáng)制nGCS[3]為高(禁用片選)注:即使Reg_nCE1?和?Reg_nCE0?同時(shí)被設(shè)置為0,它們之中也只有一個(gè)被聲明
#define?MODE 1 //NAND?Flash?控制器操作模式:0:NAND?Flash?控制器禁用(不工作)1:NAND?Flash?控制器使能
//NAND?FLASH操作宏
#define?NANDCMD(cmd) (NAND->CMMD?=?(cmd)) //向NAND?flash寫入命令
#define?NANDADDR(addr) (NAND->ADDR?=?(addr)) //向NAND?flash寫入地址
#define?NANDDATA (NAND->DATA) //向NAND?flash讀寫數(shù)據(jù)
#define?NF_nCS3_L (NAND->CONT&=~(1<CONT|=(1<CONT&=~(1<CONT|=(1<STAT?&?BIT0) //0:存儲(chǔ)器忙,1:空閑
//NAND?FLASH信息宏
#define?FLASH_MAX_ADDR? 0x80000000 //FLASH最大能夠達(dá)到的地址,是2GB
#define?FLASH_BLOCK_SIZE? 0x20000 //FLASH塊大小,為512KB
#define?FLASH_PAGE_SIZE? 0x1000 //FLASH頁(yè)大小,為4KB
//ECC?8BIT?512B
//NAND?FLASH 命令定義
#define?NAND_READ_1th 0x00 //讀數(shù)據(jù)區(qū),第一個(gè)訪問(wèn)周期
#define?NAND_READ_2th 0x30 //讀數(shù)據(jù)區(qū),第二個(gè)訪問(wèn)周期
#define?NAND_READ_ID 0x90 //讀NAND?ID
#define?NAND_READ_STATUS1 0x70 //讀狀態(tài)1
#define?NAND_READ_STATUS2 0xf1 //讀狀態(tài)2
#define?NAND_RESET 0xff //復(fù)位
/*************************************************************************************************************************
*函數(shù)????????: void?NnadFlashWait(void)
*功能????????: 等待操作完成
*參數(shù)????????: 無(wú)
*返回????????: 無(wú)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 低電平操作忙
*************************************************************************************************************************/
void?NnadFlashWait(void)
{
while(NF_RnB?==?0);??//等待寫完成??為低表示忙
}
/*************************************************************************************************************************
*函數(shù)????????: static?void?NandFlashWrite5BitAddr(vu32?Addr)
*功能????????: 向NAND?FLASH寫入4字節(jié)的地址
*參數(shù)????????: 地址
*返回????????: 無(wú)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 寫NAND地址,地址共32bit,分5次寫入
*************************************************************************************************************************/
static?void?NandFlashWrite5BitAddr(vu32?Addr)
{
vu8?temp;
temp?=?Addr?&?0xff; //取低8位地址
printf("rn1th=%02X?",temp);
NANDADDR(temp); //寫入A0-A7;
temp?=?(Addr?>>?8)?&?0x1f;
printf("rn2th=%02X?",temp);
NANDADDR(temp); //寫A8-A12,0,0,0
temp?=?(Addr?>>?13);
printf("rn3th=%02X?",temp);
NANDADDR(temp);
temp?=?(Addr?>>?21);//寫A13-A20
printf("rn4th=%02X?",temp);
NANDADDR(temp); //寫A21-A28
temp?=?(Addr?>>?29)?&?0x07;
printf("rn5th=%02X?",temp);
NANDADDR(temp); //寫A29-A31,0,0,0,0,0
}
/*************************************************************************************************************************
*函數(shù)????????: void?NandFlashReset(void)
*功能????????: NandFlash復(fù)位
*參數(shù)????????: 無(wú)
*返回????????: 無(wú)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 寫入復(fù)位命令等待復(fù)位完成
*************************************************************************************************************************/
void?NandFlashReset(void)
{
NANDADDR(0x00); //地址復(fù)位
NANDCMD(NAND_RESET); //寫入復(fù)位命令
NnadFlashWait(); //等待操作完成
}
/*************************************************************************************************************************
*函數(shù)????????: void?NandFlashInit(void)
*功能????????: NandFlash初始化函數(shù)
*參數(shù)????????: 無(wú)
*返回????????: 無(wú)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 用于初始化NAND
*************************************************************************************************************************/
void?NandFlashInit(void)
{
// rGPPCON?&=?~(3?<<?14); //GPIOP7輸入
NAND->CONF?=?(ECCType?<<?24)?+?(TACLS?<<?12)?+?(TWRPH0?<<?8)?+?(TWRPH1?<<?4)?+?(AdvFlash?<<?3)?+?BIT2?+?(AddrCycle?<<?1); //配置NAND?FLASH
NAND->CONT?=?(SoftLock?<<?16)?+?(MainECCLock?<<?7)?+?(SpareECCLock?<<?6)?+?(RegNCE1?<<?2)?+?(MODE?<<?0);//初始化控制寄存器
NandFlashReset(); //復(fù)位NAND?FLASH
}
/*************************************************************************************************************************
*函數(shù)????????: u32?NandFlashReadStatus(void)
*功能????????: 讀取NandFlash狀態(tài)
*參數(shù)????????: 無(wú)
*返回????????: 狀態(tài)參數(shù)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 讀取狀態(tài)
*************************************************************************************************************************/
u32?NandFlashReadStatus(void)
{
NF_nCS2_L;
NANDCMD(NAND_READ_STATUS1); //寫查詢命令
NnadFlashWait(); //等待操作完成
NF_nCS2_H;
return?NANDDATA; //返回狀態(tài)信息
}
/*************************************************************************************************************************
*函數(shù)????????: u32?NandFlashReadStatus1(void)
*功能????????: 讀取NandFlash狀態(tài)1
*參數(shù)????????: 無(wú)
*返回????????: 狀態(tài)參數(shù)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120331
*說(shuō)明????????: 讀取狀態(tài)1
*************************************************************************************************************************/
u32?NandFlashReadStatus1(void)
{
NF_nCS2_L;
NANDCMD(NAND_READ_STATUS2); //寫查詢命令1
NnadFlashWait(); //等待操作完成
NF_nCS2_H;
return?NANDDATA; //返回狀態(tài)信息
}
/*************************************************************************************************************************
*函數(shù)????????: void?NandFlashReadID(u8?*pbuff)
*功能????????: 讀取NandFlash?ID
*參數(shù)????????: 緩沖區(qū)指針
*返回????????: 無(wú)
*依賴????????:? 無(wú)
*作者????????: 陳鵬
*時(shí)間????????: 20120331
*最后修改時(shí)間: 20120720
*說(shuō)明????????: 讀取ID,注意ID為6字節(jié),ECH,DeviceCode,3rd?cyc,4th?cyc,5th?cyc,6th?cyc,讀一次是32BIT,4 字節(jié)
*************************************************************************************************************************/
void?NandFlashReadID(u8?*pbuff)
{
u8?i;
u32?buff[2];
u8?*p?=?(u8?*)buff;
NF_nCS2_L;
NANDCMD(NAND_READ_ID); //寫讀取ID命令
NANDADDR(0x00); //地址復(fù)位
NnadFlashWait(); //等待操作完成
//讀取2次,共8字節(jié)
for(i?=?0;i?<?2;i?++)
buff[i]?=?NANDDATA;
NF_nCS2_H;
//復(fù)制前面的6字節(jié)ID
for(i?=?0;i?<?6;i?++)
pbuff[i]?=?p[i];
}
/*************************************************************************************************************************
*函數(shù)????????: u8?NandFlashReadOneSector(u32?Addr,u8?*pBuff)
*功能????????: 讀取nand?flash一頁(yè)
*參數(shù)????????: Addr:頁(yè)地址,pBuff:緩沖區(qū)指針;
*返回????????: 狀態(tài)
*依賴????????:? 底層操作函數(shù)
*作者????????: 陳鵬
*時(shí)間????????: 20120401
*最后修改時(shí)間: 20120401
*說(shuō)明????????: 讀取一頁(yè),一頁(yè)4KB,注意緩沖區(qū)不要越界,讀一次是32BIT,4 字節(jié)
*************************************************************************************************************************/
u8?NandFlashReadOneSector(u32?Addr,u8?*pBuff)
{
u32?i;
u32?*p?=?(u32?*)pBuff;
u32?cnt?=?FLASH_PAGE_SIZE?/?4; //讀取次數(shù),每次讀取4字節(jié)
if(Addr?>?FLASH_MAX_ADDR) //地址超出范圍返,返回錯(cuò)誤代碼1,地址越界
return?1;
NF_nCS2_L;
//如果跨頁(yè)的,則寫讀數(shù)據(jù)命令
NANDCMD(NAND_READ_1th);
NandFlashWrite5BitAddr(Addr);
NANDCMD(NAND_READ_2th);
NnadFlashWait();?//等待數(shù)據(jù)讀回
for(i?=?0;i?<?cnt;i++)
{
p[i]?=?NANDDATA;??//讀一字節(jié)數(shù)據(jù)
}
NF_nCS2_H;
return?0;
}