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

? ? ? ??
资源工具
? ? ? ? 同《?
S5PV210的LED应用(一)》
? ? ? ? NandFlash: K9GAG08U0F (2G)
着手写程序
? ? ? ? start.S中的代码拷贝很重要,Makefile中的链接地址很重要。
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ??
- ?
- ?
- ?
- ?
- ??
- ??
- ??
- ?
- ??
- #define?NAND_CMD_READ0??????0??
- #define?NAND_CMD_READ1??????1??
- #define?NAND_CMD_RNDOUT?????5??
- #define?NAND_CMD_PAGEPROG???0x10??
- #define?NAND_CMD_READOOB????0x50??
- #define?NAND_CMD_ERASE1?????0x60??
- #define?NAND_CMD_STATUS?????0x70??
- #define?NAND_CMD_STATUS_MULTI???0x71??
- #define?NAND_CMD_SEQIN??????0x80??
- #define?NAND_CMD_RNDIN??????0x85??
- #define?NAND_CMD_READID?????0x90??
- #define?NAND_CMD_PARAM??????0xec??
- #define?NAND_CMD_ERASE2?????0xd0??
- #define?NAND_CMD_RESET??????0xff??
- ??
- ??
- #define?NAND_CMD_READSTART??0x30??
- #define?NAND_CMD_RNDOUTSTART????0xE0??
- #define?NAND_CMD_CACHEDPROG?0x15??
- ??
- #define?NAND_DISABLE_CE()???(NFCONT_REG?|=?(1?<<?1))??
- #define?NAND_ENABLE_CE()????(NFCONT_REG?&=?~(1?<<?1))??
- #define?NF_TRANSRnB()???????do?{?while(!(NFSTAT_REG?&?(1?<<?0)));?}?while(0)??
- ??
- ??
- ??
- #include?"s5pc110.h"??
- #define?COPY_BL2_SIZE???????0x80000??
- ??
- #define?NAND_CONTROL_ENABLE()???(NFCONT_REG?|=?(1?<<?0))??
- ??
- ?
- ?
- ?
- ?
- ??
- ??
- static?int?nandll_read_page?(uchar?*buf,?ulong?addr,?int?large_block)??
- {??
- ????int?i;??
- ????int?page_size?=?512;??
- ??
- ????if?(1?==?large_block)??
- ????????page_size?=?2048;??
- ??????????
- ????else?if?(2?==?large_block)??
- ????????page_size?=?8192;??
- ??
- ????NAND_ENABLE_CE();??
- ??
- ????NFCMD_REG?=?NAND_CMD_READ0;??
- ??
- ??????
- ????NFADDR_REG?=?0;??
- ??
- ????if?(large_block)??
- ????????NFADDR_REG?=?0;??
- ??
- ????NFADDR_REG?=?(addr)?&?0xff;??
- ????NFADDR_REG?=?(addr?>>?8)?&?0xff;??
- ????NFADDR_REG?=?(addr?>>?16)?&?0xff;??
- ??
- ????if?(large_block)??
- ????????NFCMD_REG?=?NAND_CMD_READSTART;??
- ??
- ????????NF_TRANSRnB();??
- ??
- ??????
- ????for(i=0;?i?<?page_size;?i++)?{??
- ????????????????*buf++?=?NFDATA8_REG;??
- ????????}??
- ??
- ????????NAND_DISABLE_CE();??
- ????????return?0;??
- }??
- ??
- ?
- ?
- ??
- int?nandll_read_blocks?(ulong?dst_addr,?ulong?size,51); font-weight:bold">int?large_block)??
- {??
- ????uchar?*buf?=?(uchar?*)dst_addr;??
- ????int?i;??
- ????uint?page_shift?=?9;??
- ??
- ????if?(1?==?large_block)??
- ????{??
- ????????page_shift?=?11;??
- ??????
- ??????????
- ????????for?(i?=?(0x6000>>page_shift);?i?<?(size>>page_shift);?i++,?buf+=(1<<page_shift))???
- ????????{??
- ????????????nandll_read_page(buf,?i,?large_block);??
- ????????}??
- ????}??
- ????if(2?==?large_block)??
- ????{??
- ????????page_shift?=?12;??
- ????????for?(i?=?0;?i?<?(size>>page_shift);?i++,?buf+=(1<<(page_shift-1)))???
- ????????{??
- ????????????????nandll_read_page(buf,?large_block);??
- ????????}??
- ????}??
- ??????????
- ????return?0;??
- }??
- ??
- int?copy_uboot_to_ram_nand?(void)??
- {??
- ????int?large_block?=?0;??
- ????int?i;??
- ????vu_char?id;??
- ??
- ????NAND_CONTROL_ENABLE();??
- ????????NAND_ENABLE_CE();??
- ????????NFCMD_REG?=?NAND_CMD_READID;??
- ????????NFADDR_REG?=??0x00;??
- ??
- ??????
- ????????for?(i=0;?i<200;?i++);??
- ????id?=?NFDATA8_REG;??
- ????id?=?NFDATA8_REG;??
- ??
- ????if?(id?>?0x80)??
- ????????large_block?=?1;??
- ??????????
- ????if(id?==?0xd5)??
- ????{??
- ????????large_block?=?2;??
- ????}??
- ??
- ?????
- ?
- ?
- ??
- ??????
- ????return?nandll_read_blocks(0xd0024000,?0x4000,?large_block);??
- }??
- void?board_init_f_nand(unsigned?long?bootflag)??
- {??
- ????????__attribute__((noreturn))?void?(*uboot)(void);??
- ????????copy_uboot_to_ram_nand();??
- ??
- ??????????
- ????????uboot?=?(void?*)0xd024010;??
- ????(*uboot)();??
- ??????????
- }??
- @******************************************************************************??
- @?File:start.S??
- @?功能:启动代码,设置栈,拷贝16k到0xd0020000处??
- @******************************************************************************????
- .text??
- ??
- .global?_start??
- ??
- _start:??
- ??????
- ????ldr?sp,?=0xD0037D80???????@?设置栈,以便调用c函数???????????????????????
- ??????
- ????adr?r0,?_start????????????????@?重定位???
- ????????????????????????????@?_start当前所位于的地址:0xd0020010?(前边放有16bit的头信息)??
- ??????
- ????ldr?r1,?=_start???????????@?_start的链接地址:0xd0024010????
- ??????
- ????ldr?r2,?=0xd0028000???????@?0xd0028000?=?0xd0024000?+?0x4000(16k)???
- ????cmp?r0,?r1??
- ????beq?run_on_dram??
- ??
- ????bl??nand_asm_init??
- ????bl??copy_uboot_to_ram_nand??
- ??
- ??????
- run_on_dram:???????????????
- ????ldr?pc,?=main?????????????@?跳转????????
- ??
- ??
- halt:??
- ????b?halt??
- ??
- ??
- led_debug:???????
- ????ldr?????R0,=0xE0200280??????@?R0设为GPJ2CON寄存器。此寄存器??
- ????????????????????????????????????????@?用于选择端口J各引脚的功能:??
- ????????????????????????????????????????@?是输出、是输入、还是其他??
- ????mov?????R1,#0x00000001??????????
- ????str?????R1,[R0]?????????????@?设置GPJ2_0为输出口,?位[10:9]=0b01??
- ????ldr?????R0,=0xE0200284??????@?R0设为GPJ2DAT寄存器。此寄存器??
- ????????????????????????????????????????@?用于读/写端口GPJ2各引脚的数据??
- ????mov?????R1,#0x00000000??????@?此值改为0x00000001,??
- ????????????????????????????????????????@?可让LED1熄灭??
- ????str?????R1,[R0]?????????????@?GPJ2_0输出0,LED1点亮??
- ????mov?pc,?lr??
- ??
- ??
- ??
- ??????
- ??????
- ??????
- nand_asm_init:??
- ??????
- ?
- ??
- ???
- #define?ELFIN_GPIO_BASE?????????0xE0200000???
- #define?ELFIN_NAND_BASE?????????0xB0E00000??
- #define?NFCONF_VAL??(7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)??
- #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)??
- ??
- #define?MP01CON_OFFSET??????????0x2E0??
- #define?MP01PUD_OFFSET??????????0x2E8??
- #define?MP03CON_OFFSET??????0x320??
- #define?MP03PUD_OFFSET??????0x328??
- #define?NFCONF_OFFSET???????0x00??
- #define?NFCONT_OFFSET???????0x04??
- ???
- ??
- ????ldr?r0,?=ELFIN_GPIO_BASE??
- ??
- ????ldr?r1,?[r0,?#MP01CON_OFFSET]??
- ????bic?r1,?r1,?#(0xf<<8)??
- ????orr?r1,?#(0x3<<8)??
- ????str?r1,?#MP01CON_OFFSET]??
- ??
- ????ldr?r1,?#MP01PUD_OFFSET]??
- ????bic?r1,?#(0x3<<4)??
- ????str?r1,?#MP01PUD_OFFSET]??
- ??
- ????ldr?r1,?#MP03CON_OFFSET]??
- ????bic?r1,?#0xFFFFFF??
- ????ldr?r2,?=0x22222222??
- ????orr?r1,?r2??
- ????str?r1,?#MP03CON_OFFSET]??
- ??
- ????ldr?r1,?#MP03PUD_OFFSET]??
- ????ldr?r2,?=0x3fff??
- ????bic?r1,?r2??
- ????str?r1,?#MP03PUD_OFFSET]??
- ??
- ????ldr?r0,?=ELFIN_NAND_BASE??
- ??
- ????ldr?r1,?#NFCONF_OFFSET]??
- ????ldr?r2,?=0x777F??
- ????bic?r1,?r2??
- ????ldr?r2,?=NFCONF_VAL??
- ????orr?r1,?#NFCONF_OFFSET]??
- ??
- ????ldr?r1,?#NFCONT_OFFSET]??
- ????ldr?r2,?=0x707C7??
- ????bic?r1,?r2??
- ????ldr?r2,?=NFCONT_VAL??
- ????orr?r1,?#NFCONT_OFFSET]??
- ??
- ????ldr?r1,?#NFCONF_OFFSET]??
- ????orr?r1,?#0x70??
- ????orr?r1,?#0x7700??
- ????str?????r1,?#NFCONT_OFFSET]??
- ????orr?r1,?#0x03??
- ????str?????r1,?#NFCONT_OFFSET]??
- ??
- ????mov?pc,?lr??
main.c
- #define?????GPJ2CON?????(*(volatile?unsigned?long?*)?0xE0200280)??
- #define?????GPJ2DAT?????(*(volatile?unsigned?long?*)?0xE0200284)??
- ??
- ??
- void?delay(unsigned?long?count)??
- {??
- ????volatile?unsigned?long?i?=?count;??
- ????while?(i--)??
- ????????;??
- }??
- ??
- void?main()???????????????
- {??
- ????GPJ2CON?=?0x00001111;?????????
- ????while(1)??????????????????????
- ????{??
- ????????GPJ2DAT?=?0;??????????????
- ????????delay(0x100000);??
- ????????GPJ2DAT?=?0xf;????????????
- ????????delay(0x100000);??
- ????}??
- }??
下载运行
? ? ? ? 同《?
S5PV210的LED应用(一)》
运行调试
? ? ? ?
? ? ? ? 一开始以为程序会很难,应该MLC的,这样的NandFlash涉及到了ECC校验,颇为麻烦,但是细想,只实现读操作,会少许简单一些。最后发现读的时候问题并不多。也并不是那么困难。nand_asm_init和nand_cp.c提取于u-boot,并加以移植。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|