LPC2300.s
上传用户:ssllxx2007
上传日期:2022-06-12
资源大小:784k
文件大小:20k
源码类别:

uCOS

开发平台:

C/C++

  1. ;/*****************************************************************************/
  2. ;/* LPC2300.S: Startup file for Philips LPC2300 device series                 */
  3. ;/*****************************************************************************/
  4. ;/* <<< Use Configuration Wizard in Context Menu >>>                          */
  5. ;/*****************************************************************************/
  6. ;/* This file is part of the uVision/ARM development tools.                   */
  7. ;/* Copyright (c) 2006 Keil - An ARM Company. All rights reserved.            */
  8. ;/* This software may only be used under the terms of a valid, current,       */
  9. ;/* end user licence from KEIL for a compatible version of KEIL software      */
  10. ;/* development tools. Nothing else gives you the right to use this software. */
  11. ;/*****************************************************************************/
  12. ;/*
  13. ; *  The LPC2300.S code is executed after CPU Reset. This file may be 
  14. ; *  translated with the following SET symbols. In uVision these SET 
  15. ; *  symbols are entered under Options - ASM - Define.
  16. ; *
  17. ; *  REMAP: when set the startup code initializes the register MEMMAP 
  18. ; *  which overwrites the settings of the CPU configuration pins. The 
  19. ; *  startup and interrupt vectors are remapped from:
  20. ; *     0x00000000  default setting (not remapped)
  21. ; *     0x40000000  when RAM_MODE is used
  22. ; *
  23. ; *  RAM_MODE: when set the device is configured for code execution
  24. ; *  from on-chip RAM starting at address 0x40000000. 
  25. ; */
  26. ; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
  27. Mode_USR        EQU     0x10
  28. Mode_FIQ        EQU     0x11
  29. Mode_IRQ        EQU     0x12
  30. Mode_SVC        EQU     0x13
  31. Mode_ABT        EQU     0x17
  32. Mode_UND        EQU     0x1B
  33. Mode_SYS        EQU     0x1F
  34. I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
  35. F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
  36. ;// <h> Stack Configuration (Stack Sizes in Bytes)
  37. ;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
  38. ;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
  39. ;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
  40. ;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
  41. ;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
  42. ;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
  43. ;// </h>
  44. UND_Stack_Size  EQU     0x00000000
  45. SVC_Stack_Size  EQU     0x00000008
  46. ABT_Stack_Size  EQU     0x00000000
  47. FIQ_Stack_Size  EQU     0x00000000
  48. IRQ_Stack_Size  EQU     0x00000100
  49. USR_Stack_Size  EQU     0x00000400
  50. Stack_Size      EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + 
  51.                          FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
  52.                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
  53. Stack_Mem       SPACE   Stack_Size
  54. Stack_Top       EQU     Stack_Mem + Stack_Size
  55. ;// <h> Heap Configuration
  56. ;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
  57. ;// </h>
  58. Heap_Size       EQU     0x00000000
  59.                 AREA    HEAP, NOINIT, READWRITE, ALIGN=3
  60. Heap_Mem        SPACE   Heap_Size
  61. ; System Control Block (SCB) Module Definitions
  62. SCB_BASE        EQU     0xE01FC000      ; SCB Base Address
  63. PLLCON_OFS      EQU     0x80            ; PLL Control Offset
  64. PLLCFG_OFS      EQU     0x84            ; PLL Configuration Offset
  65. PLLSTAT_OFS     EQU     0x88            ; PLL Status Offset
  66. PLLFEED_OFS     EQU     0x8C            ; PLL Feed Offset
  67. CCLKCFG_OFS     EQU     0x104           ; CPU Clock Divider Reg Offset
  68. USBCLKCFG_OFS   EQU     0x108           ; USB Clock Divider Reg Offset
  69. CLKSRCSEL_OFS   EQU     0x10C           ; Clock Source Sel Reg Offset
  70. SCS_OFS         EQU     0x1A0           ; Sys Control and Status Reg Offset
  71. PCLKSEL0_OFS    EQU     0x1A8           ; Periph Clock Sel Reg 0 Offset
  72. PCLKSEL1_OFS    EQU     0x1AC           ; Periph Clock Sel Reg 0 Offset
  73. ; Constants
  74. OSCRANGE        EQU     (1<<4)          ; Oscillator Range Select
  75. OSCEN           EQU     (1<<5)          ; Main oscillator Enable
  76. OSCSTAT         EQU     (1<<6)          ; Main Oscillator Status
  77. PLLCON_PLLE     EQU     (1<<0)          ; PLL Enable
  78. PLLCON_PLLC     EQU     (1<<1)          ; PLL Connect
  79. PLLSTAT_M       EQU     (0x7FFF<<0)     ; PLL M Value
  80. PLLSTAT_N       EQU     (0xFF<<16)      ; PLL N Value
  81. PLLSTAT_PLOCK   EQU     (1<<26)         ; PLL Lock Status
  82. ;// <e> Clock Setup
  83. ;//   <h> System Controls and Status Register (SYS)
  84. ;//     <o1.4>    OSCRANGE: Main Oscillator Range Select
  85. ;//                     <0=>  1 MHz to 20 MHz
  86. ;//                     <1=> 15 MHz to 24 MHz
  87. ;//     <e1.5>       OSCEN: Main Oscillator Enable
  88. ;//     </e>
  89. ;//   </h>
  90. ;//
  91. ;//   <h> PLL Clock Source Select Register (CLKSRCSEL)
  92. ;//     <o2.0..1>   CLKSRC: PLL Clock Source Selection
  93. ;//                     <0=> Internal RC oscillator
  94. ;//                     <1=> Main oscillator
  95. ;//                     <1=> RTC oscillator
  96. ;//   </h>
  97. ;//
  98. ;//   <h> PLL Configuration Register (PLLCFG)
  99. ;//                     <i> PLL_clk = (2* M * PLL_clk_src) / N
  100. ;//     <o3.0..14>    MSEL: PLL Multiplier Selection
  101. ;//                     <1-32768><#-1>
  102. ;//                     <i> M Value
  103. ;//     <o3.16..23>   NSEL: PLL Divider Selection
  104. ;//                     <1-256><#-1>
  105. ;//                     <i> N Value
  106. ;//   </h>
  107. ;//
  108. ;//   <h> CPU Clock Configuration Register (CCLKCFG)
  109. ;//     <o4.0..7>  CCLKSEL: Divide Value for CPU Clock from PLL
  110. ;//                     <1-256><#-1>
  111. ;//   </h>
  112. ;//
  113. ;//   <h> USB Clock Configuration Register (USBCLKCFG)
  114. ;//     <o5.0..3>   USBSEL: Divide Value for USB Clock from PLL
  115. ;//                     <1-16><#-1>
  116. ;//   </h>
  117. ;//
  118. ;//   <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
  119. ;//     <o6.0..1>      PCLK_WDT: Peripheral Clock Selection for WDT
  120. ;//                     <0=> Pclk = Cclk / 4
  121. ;//                     <1=> Pclk = Cclk
  122. ;//                     <2=> Pclk = Cclk / 2
  123. ;//                     <3=> Pclk = Cclk / 8
  124. ;//     <o6.2..3>   PCLK_TIMER0: Peripheral Clock Selection for TIMER0
  125. ;//                     <0=> Pclk = Cclk / 4
  126. ;//                     <1=> Pclk = Cclk
  127. ;//                     <2=> Pclk = Cclk / 2
  128. ;//                     <3=> Pclk = Cclk / 8
  129. ;//     <o6.4..5>   PCLK_TIMER1: Peripheral Clock Selection for TIMER1
  130. ;//                     <0=> Pclk = Cclk / 4
  131. ;//                     <1=> Pclk = Cclk
  132. ;//                     <2=> Pclk = Cclk / 2
  133. ;//                     <3=> Pclk = Cclk / 8
  134. ;//     <o6.6..7>    PCLK_UART0: Peripheral Clock Selection for UART0
  135. ;//                     <0=> Pclk = Cclk / 4
  136. ;//                     <1=> Pclk = Cclk
  137. ;//                     <2=> Pclk = Cclk / 2
  138. ;//                     <3=> Pclk = Cclk / 8
  139. ;//     <o6.8..9>    PCLK_UART1: Peripheral Clock Selection for UART1
  140. ;//                     <0=> Pclk = Cclk / 4
  141. ;//                     <1=> Pclk = Cclk
  142. ;//                     <2=> Pclk = Cclk / 2
  143. ;//                     <3=> Pclk = Cclk / 8
  144. ;//     <o6.10..11>   PCLK_PWM0: Peripheral Clock Selection for PWM0
  145. ;//                     <0=> Pclk = Cclk / 4
  146. ;//                     <1=> Pclk = Cclk
  147. ;//                     <2=> Pclk = Cclk / 2
  148. ;//                     <3=> Pclk = Cclk / 8
  149. ;//     <o6.12..13>   PCLK_PWM1: Peripheral Clock Selection for PWM1
  150. ;//                     <0=> Pclk = Cclk / 4
  151. ;//                     <1=> Pclk = Cclk
  152. ;//                     <2=> Pclk = Cclk / 2
  153. ;//                     <3=> Pclk = Cclk / 8
  154. ;//     <o6.14..15>   PCLK_I2C0: Peripheral Clock Selection for I2C0
  155. ;//                     <0=> Pclk = Cclk / 4
  156. ;//                     <1=> Pclk = Cclk
  157. ;//                     <2=> Pclk = Cclk / 2
  158. ;//                     <3=> Pclk = Cclk / 8
  159. ;//     <o6.16..17>    PCLK_SPI: Peripheral Clock Selection for SPI
  160. ;//                     <0=> Pclk = Cclk / 4
  161. ;//                     <1=> Pclk = Cclk
  162. ;//                     <2=> Pclk = Cclk / 2
  163. ;//                     <3=> Pclk = Cclk / 8
  164. ;//     <o6.18..19>    PCLK_RTC: Peripheral Clock Selection for RTC
  165. ;//                     <0=> Pclk = Cclk / 4
  166. ;//                     <1=> Pclk = Cclk
  167. ;//                     <2=> Pclk = Cclk / 2
  168. ;//                     <3=> Pclk = Cclk / 8
  169. ;//     <o6.20..21>   PCLK_SSP1: Peripheral Clock Selection for SSP1
  170. ;//                     <0=> Pclk = Cclk / 4
  171. ;//                     <1=> Pclk = Cclk
  172. ;//                     <2=> Pclk = Cclk / 2
  173. ;//                     <3=> Pclk = Cclk / 8
  174. ;//     <o6.22..23>    PCLK_DAC: Peripheral Clock Selection for DAC
  175. ;//                     <0=> Pclk = Cclk / 4
  176. ;//                     <1=> Pclk = Cclk
  177. ;//                     <2=> Pclk = Cclk / 2
  178. ;//                     <3=> Pclk = Cclk / 8
  179. ;//     <o6.24..25>    PCLK_ADC: Peripheral Clock Selection for ADC
  180. ;//                     <0=> Pclk = Cclk / 4
  181. ;//                     <1=> Pclk = Cclk
  182. ;//                     <2=> Pclk = Cclk / 2
  183. ;//                     <3=> Pclk = Cclk / 8
  184. ;//     <o6.26..27>   PCLK_CAN1: Peripheral Clock Selection for CAN1
  185. ;//                     <0=> Pclk = Cclk / 4
  186. ;//                     <1=> Pclk = Cclk
  187. ;//                     <2=> Pclk = Cclk / 2
  188. ;//                     <3=> Pclk = Cclk / 6
  189. ;//     <o6.28..29>   PCLK_CAN2: Peripheral Clock Selection for CAN2
  190. ;//                     <0=> Pclk = Cclk / 4
  191. ;//                     <1=> Pclk = Cclk
  192. ;//                     <2=> Pclk = Cclk / 2
  193. ;//                     <3=> Pclk = Cclk / 6
  194. ;//     <o6.30..31>    PCLK_ACF: Peripheral Clock Selection for ACF
  195. ;//                     <0=> Pclk = Cclk / 4
  196. ;//                     <1=> Pclk = Cclk
  197. ;//                     <2=> Pclk = Cclk / 2
  198. ;//                     <3=> Pclk = Cclk / 6
  199. ;//   </h>
  200. ;//
  201. ;//   <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
  202. ;//     <o7.0..1>  PCLK_BAT_RAM: Peripheral Clock Selection for the Battery Supported RAM
  203. ;//                     <0=> Pclk = Cclk / 4
  204. ;//                     <1=> Pclk = Cclk
  205. ;//                     <2=> Pclk = Cclk / 2
  206. ;//                     <3=> Pclk = Cclk / 8
  207. ;//     <o7.2..3>     PCLK_GPIO: Peripheral Clock Selection for GPIOs
  208. ;//                     <0=> Pclk = Cclk / 4
  209. ;//                     <1=> Pclk = Cclk
  210. ;//                     <2=> Pclk = Cclk / 2
  211. ;//                     <3=> Pclk = Cclk / 8
  212. ;//     <o7.4..5>      PCLK_PCB: Peripheral Clock Selection for Pin Connect Block
  213. ;//                     <0=> Pclk = Cclk / 4
  214. ;//                     <1=> Pclk = Cclk
  215. ;//                     <2=> Pclk = Cclk / 2
  216. ;//                     <3=> Pclk = Cclk / 8
  217. ;//     <o7.6..7>     PCLK_I2C1: Peripheral Clock Selection for I2C1
  218. ;//                     <0=> Pclk = Cclk / 4
  219. ;//                     <1=> Pclk = Cclk
  220. ;//                     <2=> Pclk = Cclk / 2
  221. ;//                     <3=> Pclk = Cclk / 8
  222. ;//     <o7.10..11>   PCLK_SSP0: Peripheral Clock Selection for SSP0
  223. ;//                     <0=> Pclk = Cclk / 4
  224. ;//                     <1=> Pclk = Cclk
  225. ;//                     <2=> Pclk = Cclk / 2
  226. ;//                     <3=> Pclk = Cclk / 8
  227. ;//     <o7.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
  228. ;//                     <0=> Pclk = Cclk / 4
  229. ;//                     <1=> Pclk = Cclk
  230. ;//                     <2=> Pclk = Cclk / 2
  231. ;//                     <3=> Pclk = Cclk / 8
  232. ;//     <o7.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
  233. ;//                     <0=> Pclk = Cclk / 4
  234. ;//                     <1=> Pclk = Cclk
  235. ;//                     <2=> Pclk = Cclk / 2
  236. ;//                     <3=> Pclk = Cclk / 8
  237. ;//     <o7.16..17>  PCLK_UART2: Peripheral Clock Selection for UART2
  238. ;//                     <0=> Pclk = Cclk / 4
  239. ;//                     <1=> Pclk = Cclk
  240. ;//                     <2=> Pclk = Cclk / 2
  241. ;//                     <3=> Pclk = Cclk / 8
  242. ;//     <o7.18..19>  PCLK_UART3: Peripheral Clock Selection for UART3
  243. ;//                     <0=> Pclk = Cclk / 4
  244. ;//                     <1=> Pclk = Cclk
  245. ;//                     <2=> Pclk = Cclk / 2
  246. ;//                     <3=> Pclk = Cclk / 8
  247. ;//     <o7.20..21>   PCLK_I2C2: Peripheral Clock Selection for I2C2
  248. ;//                     <0=> Pclk = Cclk / 4
  249. ;//                     <1=> Pclk = Cclk
  250. ;//                     <2=> Pclk = Cclk / 2
  251. ;//                     <3=> Pclk = Cclk / 8
  252. ;//     <o7.22..23>    PCLK_I2S: Peripheral Clock Selection for I2S
  253. ;//                     <0=> Pclk = Cclk / 4
  254. ;//                     <1=> Pclk = Cclk
  255. ;//                     <2=> Pclk = Cclk / 2
  256. ;//                     <3=> Pclk = Cclk / 8
  257. ;//     <o7.24..25>    PCLK_MCI: Peripheral Clock Selection for MCI
  258. ;//                     <0=> Pclk = Cclk / 4
  259. ;//                     <1=> Pclk = Cclk
  260. ;//                     <2=> Pclk = Cclk / 2
  261. ;//                     <3=> Pclk = Cclk / 8
  262. ;//     <o7.28..29> PCLK_SYSCON: Peripheral Clock Selection for System Control Block
  263. ;//                     <0=> Pclk = Cclk / 4
  264. ;//                     <1=> Pclk = Cclk
  265. ;//                     <2=> Pclk = Cclk / 2
  266. ;//                     <3=> Pclk = Cclk / 8
  267. ;//   </h>
  268. ;// </e>
  269. CLOCK_SETUP     EQU     1
  270. SCS_Val         EQU     0x00000020
  271. CLKSRCSEL_Val   EQU     0x00000001
  272. PLLCFG_Val      EQU     0x0000000B
  273. CCLKCFG_Val     EQU     0x00000004
  274. USBCLKCFG_Val   EQU     0x00000005
  275. PCLKSEL0_Val    EQU     0x00000000
  276. PCLKSEL1_Val    EQU     0x00000000
  277. ; Memory Accelerator Module (MAM) definitions
  278. MAM_BASE        EQU     0xE01FC000      ; MAM Base Address
  279. MAMCR_OFS       EQU     0x00            ; MAM Control Offset
  280. MAMTIM_OFS      EQU     0x04            ; MAM Timing Offset
  281. ;// <e> MAM Setup
  282. ;//   <o1.0..1>   MAM Control
  283. ;//               <0=> Disabled
  284. ;//               <1=> Partially Enabled
  285. ;//               <2=> Fully Enabled
  286. ;//               <i> Mode
  287. ;//   <o2.0..2>   MAM Timing
  288. ;//               <0=> Reserved  <1=> 1   <2=> 2   <3=> 3
  289. ;//               <4=> 4         <5=> 5   <6=> 6   <7=> 7
  290. ;//               <i> Fetch Cycles
  291. ;// </e>
  292. MAM_SETUP       EQU     1
  293. MAMCR_Val       EQU     0x00000002
  294. MAMTIM_Val      EQU     0x00000004
  295. ; Area Definition and Entry Point
  296. ;  Startup Code must be linked first at Address at which it expects to run.
  297.                 AREA    RESET, CODE, READONLY
  298.                 ARM
  299. ; Exception Vectors
  300. ;  Mapped to Address 0.
  301. ;  Absolute addressing mode must be used.
  302. ;  Dummy Handlers are implemented as infinite loops which can be modified.
  303. Vectors         LDR     PC, Reset_Addr         
  304.                 LDR     PC, Undef_Addr
  305.                 LDR     PC, SWI_Addr
  306.                 LDR     PC, PAbt_Addr
  307.                 LDR     PC, DAbt_Addr
  308.                 NOP                            ; Reserved Vector 
  309. ;               LDR     PC, IRQ_Addr
  310.                 LDR     PC, [PC, #-0x0120]     ; Vector from VicVectAddr
  311.                 LDR     PC, FIQ_Addr
  312. Reset_Addr      DCD     Reset_Handler
  313. Undef_Addr      DCD     Undef_Handler
  314. SWI_Addr        DCD     SWI_Handler
  315. PAbt_Addr       DCD     PAbt_Handler
  316. DAbt_Addr       DCD     DAbt_Handler
  317.                 DCD     0                      ; Reserved Address 
  318. IRQ_Addr        DCD     IRQ_Handler
  319. FIQ_Addr        DCD     FIQ_Handler
  320. Undef_Handler   B       Undef_Handler
  321. SWI_Handler     B       SWI_Handler
  322. PAbt_Handler    B       PAbt_Handler
  323. DAbt_Handler    B       DAbt_Handler
  324. IRQ_Handler     B       IRQ_Handler
  325. FIQ_Handler     B       FIQ_Handler
  326. ; Reset Handler
  327.                 EXPORT  Reset_Handler
  328. Reset_Handler   
  329. ; Setup Clock
  330.                 IF      CLOCK_SETUP != 0
  331.                 LDR     R0, =SCB_BASE
  332.                 MOV     R1, #0xAA
  333.                 MOV     R2, #0x55
  334. ;  Configure and Enable PLL
  335.                 LDR     R3, =SCS_Val          ; Enable main oscillator
  336.                 STR     R3, [R0, #SCS_OFS] 
  337.                 IF      (SCS_Val:AND:OSCEN) != 0  
  338. OSC_Loop        LDR     R3, [R0, #SCS_OFS]    ; Wait for main osc stabilize
  339.                 ANDS    R3, R3, #OSCSTAT
  340.                 BEQ     OSC_Loop
  341.                 ENDIF
  342.                 LDR     R3, =CLKSRCSEL_Val    ; Select PLL source clock
  343.                 STR     R3, [R0, #CLKSRCSEL_OFS] 
  344.                 LDR     R3, =PLLCFG_Val
  345.                 STR     R3, [R0, #PLLCFG_OFS] 
  346.                 STR     R1, [R0, #PLLFEED_OFS]
  347.                 STR     R2, [R0, #PLLFEED_OFS]
  348.                 MOV     R3, #PLLCON_PLLE
  349.                 STR     R3, [R0, #PLLCON_OFS]
  350.                 STR     R1, [R0, #PLLFEED_OFS]
  351.                 STR     R2, [R0, #PLLFEED_OFS]
  352. ;  Wait until PLL Locked
  353. PLL_Loop        LDR     R3, [R0, #PLLSTAT_OFS]
  354.                 ANDS    R3, R3, #PLLSTAT_PLOCK
  355.                 BEQ     PLL_Loop
  356. M_N_Lock        LDR     R3, [R0, #PLLSTAT_OFS]
  357.                 LDR     R4, =(PLLSTAT_M:OR:PLLSTAT_N)
  358.                 AND     R3, R3, R4
  359.                 LDR     R4, =PLLCFG_Val
  360.                 EORS    R3, R3, R4
  361.                 BNE     M_N_Lock
  362. ;  Setup CPU clock divider
  363.                 MOV     R3, #CCLKCFG_Val
  364.                 STR     R3, [R0, #CCLKCFG_OFS]
  365. ;  Setup USB clock divider
  366.                 LDR     R3, =USBCLKCFG_Val
  367.                 STR     R3, [R0, #USBCLKCFG_OFS]
  368. ;  Setup Peripheral Clock
  369.                 LDR     R3, =PCLKSEL0_Val
  370.                 STR     R3, [R0, #PCLKSEL0_OFS]
  371.                 LDR     R3, =PCLKSEL1_Val
  372.                 STR     R3, [R0, #PCLKSEL1_OFS]
  373. ;  Switch to PLL Clock
  374.                 MOV     R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
  375.                 STR     R3, [R0, #PLLCON_OFS]
  376.                 STR     R1, [R0, #PLLFEED_OFS]
  377.                 STR     R2, [R0, #PLLFEED_OFS]
  378.                 ENDIF   ; CLOCK_SETUP
  379. ; Setup MAM
  380.                 IF      MAM_SETUP != 0
  381.                 LDR     R0, =MAM_BASE
  382.                 MOV     R1, #MAMTIM_Val
  383.                 STR     R1, [R0, #MAMTIM_OFS] 
  384.                 MOV     R1, #MAMCR_Val
  385.                 STR     R1, [R0, #MAMCR_OFS] 
  386.                 ENDIF   ; MAM_SETUP
  387. ; Memory Mapping (when Interrupt Vectors are in RAM)
  388. MEMMAP          EQU     0xE01FC040      ; Memory Mapping Control
  389.                 IF      :DEF:REMAP
  390.                 LDR     R0, =MEMMAP
  391.                 IF      :DEF:RAM_MODE
  392.                 MOV     R1, #2
  393.                 ELSE
  394.                 MOV     R1, #1
  395.                 ENDIF
  396.                 STR     R1, [R0]
  397.                 ENDIF
  398. ; Initialise Interrupt System
  399. ;  ...
  400. ; Setup Stack for each mode
  401.                 LDR     R0, =Stack_Top
  402. ;  Enter Undefined Instruction Mode and set its Stack Pointer
  403.                 MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
  404.                 MOV     SP, R0
  405.                 SUB     R0, R0, #UND_Stack_Size
  406. ;  Enter Abort Mode and set its Stack Pointer
  407.                 MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
  408.                 MOV     SP, R0
  409.                 SUB     R0, R0, #ABT_Stack_Size
  410. ;  Enter FIQ Mode and set its Stack Pointer
  411.                 MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
  412.                 MOV     SP, R0
  413.                 SUB     R0, R0, #FIQ_Stack_Size
  414. ;  Enter IRQ Mode and set its Stack Pointer
  415.                 MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
  416.                 MOV     SP, R0
  417.                 SUB     R0, R0, #IRQ_Stack_Size
  418. ;  Enter Supervisor Mode and set its Stack Pointer
  419.                 MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
  420.                 MOV     SP, R0
  421.                 SUB     R0, R0, #SVC_Stack_Size
  422. ;  Enter User Mode and set its Stack Pointer
  423.                 MSR     CPSR_c, #Mode_USR
  424.                 MOV     SP, R0
  425.                 SUB     SL, SP, #USR_Stack_Size
  426. ; Enter the C code
  427.                 IMPORT  __main
  428.                 LDR     R0, =__main
  429.                 BX      R0
  430. ; User Initial Stack & Heap
  431.                 AREA    |.text|, CODE, READONLY
  432.                 IMPORT  __use_two_region_memory
  433.                 EXPORT  __user_initial_stackheap
  434. __user_initial_stackheap
  435.                 LDR     R0, =  Heap_Mem
  436.                 LDR     R1, =(Stack_Mem + USR_Stack_Size)
  437.                 LDR     R2, = (Heap_Mem +      Heap_Size)
  438.                 LDR     R3, = Stack_Mem
  439.                 BX      LR
  440.                 END