Search

Technical Discussion Group Forum

This forum is provided for user discussion. While Beacon EmbeddedWorks support staff and engineers participate, Beacon EmbeddedWorks does not guarantee the accuracy of all information within in the Technical Discussion Group (TDG).

The "Articles" forums provide brief Articles written by Beacon EmbeddedWorks engineers that address the most frequently asked technical questions.

To receive email notifications when updates are posted for a Beacon EmbeddedWorks product download, please subscribe to the TDG Forum of interest.

TDG Forum

PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 15 Feb 2005 12:48 PM by  Anonymous
IAR EWARM and startup code
 1 Replies
Sort:
You are not authorized to post a reply.
Author Messages
Patrick Perdu
New Member
New Member
Posts:3


--
15 Feb 2005 12:39 PM
    Hi all,

    I recently had questions here about SDRAM initialization and startup consideratins.
    I figured it out so I would like to ensure at least taht nobody blocks stupidly as I did. Here is the CStartup.s79 file I ended with.

    Please note tnhat the stacks are not initialized, the interrupt vectors are neither. All this must be done, I elected to do it in C in the low_level_init() function called by IAR system after (very) low level init.
    Of course to init the vectors, we need to have them in RAM.

    The #ifdef around the SDRAm initialization is there to allow compiling versions to download into SDRAM for bench tests so that it does not saw the branch on which it sits.

    Also the funny C-style comments are for doxygen. Dont worry about them.
    If anybody has improvement suggestions, you are very welcome.

    (Apparently all the tabs have been removed. Good luck)

    Best regards to all of you out there working on that board.

    Patrick



    ; /**
    ; \file cstartup.s79
    ; \brief This is the bootstrap code: It initializes the CPU clocks and busses, sets the pins functions and initializes the SDRAM.
    ; */





    ;-----------------------------------------------------------------------------
    ; This file contains the startup code used by the ICCARM C compiler.
    ;
    ; All code in the modules (except ?RESET) will be placed in the ICODE segment.
    ;
    ;-----------------------------------------------------------------------------

    ;---------------------------------------------------------------
    ; Macros and definitions for the whole file
    ;---------------------------------------------------------------

    ; Mode, correspords to bits 0-5 in CPSR
    MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR
    USR_MODE DEFINE 0x10 ; User mode
    FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
    IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
    SVC_MODE DEFINE 0x13 ; Supervisor mode
    ABT_MODE DEFINE 0x17 ; Abort mode
    UND_MODE DEFINE 0x1B ; Undefined Instruction mode
    SYS_MODE DEFINE 0x1F ; System mode


    ;---------------------------------------------------------------
    ; ?RESET
    ; Reset Vector.
    ;---------------------------------------------------------------

    MODULE ?RESET
    COMMON INTVEC:CODE:NOROOT(2)
    PUBLIC __program_start
    EXTERN ?cstartup
    EXTERN undef_handler, swi_handler, prefetch_handler
    EXTERN data_handler, irq_handler, fiq_handler
    CODE32 ; Always ARM mode after reset
    ORG 0x00
    __program_start
    ; Here are the main ARM interrupt vectors.
    ldr pc,=?cstartup ; Absolute jump can reach 4 GByte
    ; b ?cstartup ; Relative branch allows remap, limited to 32 MByte
    org 0x04
    ; ldr pc,=undef_handler
    org 0x08
    ; ldr pc,=swi_handler
    org 0x0c
    ; ldr pc,=prefetch_handler
    org 0x10
    ; ldr pc,=data_handler
    org 0x18
    ; ldr pc,=irq_handler
    org 0x1c
    ; ldr pc,=fiq_handler

    ; Constant table entries (for ldr pc) will be placed at 0x20
    org 0x20
    LTORG
    ; ENDMOD __program_start
    ENDMOD


    ;---------------------------------------------------------------
    ; ?CSTARTUP
    ;---------------------------------------------------------------
    MODULE ?CSTARTUP

    RSEG IRQ_STACK:DATA(2)
    RSEG SVC_STACK:DATA:NOROOT(2)
    RSEG CSTACK:DATA(2)
    RSEG ICODE:CODE:NOROOT(2)
    PUBLIC ?cstartup
    EXTERN ?main

    ; Execution starts here.
    ; After a reset, the mode is ARM, Supervisor, interrupts disabled.


    CODE32
    ?cstartup

    ; Add initialization nedded before setup of stackpointers here


    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX



    ; Disable the MMU
    mov r1,#0x70
    mcr p15, 0, r1, c1, c0, 0

    ; set SVC mode
    mov r0,#0xd3
    msr cpsr_cxsf,r0
    nop

    ; Disable the interruption
    ldr r1,=0xfffff000 ; =VIC_BASE #
    mov r0,#0
    str r0,[r1,#0x10] ; VICIntEnable

    ; unlock the RCPC
    ldr r1,=0xfffe2000 ; =RCPC_BASE #
    ldr r0,[r1,#0]
    orr r0,r0,#0x200
    str r0,[r1,#0] ; RCPC Control

    ; // Enable crystal osc; enable the PLL, select the PLL
    ; RCPC_Ctrl = 0x23;

    ; set the CPU running as FAST mode
    ldr r1,=0xfffe2000 ; =RCPC_BASE #
    ldr r0,[r1,#0x88]
    bic r0,r0,#3
    str r0,[r1,#0x88] ; CoreClkConfig

    ; set the CPU running at 50 Mhz
    ldr r1,=0xfffe2000 ; =RCPC_BASE #
    mov r0,#3
    str r0,[r1,#0x1c] ; CpuClkPrescale

    ; set the HCLK running at 50 Mhz
    ldr r1,=0xfffe2000 ; =RCPC_BASE #
    mov r0,#3
    str r0,[r1,#0x18] ; HclkPrescale

    ; set the Mux pin register
    ldr r1,=0xfffe5000 ; =MUX_BASE #
    ldr r0,[r1,#0]
    and r0,r0,#0
    orr r0,r0,#0x1700
    orr r0,r0,#0xef
    ; set the MemMux register
    str r0,[r1,#0] ; MemMux
    ldr r0,[r1,#8]
    and r0,r0,#0
    orr r0,r0,#0x100
    orr r0,r0,#0xfe
    ; set the MiscMux register
    str r0,[r1,#8] ; MiscMux
    ldr r0,[r1,#0x10]
    and r0,r0,#0
    orr r0,r0,#0xf
    ; set the UARTMux register
    str r0,[r1,#0x10] ; UARTMux

    ; enable the clock to AHB bus
    ldr r1,=0xfffe2000 ; =RCPC_BASE #
    ldr r0,[r1,#0x2c]
    and r0,r0,#0
    orr r0,r0,#5
    str r0,[r1,#0x2c] ; AHBClkCtrl

    ; start to config the SDRAM
    #ifdef INIT_SDRAM
    ; set SDRCRefTimer = 10
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#8]
    and r0,r0,#0
    orr r0,r0,#0xa ; is 0xa
    str r0,[r1,#8] ; SDRCRefTimer

    ; issue NOP command for 0x10000 times
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#4] ; SDRCConfig1
    bic r0,r0,#3
    orr r0,r0,#3
    mov r2,#0x10000
    wait_10000
    str r0,[r1,#4] ; SDRCConfig1
    sub r2,r2,#1
    cmp r2,#0
    beq wait_10000_done
    nop
    b wait_10000

    wait_10000_done
    ; issue Precharge All command
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#4]
    bic r0,r0,#3
    orr r0,r0,#1
    str r0,[r1,#4] ; SDRCConfig1

    ; wait for a while = 20 cycles
    mov r2,#0x20
    wait_20
    sub r2,r2,#1
    cmp r2,#0
    beq wait_20_done
    nop
    b wait_20
    wait_20_done
    ; set SDRCRefTimer = 0x2ee = 750
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#8]
    and r0,r0,#0
    orr r0,r0,#0xee
    orr r0,r0,#0x200
    str r0,[r1,#8] ; SDRCRefTimer

    ; SDRAM_BASE_ADDR | (0x22 << 12)
    mov r1,#0x20000000 ; SDRAM_BASE_ADDRESS
    mov r3,#0x22
    mov r3,r3,lsl #12
    orr r3,r3,r1

    ; issue Enable SDRAM MODE command
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#4] ; SDRCConfig1
    bic r0,r0,#3
    orr r0,r0,#2
    str r0,[r1,#4] ; SDRCConfig1

    ; tmp = *((int *)(SDRAM_BASE_ADDR | (0x22 << 12))
    ldr r1,[r3,#0]

    ; Wait until idle
    ldr r1,=0xffff2000 ; SDRC_BASE
    wait_idle_1
    ldr r0,[r1,#4] ; SDRCConfig1
    tst r0,#0x20
    beq wait_idle_1
    nop

    ; Set SDRCCongig0 register
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#0] ; SDRCConfig0
    and r0,r0,#0
    orr r0,r0,#0x1000000
    orr r0,r0,#0xa00000
    orr r0,r0,#0x40000
    orr r0,r0,#0x88
    str r0,[r1,#0] ; SDRCConfig0

    ; Wait until idle
    ldr r1,=0xffff2000 ; SDRC_BASE
    wait_idle_2
    ldr r0,[r1,#4] ; SDRCConfig1
    tst r0,#0x20
    beq wait_idle_2
    nop

    ; issue NORMAL command
    ldr r1,=0xffff2000 ; SDRC_BASE
    ldr r0,[r1,#4]
    bic r0,r0,#3
    str r0,[r1,#4] ; SDRCConfig1

    ; wait until idle
    ldr r1,=0xffff2000 ; SDRC_BASE
    wait_idle_3
    ldr r0,[r1,#4] ; SDRCConfig1
    tst r0,#0x20
    beq wait_idle_3
    nop
    #endif ; INIT_SDRAM

    ; SDRAM is ready to use now

    ; Stop the Watchdog Timer
    eor r0,r0,r0
    ldr r1,=0xFFFE3000 ; =WDT_BASE
    str r0,[r1,#0]

    ; Clear Peripheral Clock Control bits so Timers,
    ; RTC, PWM's, UART's
    ; will work
    ldr r1,=0xfffe2000 ; =RCPC_BASE
    mvn r0,#0
    ldr r2,=0x3B7
    bic r0,r0,r2
    str r0,[r1,#0x24] ; address for PeriphClkCtrl


    ; Enable the LCD clock to enable the LCD
    ldr r1,=0xfffe2000 ; =RCPC_BASE
    mov r0,#0x0
    str r0,[r1,#0x28] ; address for PeriphClkCtrl2


    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Flash memory is slow upon reset, maker it faster here
    ; configure the SMC for accessing the flash from bank 0 (nCS0).
    ; the LH28F320BJE is a 90 ns device with about 15 extra ns
    ; of gate delays. 5 wait states makes 96.88 ns, not enough.
    ; 6 wait states makes 116.26 ns, which is OK. Program as follows:
    ; No Retry, Width 16 bits, non-burst, write-enabled, clear errors,
    ; 6 write wait states, all byte lane controls are high during
    ; reads, 6 read wait states, 1 HCLK bus turnaround time
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ldr r1,=0xFFFF1000 ; =SMC_BASE
    ldr r0,=0x13002CA0
    str r0,[r1,#0]

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Chip select SMCBCRx register set
    ; All set as 16 bit bus width
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ldr r1,=0xFFFF1000 ; =SMC_BASE
    ldr r0,=0x13002CA0 ; 6 wait status
    str r0,[r1,#0x4] ; nCS1
    str r0,[r1,#0x8] ; nCS2
    str r0,[r1,#0xC] ; nCS3
    ldr r0,=0x13008CE0
    str r0,[r1,#0x10] ; nCS4 slow for Compact Flash
    ldr r0,=0x1300FD03
    str r0,[r1,#0x14] ; nCS5
    str r0,[r1,#0x18] ; nCS6


    ; ; --- Initialize stack pointer registers
    ; ; Enter IRQ mode and set up the IRQ stack pointer
    ; mov r0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
    ; msr cpsr_c, r0
    ; ldr sp, =IRQ_Stack
    ;
    ; ; Enter FIQ mode and set up the FIQ stack pointer
    ; mov r0, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
    ; msr cpsr_c, r0
    ; ldr sp, =FIQ_Stack
    ;
    ; ; Enter ABT mode and set up the ABT stack pointer
    ; mov r0, #Mode_ABT:OR:I_Bit:OR:F_Bit ; No interrupts
    ; msr cpsr_c, r0
    ; ldr sp, =ABT_Stack
    ;
    ; ; Enter IRQ mode and set up the IRQ stack pointer
    ; mov r0, #Mode_UNDEF:OR:I_Bit:OR:F_Bit ; No interrupts
    ; msr cpsr_c, r0
    ; ldr sp, =UNDEF_Stack
    ;
    ; ; Set up the SVC stack pointer last and return to SVC mode
    ; mov r0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
    ; msr cpsr_c, r0
    ; ldr sp, =SVC_Stack

    ; ; clear all the existing interrupts


    ldr r1,=0xfffff000 ;VIC controller base
    ldr r0,=0xFFFFFFFF
    str r0,[r1,#0x14] ;VICIntEnableClear
    str r0,[r1,#0x1C] ;VICSoftIntClear
    mov r0,#0
    str r0,[r1,#0x30] ;Interrupt Vector Address
    str r0,[r1,#0x200] ;Interrupt Vector Control[0]
    str r0,[r1,#0x204] ;Interrupt Vector Control[1]
    str r0,[r1,#0x208] ;Interrupt Vector Control[2]
    str r0,[r1,#0x20c] ;Interrupt Vector Control[3]
    str r0,[r1,#0x210] ;Interrupt Vector Control[4]
    str r0,[r1,#0x214] ;Interrupt Vector Control[5]
    str r0,[r1,#0x218] ;Interrupt Vector Control[6]
    str r0,[r1,#0x21c] ;Interrupt Vector Control[7]
    str r0,[r1,#0x220] ;Interrupt Vector Control[8]
    str r0,[r1,#0x224] ;Interrupt Vector Control[9]
    str r0,[r1,#0x228] ;Interrupt Vector Control[10]
    str r0,[r1,#0x22c] ;Interrupt Vector Control[11]
    str r0,[r1,#0x230] ;Interrupt Vector Control[12]
    str r0,[r1,#0x234] ;Interrupt Vector Control[13]
    str r0,[r1,#0x238] ;Interrupt Vector Control[14]
    str r0,[r1,#0x23c] ;Interrupt Vector Control[15]

    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    ; Initialize the stack pointers.
    ; The pattern below can be used for any of the exception stacks:
    ; FIQ, IRQ, SVC, ABT, UND, SYS.
    ; The USR mode uses the same stack as SYS.
    ; The stack segments must be defined in the linker command file,
    ; and be declared above.

    mrs r0,cpsr ; Original PSR value

    ; Interrupt
    bic r0,r0,#MODE_BITS ; Clear the mode bits
    orr r0,r0,#IRQ_MODE ; Set IRQ mode bits
    msr cpsr_c,r0 ; Change the mode
    ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK

    ; User and system
    bic r0,r0,#MODE_BITS ; Clear the mode bits
    orr r0,r0,#SYS_MODE ; Set System mode bits
    msr cpsr_c,r0 ; Change the mode
    ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK

    ; ; Fast interrupt
    ; bic r0,r0,#MODE_BITS ; Clear the mode bits
    ; orr r0,r0,#FIQ_MODE ; Set System mode bits
    ; msr cpsr_c,r0 ; Change the mode
    ; ldr sp,=SFE(FIQSTACK) & 0xFFFFFFF8 ; End of FIQSTACK
    ;
    ; ; Supervisor
    ; bic r0,r0,#MODE_BITS ; Clear the mode bits
    ; orr r0,r0,#SYS_MODE ; Set System mode bits
    ; msr cpsr_c,r0 ; Change the mode
    ; ldr sp,=SFE(SRVTACK) & 0xFFFFFFF8 ; End of CSTACK
    ;
    ; ; Undefined instruction
    ; bic r0,r0,#MODE_BITS ; Clear the mode bits
    ; orr r0,r0,#SYS_MODE ; Set System mode bits
    ; msr cpsr_c,r0 ; Change the mode
    ; ldr sp,=SFE(UNDTACK) & 0xFFFFFFF8 ; End of CSTACK
    ;
    ; ; Abort
    ; bic r0,r0,#MODE_BITS ; Clear the mode bits
    ; orr r0,r0,#SYS_MODE ; Set System mode bits
    ; msr cpsr_c,r0 ; Change the mode
    ; ldr sp,=SFE(ABTSTACK) & 0xFFFFFFF8 ; End of CSTACK

    #ifdef __ARMVFP__
    ; Enable the VFP coprocessor.
    mov r0, #0x40000000 ; Set EN bit in VFP
    fmxr fpexc, r0 ; FPEXC, clear others.

    ; Disable underflow exceptions by setting flush to zero mode.
    ; For full IEEE 754 underflow compliance this code should be removed
    ; and the appropriate exception handler installed.
    mov r0, #0x01000000 ; Set FZ bit in VFP
    fmxr fpscr, r0 ; FPSCR, clear others.
    #endif

    ; Add more initialization here




    ; Continue to ?main for more IAR specific system startup

    ldr r0,=?main
    bx r0

    LTORG

    ENDMOD


    END
    Anonymous
    Posts:


    --
    15 Feb 2005 12:48 PM
    Patrick,

    Thanks for posting this!

    Regards,
    You are not authorized to post a reply.