nand flash相关

发布时间:2023-06-13  

关于nandflash的说明,请参考其他。


现在先贴出来韦东山先生的代码,作我学习之用。


 1 @************************************************

 2 @ File:head.s

 3 @ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

 4 @************************************************  

 5   

 6 .text

 7 .global _start

 8 _start:

 9            @函数disable_watch_dog, memsetup, init_nand,      nand_read_ll在init.c中定义

10             ldr     sp, =4096               @设置堆栈 

11             bl      disable_watch_dog       @关WATCH DOG

12             bl      memsetup                @初始化SDRAM

13             bl      nand_init               @初始化NAND Flash

14 

15             @将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中

16                                             @nand_read_ll函数需要3个参数:

17             ldr     r0,     =0x30000000         @1. 目标地址=0x30000000,这是SDRAM的起始地址

18             mov     r1,     #4096           @2.  源地址   = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处

19             mov     r2,     #2048           @3.  复制长度= 2048(bytes),对于本实验的main.c,这是足够了

20             bl      nand_read               @调用C函数nand_read

21 

22             ldr     sp, =0x34000000         @设置栈

23             ldr     lr, =halt_loop          @设置返回地址

24             ldr     pc, =main               @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转

25 

26 halt_loop:

27             b       halt_loop

28  


上面的代码的作用很明显,现在主要说明地址相关的东西;


ldr     sp, =4096               @设置堆栈   首先上电后4k代码会自动拷贝到steppingstone里面,disable_watch_dog,memsetup等函数都是在这4k范围里面。


后面的链接脚本如下:


1 SECTIONS { 

2   firtst      0x00000000 : { head.o init.o nand.o}     @在nand flash里面地址为0x0000_0000初存放head.o,init.o,nand.o等

3   second     0x30000000 : AT(4096) { main.o }          @在4096处,注意此时是4k以外,这个代码就是指出当代码大小大于4k时的处理方法。

4 }                                @可以看到main.o的运行地址是0x3000_0000,说明运行4k以后的代码需要复制到sdram里面执行。


5  


上面说明main函数是在刚才提到的4k范围以外。所以head文件里面会有将4096(4k)的main函数编译出来的东西拷贝到3000_0000也就是sdram的地方。


这个在以后程序比较大的时候基本是比较通用的函数,所以一定得花时间搞明白。上面简单的说明来地址映射方面的问题。


再看init.c,这个文件只是关闭看门狗和初始化sdram:


 1 /* WOTCH DOG register */

 2 #define     WTCON                (*(volatile unsigned long *)0x53000000)

 3 

 4 /* SDRAM regisers */

 5 #define     MEM_CTL_BASE        0x48000000      //定义寄存器的方法

 6  

 7 void disable_watch_dog();

 8 void memsetup();

 9 

10 /*上电后,WATCH DOG默认是开着的,要把它关掉 */

11 void disable_watch_dog()

12 {

13     WTCON    = 0;

14 }

15 

16 /* 设置控制SDRAM的13个寄存器 */

17 void memsetup()

18 {

19     int     i = 0;

20     unsigned long *p = (unsigned long *)MEM_CTL_BASE;

21 

22     /* SDRAM 13个寄存器的值 */

23     unsigned long  const    mem_cfg_val[]={ 0x22011110,     //BWSCON

24                                             0x00000700,     //BANKCON0

25                                             0x00000700,     //BANKCON1

26                                             0x00000700,     //BANKCON2

27                                             0x00000700,     //BANKCON3  

28                                             0x00000700,     //BANKCON4

29                                             0x00000700,     //BANKCON5

30                                             0x00018005,     //BANKCON6

31                                             0x00018005,     //BANKCON7

32                                             0x008C07A3,     //REFRESH

33                                             0x000000B1,     //BANKSIZE

34                                             0x00000030,     //MRSRB6

35                                             0x00000030,     //MRSRB7

36                                     };

37 

38     for(; i < 13; i++)

39         p[i] = mem_cfg_val[i];

40 }


 上面设置sdram寄存器的方法是用c语言,现在贴出汇编的方法来比较;


 1 memsetup:

 2     @ 设置存储控制器以便使用SDRAM等外设

 3 

 4     mov r1,     #MEM_CTL_BASE       @ 存储控制器的13个寄存器的开始地址

 5     adrl    r2, mem_cfg_val         @ 这13个值的起始存储地址

 6     add r3,     r1, #52             @ 13*4 = 54

 7 1:  

 8     ldr r4,     [r2], #4            @ 读取设置值,并让r2加4

 9     str r4,     [r1], #4            @ 将此值写入寄存器,并让r1加4

10     cmp r1,     r3                  @ 判断是否设置完所有13个寄存器

11     bne 1b                          @ 若没有写成,继续

12     mov pc,     lr                  @ 返回

13 

14 

15 .align 4

16 mem_cfg_val:

17     @ 存储控制器13个寄存器的设置值

18     .long   0x22011110      @ BWSCON

19     .long   0x00000700      @ BANKCON0

20     .long   0x00000700      @ BANKCON1

21     .long   0x00000700      @ BANKCON2

22     .long   0x00000700      @ BANKCON3  

23     .long   0x00000700      @ BANKCON4

24     .long   0x00000700      @ BANKCON5

25     .long   0x00018005      @ BANKCON6

26     .long   0x00018005      @ BANKCON7

27     .long   0x008C07A3      @ REFRESH

28     .long   0x000000B1      @ BANKSIZE

29     .long   0x00000030      @ MRSRB6

30     .long   0x00000030      @ MRSRB7


同样是往这13个寄存器写值。


而main函数只是led的亮灭,这里就不贴出来了


现在主要看nand.c文件。


先贴出来如下:


//===================================我是分解线=============================


//@nand.c


  1 #define LARGER_NAND_PAGE

  2 

  3 #define GSTATUS1        (*(volatile unsigned int *)0x560000B0)

  4 #define BUSY            1

  5 

  6 #define NAND_SECTOR_SIZE    512              @小页

  7 #define NAND_BLOCK_MASK     (NAND_SECTOR_SIZE - 1)     511  0b1_1111_1111

  8 

  9 #define NAND_SECTOR_SIZE_LP    2048         @2k   大页

 10 #define NAND_BLOCK_MASK_LP     (NAND_SECTOR_SIZE_LP - 1)    @2047  0b111_1111_1111

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>