想跑下韦东山的nand程序,搞了3天,查遍了网上的程序,分析了,还是不行。程序通过ViVi的a选择下载到nandflash中。
程序的执行时这样的:从nand启动,前面4k的程序,完成初始化,把4K后的代码复制到0x30000000执行,
可是结果总是不对,找不到原因,头大了,请高手帮忙分析:
程序如下:
@ File:head.s
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@******************************************************************************
.text
.global _start
_start:
@函数disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定义
ldr sp, =4096 @设置堆栈 ,此处是为了下面调用c函数
bl disable_watch_dog @关WATCH DOG
bl memsetup @初始化SDRAM
bl RdNF2SDRAM @调用C函数nand_read
ldr sp, =0x34000000 @设置栈
ldr lr, =halt_loop @设置返回地址
ldr pc, =main @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
halt_loop:
b halt_loop
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
存储器初始化:init.c
/* WOTCH DOG register */
#define WTCON (*(volatile unsigned long *)0x53000000)
/* SDRAM regisers */
#define MEM_CTL_BASE 0x48000000
void disable_watch_dog();
void memsetup();
/*上电后,WATCH DOG默认是开着的,要把它关掉 */
void disable_watch_dog()
{
WTCON = 0;
}
/* 设置控制SDRAM的13个寄存器 */
void memsetup()
{
int i = 0;
unsigned long *p = (unsigned long *)MEM_CTL_BASE;
/* SDRAM 13个寄存器的值 */
unsigned long const mem_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 = mem_cfg_val;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
nandflash初始化和读程序:nand.c
//nandflash程序
#define rGPACON (*(volatile unsigned *)0x56000000) //Port A control
#define rNFCONF (*(volatile unsigned *)0x4E000000) //NAND Flash configuration
#define rNFCONT (*(volatile unsigned *)0x4E000004) //NAND Flash control
#define rNFCMD (*(volatile unsigned *)0x4E000008) //NAND Flash command
#define rNFADDR (*(volatile unsigned *)0x4E00000C) //NAND Flash address
#define rNFDATA8 (*(volatile unsigned char *)0x4E000010) //NAND Flash data
#define rNFSTAT (*(volatile unsigned *)0x4E000020) //NAND Flash operation status
#define NF_CMD(data) {rNFCMD = (data); }
#define NF_ADDR(addr) {rNFADDR = (addr); }
#define NF_nFCE_L() {rNFCONT &= ~(1<<1); }
#define NF_nFCE_H() {rNFCONT |= (1<<1); }
#define NF_RDDATA8() (rNFDATA8)
#define NF_CLEAR_RB() {rNFSTAT |= (1<<2); }
#define NF_DETECT_RB() {while(!(rNFSTAT&(1<<2)));}
#define NF_CE_L() NF_nFCE_L()
#define NF_CE_H() NF_nFCE_H()
//nandflash命令集
#define CMD_READ1 0x00 //读命令周期1
#define CMD_READ2 0x30 //读命令周期2
#define CMD_RESET 0xff //复位
// HCLK=100Mhz
#define TACLS 1
#define TWRPH0 4
#define TWRPH1 0
//把nandflash中的数据复制到SRAM
void RdNF2SDRAM( )
{
unsigned int i, j;
unsigned int start_addr = 0x0; //nandflash起始地址
unsigned char * to = (unsigned char *)0x30000000; //SRAM起始地址
unsigned int size = 2048; //复制数据的大小
//初始化nandflash
rGPACON = (rGPACON &~(0x3f<<17)) | (0x3f<<17);
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
//开始复制数据
for(i = (start_addr >> 11); size > 0; )
{
//nandflash复位
NF_CE_L();
NF_CLEAR_RB();
NF_CMD(CMD_RESET);
NF_DETECT_RB();
NF_CE_H();
NF_nFCE_L();
NF_CLEAR_RB();
NF_CMD(CMD_READ1); //读命令
//5个周期地址
NF_ADDR(0x00);
NF_ADDR(0x00);
NF_ADDR((i) & 0xff);
NF_ADDR((i >> 8) & 0xff);
NF_ADDR((i >> 16) & 0xff);
NF_CMD(CMD_READ2); //读命
NF_DETECT_RB(); //等待
//开始复制一页数据
for (j = 0; j < 2048; j++)
{
to[j] = NF_RDDATA8();
}
NF_nFCE_H();
size -= 2048;
to += 2048;
i += 2048;
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
连接文件:nand.lds
SECTIONS {
firtst 0x00000000 : { head.o init.o nand.o}
second 0x30000000 : AT(4096) { main.o }
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
makefile文件:
objs := head.o init.o nand.o main.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 -Wall -c -O2 -o $@ $<
%.o:%.S
arm-linux-gcc -Wall -c -O2 -o $@ $<
clean:
rm -f nand.dis nand.bin nand_elf *.o *.bak
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------