当前位置:首页 > 单片机 > 单片机
[导读]接上一篇:s3c2440硬件篇之三:NandFlash(1)介绍s3c2440读NAND Flash的步骤:①设置NFCONF 在HCLK=100Mhz的情况下,TACLS=0,TWRPH0=3,TWRPH1=0,则 NFCONF = 0x300 使能NAND Flash控制器、禁止控制引脚信号nFCE,

接上一篇:s3c2440硬件篇之三:NandFlash(1)介绍

s3c2440读NAND Flash的步骤:

①设置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硬件连接:

代码详解:(参考韦东山大哥代码)

说明:本实例的目的是把一部分代码存放在NAND Flash地址4096(即4K)之后,当程序启动后通过NAND Flash控制器读出代码,执行。

(1)连接脚本nand.lds

SECTIONS {
firtst 0x00000000:{ head.o init.o nand.o}
second 0x30000000:AT(4096){ main.o }
}

(2)head.S

@******************************************************************************
@ File:head.s
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@******************************************************************************

.text
.global _start
_start:
@函数disable_watch_dog,memsetup,init_nand,nand_read_ll在init.c中定义
ldr sp,=4096 @设置堆栈
bldisable_watch_dog @关WATCH DOG
blmemsetup @初始化SDRAM
blnand_init @初始化NAND Flash

@将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中
@nand_read_ll函数需要3个参数:
ldr r0,=0x30000000 @1.目标地址=0x30000000,这是SDRAM的起始地址
movr1,#4096 @2.源地址=4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处
movr2,#2048 @3.复制长度=2048(bytes),对于本实验的main.c,这是足够了
blnand_read @调用C函数nand_read

ldr sp,=0x34000000 @设置栈
ldr lr,=halt_loop @设置返回地址
ldr pc,=main @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
halt_loop:
b halt_loop

(3)init.c

/* WOTCH DOG register */
#defineWTCON(*(volatileunsignedlong*)0x53000000)

/* SDRAM regisers */
#defineMEM_CTL_BASE0x48000000

voiddisable_watch_dog();
voidmemsetup();

/*上电后,WATCH DOG默认是开着的,要把它关掉 */
voiddisable_watch_dog()
{
WTCON=0;
}

/* 设置控制SDRAM的13个寄存器 */
voidmemsetup()
{
inti=0;
unsignedlong*p=(unsignedlong*)MEM_CTL_BASE;

/* SDRAM 13个寄存器的值 */
unsignedlongconstmem_cfg_val[]={0x22011110,//BWSCON

0x00000700,//BANKCON0

0x00000700,//BANKCON1

0x00000700,//BANKCON2

0x00000700,//BANKCON3

0x00000700,//BANKCON4

0x00000700,//BANKCON5

0x00018005,//BANKCON6

0x00018005,//BANKCON7

0x008C07A3,//REFRESH

0x000000B1,//BANKSIZE

0x00000030,//MRSRB6

0x00000030,//MRSRB7

};

for(;i<13;i++)
p[i]=mem_cfg_val[i];
}


(4)nand.c ,定义一个宏#defineLARGER_NAND_PAGE来区分大页小页。


#defineLARGER_NAND_PAGE

#defineGSTATUS1(*(volatileunsignedint*)0x560000B0)
#defineBUSY 1

#defineNAND_SECTOR_SIZE 512
#defineNAND_BLOCK_MASK(NAND_SECTOR_SIZE-1)

#defineNAND_SECTOR_SIZE_LP 2048
#defineNAND_BLOCK_MASK_LP(NAND_SECTOR_SIZE_LP-1)

typedefunsignedintS3C24X0_REG32;


/* NAND FLASH (see S3C2410 manual chapter 6) */
typedefstruct{
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFECC;
}S3C2410_NAND;

/* NAND FLASH (see S3C2440 manual chapter 6, www.100ask.net) */
typedefstruct{
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECCD0;
S3C24X0_REG32 NFMECCD1;
S3C24X0_REG32 NFSECCD;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSBLK;
S3C24X0_REG32 NFEBLK;
}S3C2440_NAND;


