SAM7S.s 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /***********************************************************************/
  2. /* This file is part of the CA ARM C Compiler package */
  3. /* Copyright KEIL ELEKTRONIK GmbH 2002-2005 */
  4. /***********************************************************************/
  5. /* */
  6. /* SAM7S.S: Startup file for Atmel AT91SAM7S device series */
  7. /* */
  8. /***********************************************************************/
  9. /*
  10. //*** <<< Use Configuration Wizard in Context Menu >>> ***
  11. */
  12. /*
  13. * The STARTUP.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 - Set.
  16. *
  17. * REMAP: when set the startup code remaps exception vectors from
  18. * on-chip RAM to address 0.
  19. *
  20. * RAM_INTVEC: when set the startup code copies exception vectors
  21. * from on-chip Flash to on-chip RAM.
  22. *
  23. * RAM_MODE: when set the device is configured for code execution
  24. * from on-chip RAM starting at address 0x00200000. The startup
  25. * vectors are located to 0x00200000.
  26. */
  27. // Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
  28. Mode_USR EQU 0x10
  29. Mode_FIQ EQU 0x11
  30. Mode_IRQ EQU 0x12
  31. Mode_SVC EQU 0x13
  32. Mode_ABT EQU 0x17
  33. Mode_UND EQU 0x1B
  34. Mode_SYS EQU 0x1F
  35. I_Bit EQU 0x80 /* when I bit is set, IRQ is disabled */
  36. F_Bit EQU 0x40 /* when F bit is set, FIQ is disabled */
  37. // Internal Memory Base Addresses
  38. FLASH_BASE EQU 0x00100000
  39. RAM_BASE EQU 0x00200000
  40. /*
  41. // <h> Stack Configuration (Stack Sizes in Bytes)
  42. // <o0> Undefined Mode <0x0-0xFFFFFFFF:4>
  43. // <o1> Supervisor Mode <0x0-0xFFFFFFFF:4>
  44. // <o2> Abort Mode <0x0-0xFFFFFFFF:4>
  45. // <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:4>
  46. // <o4> Interrupt Mode <0x0-0xFFFFFFFF:4>
  47. // <o5> User/System Mode <0x0-0xFFFFFFFF:4>
  48. // </h>
  49. */
  50. UND_Stack_Size EQU 0x00000004
  51. SVC_Stack_Size EQU 0x00000004
  52. ABT_Stack_Size EQU 0x00000004
  53. FIQ_Stack_Size EQU 0x00000004
  54. IRQ_Stack_Size EQU 0x00000080
  55. USR_Stack_Size EQU 0x00000400
  56. AREA STACK, DATA, READWRITE, ALIGN=2
  57. DS (USR_Stack_Size+3)&~3 ; Stack for User/System Mode
  58. DS (SVC_Stack_Size+3)&~3 ; Stack for Supervisor Mode
  59. DS (IRQ_Stack_Size+3)&~3 ; Stack for Interrupt Mode
  60. DS (FIQ_Stack_Size+3)&~3 ; Stack for Fast Interrupt Mode
  61. DS (ABT_Stack_Size+3)&~3 ; Stack for Abort Mode
  62. DS (UND_Stack_Size+3)&~3 ; Stack for Undefined Mode
  63. Top_Stack:
  64. // Embedded Flash Controller (EFC) definitions
  65. EFC_BASE EQU 0xFFFFFF00 /* EFC Base Address */
  66. EFC_FMR EQU 0x60 /* EFC_FMR Offset */
  67. /*
  68. // <e> Embedded Flash Controller (EFC)
  69. // <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
  70. // <i> Number of Master Clock Cycles in 1us
  71. // <o1.8..9> FWS: Flash Wait State
  72. // <0=> Read: 1 cycle / Write: 2 cycles
  73. // <1=> Read: 2 cycle / Write: 3 cycles
  74. // <2=> Read: 3 cycle / Write: 4 cycles
  75. // <3=> Read: 4 cycle / Write: 4 cycles
  76. // </e>
  77. */
  78. EFC_SETUP EQU 1
  79. EFC_FMR_Val EQU 0x00320100
  80. // Watchdog Timer (WDT) definitions
  81. WDT_BASE EQU 0xFFFFFD40 /* WDT Base Address */
  82. WDT_MR EQU 0x04 /* WDT_MR Offset */
  83. /*
  84. // <e> Watchdog Timer (WDT)
  85. // <o1.0..11> WDV: Watchdog Counter Value <0-4095>
  86. // <o1.16..27> WDD: Watchdog Delta Value <0-4095>
  87. // <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
  88. // <o1.13> WDRSTEN: Watchdog Reset Enable
  89. // <o1.14> WDRPROC: Watchdog Reset Processor
  90. // <o1.28> WDDBGHLT: Watchdog Debug Halt
  91. // <o1.29> WDIDLEHLT: Watchdog Idle Halt
  92. // <o1.15> WDDIS: Watchdog Disable
  93. // </e>
  94. */
  95. WDT_SETUP EQU 1
  96. WDT_MR_Val EQU 0x00008000
  97. // Power Mangement Controller (PMC) definitions
  98. PMC_BASE EQU 0xFFFFFC00 /* PMC Base Address */
  99. PMC_MOR EQU 0x20 /* PMC_MOR Offset */
  100. PMC_MCFR EQU 0x24 /* PMC_MCFR Offset */
  101. PMC_PLLR EQU 0x2C /* PMC_PLLR Offset */
  102. PMC_MCKR EQU 0x30 /* PMC_MCKR Offset */
  103. PMC_SR EQU 0x68 /* PMC_SR Offset */
  104. PMC_MOSCEN EQU (1<<0) /* Main Oscillator Enable */
  105. PMC_OSCBYPASS EQU (1<<1) /* Main Oscillator Bypass */
  106. PMC_OSCOUNT EQU (0xFF<<8) /* Main OScillator Start-up Time */
  107. PMC_DIV EQU (0xFF<<0) /* PLL Divider */
  108. PMC_PLLCOUNT EQU (0x3F<<8) /* PLL Lock Counter */
  109. PMC_OUT EQU (0x03<<14) /* PLL Clock Frequency Range */
  110. PMC_MUL EQU (0x7FF<<16) /* PLL Multiplier */
  111. PMC_USBDIV EQU (0x03<<28) /* USB Clock Divider */
  112. PMC_CSS EQU (3<<0) /* Clock Source Selection */
  113. PMC_PRES EQU (7<<2) /* Prescaler Selection */
  114. PMC_MOSCS EQU (1<<0) /* Main Oscillator Stable */
  115. PMC_LOCK EQU (1<<2) /* PLL Lock Status */
  116. /*
  117. // <e> Power Mangement Controller (PMC)
  118. // <h> Main Oscillator
  119. // <o1.0> MOSCEN: Main Oscillator Enable
  120. // <o1.1> OSCBYPASS: Oscillator Bypass
  121. // <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
  122. // </h>
  123. // <h> Phase Locked Loop (PLL)
  124. // <o2.0..7> DIV: PLL Divider <0-255>
  125. // <o2.16..26> MUL: PLL Multiplier <0-2047>
  126. // <i> PLL Output is multiplied by MUL+1
  127. // <o2.14..15> OUT: PLL Clock Frequency Range
  128. // <0=> 80..160MHz <1=> Reserved
  129. // <2=> 150..220MHz <3=> Reserved
  130. // <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
  131. // <o2.28..29> USBDIV: USB Clock Divider
  132. // <0=> None <1=> 2 <2=> 4 <3=> Reserved
  133. // </h>
  134. // <o3.0..1> CSS: Clock Source Selection
  135. // <0=> Slow Clock
  136. // <1=> Main Clock
  137. // <2=> Reserved
  138. // <3=> PLL Clock
  139. // <o3.2..4> PRES: Prescaler
  140. // <0=> None
  141. // <1=> Clock / 2 <2=> Clock / 4
  142. // <3=> Clock / 8 <4=> Clock / 16
  143. // <5=> Clock / 32 <6=> Clock / 64
  144. // <7=> Reserved
  145. // </e>
  146. */
  147. PMC_SETUP EQU 1
  148. PMC_MOR_Val EQU 0x00000601
  149. PMC_PLLR_Val EQU 0x00191C05
  150. PMC_MCKR_Val EQU 0x00000007
  151. $IF (RAM_INTVEC)
  152. // Exception Vector Area in RAM
  153. AREA VECTORS, DATA, AT RAM_BASE
  154. DS 64
  155. $ENDIF
  156. // Startup Code must be linked at address which it expects to run.
  157. $IF (RAM_MODE)
  158. CODE_BASE EQU RAM_BASE
  159. $ELSE
  160. CODE_BASE EQU FLASH_BASE
  161. $ENDIF
  162. AREA STARTUPCODE, CODE, AT CODE_BASE
  163. PUBLIC __startup
  164. EXTERN CODE32 (?C?INIT)
  165. __startup PROC CODE32
  166. // Pre-defined interrupt handlers that may be directly
  167. // overwritten by C interrupt functions
  168. EXTERN CODE32 (Undef_Handler?A)
  169. EXTERN CODE32 (SWI_Handler?A)
  170. EXTERN CODE32 (PAbt_Handler?A)
  171. EXTERN CODE32 (DAbt_Handler?A)
  172. ; EXTERN CODE32 (IRQ_Handler?A)
  173. ; EXTERN CODE32 (FIQ_Handler?A)
  174. // Exception Vectors
  175. // Mapped to Address 0.
  176. // Absolute addressing mode must be used.
  177. Vectors: LDR PC,Reset_Addr
  178. LDR PC,Undef_Addr
  179. LDR PC,SWI_Addr
  180. LDR PC,PAbt_Addr
  181. LDR PC,DAbt_Addr
  182. NOP /* Reserved Vector */
  183. ; LDR PC,IRQ_Addr
  184. LDR PC,[PC,#-0xF20] /* Vector From AIC_IVR */
  185. ; LDR PC,FIQ_Addr
  186. LDR PC,[PC,#-0xF20] /* Vector From AIC_FVR */
  187. Reset_Addr: DD Reset_Handler
  188. Undef_Addr: DD Undef_Handler?A
  189. SWI_Addr: DD SWI_Handler?A
  190. PAbt_Addr: DD PAbt_Handler?A
  191. DAbt_Addr: DD DAbt_Handler?A
  192. DD 0 /* Reserved Address */
  193. ;IRQ_Addr: DD IRQ_Handler?A
  194. IRQ_Addr: DD 0
  195. ;FIQ_Addr: DD FIQ_Handler?A
  196. FIQ_Addr: DD 0
  197. // Reset Handler
  198. Reset_Handler:
  199. // Setup EFC
  200. IF (EFC_SETUP != 0)
  201. LDR R0, =EFC_BASE
  202. LDR R1, =EFC_FMR_Val
  203. STR R1, [R0, #EFC_FMR]
  204. ENDIF
  205. // Setup WDT
  206. IF (WDT_SETUP != 0)
  207. LDR R0, =WDT_BASE
  208. LDR R1, =WDT_MR_Val
  209. STR R1, [R0, #WDT_MR]
  210. ENDIF
  211. // Setup PMC
  212. IF (PMC_SETUP != 0)
  213. LDR R0, =PMC_BASE
  214. // Setup Main Oscillator
  215. LDR R1, =PMC_MOR_Val
  216. STR R1, [R0, #PMC_MOR]
  217. // Wait until Main Oscillator is stablilized
  218. IF ((PMC_MOR_Val & PMC_MOSCEN) != 0)
  219. MOSCS_Loop: LDR R2, [R0, #PMC_SR]
  220. ANDS R2, R2, #PMC_MOSCS
  221. BEQ MOSCS_Loop
  222. ENDIF
  223. // Setup the PLL
  224. IF ((PMC_PLLR_Val & PMC_MUL) != 0)
  225. LDR R1, =PMC_PLLR_Val
  226. STR R1, [R0, #PMC_PLLR]
  227. // Wait until PLL is stabilized
  228. PLL_Loop: LDR R2, [R0, #PMC_SR]
  229. ANDS R2, R2, #PMC_LOCK
  230. BEQ PLL_Loop
  231. ENDIF
  232. // Select Clock
  233. LDR R1, =PMC_MCKR_Val
  234. STR R1, [R0, #PMC_MCKR]
  235. ENDIF
  236. // Copy Exception Vectors to Internal RAM
  237. $IF (RAM_INTVEC)
  238. ADR R8, Vectors ; Source
  239. LDR R9, =RAM_BASE ; Destination
  240. LDMIA R8!, {R0-R7} ; Load Vectors
  241. STMIA R9!, {R0-R7} ; Store Vectors
  242. LDMIA R8!, {R0-R7} ; Load Handler Addresses
  243. STMIA R9!, {R0-R7} ; Store Handler Addresses
  244. $ENDIF
  245. // Remap on-chip RAM to address 0
  246. MC_BASE EQU 0xFFFFFF00 /* MC Base Address */
  247. MC_RCR EQU 0x00 /* MC_RCR Offset */
  248. $IF (REMAP)
  249. LDR R0, =MC_BASE
  250. MOV R1, #1
  251. STR R1, [R0, #MC_RCR] ; Remap
  252. $ENDIF
  253. // Setup Stack for each mode
  254. LDR R0, =Top_Stack
  255. // Enter Undefined Instruction Mode and set its Stack Pointer
  256. MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
  257. MOV SP, R0
  258. SUB R0, R0, #UND_Stack_Size
  259. // Enter Abort Mode and set its Stack Pointer
  260. MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
  261. MOV SP, R0
  262. SUB R0, R0, #ABT_Stack_Size
  263. // Enter FIQ Mode and set its Stack Pointer
  264. MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
  265. MOV SP, R0
  266. SUB R0, R0, #FIQ_Stack_Size
  267. // Enter IRQ Mode and set its Stack Pointer
  268. MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
  269. MOV SP, R0
  270. SUB R0, R0, #IRQ_Stack_Size
  271. // Enter Supervisor Mode and set its Stack Pointer
  272. MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
  273. MOV SP, R0
  274. SUB R0, R0, #SVC_Stack_Size
  275. // Enter User Mode and set its Stack Pointer
  276. MSR CPSR_c, #Mode_USR
  277. MOV SP, R0
  278. // Enter the C code
  279. LDR R0,=?C?INIT
  280. TST R0,#1 ; Bit-0 set: main is Thumb
  281. LDREQ LR,=exit?A ; ARM Mode
  282. LDRNE LR,=exit?T ; Thumb Mode
  283. BX R0
  284. ENDP
  285. PUBLIC exit?A
  286. exit?A PROC CODE32
  287. B exit?A
  288. ENDP
  289. PUBLIC exit?T
  290. exit?T PROC CODE16
  291. B exit?T
  292. ENDP
  293. END