//=============================================================================
// FILE: DEV_NAND.C
// DESC:
// HIST:
//=============================================================================
#include "OS_ARCH.H"
#include "S3C2440.H"
#include "DEV_NAND.H"
//=============================================================================
// K9F1G08U0C寄存器
//=============================================================================
#define rNFCONF (*(U32*)(&S3C2440_GETBASE_NAND->NFCONF))
#define rNFCONT (*(U32*)(&S3C2440_GETBASE_NAND->NFCONT))
#define rNFCMD (*(U32*)(&S3C2440_GETBASE_NAND->NFCMD))
#define rNFADDR (*(U32*)(&S3C2440_GETBASE_NAND->NFADDR))
#define rNFDATA (*(U32*)(&S3C2440_GETBASE_NAND->NFDATA))
#define rNFDATA8 (*(U8 *)(&S3C2440_GETBASE_NAND->NFDATA))
#define rNFECCD0 (*(U32*)(&S3C2440_GETBASE_NAND->NFECCD0))
#define rNFECCD1 (*(U32*)(&S3C2440_GETBASE_NAND->NFECCD1))
#define rNFECCD (*(U32*)(&S3C2440_GETBASE_NAND->NFECCD))
#define rNFSTAT (*(U32*)(&S3C2440_GETBASE_NAND->NFSTAT))
#define rNFSTAT0 (*(U32*)(&S3C2440_GETBASE_NAND->NFSTAT0))
#define rNFSTAT1 (*(U32*)(&S3C2440_GETBASE_NAND->NFSTAT1))
//=============================================================================
// K9F1G08U0C命令字
//=============================================================================
#define K9F1G_CMD_READID 0x90 // 读器件ID
#define K9F1G_CMD_RESET 0xFF // 复位芯片
#define K9F1G_CMD_PAGE_READ1 0x00 // 页读命令周期1
#define K9F1G_CMD_PAGE_READ2 0x30 // 页读命令周期2
#define K9F1G_CMD_RANDOM_DATA_OUTPUT1 0x05 // 随意读命令周期1
#define K9F1G_CMD_RANDOM_DATA_OUTPUT2 0xE0 // 随意读命令周期2
#define K9F1G_CMD_PAGE_PROGRAM1 0x80 // 页编程指令1
#define K9F1G_CMD_PAGE_PROGRAM2 0x10 // 页编程指令2
#define K9F1G_CMD_RANDOM_DATA_INPUT 0x85 // 页内随机编程
#define K9F1G_CMD_BLOCK_ERASE1 0x60 // 块擦除指令1
#define K9F1G_CMD_BLOCK_ERASE2 0xD0 // 块擦除指令2
#define K9F1G_CMD_READ_STATUS 0x70 // 读器件状态
#define K9F1G_CMD_CACHE_PROGRAM1 0x80 // Cache编程周期1
#define K9F1G_CMD_CACHE_PROGRAM2 0x15 // Cache编程周期2
#define K9F1G_CMD_COPY_BACK_READ1 0x00 // 芯片内页拷贝读周期1
#define K9F1G_CMD_COPY_BACK_READ2 0x35 // 芯片内页拷贝读周期2
#define K9F1G_CMD_COPY_BACK_PROGRAM1 0x85 // 芯片内页拷贝编程周期1
#define K9F1G_CMD_COPY_BACK_PROGRAM2 0x10 // 芯片内页拷贝编程周期2
//=============================================================================
// K9F1G08U0C基本控制位
//=============================================================================
#define NF_CMD(cmd) { rNFCMD = (cmd); } // 传输命令
#define NF_ADDR(addr) { rNFADDR = (addr); } // 传输地址
#define NF_CE_L { rNFCONT &=~(1<<1); } // 打开nandflash片选
#define NF_CE_H { rNFCONT |= (1<<1); } // 关闭nandflash片选
#define NF_RSTECC { rNFCONT |= (1<<4); } // 复位ECC
#define NF_MECC_LOCK { rNFCONT |= (1<<5); } // 锁定main区ECC
#define NF_MECC_UNLOCK { rNFCONT &=~(1<<5); } // 解锁main区ECC
#define NF_SECC_LOCK { rNFCONT |= (1<<6); } // 锁定spare区ECC
#define NF_SECC_UNLOCK { rNFCONT &=~(1<<6); } // 解锁spare区ECC
#define NF_WAIT_RB { while (!(rNFSTAT & (1<<0))); } // 等待NAND Flash运行就绪
#define NF_DETECT_RB { while (!(rNFSTAT & (1<<2))); } // 等待RnB变高, 发生传输
#define NF_CLEAR_RB { rNFCONT |= (1<<2); } // 清除RnB信号, 检测RnB传输
#define NF_CHECK_BUSY(stat) ((stat)&(1<<6))
#define NF_CHECK_OK(stat) ((stat)&(1<<0))
#define NF_BAD_BLOCK (0xFF)
//=============================================================================
// 初始化芯片
//=============================================================================
void eNandInit(void)
{
S3C2440_GPIO *gpio = S3C2440_GETBASE_GPIO;
S3C2440_NAND *nand = S3C2440_GETBASE_NAND;
#define TACLS 1 // 1-clk(0ns)
#define TWRPH0 6 // 3-clk(25ns)
#define TWRPH1 2 // 1-clk(10ns)
gpio->GPACON = (gpio->GPACON & ~(0x3F<<17)) | (0x3F<<17);
nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
nand->NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
}
//=============================================================================
// 重置芯片
//=============================================================================
void eNandReset(void)
{
NF_CE_L;
NF_CLEAR_RB;
NF_CMD(K9F1G_CMD_RESET);
NF_DETECT_RB;
NF_CE_H;
}
//=============================================================================
// 读芯片ID
// 返回: ret[31:24]=MID
// ret[23:16]=DID
// ret[15: 8]=ID3rd
// ret[ 7: 0]=ID4th
//=============================================================================
U32 eNandReadID(void)
{
U32 id1;
U32 id2;
U32 id3;
U32 id4;
NF_CE_L;
NF_CLEAR_RB;
NF_CMD(K9F1G_CMD_READID);
NF_ADDR(0x00);
id1 = rNFDATA8;
id2 = rNFDATA8;
id3 = rNFDATA8;
id4 = rNFDATA8;
NF_CE_H;
return (id1<<24|id2<<16|id3<<8|id4);
}
//=============================================================================
// 随机读数据
// 参数: size: 读取大小, 小于(NAND_BYTES_PER_PAGE * NAND_PAGE_PER_BLOCK * NAND_BLOCK_PER_CHIP) - start
// startAddr: 起始地址, 范围[0, NAND_BYTES_PER_PAGE * NAND_PAGE_PER_BLOCK * NAND_BLOCK_PER_CHIP)
//=============================================================================
U32 eNandRead(U8 *buf, U32 size, U32 startAddr, BOOL skipBadBlock)
{
U32 pageIndex;
U32 pageOffset;
U32 pageCount;
U32 pageBlock;
U32 readBytes;
U32 totalSize;
pageIndex = startAddr / NAND_BYTES_PER_PAGE;
pageOffset= startAddr % NAND_BYTES_PER_PAGE;
readBytes = NAND_BYTES_PER_PAGE - pageOffset;
readBytes = readBytes < size ? readBytes : size;
pageCount = NAND_PAGE_PER_BLOCK * NAND_BLOCK_PER_CHIP;
pageBlock = 0;
totalSize = 0;
while ((pageIndex < pageCount) && (totalSize < size))
{
if (pageIndex >= (pageBlock * NAND_PAGE_PER_BLOCK))
{
pageBlock++;
if (!eNandCheckBlock(pageBlock-1))
{
if (skipBadBlock)
{
pageIndex = pageBlock * NAND_PAGE_PER_BLOCK;
continue;
}
else
{
return totalSize;
}
}
}
if (eNandReadPage(buf, readBytes, pageIndex, pageOffset))
{
buf += readBytes;
totalSize += readBytes;
}
pageOffset = 0;
readBytes = size - totalSize;
if (readBytes > NAND_BYTES_PER_PAGE)
readBytes = NAND_BYTES_PER_PAGE;
pageIndex++;
}
return totalSize;
}
//=============================================================================
// 随机读页数据
// 参数: size: 读取大小, 小于(NAND_BYTES_PER_PAGE + NAND_BYTES_PER_PAGE_SPARE) - start
// pageIndex: 页索引, 范围[0, NAND_PAGE_PER_BLOCK * NAND_BLOCK_PER_CHIP)
// start: 页起始位置, 范围[0, NAND_BYTES_PER_PAGE + NAND_BYTES_PER_PAGE_SPARE)
//=============================================================================
BOOL eNandReadPage(U8 *buf, U32 size, U32 pageIndex, U32 start)
{
U32 index;
if (pageIndex >= (NAND_PAGE_PER_BLOCK * NAND_BLOCK_PER_CHIP))
return FALSE;
if ((start + size) > (NAND_BYTES_P
S3C2440启动代码的实现
5星 · 超过95%的资源 需积分: 10 185 浏览量
2013-07-16
13:31:51
上传
评论
收藏 34KB RAR 举报
奋斗拼搏
- 粉丝: 5
- 资源: 35
最新资源
- 历届(第1-21届)希望杯数学竞赛初一试题及答案(最新整理).doc全国数学邀请赛(264页资料)
- 水滴.psd
- TokenPocket_V2.1.2_release.apk
- Apache-druid-kafka-rce.yaml
- 基于C#的ASP.NET数据库原理及应用技术课程指导平台的开发
- 基于ROS的智能车轨迹跟踪算法的仿真与设计源码运用PID跟踪算法.zip.zip
- Bug Bounty Tip - i春秋Self-XSS变废为宝的奇思妙想
- 1991-2015年全国初中化学竞赛复赛试题汇编(212页)(24年竞赛复赛真题).docx天原杯
- Apache Flink 未授权访问+远程代码执行.pdf
- hadoop-基于hive的聊天数据分析报表可视化案例数据源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