PRESERVE8<br /> <br /><br />; Area Definition and Entry Point<br />; Startup Code must be linked first at Address at which it expects to run.<br /><br /> AREA RESET, CODE, READONLY<br /> ARM<br /><br /><br />; Exception Vectors<br />; Mapped to Address 0.<br />; Absolute addressing mode must be used.<br />; Dummy Handlers are implemented as infinite loops which can be modified.<br /><br />Vectors LDR PC, Reset_Addr <br /> LDR PC, Undef_Addr<br /> LDR PC, SWI_Addr<br /> LDR PC, PAbt_Addr<br /> LDR PC, DAbt_Addr<br /> NOP ; Reserved Vector <br /> LDR PC, IRQ_Addr<br /> LDR PC, FIQ_Addr<br /><br /><br /> IF IntVT_SETUP <> 0<br /><br />;Interrupt Vector Table Address <br />HandleEINT0 EQU IntVTAddress <br />HandleEINT1 EQU IntVTAddress +4<br />HandleEINT2 EQU IntVTAddress +4*2<br />HandleEINT3 EQU IntVTAddress +4*3<br />HandleEINT4_7 EQU IntVTAddress +4*4<br />HandleEINT8_23 EQU IntVTAddress +4*5<br />HandleCAM EQU IntVTAddress +4*6<br />HandleBATFLT EQU IntVTAddress +4*7<br />HandleTICK EQU IntVTAddress +4*8<br />HandleWDT EQU IntVTAddress +4*9<br />HandleTIMER0 EQU IntVTAddress +4*10<br />HandleTIMER1 EQU IntVTAddress +4*11<br />HandleTIMER2 EQU IntVTAddress +4*12<br />HandleTIMER3 EQU IntVTAddress +4*13<br />HandleTIMER4 EQU IntVTAddress +4*14<br />HandleUART2 EQU IntVTAddress +4*15<br />HandleLCD EQU IntVTAddress +4*16<br />HandleDMA0 EQU IntVTAddress +4*17<br />HandleDMA1 EQU IntVTAddress +4*18<br />HandleDMA2 EQU IntVTAddress +4*19<br />HandleDMA3 EQU IntVTAddress +4*20<br />HandleMMC EQU IntVTAddress +4*21<br />HandleSPI0 EQU IntVTAddress +4*22<br />HandleUART1 EQU IntVTAddress +4*23<br />HandleNFCON EQU IntVTAddress +4*24<br />HandleUSBD EQU IntVTAddress +4*25<br />HandleUSBH EQU IntVTAddress +4*26<br />HandleIIC EQU IntVTAddress +4*27<br />HandleUART0 EQU IntVTAddress +4*28<br />HandleSPI1 EQU IntVTAddress +4*39<br />HandleRTC EQU IntVTAddress +4*30<br />HandleADC EQU IntVTAddress +4*31<br /><br />IRQ_Entry<br /> sub sp,sp,#4 ;reserved for PC<br /> stmfd sp!,{r8-r9}<br /> <br /> ldr r9,=INTOFFSET<br /> ldr r9,[r9]<br /> ldr r8,=HandleEINT0<br /> add r8,r8,r9,lsl #2<br /> ldr r8,[r8]<br /> str r8,[sp,#8]<br /> ldmfd sp!,{r8-r9,pc} <br /> <br /> ENDIF<br /><br />Reset_Addr DCD Reset_Handler<br />Undef_Addr DCD Undef_Handler<br />SWI_Addr DCD SWI_Handler<br />PAbt_Addr DCD PAbt_Handler<br />DAbt_Addr DCD DAbt_Handler<br /> DCD 0 ; Reserved Address <br />IRQ_Addr DCD IRQ_Handler<br />FIQ_Addr DCD FIQ_Handler<br /><br />Undef_Handler B Undef_Handler<br />SWI_Handler B SWI_Handler<br />PAbt_Handler B PAbt_Handler<br />DAbt_Handler B DAbt_Handler<br /> <br /> IF IntVT_SETUP <> 1<br />IRQ_Handler B IRQ_Handler<br /> ENDIF<br /> <br /> IF IntVT_SETUP <> 0<br />IRQ_Handler B IRQ_Entry<br /> ENDIF<br /> <br />FIQ_Handler B FIQ_Handler<br /><br /><br /><br />; Memory Controller Configuration<br /> IF MC_SETUP <> 0<br />MC_CFG<br /> DCD BWSCON_Val<br /> DCD BANKCON0_Val<br /> DCD BANKCON1_Val<br /> DCD BANKCON2_Val<br /> DCD BANKCON3_Val<br /> DCD BANKCON4_Val<br /> DCD BANKCON5_Val<br /> DCD BANKCON6_Val<br /> DCD BANKCON7_Val<br /> DCD REFRESH_Val<br /> DCD BANKSIZE_Val<br /> DCD MRSRB6_Val<br /> DCD MRSRB7_Val<br /> ENDIF<br /><br /><br />; Clock Management Configuration<br /> IF CLOCK_SETUP <> 0<br />CLK_CFG<br /> DCD LOCKTIME_Val <br /> DCD CLKDIVN_Val <br /> DCD UPLLCON_Val <br /> DCD MPLLCON_Val <br /> DCD CLKSLOW_Val <br /> DCD CLKCON_Val <br /> DCD CAMDIVN_Val <br /> ENDIF <br /><br /> <br /><br />; I/O Configuration<br /> <br /> IF PIO_SETUP <> 0<br />PIOA_CFG <br /> DCD PCONA_Val<br />PIOB_CFG DCD PCONB_Val<br /> DCD PUPB_Val<br />PIOC_CFG DCD PCONC_Val<br /> DCD PUPC_Val<br />PIOD_CFG DCD PCOND_Val<br /> DCD PUPD_Val<br />PIOE_CFG DCD PCONE_Val<br /> DCD PUPE_Val<br />PIOF_CFG DCD PCONF_Val<br /> DCD PUPF_Val<br />PIOG_CFG DCD PCONG_Val<br /> DCD PUPG_Val<br />PIOH_CFG DCD PCONH_Val<br /> DCD PUPH_Val<br />PIOJ_CFG DCD PCONJ_Val<br /> DCD PUPJ_Val<br /> ENDIF<br /><br />; Reset Handler<br /><br /> EXPORT Reset_Handler<br />Reset_Handler <br /><br /> IF WT_SETUP <> 0<br /> LDR R0, =WT_BASE<br /> LDR R1, =WTCON_Val<br /> LDR R2, =WTDAT_Val<br /> STR R2, [R0, #WTCNT_OFS]<br /> STR R2, [R0, #WTDAT_OFS]<br /> STR R1, [R0, #WTCON_OFS]<br /> ENDIF<br /> <br /> <br /> IF CLOCK_SETUP <> 0 <br /> LDR R0, =CLK_BASE <br /> ADR R8, CLK_CFG<br /> LDMIA R8, {R1-R7} <br /> STR R1, [R0, #LOCKTIME_OFS]<br /> STR R2, [R0, #CLKDIVN_OFS] <br /> STR R3, [R0, #UPLLCON_OFS] <br /> nop<br /> nop<br /> nop<br /> nop<br /> nop<br /> nop<br /> nop<br /> STR R4, [R0, #MPLLCON_OFS] <br /> STR R5, [R0, #CLKSLOW_OFS]<br /> STR R6, [R0, #CLKCON_OFS]<br /> STR R7, [R0, #CAMDIVN_OFS]<br /> ENDIF <br /><br /> <br /> IF MC_SETUP <> 0<br /> ADR R13, MC_CFG<br /> LDMIA R13, {R0-R12}<br /> LDR R13, =MC_BASE<br /> STMIA R13, {R0-R12}<br /> ENDIF <br /> <br /> <br /> IF PIO_SETUP <> 0<br /> LDR R13, =PIO_BASE<br /><br /> IF PIOA_SETUP <> 0<br /> ADR R0, PIOA_CFG<br /> STR R0, [R13, #PCONA_OFS]<br /> ENDIF<br /><br /> IF PIOB_SETUP <> 0<br /> ADR R0, PIOB_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONB_OFS]<br /> STR R1, [R13, #PUPB_OFS]<br /> ENDIF<br /><br /> IF PIOC_SETUP <> 0<br /> ADR R0, PIOC_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONC_OFS]<br /> STR R1, [R13, #PUPC_OFS]<br /> ENDIF<br /><br /> IF PIOD_SETUP <> 0<br /> ADR R0, PIOD_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCOND_OFS]<br /> STR R1, [R13, #PUPD_OFS]<br /> ENDIF<br /><br /> IF PIOE_SETUP <> 0<br /> ADR R0, PIOE_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONE_OFS]<br /> STR R1, [R13, #PUPE_OFS]<br /> ENDIF<br /><br /> IF PIOF_SETUP <> 0<br /> ADR R0, PIOF_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONF_OFS]<br /> STR R1, [R13, #PUPF_OFS]<br /> ENDIF<br /><br /> IF PIOG_SETUP <> 0<br /> ADR R0, PIOG_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONG_OFS]<br /> STR R1, [R13, #PUPG_OFS]<br /> ENDIF<br /> <br /> IF PIOH_SETUP <> 0<br /> ADR R0, PIOH_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONH_OFS]<br /> STR R1, [R13, #PUPH_OFS]<br /> ENDIF<br /> <br /> IF PIOJ_SETUP <> 0<br /> ADR R0, PIOJ_CFG<br /> LDR R1, [R0,#4]<br /> STR R0, [R13, #PCONJ_OFS]<br /> STR R1, [R13, #PUPJ_OFS]<br /> ENDIF <br /><br /> ENDIF<br /> <br /> <br />; Setup Stack for each mode<br /><br /> LDR R0, =Stack_Top<br /><br />; Enter Undefined Instruction Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit<br /> MOV SP, R0<br /> SUB R0, R0, #UND_Stack_Size<br /><br />; Enter Abort Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit<br /> MOV SP, R0<br /> SUB R0, R0, #ABT_Stack_Size<br /><br />; Enter FIQ Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit<br /> MOV SP, R0<br /> SUB R0, R0, #FIQ_Stack_Size<br /><br />; Enter IRQ Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit<br /> MOV SP, R0<br /> SUB R0, R0, #IRQ_Stack_Size<br /><br />; Enter Supervisor Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit<br /> MOV SP, R0<br /> SUB R0, R0, #SVC_Stack_Size<br />; IMPORT MMU_EnableICache<br />; bl MMU_EnableICache<br /><br /><br />; Enter User Mode and set its Stack Pointer<br /> MSR CPSR_c, #Mode_USR<br /> MOV SP, R0<br /> SUB SL, SP, #USR_Stack_Size<br /><br /><br />; Enter the C code<br /> ;<br /> IMPORT __main<br /> LDR R0, =__main<br /> BX R0<br /><br /><br />; User Initial Stack & Heap<br /> AREA |.text|, CODE, READONLY<br /><br /> ; IMPORT __use_two_region_memory<br /><br /> EXPORT __user_initial_stackheap<br />__user_initial_stackheap<br /><br /> LDR R0, = Heap_Mem<br /> LDR R1, =(Stack_Mem + USR_Stack_Size)<br /> LDR R2, = (Heap_Mem + Heap_Size)<br /> LDR R3, = Stack_Mem<br /> BX LR<br /><br /><br /><br /> END
|