S5PV210的NandFlash应用(二)

准备分析

        《S5PV210的NandFlash应用(一)》有很多bug,为了文章完整性就不在原文上进行修改了。(一)是在调试nand_cp.c的时候,程序运行过之后,灯立即亮了起来,让我误以为我的NandFlash读操作正常了,最后在往下进行大文件拷贝的时候出现异常,我不得不重新回到这个Nand_cp.c这里来。这次结合Uart打印出NandFlash读出的数据,和210.bin文件进行对比,发现后边错误很多,但是我的程序也能运行。总结出了(一)里边的bug有: 1.nand_cp.c中应该调用board_init_f_nand(),而非copy_uboot_to_ram_nand()。2.board_init_f_nand中的跳转代码uboot = (void *)0xd024010明显有误,为什么能够运行,就是实质都没有调用;3.是在start.S中通过相跳转到了main函数的,而非链接地址跳转的,造成了假象。 用一天冷静下来,重新来理清思路。 1.先把Uart调试通。2.通过Uart打印出NFDATA8_REG寄存器的值。3.和210.bin二进制文件对比。4.自己做二进制文件到210.bin的后边,进行对比。
        

资源工具

        同《  S5PV210的LED应用(一)
        NandFlash: K9GAG08U0F (2G)

着手写程序
        (1) void board_init_f_nand ((unsigned long bootflag)) ,负责调用copy_uboot_to_ram_nand()和uboot = (void *)0xd0024010;
        (2) int copy_uboot_to_ram_nand (void),判断NandFlash类型页的大小。调用int nandll_read_blocks。
        (3) int nandll_read_blocks (ulong dst_addr, ulong size, int large_block),读一块大小。
        (4) int nandll_read_page (uchar *buf, ulong addr, int large_block),读一页大小,并通过串口打印出NFDATA8_REG寄存器的值。
具体的实现:

  1. void board_init_f_nand(unsigned long bootflag)  
  2. {  
  3.     __attribute__((noreturn)) void (*uboot)(void);  
  4.     copy_uboot_to_ram_nand();  
  5.   
  6.     /* Jump to U-Boot image */  
  7.     uboot = (void *)0xd0024010;  
  8.     (*uboot)();  
  9.     /* Never returns Here */  
  10. }  

  1. int copy_uboot_to_ram_nand (void)  
  2. {  
  3.     int large_block = 0;  
  4.     int i;  
  5.     vu_char id;  
  6.   
  7.     NAND_CONTROL_ENABLE();  
  8.   NAND_ENABLE_CE();  
  9.   NFCMD_REG = NAND_CMD_READID;  
  10.   NFADDR_REG =  0x00;  
  11.   
  12.     /* wait for a while */  
  13.   for (i=0; i<200; i++);  
  14.     id = NFDATA8_REG;  
  15.     id = NFDATA8_REG;  
  16.   
  17.     if (id > 0x80)  
  18.         large_block = 1;  
  19.           
  20.     if(id == 0xd5)  
  21.     { //page_size = 8k  
  22.         large_block = 3;  
  23.     }  
  24.   
  25.     /* read NAND Block. 
  26.      * 128KB ->240KB because of U-Boot size increase. by scsuh 
  27.      * So, read 0x3c000 bytes not 0x20000(128KB). 
  28.      */  
  29.     //return nandll_read_blocks(CONFIG_SYS_TEXT_BASE, COPY_BL2_SIZE, large_block);  
  30.     return nandll_read_blocks(0xd0024000, 0x4000, large_block);  
  31. }  

  1. /* 
  2.  * Read data from NAND. 
  3.  */  
  4. static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)  
  5. {  
  6.     uchar *buf = (uchar *)dst_addr;  
  7.     int i;  
  8.     uint page_shift = 9;  
  9.   
  10.     if (1 == large_block)  
  11.     {  
  12.         page_shift = 11;  
  13.       
  14.         /* Read pages */  
  15.         for (i = (0x6000>>page_shift); i < (size>>page_shift); i++, buf+=(1<<page_shift))   
  16.         {  
  17.             nandll_read_page(buf, i, large_block);  
  18.         }  
  19.     }  
  20.     else if(3 == large_block)  
  21.     {  
  22.         page_shift = 13;  
  23.           
  24.         for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1)))   
  25.         {  
  26.                 nandll_read_page(buf, i, large_block-1);  
  27.         }  
  28.     }  
  29.           
  30.     return 0;  
  31. }  

  1. /* 
  2.  * address format 
  3.  *              17 16         9 8            0 
  4.  * -------------------------------------------- 
  5.  * | block(12bit) | page(5bit) | offset(9bit) | 
  6.  * -------------------------------------------- 
  7.  */  
  8.   
  9. static int nandll_read_page (uchar *buf, ulong addr, int large_block)  
  10. {  
  11.     int i;  
  12.     volatile char c;  
  13.     int page_size = 512;  
  14.   
  15.     if (1 == large_block)  
  16.         page_size = 2048;  
  17.           
  18.     else if (2 == large_block)  
  19.         page_size = 4096;  
  20.       
  21.     else if (3 == large_block)  
  22.         page_size = 8192;  
  23.   
  24.     NAND_ENABLE_CE();  
  25.   
  26.     NFCMD_REG = NAND_CMD_READ0;  
  27.   
  28.     /* Write Address */  
  29.     NFADDR_REG = 0;  
  30.   
  31.     if (large_block)  
  32.         NFADDR_REG = 0;  
  33.   
  34.     NFADDR_REG = (addr) & 0xff;  
  35.     NFADDR_REG = (addr >> 8) & 0xff;  
  36.     NFADDR_REG = (addr >> 16) & 0xff;  
  37.   
  38.     if (large_block)  
  39.         NFCMD_REG = NAND_CMD_READSTART;  
  40.   
  41.         NF_TRANSRnB();  
  42.   
  43.     /* for compatibility(2460). u32 cannot be used. by scsuh */  
  44.     for(i=0; i < page_size; i++)   
  45.     {  
  46.         c = NFDATA8_REG;   
  47.         *buf++ = c;  
  48.         puthex(c);  
  49.         putc(' ');  
  50.                   
  51.   }  
  52.   
  53.     NAND_DISABLE_CE();  
  54.     return 0;  
  55. }  

下载运行

        同《  S5PV210的LED应用(一)

运行调试
       
        对比如图所示:



         得到结论,前16k代码在NandFlash存储方式如下:
         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值