startup_gcc.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. //*****************************************************************************
  2. //
  3. //! @file startup_gcc.c
  4. //!
  5. //! @brief Definitions for interrupt handlers, the vector table, and the stack.
  6. //
  7. //*****************************************************************************
  8. //*****************************************************************************
  9. //
  10. // Copyright (c) 2017, Ambiq Micro
  11. // All rights reserved.
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions are met:
  15. //
  16. // 1. Redistributions of source code must retain the above copyright notice,
  17. // this list of conditions and the following disclaimer.
  18. //
  19. // 2. Redistributions in binary form must reproduce the above copyright
  20. // notice, this list of conditions and the following disclaimer in the
  21. // documentation and/or other materials provided with the distribution.
  22. //
  23. // 3. Neither the name of the copyright holder nor the names of its
  24. // contributors may be used to endorse or promote products derived from this
  25. // software without specific prior written permission.
  26. //
  27. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  31. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. // POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. // This is part of revision 1.2.9 of the AmbiqSuite Development Package.
  40. //
  41. //*****************************************************************************
  42. #include <stdint.h>
  43. //*****************************************************************************
  44. //
  45. // Forward declaration of interrupt handlers.
  46. //
  47. //*****************************************************************************
  48. extern void am_reset_isr(void) __attribute ((naked));
  49. extern void am_nmi_isr(void) __attribute ((weak));
  50. extern void am_fault_isr(void) __attribute ((weak));
  51. extern void am_mpufault_isr(void) __attribute ((weak, alias ("am_fault_isr")));
  52. extern void am_busfault_isr(void) __attribute ((weak, alias ("am_fault_isr")));
  53. extern void am_usagefault_isr(void) __attribute ((weak, alias ("am_fault_isr")));
  54. extern void am_svcall_isr(void) __attribute ((weak, alias ("am_default_isr")));
  55. extern void am_debugmon_isr(void) __attribute ((weak, alias ("am_default_isr")));
  56. extern void am_pendsv_isr(void) __attribute ((weak, alias ("am_default_isr")));
  57. extern void am_systick_isr(void) __attribute ((weak, alias ("am_default_isr")));
  58. extern void am_brownout_isr(void) __attribute ((weak, alias ("am_default_isr")));
  59. extern void am_watchdog_isr(void) __attribute ((weak, alias ("am_default_isr")));
  60. extern void am_clkgen_isr(void) __attribute ((weak, alias ("am_default_isr")));
  61. extern void am_vcomp_isr(void) __attribute ((weak, alias ("am_default_isr")));
  62. extern void am_ioslave_ios_isr(void) __attribute ((weak, alias ("am_default_isr")));
  63. extern void am_ioslave_acc_isr(void) __attribute ((weak, alias ("am_default_isr")));
  64. extern void am_iomaster0_isr(void) __attribute ((weak, alias ("am_default_isr")));
  65. extern void am_iomaster1_isr(void) __attribute ((weak, alias ("am_default_isr")));
  66. extern void am_iomaster2_isr(void) __attribute ((weak, alias ("am_default_isr")));
  67. extern void am_iomaster3_isr(void) __attribute ((weak, alias ("am_default_isr")));
  68. extern void am_iomaster4_isr(void) __attribute ((weak, alias ("am_default_isr")));
  69. extern void am_iomaster5_isr(void) __attribute ((weak, alias ("am_default_isr")));
  70. extern void am_gpio_isr(void) __attribute ((weak, alias ("am_default_isr")));
  71. extern void am_ctimer_isr(void) __attribute ((weak, alias ("am_default_isr")));
  72. extern void am_uart_isr(void) __attribute ((weak, alias ("am_default_isr")));
  73. extern void am_uart1_isr(void) __attribute ((weak, alias ("am_default_isr")));
  74. extern void am_adc_isr(void) __attribute ((weak, alias ("am_default_isr")));
  75. extern void am_pdm_isr(void) __attribute ((weak, alias ("am_default_isr")));
  76. extern void am_stimer_isr(void) __attribute ((weak, alias ("am_default_isr")));
  77. extern void am_stimer_cmpr0_isr(void) __attribute ((weak, alias ("am_default_isr")));
  78. extern void am_stimer_cmpr1_isr(void) __attribute ((weak, alias ("am_default_isr")));
  79. extern void am_stimer_cmpr2_isr(void) __attribute ((weak, alias ("am_default_isr")));
  80. extern void am_stimer_cmpr3_isr(void) __attribute ((weak, alias ("am_default_isr")));
  81. extern void am_stimer_cmpr4_isr(void) __attribute ((weak, alias ("am_default_isr")));
  82. extern void am_stimer_cmpr5_isr(void) __attribute ((weak, alias ("am_default_isr")));
  83. extern void am_stimer_cmpr6_isr(void) __attribute ((weak, alias ("am_default_isr")));
  84. extern void am_stimer_cmpr7_isr(void) __attribute ((weak, alias ("am_default_isr")));
  85. extern void am_flash_isr(void) __attribute ((weak, alias ("am_default_isr")));
  86. extern void am_software0_isr(void) __attribute ((weak, alias ("am_default_isr")));
  87. extern void am_software1_isr(void) __attribute ((weak, alias ("am_default_isr")));
  88. extern void am_software2_isr(void) __attribute ((weak, alias ("am_default_isr")));
  89. extern void am_software3_isr(void) __attribute ((weak, alias ("am_default_isr")));
  90. extern void am_default_isr(void) __attribute ((weak));
  91. //*****************************************************************************
  92. //
  93. // The entry point for the application.
  94. //
  95. //*****************************************************************************
  96. extern int main(void);
  97. //*****************************************************************************
  98. //
  99. // Reserve space for the system stack.
  100. //
  101. //*****************************************************************************
  102. __attribute__ ((section(".stack")))
  103. static uint32_t g_pui32Stack[1024];
  104. //*****************************************************************************
  105. //
  106. // The vector table. Note that the proper constructs must be placed on this to
  107. // ensure that it ends up at physical address 0x0000.0000.
  108. //
  109. // Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
  110. // am_usagefault_isr does not work if am_fault_isr is defined externally.
  111. // Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
  112. //
  113. //*****************************************************************************
  114. __attribute__ ((section(".isr_vector")))
  115. void (* const g_am_pfnVectors[])(void) =
  116. {
  117. (void (*)(void))((uint32_t)g_pui32Stack + sizeof(g_pui32Stack)),
  118. // The initial stack pointer
  119. am_reset_isr, // The reset handler
  120. am_nmi_isr, // The NMI handler
  121. am_fault_isr, // The hard fault handler
  122. am_fault_isr, // The MPU fault handler
  123. am_fault_isr, // The bus fault handler
  124. am_fault_isr, // The usage fault handler
  125. 0, // Reserved
  126. 0, // Reserved
  127. 0, // Reserved
  128. 0, // Reserved
  129. am_svcall_isr, // SVCall handle
  130. am_debugmon_isr, // Debug monitor handler
  131. 0, // Reserved
  132. am_pendsv_isr, // The PendSV handler
  133. am_systick_isr, // The SysTick handler
  134. //
  135. // Peripheral Interrupts
  136. //
  137. am_brownout_isr, // 0: Brownout
  138. am_watchdog_isr, // 1: Watchdog
  139. am_clkgen_isr, // 2: CLKGEN
  140. am_vcomp_isr, // 3: Voltage Comparator
  141. am_ioslave_ios_isr, // 4: I/O Slave general
  142. am_ioslave_acc_isr, // 5: I/O Slave access
  143. am_iomaster0_isr, // 6: I/O Master 0
  144. am_iomaster1_isr, // 7: I/O Master 1
  145. am_iomaster2_isr, // 8: I/O Master 2
  146. am_iomaster3_isr, // 9: I/O Master 3
  147. am_iomaster4_isr, // 10: I/O Master 4
  148. am_iomaster5_isr, // 11: I/O Master 5
  149. am_gpio_isr, // 12: GPIO
  150. am_ctimer_isr, // 13: CTIMER
  151. am_uart_isr, // 14: UART
  152. am_uart1_isr, // 15: UART
  153. am_adc_isr, // 16: ADC
  154. am_pdm_isr, // 17: ADC
  155. am_stimer_isr, // 18: SYSTEM TIMER
  156. am_stimer_cmpr0_isr, // 19: SYSTEM TIMER COMPARE0
  157. am_stimer_cmpr1_isr, // 20: SYSTEM TIMER COMPARE1
  158. am_stimer_cmpr2_isr, // 21: SYSTEM TIMER COMPARE2
  159. am_stimer_cmpr3_isr, // 22: SYSTEM TIMER COMPARE3
  160. am_stimer_cmpr4_isr, // 23: SYSTEM TIMER COMPARE4
  161. am_stimer_cmpr5_isr, // 24: SYSTEM TIMER COMPARE5
  162. am_stimer_cmpr6_isr, // 25: SYSTEM TIMER COMPARE6
  163. am_stimer_cmpr7_isr, // 26: SYSTEM TIMER COMPARE7
  164. am_flash_isr, // 27: FLASH
  165. am_software0_isr, // 28: SOFTWARE0
  166. am_software1_isr, // 29: SOFTWARE1
  167. am_software2_isr, // 30: SOFTWARE2
  168. am_software3_isr // 31: SOFTWARE3
  169. };
  170. //*****************************************************************************
  171. //
  172. // The following are constructs created by the linker, indicating where the
  173. // the "data" and "bss" segments reside in memory. The initializers for the
  174. // "data" segment resides immediately following the "text" segment.
  175. //
  176. //*****************************************************************************
  177. extern uint32_t _etext;
  178. extern uint32_t _sdata;
  179. extern uint32_t _edata;
  180. extern uint32_t _sbss;
  181. extern uint32_t _ebss;
  182. //*****************************************************************************
  183. //
  184. // This is the code that gets called when the processor first starts execution
  185. // following a reset event. Only the absolutely necessary set is performed,
  186. // after which the application supplied entry() routine is called.
  187. //
  188. //*****************************************************************************
  189. #if defined(__GNUC_STDC_INLINE__)
  190. void
  191. am_reset_isr(void)
  192. {
  193. //
  194. // Set the vector table pointer.
  195. //
  196. __asm(" ldr r0, =0xE000ED08\n"
  197. " ldr r1, =g_am_pfnVectors\n"
  198. " str r1, [r0]");
  199. //
  200. // Set the stack pointer.
  201. //
  202. __asm(" ldr sp, [r1]");
  203. #ifndef NOFPU
  204. //
  205. // Enable the FPU.
  206. //
  207. __asm("ldr r0, =0xE000ED88\n"
  208. "ldr r1,[r0]\n"
  209. "orr r1,#(0xF << 20)\n"
  210. "str r1,[r0]\n"
  211. "dsb\n"
  212. "isb\n");
  213. #endif
  214. //
  215. // Copy the data segment initializers from flash to SRAM.
  216. //
  217. __asm(" ldr r0, =_init_data\n"
  218. " ldr r1, =_sdata\n"
  219. " ldr r2, =_edata\n"
  220. "copy_loop:\n"
  221. " ldr r3, [r0], #4\n"
  222. " str r3, [r1], #4\n"
  223. " cmp r1, r2\n"
  224. " blt copy_loop\n");
  225. //
  226. // Zero fill the bss segment.
  227. //
  228. __asm(" ldr r0, =_sbss\n"
  229. " ldr r1, =_ebss\n"
  230. " mov r2, #0\n"
  231. "zero_loop:\n"
  232. " cmp r0, r1\n"
  233. " it lt\n"
  234. " strlt r2, [r0], #4\n"
  235. " blt zero_loop");
  236. //
  237. // Call the application's entry point.
  238. //
  239. main();
  240. //
  241. // If main returns then execute a break point instruction
  242. //
  243. __asm(" bkpt ");
  244. }
  245. #else
  246. #error GNU STDC inline not supported.
  247. #endif
  248. //*****************************************************************************
  249. //
  250. // This is the code that gets called when the processor receives a NMI. This
  251. // simply enters an infinite loop, preserving the system state for examination
  252. // by a debugger.
  253. //
  254. //*****************************************************************************
  255. void
  256. am_nmi_isr(void)
  257. {
  258. //
  259. // Go into an infinite loop.
  260. //
  261. while(1)
  262. {
  263. }
  264. }
  265. //*****************************************************************************
  266. //
  267. // This is the code that gets called when the processor receives a fault
  268. // interrupt. This simply enters an infinite loop, preserving the system state
  269. // for examination by a debugger.
  270. //
  271. //*****************************************************************************
  272. void
  273. am_fault_isr(void)
  274. {
  275. //
  276. // Go into an infinite loop.
  277. //
  278. while(1)
  279. {
  280. }
  281. }
  282. //*****************************************************************************
  283. //
  284. // This is the code that gets called when the processor receives an unexpected
  285. // interrupt. This simply enters an infinite loop, preserving the system state
  286. // for examination by a debugger.
  287. //
  288. //*****************************************************************************
  289. void
  290. am_default_isr(void)
  291. {
  292. //
  293. // Go into an infinite loop.
  294. //
  295. while(1)
  296. {
  297. }
  298. }