主题 : 关于k9F1G08读写求教 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 63263
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
综合积分: 8 分
注册时间: 2012-02-16
最后登录: 2012-05-29
楼主  发表于: 2012-03-03 15:50

 关于k9F1G08读写求教

想跑下韦东山的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
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
级别: 新手上路
UID: 55347
精华: 0
发帖: 37
金钱: 185 两
威望: 37 点
综合积分: 74 分
注册时间: 2011-09-16
最后登录: 2013-04-21
1楼  发表于: 2012-03-18 19:24
我也在弄这个程序,我插入点亮Led语句去检测,结果发现程序while(!(NFSTAT&(1<<2)));这里有问题;只要把点亮led插到有 这个语句的地方,就不亮了。有待研究。
级别: 新手上路
UID: 65779
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2012-03-22
最后登录: 2012-04-26
2楼  发表于: 2012-03-22 18:18
我的板子上NAND flash是K9F2G08U0C,命令周期,写地址,这些操作都是按着K9F2G08U0A的芯片手册来的。就是读操作失败。。难道是因为没有进行ECC校验的原因??友善没有裸机驱动示例吗。。给个模板也好。。