硬件平台 :JZ2440

实现功能:初始化 Nand Flash 和 sdram,并将代码从 Nand Flash 拷贝到 sdram。

start.s      --> 上电初始化 nand 与sdram

nand.c     -->  Nand Flash 初始化函数

sdram.c   --> sdram 初始化函数

leds.c      -->  led 闪烁

start.s 源码:

.text
.global _start
_start:
ldr sp,=
bl disable_watch_dog
bl sdram_init
bl nand_init
ldr r0,=0x30000000
mov r1,#
mov r2,#
bl nand_read
ldr sp,=0x34000000
ldr lr,=loop1
ldr pc,=0x30000000
loop1:
b loop1

nand.c 源码:

#define BUSY          1

#define NAND_SECTOR_SIZE_LP    2048
#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1) typedef struct
{
int NFCONF;
int NFCONT;
int NFCMD;
int NFADDR;
int NFDATA;
int NFMECCD0;
int NFMECCD1;
int NFSECCD;
int NFSTAT;
int NFESTAT0;
int NFESTAT1;
int NFMECC0;
int NFMECC1;
int NFSECC;
int NFSBLK;
int NFEBLK;
} S3C2440_NAND; static S3C2440_NAND *s3c2440nand = (S3C2440_NAND *)0x4e000000; /* 供外部调用的函数 */
void nand_init(void);
void nand_read(unsigned char *buf, unsigned long start_addr, int size); /* S3C2440的NAND Flash处理函数 */
static void nand_reset(void);
static void wait_idle(void);
static void nand_select_chip(void);
static void nand_deselect_chip(void);
static void write_cmd(int cmd);
static void write_addr(unsigned int addr);
static unsigned char read_data(void); /* 复位 */
static void nand_reset(void)
{
nand_select_chip();
write_cmd(0xff); // 复位命令
wait_idle();
nand_deselect_chip();
} /* 等待NAND Flash就绪 */
static void wait_idle(void)
{
int i;
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
while(!(*p & BUSY))
for(i=; i<; i++);
} /* 发出片选信号 */
static void nand_select_chip(void)
{
int i;
s3c2440nand->NFCONT &= ~(<<);
for(i=; i<; i++);
} /* 取消片选信号 */
static void nand_deselect_chip(void)
{
s3c2440nand->NFCONT |= (<<);
} /* 发出命令 */
static void write_cmd(int cmd)
{
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
*p = cmd;
} /* 发出地址 */
static void write_addr(unsigned int addr)
{
int i;
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
int col, page; col = addr & NAND_BLOCK_MASK_LP;
page = addr / NAND_SECTOR_SIZE_LP; *p = col & 0xff; /* Column Address A0~A7 */
for(i=; i<; i++);
*p = (col >> ) & 0x0f; /* Column Address A8~A11 */
for(i=; i<; i++);
*p = page & 0xff; /* Row Address A12~A19 */
for(i=; i<; i++);
*p = (page >> ) & 0xff; /* Row Address A20~A27 */
for(i=; i<; i++);
*p = (page >> ) & 0x03; /* Row Address A28~A29 */
for(i=; i<; i++);
} /* 读取数据 */
static unsigned char read_data(void)
{
volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
return *p;
} /* 初始化NAND Flash */
void nand_init(void)
{
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0 /* 设置时序 */
s3c2440nand->NFCONF = (TACLS<<)|(TWRPH0<<)|(TWRPH1<<);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
s3c2440nand->NFCONT = (<<)|(<<)|(<<);
/* 复位NAND Flash */
nand_reset();
} /* 读函数 */
void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
{
return ; /* 地址或长度不对齐 */
}
/* 选中芯片 */
nand_select_chip();
for(i=start_addr; i < (start_addr + size);)
{
/* 发出READ0命令 */
write_cmd();
/* Write Address */
write_addr(i);
write_cmd(0x30);
wait_idle();
for(j=; j < NAND_SECTOR_SIZE_LP; j++, i++) //一页2k
{
*buf = read_data();
buf++;
}
}
/* 取消片选信号 */
nand_deselect_chip();
return ;
}

sdram.c 源码:

void disable_watch_dog(void)
{
(*(unsigned long *)0x53000000)=;
} void sdram_init(void)
{
unsigned long p[]={ 0x22011110,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00000700,
0x00018005,
0x00018005,
0x008c07a3,
0x000000b1,
0x00000030,
0x00000030 };
unsigned long *sdram_base=(unsigned long *)0x48000000;
int i=;
for(;i<;i++) sdram_base[i]=p[i];
}

leds.c 源码:

#define    GPFCON        (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPF4_out (1<<(4*2))
#define GPF5_out (1<<(5*2))
#define GPF6_out (1<<(6*2)) void wait(volatile unsigned long dly)
{
for(; dly > ; dly--);
} int main(void)
{
unsigned long i = ; GPFCON = GPF4_out|GPF5_out|GPF6_out; // 将LED1-3对应的GPF4/5/6三个引脚设为输出 while(){
wait();
GPFDAT = (~(i<<)); // 根据i的值,点亮LED1-3
if(++i == )
i = ;
} return ;
}

链接脚本 nand.lds:

SECTIONS
{
first 0x00000000 :{start.o sdram.o nand.o}
seconed 0x30000000 :AT() {leds.o}
}

编译的Makefile:

objs:=start.o sdram.o nand.o leds.o

nand.bin:$(objs)
arm-linux-ld -Tnand.lds -o nand_elf $^
arm-linux-objcopy -O binary -S nand_elf $@
arm-linux-objdump -D -m arm nand_elf > nand.dis
%.o:%.c
arm-linux-gcc -o $@ -c $<
%.o:%.S
arm-linux-gcc -o $@ -c $< clean:
rm *.o *.bin *.dis nand_elf

Nand Flash 裸机程序的更多相关文章

  1. S5PV210 NAND Flash

    NAND Flash 关于NAND FlashS5PV210的NAND Flash控制器有如下特点:1) 支持512byte,2k,4k,8k的页大小2) 通过各种软件模式来进行NAND Flash的 ...

  2. u-boot移植总结(三)(转)S3C2440对Nand Flash操作和电路原理(基于K9F2G08U0A)

    S3C2440对Nand Flash操作和电路原理(基于K9F2G08U0A) 转载自:http://www.cnblogs.com/idle_man/archive/2010/12/23/19153 ...

  3. NOR flash和NAND flash区别,RAM 和ROM区别

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  4. NOR flash和NAND flash区别,RAM 和ROM区别d

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  5. SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别

                          SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别 RAM / ROM 存储器 ROM和RAM指的都是半导体存储器,R ...

  6. nor flash 和nand flash 的区别

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  7. Nand Flash与Nor

    转:http://www.360doc.com/content/11/1215/15/1299815_172458274.shtml Flash经常在一些地方被提到,一直没认真去理解它们的区别,因此, ...

  8. 十八、Nand Flash驱动和Nor Flash驱动

    在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...

  9. S3C2440从NAND Flash启动和NOR FLASH启动的问题

    1.为什么NAND FLASH不能直接运行程序     NAND FLASH本身是连接到了控制器上而不是系统总线上.CPU运行机制为:CPU启动后是要取指令执行的,如果是SROM.NOR FLASH ...

随机推荐

  1. 【转】JS获取浏览器可视区域的尺寸

    from: http://www.xiaoboy.com/detail/1341545044.html 所谓可视区域是指能看得见的区域,即在浏览器中能看到页面的区域(高度与宽度).刚刚使用 docum ...

  2. Git 删除提交记录

    .Checkout git checkout --orphan latest_branch 2. Add all the files git add -A 3. Commit the changes ...

  3. oracle存储过程遇到的问题

    最近新的项目,会批量执行数据,用到了存储过程和函数,遇到的问题记录如下: 1.涉及大量数据,所以决定分批commit数据 2.out无论是存储过程还是函数,都会返回数据,当时当我们手动raise(抛出 ...

  4. jdk 自带的数据库Derby使用

    ij是derby自带的一个功能强大的数据库管理工具,可以进行很多数据库管理的操作,包括创建数据库, 启动/关闭数据库,执行SQL脚本等.完成准备工作后,就可以启动并使用ij工具了. 在cmd中输入如下 ...

  5. python网络编程之UDP方式传输数据

    UDP --- 用户数据报协议(User Datagram Protocol),是一个无连接的简单的面向数据报的运输层协议. UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能 ...

  6. Pro ASP.NET MVC –第三章 MVC模式

    在第七章,我们将创建一个更复杂的ASP.NET MVC示例,但在那之前,我们会深入ASP.NET MVC框架的细节:我们希望你能熟悉MVC设计模式,并且考虑为什么这样设计.在本章,我们将讨论下列内容 ...

  7. C++内存管理(转)

    C++内存管理 [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理 ...

  8. 7.11登入表单html

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 有重复行,查询时只保留最新一行的sql

    一.表结构如下:表名test 二.sql select temp.* from (select test.*, row_number() over(partition by obd_code orde ...

  10. J - Vertical Histogram(1.5.7)

    J - Vertical Histogram(1.5.7) Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d &am ...