ARM Series -- Memory Migration Experiment on FS2410 Development Board

Publisher:alpha11Latest update time:2016-12-02 Source: eefocusKeywords:FS2410 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Purpose
   By moving the first 4K code of Nand Flash to SDRAM, we can understand how to initialize and use ARM memory, and
   prepare for writing ARM bootloader and moving the kernel to memory.

2. Code
   As for how to set up the development environment, I have introduced it in my previous essay (FS2401 LED Cycle Lighting), please
   refer to it. To initialize and use the memory, you need to understand some very small details. It is a bit awkward to talk about these knowledge points right away,
   so it is better to explain them directly in the code.

   @ File head.s
   @ Function: Close watchdog, set memory, move the first 4K code of Nand Flash to SDRAM, set stack,
   @ Call main function that has been moved to SDRAM.text
   .global
   _start
   _start:
    ldr r0, =0x53000000 @ Close watch-dog
    mov r1, #0x0
    str r1, [r0]
    bl memory_setup @ Initialize memory setting
    bl copy_block_to_sdram @ Move code to SDRAM
    ldr sp, =0x34000000 @ Set stack pointer
    ldr pc, =main @ call main in SDRAM
    
   halt_loop:
    b halt_loop
   
   copy_block_to_sdram:
    mov r0, #0x0
    mov r1, #0x30000000
    mov r2, #4096
   copy_loop:
    ldmia r0!, {r3-r10}
    stmia r1!, {r3-r10}
    cmp r0, r2
    blo copy_loop
  
   Note: Watchdog Timer (WDT) technology is the most common anti-interference technology, which is actually a
   timer counter that can be cleared.
   
   @ File memory.s
   @ Initialize memory control registers
   .global memory_setup @ Export memory_setup to make it visible to the linker
   memory_setup:
    mov r1, #0x48000000 @ BWSCON memory control register address
    adrl r2, mem_cfg_val    
    add r3, r1, #13*4
   1: 
    @ write initial values ​​to registers
    ldr r4, [r2], #4
    str r4, [r1], #4
    cmp r1, r3
    bne 1b
    mov pc, lr
    
    .align 4
   mem_cfg_val:
    .long 0x22111110 @ BWSCON
    .long 0x00000700 @ BANKCON0
    .long 0x00000700 @ BANKCON1
    .long 0x00000700 @ BANKCON2
    .long 0x00000700 @ BANKCON3
    .long 0x00000700 @ BANKCON4
    .long 0x00000700 @ BANKCON5
    .long 0x00018005 @ BANKCON6
    .long 0x00018005 @ BANKCON7 9bit
    .long 0x008e07a3 @ REFRESH
    .long 0x000 000b2 @ BANKSIZE 
    .long 0x00000030 @ MRSRB6
    .long 0x00000030 @ MRSRB7

   Note: To understand the register settings here, you need to read the manual and information. Here is a brief introduction:
   1. BWSCON: Corresponding to BANK0-BANK7, each BANK uses 4 bits. These 4 bits represent:
      a. STx: Enable/disable SDRAM data mask pin, for SDRAM, this bit is 0; for SRAM, this bit is 1
      b. WSx: Whether to use the WAIT signal of the memory, usually set to 0
      c. DWx: Use two bits to set the bit width of the memory: 00-8 bits, 01-16 bits, 10-32 bits, 11-reserved.
      d. The 4 bits corresponding to BANK0 are more special. They are determined by hardware jumpers and are read-only.
      e. For this development board, two SDRAMs with a capacity of 32Mbyte and a bit width of 16 are used to form
        a memory with a capacity of 64Mbyte and a bit width of 32, so the corresponding bits of its BWSCON are: 0010. For this development board, BWSCON can be set to
        0x22111110: In fact, we only need to set the 4 bits corresponding to BANK6 to 0010. The other values
        ​​have no effect. This value is given in the reference manual.
   2. BANKCON0-BANKCON5: We don't use them. Use the default value 0x00000700
   . 3. BANKCON6-BANKCON7: Set to 0x00018005.
      Among the 8 BANKs, only BANK6 and BANK7 can use SRAM or SDRAM, which is a little different from BANKCON0-5:
      a. MT ([16:15]): Used to set whether the external BANK is SRAM or SDRAM: SRAM-0b00, SDRAM-0b11
      b. When MT=0b11, two parameters need to be set:
         Trcd([3:2]): RAS to CAS delay, set to the recommended value 0b01
         SCAN([1:0]): The number of SDRAM column address bits. The SDRAM column address bits of this development board are 9, so SCAN=0b01
   4. REFRESH (SDRAM refresh control register):
      R_CNT is used to control the refresh cycle of SDRAM and occupies the [10:0] bits of the REFRESH register. Its value can
      be calculated as follows (the SDRAM clock frequency is HCLK):
      R_CNT = 2^11 + 1 – SDRAM clock frequency (MHz) * SDRAM refresh cycle (uS)
      When PLL is not used, the SDRAM clock frequency is equal to the crystal frequency of 12MHz; the refresh cycle of SDRAM is indicated in the SDRAM
      data sheet. In the data sheet of the SDRAM HY57V561620CT-H used in this development board, you can see
      a line like "8192 refresh cycles / 64ms": Therefore, refresh cycle = 64ms/8192 = 7.8125 uS.

      For this experiment, R_CNT = 2^11 + 1 – 12 * 7.8125 = 1955
      REFRESH = 0x008e0000 + 1955 = 0x008e07a3
   5. BANKSIZE: 0x000000b2
      Bit [7] = 1: Enable burst operation
      Bit [5] = 1: SDRAM power down mode enable
      Bit [4] = 1: SCLK is active only during the access (recommended)
      Bit [2:1] = 010 The address space corresponding to BANK6 and BANK7: 010-128M/128M, 001-64M/64M
   6. MRSRB6, MRSRB7: 0x00000030
      allows us to modify only bit [6:4] (CL). SDRAM HY57V561620CT-H does not support CL=1, so
      bit [6:4] takes the value 010 (CL=2) or 011 (CL=3).


   /* File sdram.c */
   /* The function is to light up the four LEDs D9, D10, D11 and D12 on the development board in a loop*/
   #define GPFCON (*(volatile unsigned long *)0x56000050) /* The GPFCON port address is 0x56000050 */
   #define GPFDAT (*(volatile unsigned long *)0x56000054) /* The GPFDAT port address is 0x56000054 */
   
   int main()
   { 
     int i,j;
     while(1) {
       for (i = 0; i <4; ++i) {
         GPFCON = 0x1<<(8+i*2); /* How to set these two registers to make the diode light up, the previous*/
         GPFDAT = 0x0; /* Essay (FS2401 LED light-emitting diode cycle lighting) */
                                            /* Introduced in*/
         // for delay
         for(j=0;j<50000;++j) ;
       }
     }
   }

   # Makefile
   # Compile the above three code files and link the generated target files, 
   # then convert the target files (ELF format) into binary format files
   sdram:head.s memory.s sdram.c
        arm-linux-gcc -c -o head.o head.s
        arm-linux-gcc -c -o memory.o memory.s
        arm-linux-gcc -c -o sdram.o sdram.c


        # -Ttext 0x30000000 will add the base address # 0x30000000 to the         pc in the ldr pc, =main instruction in the target file , and #0x30000000 is exactly
        the # starting address where we want to move the code to SDRAM. For more details, please refer to the usage of arm-linux-ld -Ttext
        arm-linux-ld -Ttext 0x30000000 head.o memory.o sdram.o -o sdram_tmp.o
        arm-linux-objcopy -O binary -S sdram_tmp.o sdram
  clean:
        rm -f *.o
        rm -f sdram


3. Compile, burn and test
   Make and the sdram file we need will be generated. Burn it into Nand Flash through JTAG. Reset
   the development board and enjoy your experimental results.


Keywords:FS2410 Reference address:ARM Series -- Memory Migration Experiment on FS2410 Development Board

Previous article:ARM Series--FS2410 LED Cyclic Lighting
Next article:ARM Series--Serial Communication Programming on FS2410 Development Board

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号