typedefstruct{
void(*nand_reset)(void);
void(*wait_idle)(void);
void(*nand_select_chip)(void);
void(*nand_deselect_chip)(void);
void(*write_cmd)(intcmd);
void(*write_addr)(unsignedintaddr);
unsignedchar(*read_data)(void);
}t_nand_chip;

staticS3C2410_NAND*s3c2410nand=(S3C2410_NAND*)0x4e000000;
staticS3C2440_NAND*s3c2440nand=(S3C2440_NAND*)0x4e000000;

statict_nand_chip nand_chip;

/* 供外部调用的函数 */
voidnand_init(void);
voidnand_read(unsignedchar*buf,unsignedlongstart_addr,intsize);

/* NAND Flash操作的总入口, 它们将调用S3C2410或S3C2440的相应函数 */
staticvoidnand_reset(void);
staticvoidwait_idle(void);
staticvoidnand_select_chip(void);
staticvoidnand_deselect_chip(void);
staticvoidwrite_cmd(intcmd);
staticvoidwrite_addr(unsignedintaddr);
staticunsignedcharread_data(void);

/* S3C2410的NAND Flash处理函数 */
staticvoids3c2410_nand_reset(void);
staticvoids3c2410_wait_idle(void);
staticvoids3c2410_nand_select_chip(void);
staticvoids3c2410_nand_deselect_chip(void);
staticvoids3c2410_write_cmd(intcmd);
staticvoids3c2410_write_addr(unsignedintaddr);
staticunsignedchars3c2410_read_data();

/* S3C2440的NAND Flash处理函数 */
staticvoids3c2440_nand_reset(void);
staticvoids3c2440_wait_idle(void);
staticvoids3c2440_nand_select_chip(void);
staticvoids3c2440_nand_deselect_chip(void);
staticvoids3c2440_write_cmd(intcmd);
staticvoids3c2440_write_addr(unsignedintaddr);
staticunsignedchars3c2440_read_data(void);

/* S3C2410的NAND Flash操作函数 */

/* 复位 */
staticvoids3c2410_nand_reset(void)
{
s3c2410_nand_select_chip();
s3c2410_write_cmd(0xff);// 复位命令

s3c2410_wait_idle();
s3c2410_nand_deselect_chip();
}

/* 等待NAND Flash就绪 */
staticvoids3c2410_wait_idle(void)
{
inti;
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2410nand->NFSTAT;
while(!(*p&BUSY))
for(i=0;i<10;i++);
}

/* 发出片选信号 */
staticvoids3c2410_nand_select_chip(void)
{
inti;
s3c2410nand->NFCONF&=~(1<<11);
for(i=0;i<10;i++);
}

/* 取消片选信号 */
staticvoids3c2410_nand_deselect_chip(void)
{
s3c2410nand->NFCONF|=(1<<11);
}

/* 发出命令 */
staticvoids3c2410_write_cmd(intcmd)
{
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2410nand->NFCMD;
*p=cmd;
}

/* 发出地址 */
staticvoids3c2410_write_addr(unsignedintaddr)
{
inti;
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2410nand->NFADDR;

*p=addr&0xff;
for(i=0;i<10;i++);
*p=(addr>>9)&0xff;
for(i=0;i<10;i++);
*p=(addr>>17)&0xff;
for(i=0;i<10;i++);
*p=(addr>>25)&0xff;
for(i=0;i<10;i++);
}

/* 读取数据 */
staticunsignedchars3c2410_read_data(void)
{
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2410nand->NFDATA;
return*p;
}

/* S3C2440的NAND Flash操作函数 */

/* 复位 */
staticvoids3c2440_nand_reset(void)
{
s3c2440_nand_select_chip();
s3c2440_write_cmd(0xff);// 复位命令

s3c2440_wait_idle();
s3c2440_nand_deselect_chip();
}

