1/**************************************************************************//** 2 * @file startup_psoc6_02_cm0plus.S 3 * @brief CMSIS Core Device Startup File for 4 * ARMCM0plus Device Series 5 * @version V5.00 6 * @date 02. March 2016 7 ******************************************************************************/ 8/* 9 * Copyright (c) 2009-2016 ARM Limited. All rights reserved. 10 * 11 * SPDX-License-Identifier: Apache-2.0 12 * 13 * Licensed under the Apache License, Version 2.0 (the License); you may 14 * not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 */ 25 26 /* Address of the NMI handler */ 27 #define CY_NMI_HANLDER_ADDR 0x0000000D 28 29 /* The CPU VTOR register */ 30 #define CY_CPU_VTOR_ADDR 0xE000ED08 31 32 /* Copy flash vectors and data section to RAM */ 33 #define __STARTUP_COPY_MULTIPLE 34 35 /* Clear single BSS section */ 36 #define __STARTUP_CLEAR_BSS 37 38 .syntax unified 39 .arch armv6-m 40 41 .section .stack 42 .align 3 43#ifdef __STACK_SIZE 44 .equ Stack_Size, __STACK_SIZE 45#else 46 .equ Stack_Size, 0x00001000 47#endif 48 .globl __StackTop 49 .globl __StackLimit 50__StackLimit: 51 .space Stack_Size 52 .size __StackLimit, . - __StackLimit 53__StackTop: 54 .size __StackTop, . - __StackTop 55 56 .section .heap 57 .align 3 58#ifdef __HEAP_SIZE 59 .equ Heap_Size, __HEAP_SIZE 60#else 61 .equ Heap_Size, 0x00000400 62#endif 63 .globl __HeapBase 64 .globl __HeapLimit 65__HeapBase: 66 .if Heap_Size 67 .space Heap_Size 68 .endif 69 .size __HeapBase, . - __HeapBase 70__HeapLimit: 71 .size __HeapLimit, . - __HeapLimit 72 73 .section .vectors 74 .align 2 75 .globl __Vectors 76__Vectors: 77 .long __StackTop /* Top of Stack */ 78 .long Reset_Handler /* Reset Handler */ 79 .long CY_NMI_HANLDER_ADDR /* NMI Handler */ 80 .long HardFault_Handler /* Hard Fault Handler */ 81 .long 0 /* Reserved */ 82 .long 0 /* Reserved */ 83 .long 0 /* Reserved */ 84 .long 0 /* Reserved */ 85 .long 0 /* Reserved */ 86 .long 0 /* Reserved */ 87 .long 0 /* Reserved */ 88 .long SVC_Handler /* SVCall Handler */ 89 .long 0 /* Reserved */ 90 .long 0 /* Reserved */ 91 .long PendSV_Handler /* PendSV Handler */ 92 .long SysTick_Handler /* SysTick Handler */ 93 94 /* External interrupts Description */ 95 .long NvicMux0_IRQHandler /* CPU User Interrupt #0 */ 96 .long NvicMux1_IRQHandler /* CPU User Interrupt #1 */ 97 .long NvicMux2_IRQHandler /* CPU User Interrupt #2 */ 98 .long NvicMux3_IRQHandler /* CPU User Interrupt #3 */ 99 .long NvicMux4_IRQHandler /* CPU User Interrupt #4 */ 100 .long NvicMux5_IRQHandler /* CPU User Interrupt #5 */ 101 .long NvicMux6_IRQHandler /* CPU User Interrupt #6 */ 102 .long NvicMux7_IRQHandler /* CPU User Interrupt #7 */ 103 .long Internal0_IRQHandler /* Internal SW Interrupt #0 */ 104 .long Internal1_IRQHandler /* Internal SW Interrupt #1 */ 105 .long Internal2_IRQHandler /* Internal SW Interrupt #2 */ 106 .long Internal3_IRQHandler /* Internal SW Interrupt #3 */ 107 .long Internal4_IRQHandler /* Internal SW Interrupt #4 */ 108 .long Internal5_IRQHandler /* Internal SW Interrupt #5 */ 109 .long Internal6_IRQHandler /* Internal SW Interrupt #6 */ 110 .long Internal7_IRQHandler /* Internal SW Interrupt #7 */ 111 112 .size __Vectors, . - __Vectors 113 .equ __VectorsSize, . - __Vectors 114 115 .section .ram_vectors 116 .align 2 117 .globl __ramVectors 118__ramVectors: 119 .space __VectorsSize 120 .size __ramVectors, . - __ramVectors 121 122 123 .text 124 .thumb 125 .thumb_func 126 .align 2 127 128 /* 129 * Device startup customization 130 * 131 * Note. The global resources are not yet initialized (for example global variables, peripherals, clocks) 132 * because this function is executed as the first instruction in the ResetHandler. 133 * The PDL is also not initialized to use the proper register offsets. 134 * The user of this function is responsible for initializing the PDL and resources before using them. 135 */ 136 .weak Cy_OnResetUser 137 .func Cy_OnResetUser, Cy_OnResetUser 138 .type Cy_OnResetUser, %function 139 140Cy_OnResetUser: 141 bx lr 142 .size Cy_OnResetUser, . - Cy_OnResetUser 143 .endfunc 144 145 /* Reset handler */ 146 .weak Reset_Handler 147 .type Reset_Handler, %function 148 149Reset_Handler: 150 bl Cy_OnResetUser 151 cpsid i 152 153/* Firstly it copies data from read only memory to RAM. There are two schemes 154 * to copy. One can copy more than one sections. Another can only copy 155 * one section. The former scheme needs more instructions and read-only 156 * data to implement than the latter. 157 * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ 158 159#ifdef __STARTUP_COPY_MULTIPLE 160/* Multiple sections scheme. 161 * 162 * Between symbol address __copy_table_start__ and __copy_table_end__, 163 * there are array of triplets, each of which specify: 164 * offset 0: LMA of start of a section to copy from 165 * offset 4: VMA of start of a section to copy to 166 * offset 8: size of the section to copy. Must be multiply of 4 167 * 168 * All addresses must be aligned to 4 bytes boundary. 169 */ 170 ldr r4, =__copy_table_start__ 171 ldr r5, =__copy_table_end__ 172 173.L_loop0: 174 cmp r4, r5 175 bge .L_loop0_done 176 ldr r1, [r4] 177 ldr r2, [r4, #4] 178 ldr r3, [r4, #8] 179 180.L_loop0_0: 181 subs r3, #4 182 blt .L_loop0_0_done 183 ldr r0, [r1, r3] 184 str r0, [r2, r3] 185 b .L_loop0_0 186 187.L_loop0_0_done: 188 adds r4, #12 189 b .L_loop0 190 191.L_loop0_done: 192#else 193/* Single section scheme. 194 * 195 * The ranges of copy from/to are specified by following symbols 196 * __etext: LMA of start of the section to copy from. Usually end of text 197 * __data_start__: VMA of start of the section to copy to 198 * __data_end__: VMA of end of the section to copy to 199 * 200 * All addresses must be aligned to 4 bytes boundary. 201 */ 202 ldr r1, =__etext 203 ldr r2, =__data_start__ 204 ldr r3, =__data_end__ 205 206 subs r3, r2 207 ble .L_loop1_done 208 209.L_loop1: 210 subs r3, #4 211 ldr r0, [r1,r3] 212 str r0, [r2,r3] 213 bgt .L_loop1 214 215.L_loop1_done: 216#endif /*__STARTUP_COPY_MULTIPLE */ 217 218/* This part of work usually is done in C library startup code. Otherwise, 219 * define this macro to enable it in this startup. 220 * 221 * There are two schemes too. One can clear multiple BSS sections. Another 222 * can only clear one section. The former is more size expensive than the 223 * latter. 224 * 225 * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. 226 * Otherwise define macro __STARTUP_CLEAR_BSS to choose the later. 227 */ 228#ifdef __STARTUP_CLEAR_BSS_MULTIPLE 229/* Multiple sections scheme. 230 * 231 * Between symbol address __copy_table_start__ and __copy_table_end__, 232 * there are array of tuples specifying: 233 * offset 0: Start of a BSS section 234 * offset 4: Size of this BSS section. Must be multiply of 4 235 */ 236 ldr r3, =__zero_table_start__ 237 ldr r4, =__zero_table_end__ 238 239.L_loop2: 240 cmp r3, r4 241 bge .L_loop2_done 242 ldr r1, [r3] 243 ldr r2, [r3, #4] 244 movs r0, 0 245 246.L_loop2_0: 247 subs r2, #4 248 blt .L_loop2_0_done 249 str r0, [r1, r2] 250 b .L_loop2_0 251.L_loop2_0_done: 252 253 adds r3, #8 254 b .L_loop2 255.L_loop2_done: 256#elif defined (__STARTUP_CLEAR_BSS) 257/* Single BSS section scheme. 258 * 259 * The BSS section is specified by following symbols 260 * __bss_start__: start of the BSS section. 261 * __bss_end__: end of the BSS section. 262 * 263 * Both addresses must be aligned to 4 bytes boundary. 264 */ 265 ldr r1, =__bss_start__ 266 ldr r2, =__bss_end__ 267 268 movs r0, 0 269 270 subs r2, r1 271 ble .L_loop3_done 272 273.L_loop3: 274 subs r2, #4 275 str r0, [r1, r2] 276 bgt .L_loop3 277.L_loop3_done: 278#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ 279 280 /* Update Vector Table Offset Register. */ 281 ldr r0, =__ramVectors 282 ldr r1, =CY_CPU_VTOR_ADDR 283 str r0, [r1] 284 dsb 0xF 285 286#ifndef __NO_SYSTEM_INIT 287 bl SystemInit 288#endif 289 290 bl main 291 292 /* Should never get here */ 293 b . 294 295 .pool 296 .size Reset_Handler, . - Reset_Handler 297 298 .align 1 299 .thumb_func 300 .weak Default_Handler 301 .type Default_Handler, %function 302Default_Handler: 303 b . 304 .size Default_Handler, . - Default_Handler 305 .weak Cy_SysLib_FaultHandler 306 .type Cy_SysLib_FaultHandler, %function 307 308Cy_SysLib_FaultHandler: 309 b . 310 .size Cy_SysLib_FaultHandler, . - Cy_SysLib_FaultHandler 311 .type Fault_Handler, %function 312 313Fault_Handler: 314 /* Storing LR content for Creator call stack trace */ 315 push {LR} 316 movs r0, #4 317 mov r1, LR 318 tst r0, r1 319 beq .L_MSP 320 mrs r0, PSP 321 b .L_API_call 322.L_MSP: 323 mrs r0, MSP 324 /* Compensation of stack pointer address due to pushing 4 bytes of LR */ 325 adds r0, r0, #4 326.L_API_call: 327 bl Cy_SysLib_FaultHandler 328 b . 329 .size Fault_Handler, . - Fault_Handler 330 331.macro def_fault_Handler fault_handler_name 332 .weak \fault_handler_name 333 .set \fault_handler_name, Fault_Handler 334 .endm 335 336/* Macro to define default handlers. Default handler 337 * will be weak symbol and just dead loops. They can be 338 * overwritten by other handlers */ 339 .macro def_irq_handler handler_name 340 .weak \handler_name 341 .set \handler_name, Default_Handler 342 .endm 343 344 def_irq_handler NMI_Handler 345 346 def_fault_Handler HardFault_Handler 347 348 def_irq_handler SVC_Handler 349 def_irq_handler PendSV_Handler 350 def_irq_handler SysTick_Handler 351 352 def_irq_handler NvicMux0_IRQHandler /* CPU User Interrupt #0 */ 353 def_irq_handler NvicMux1_IRQHandler /* CPU User Interrupt #1 */ 354 def_irq_handler NvicMux2_IRQHandler /* CPU User Interrupt #2 */ 355 def_irq_handler NvicMux3_IRQHandler /* CPU User Interrupt #3 */ 356 def_irq_handler NvicMux4_IRQHandler /* CPU User Interrupt #4 */ 357 def_irq_handler NvicMux5_IRQHandler /* CPU User Interrupt #5 */ 358 def_irq_handler NvicMux6_IRQHandler /* CPU User Interrupt #6 */ 359 def_irq_handler NvicMux7_IRQHandler /* CPU User Interrupt #7 */ 360 def_irq_handler Internal0_IRQHandler /* Internal SW Interrupt #0 */ 361 def_irq_handler Internal1_IRQHandler /* Internal SW Interrupt #1 */ 362 def_irq_handler Internal2_IRQHandler /* Internal SW Interrupt #2 */ 363 def_irq_handler Internal3_IRQHandler /* Internal SW Interrupt #3 */ 364 def_irq_handler Internal4_IRQHandler /* Internal SW Interrupt #4 */ 365 def_irq_handler Internal5_IRQHandler /* Internal SW Interrupt #5 */ 366 def_irq_handler Internal6_IRQHandler /* Internal SW Interrupt #6 */ 367 def_irq_handler Internal7_IRQHandler /* Internal SW Interrupt #7 */ 368 369 .end 370 371 372/* [] END OF FILE */ 373