S5PV210的NandFlash应用(一)

准备分析

        标题挂了一个(一),代表这个是涉及到NandFlash并不深入,只实现读操作。还是16k的代码,这次从NandFlash中读取,读到iRAM中地址为 0xD0024000 的地方。并调用main运行。如下图所示:(CPU会自动把B区代码拷贝到A区,我用A区代码从将B区代码拷贝到C区,并调用main运行
        
资源工具

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

着手写程序
        start.S中的代码拷贝很重要,Makefile中的链接地址很重要。

  1. /* 
  2.  * $Id: nand_cp.c,v 1.1 2008/11/20 01:08:36 boyko Exp $ 
  3.  * 
  4.  * (C) Copyright 2006 Samsung Electronics 
  5.  * 
  6.  * See file CREDITS for list of people who contributed to this 
  7.  * project. 
  8.  * 
  9.  * This program is free software; you can redistribute it and/or 
  10.  * modify it under the terms of the GNU General Public License as 
  11.  * published by the Free Software Foundation; either version 2 of 
  12.  * the License, or (at your option) any later version. 
  13.  * 
  14.  * This program is distributed in the hope that it will be useful, 
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  17.  * GNU General Public License for more details. 
  18.  * 
  19.  * You should have received a copy of the GNU General Public License 
  20.  * along with this program; if not, write to the Free Software 
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
  22.  * MA 02111-1307 USA 
  23.  */  
  24.   
  25. /* 
  26.  * You must make sure that all functions in this file are designed 
  27.  * to load only U-Boot image. 
  28.  * 
  29.  * So, DO NOT USE in common read. 
  30.  * 
  31.  * By scsuh. 
  32.  */  
  33.   
  34.   
  35. /* 
  36.  * Standard NAND flash commands 
  37.  */  
  38. #define NAND_CMD_READ0      0  
  39. #define NAND_CMD_READ1      1  
  40. #define NAND_CMD_RNDOUT     5  
  41. #define NAND_CMD_PAGEPROG   0x10  
  42. #define NAND_CMD_READOOB    0x50  
  43. #define NAND_CMD_ERASE1     0x60  
  44. #define NAND_CMD_STATUS     0x70  
  45. #define NAND_CMD_STATUS_MULTI   0x71  
  46. #define NAND_CMD_SEQIN      0x80  
  47. #define NAND_CMD_RNDIN      0x85  
  48. #define NAND_CMD_READID     0x90  
  49. #define NAND_CMD_PARAM      0xec  
  50. #define NAND_CMD_ERASE2     0xd0  
  51. #define NAND_CMD_RESET      0xff  
  52.   
  53. /* Extended commands for large page devices */  
  54. #define NAND_CMD_READSTART  0x30  
  55. #define NAND_CMD_RNDOUTSTART    0xE0  
  56. #define NAND_CMD_CACHEDPROG 0x15  
  57.   
  58. #define NAND_DISABLE_CE()   (NFCONT_REG |= (1 << 1))  
  59. #define NAND_ENABLE_CE()    (NFCONT_REG &= ~(1 << 1))  
  60. #define NF_TRANSRnB()       do { while(!(NFSTAT_REG & (1 << 0))); } while(0)  
  61.   
  62. //#include <asm/io.h>  
  63. //#include <linux/mtd/nand.h>  
  64. #include "s5pc110.h"  
  65. #define COPY_BL2_SIZE       0x80000  
  66.   
  67. #define NAND_CONTROL_ENABLE()   (NFCONT_REG |= (1 << 0))  
  68.   
  69. /* 
  70.  * address format 
  71.  *              17 16         9 8            0 
  72.  * -------------------------------------------- 
  73.  * | block(12bit) | page(5bit) | offset(9bit) | 
  74.  * -------------------------------------------- 
  75.  */  
  76.   
  77. static int nandll_read_page (uchar *buf, ulong addr, int large_block)  
  78. {  
  79.     int i;  
  80.     int page_size = 512;  
  81.   
  82.     if (1 == large_block)  
  83.         page_size = 2048;  
  84.           
  85.     else if (2 == large_block)  
  86.         page_size = 8192;  
  87.   
  88.     NAND_ENABLE_CE();  
  89.   
  90.     NFCMD_REG = NAND_CMD_READ0;  
  91.   
  92.     /* Write Address */  
  93.     NFADDR_REG = 0;  
  94.   
  95.     if (large_block)  
  96.         NFADDR_REG = 0;  
  97.   
  98.     NFADDR_REG = (addr) & 0xff;  
  99.     NFADDR_REG = (addr >> 8) & 0xff;  
  100.     NFADDR_REG = (addr >> 16) & 0xff;  
  101.   
  102.     if (large_block)  
  103.         NFCMD_REG = NAND_CMD_READSTART;  
  104.   
  105.         NF_TRANSRnB();  
  106.   
  107.     /* for compatibility(2460). u32 cannot be used. by scsuh */  
  108.     for(i=0; i < page_size; i++) {  
  109.                 *buf++ = NFDATA8_REG;  
  110.         }  
  111.   
  112.         NAND_DISABLE_CE();  
  113.         return 0;  
  114. }  
  115.   
  116. /* 
  117.  * Read data from NAND. 
  118.  */  
  119. static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)  
  120. {  
  121.     uchar *buf = (uchar *)dst_addr;  
  122.     int i;  
  123.     uint page_shift = 9;  
  124.   
  125.     if (1 == large_block)  
  126.     {  
  127.         page_shift = 11;  
  128.       
  129.         /* Read pages */  
  130.         for (i = (0x6000>>page_shift); i < (size>>page_shift); i++, buf+=(1<<page_shift))   
  131.         {  
  132.             nandll_read_page(buf, i, large_block);  
  133.         }  
  134.     }  
  135.     else if(2 == large_block)  
  136.     {  
  137.         page_shift = 12;  
  138.         for (i = 0; i < (size>>page_shift); i++, buf+=(1<<(page_shift-1)))   
  139.         {  
  140.                 nandll_read_page(buf, i, large_block);  
  141.         }  
  142.     }  
  143.           
  144.     return 0;  
  145. }  
  146.   
  147. int copy_uboot_to_ram_nand (void)  
  148. {  
  149.     int large_block = 0;  
  150.     int i;  
  151.     vu_char id;  
  152.   
  153.     NAND_CONTROL_ENABLE();  
  154.         NAND_ENABLE_CE();  
  155.         NFCMD_REG = NAND_CMD_READID;  
  156.         NFADDR_REG =  0x00;  
  157.   
  158.     /* wait for a while */  
  159.         for (i=0; i<200; i++);  
  160.     id = NFDATA8_REG;  
  161.     id = NFDATA8_REG;  
  162.   
  163.     if (id > 0x80)  
  164.         large_block = 1;  
  165.           
  166.     if(id == 0xd5)  
  167.     {  
  168.         large_block = 2;  
  169.     }  
  170.   
  171.     /* read NAND Block. 
  172.      * 128KB ->240KB because of U-Boot size increase. by scsuh 
  173.      * So, read 0x3c000 bytes not 0x20000(128KB). 
  174.      */  
  175.     //return nandll_read_blocks(CONFIG_SYS_TEXT_BASE, COPY_BL2_SIZE, large_block);  
  176.     return nandll_read_blocks(0xd0024000, 0x4000, large_block);  
  177. }  
  178. void board_init_f_nand(unsigned long bootflag)  
  179. {  
  180.         __attribute__((noreturn)) void (*uboot)(void);  
  181.         copy_uboot_to_ram_nand();  
  182.   
  183.         /* Jump to U-Boot image */  
  184.         uboot = (void *)0xd024010;  
  185.     (*uboot)();  
  186.         /* Never returns Here */  
  187. }  
  1. @******************************************************************************  
  2. @ File:start.S  
  3. @ 功能:启动代码,设置栈,拷贝16k到0xd0020000处  
  4. @******************************************************************************    
  5. .text  
  6.   
  7. .global _start  
  8.   
  9. _start:  
  10.       
  11.     ldr sp, =0xD0037D80       @ 设置栈,以便调用c函数                       
  12.       
  13.     adr r0, _start                @ 重定位   
  14.                             @ _start当前所位于的地址:0xd0020010 (前边放有16bit的头信息)  
  15.       
  16.     ldr r1, =_start           @ _start的链接地址:0xd0024010    
  17.       
  18.     ldr r2, =0xd0028000       @ 0xd0028000 = 0xd0024000 + 0x4000(16k)   
  19.     cmp r0, r1  
  20.     beq run_on_dram  
  21.   
  22.     bl  nand_asm_init  
  23.     bl  copy_uboot_to_ram_nand  
  24.   
  25.       
  26. run_on_dram:               
  27.     ldr pc, =main             @ 跳转        
  28.   
  29.   
  30. halt:  
  31.     b halt  
  32.   
  33.   
  34. led_debug:       
  35.     ldr     R0,=0xE0200280      @ R0设为GPJ2CON寄存器。此寄存器  
  36.                                         @ 用于选择端口J各引脚的功能:  
  37.                                         @ 是输出、是输入、还是其他  
  38.     mov     R1,#0x00000001          
  39.     str     R1,[R0]             @ 设置GPJ2_0为输出口, 位[10:9]=0b01  
  40.     ldr     R0,=0xE0200284      @ R0设为GPJ2DAT寄存器。此寄存器  
  41.                                         @ 用于读/写端口GPJ2各引脚的数据  
  42.     mov     R1,#0x00000000      @ 此值改为0x00000001,  
  43.                                         @ 可让LED1熄灭  
  44.     str     R1,[R0]             @ GPJ2_0输出0,LED1点亮  
  45.     mov pc, lr  
  46.   
  47.   
  48.   
  49.     /* Setting GPIO for NAND */  
  50.     /* This setting is NAND initialze code at booting time in iROM. */  
  51.       
  52. nand_asm_init:  
  53.       
  54. /* 
  55.  * Nand Interface Init for SMDKC110 
  56.  */  
  57.    
  58. #define ELFIN_GPIO_BASE         0xE0200000   
  59. #define ELFIN_NAND_BASE         0xB0E00000  
  60. #define NFCONF_VAL  (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)  
  61. #define NFCONT_VAL      (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)  
  62.   
  63. #define MP01CON_OFFSET          0x2E0  
  64. #define MP01PUD_OFFSET          0x2E8  
  65. #define MP03CON_OFFSET      0x320  
  66. #define MP03PUD_OFFSET      0x328  
  67. #define NFCONF_OFFSET       0x00  
  68. #define NFCONT_OFFSET       0x04  
  69.    
  70.   
  71.     ldr r0, =ELFIN_GPIO_BASE  
  72.   
  73.     ldr r1, [r0, #MP01CON_OFFSET]  
  74.     bic r1, r1, #(0xf<<8)  
  75.     orr r1, r1, #(0x3<<8)  
  76.     str r1, [r0, #MP01CON_OFFSET]  
  77.   
  78.     ldr r1, [r0, #MP01PUD_OFFSET]  
  79.     bic r1, r1, #(0x3<<4)  
  80.     str r1, [r0, #MP01PUD_OFFSET]  
  81.   
  82.     ldr r1, [r0, #MP03CON_OFFSET]  
  83.     bic r1, r1, #0xFFFFFF  
  84.     ldr r2, =0x22222222  
  85.     orr r1, r1, r2  
  86.     str r1, [r0, #MP03CON_OFFSET]  
  87.   
  88.     ldr r1, [r0, #MP03PUD_OFFSET]  
  89.     ldr r2, =0x3fff  
  90.     bic r1, r1, r2  
  91.     str r1, [r0, #MP03PUD_OFFSET]  
  92.   
  93.     ldr r0, =ELFIN_NAND_BASE  
  94.   
  95.     ldr r1, [r0, #NFCONF_OFFSET]  
  96.     ldr r2, =0x777F  
  97.     bic r1, r1, r2  
  98.     ldr r2, =NFCONF_VAL  
  99.     orr r1, r1, r2  
  100.     str r1, [r0, #NFCONF_OFFSET]  
  101.   
  102.     ldr r1, [r0, #NFCONT_OFFSET]  
  103.     ldr r2, =0x707C7  
  104.     bic r1, r1, r2  
  105.     ldr r2, =NFCONT_VAL  
  106.     orr r1, r1, r2  
  107.     str r1, [r0, #NFCONT_OFFSET]  
  108.   
  109.     ldr r1, [r0, #NFCONF_OFFSET]  
  110.     orr r1, r1, #0x70  
  111.     orr r1, r1, #0x7700  
  112.     str     r1, [r0, #NFCONF_OFFSET]  
  113.   
  114.     ldr r1, [r0, #NFCONT_OFFSET]  
  115.     orr r1, r1, #0x03  
  116.     str     r1, [r0, #NFCONT_OFFSET]  
  117.   
  118.     mov pc, lr  
main.c
  1. #define     GPJ2CON     (*(volatile unsigned long *) 0xE0200280)  
  2. #define     GPJ2DAT     (*(volatile unsigned long *) 0xE0200284)  
  3.   
  4. // 延时函数  
  5. void delay(unsigned long count)  
  6. {  
  7.     volatile unsigned long i = count;  
  8.     while (i--)  
  9.         ;  
  10. }  
  11.   
  12. void main()             //LED 闪烁  
  13. {  
  14.     GPJ2CON = 0x00001111;       // 配置引脚  
  15.     while(1)                    // 闪烁  
  16.     {  
  17.         GPJ2DAT = 0;            // LED on  
  18.         delay(0x100000);  
  19.         GPJ2DAT = 0xf;          // LED off  
  20.         delay(0x100000);  
  21.     }  
  22. }  

下载运行

        同《  S5PV210的LED应用(一)

运行调试
       
        一开始以为程序会很难,应该MLC的,这样的NandFlash涉及到了ECC校验,颇为麻烦,但是细想,只实现读操作,会少许简单一些。最后发现读的时候问题并不多。也并不是那么困难。nand_asm_init和nand_cp.c提取于u-boot,并加以移植。
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值