/* 等待NAND Flash就绪 */
staticvoids3c2440_wait_idle(void)
{
inti;
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2440nand->NFSTAT;
while(!(*p&BUSY))
for(i=0;i<10;i++);
}

/* 发出片选信号 */
staticvoids3c2440_nand_select_chip(void)
{
inti;
s3c2440nand->NFCONT&=~(1<<1);
for(i=0;i<10;i++);
}

/* 取消片选信号 */
staticvoids3c2440_nand_deselect_chip(void)
{
s3c2440nand->NFCONT|=(1<<1);
}

/* 发出命令 */
staticvoids3c2440_write_cmd(intcmd)
{
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2440nand->NFCMD;
*p=cmd;
}

/* 发出地址 */
staticvoids3c2440_write_addr(unsignedintaddr)
{
inti;
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2440nand->NFADDR;

*p=addr&0xff;
for(i=0;i<10;i++);
*p=(addr>>9)&0xff;
for(i=0;i<10;i++);
*p=(addr>>17)&0xff;
for(i=0;i<10;i++);
*p=(addr>>25)&0xff;
for(i=0;i<10;i++);
}


staticvoids3c2440_write_addr_lp(unsignedintaddr)
{
inti;
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2440nand->NFADDR;
intcol,page;

col=addr&NAND_BLOCK_MASK_LP;
page=addr/NAND_SECTOR_SIZE_LP;

*p=col&0xff;/* Column Address A0~A7 */
for(i=0;i<10;i++);
*p=(col>>8)&0x0f;/* Column Address A8~A11 */
for(i=0;i<10;i++);
*p=page&0xff;/* Row Address A12~A19 */
for(i=0;i<10;i++);
*p=(page>>8)&0xff;/* Row Address A20~A27 */
for(i=0;i<10;i++);
*p=(page>>16)&0x03;/* Row Address A28~A29 */
for(i=0;i<10;i++);
}


/* 读取数据 */
staticunsignedchars3c2440_read_data(void)
{
volatileunsignedchar*p=(volatileunsignedchar*)&s3c2440nand->NFDATA;
return*p;
}


/* 在第一次使用NAND Flash前,复位一下NAND Flash */
staticvoidnand_reset(void)
{
nand_chip.nand_reset();
}

staticvoidwait_idle(void)
{
nand_chip.wait_idle();
}

staticvoidnand_select_chip(void)
{
inti;
nand_chip.nand_select_chip();
for(i=0;i<10;i++);
}

staticvoidnand_deselect_chip(void)
{
nand_chip.nand_deselect_chip();
}

staticvoidwrite_cmd(intcmd)
{
nand_chip.write_cmd(cmd);
}
staticvoidwrite_addr(unsignedintaddr)
{
nand_chip.write_addr(addr);
}

staticunsignedcharread_data(void)
{
returnnand_chip.read_data();
}


/* 初始化NAND Flash */
voidnand_init(void)
{
#defineTACLS 0
#defineTWRPH0 3
#defineTWRPH1 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;
#ifdefLARGER_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();
}


/* 读函数 */
voidnand_read(unsignedchar*buf,unsignedlongstart_addr,intsize)
{
inti,j;

#ifdefLARGER_NAND_PAGE
if((start_addr&NAND_BLOCK_MASK_LP)||(size&NAND_BLOCK_MASK_LP)){
return;/* 地址或长度不对齐 */
}
#else
if((start_addr&NAND_BLOCK_MASK)||(size&NAND_BLOCK_MASK)){
return;/* 地址或长度不对齐 */
}
#endif

/* 选中芯片 */
nand_select_chip();

for(i=start_addr;i<(start_addr+size);){
/* 发出READ0命令 */
write_cmd(0);

/* Write Address */
write_addr(i);
#ifdefLARGER_NAND_PAGE
write_cmd(0x30);
#endif
wait_idle();

#ifdefLARGER_NAND_PAGE
for(j=0;j#else
for(j=0;j#endif
*buf=read_data();
buf++;
}
}

/* 取消片选信号 */
nand_deselect_chip();

return;
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