1 /***************************************************************************//**
2 * \file startup_cm7.c
3 * \version 1.0
4 *
5 * The device system-source file.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2021 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25
26 #include "cy_syslib.h"
27 #include "cmsis_compiler.h"
28 #include "startup_cat1c.h"
29 #include "core_cm7.h"
30 #include "system_cat1c.h"
31
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35
36
37 extern void CM7_CpuIntr_Handler(uint8_t intrNum);
38
39 void Reset_Handler(void);
40
41 /* Internal Reference */
42 void Default_Handler(void);
43 void Default_NMIException_Handler(void);
44 void Default_Fault_Handler(void);
45 void SysLib_FaultHandler(uint32_t const *faultStackAddr);
46 __WEAK void cy_toolchain_init(void);
47 void FpuEnable(void);
48
49
50 #if defined(__ARMCC_VERSION)
51 extern unsigned int Image$$ARM_LIB_STACK$$ZI$$Limit;
52 interrupt_type extern void __main(void);
53 cy_israddress __ramVectors[VECTORTABLE_SIZE] __attribute__( ( section(".bss.noinit.RESET_RAM"))) __attribute__((aligned(VECTORTABLE_ALIGN)));
54 #elif defined (__GNUC__)
55 extern unsigned int __StackTop;
56 extern uint32_t __StackLimit;
57 cy_israddress __ramVectors[VECTORTABLE_SIZE] __attribute__( ( section(".ram_vectors"))) __attribute__((aligned(VECTORTABLE_ALIGN)));
58 #elif defined (__ICCARM__)
59 extern unsigned int CSTACK$$Limit;
60 interrupt_type extern void __cmain();
61 cy_israddress __ramVectors[VECTORTABLE_SIZE] __attribute__( ( section(".intvec_ram"))) __attribute__((aligned(VECTORTABLE_ALIGN)));
62 #else
63 #error "An unsupported toolchain"
64 #endif /* (__ARMCC_VERSION) */
65
66 /* SCB->CPACR */
67 #define SCB_CPACR_CP10_CP11_ENABLE (0xFUL << 20u)
68
69 /*******************************************************************************
70 * Function Name: FpuEnable
71 ****************************************************************************//**
72 *
73 * Enables the FPU if it is used. The function is called from the startup file.
74 *
75 *******************************************************************************/
FpuEnable(void)76 void FpuEnable(void)
77 {
78 #if defined (__FPU_USED) && (__FPU_USED == 1U)
79 uint32_t interruptState;
80 interruptState = Cy_SaveIRQ();
81 SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE;
82 __DSB();
83 __ISB();
84 Cy_RestoreIRQ(interruptState);
85 #endif /* (__FPU_USED) && (__FPU_USED == 1U) */
86 }
87
88
SysLib_FaultHandler(uint32_t const * faultStackAddr)89 void SysLib_FaultHandler(uint32_t const *faultStackAddr)
90 {
91 Cy_SysLib_FaultHandler(faultStackAddr);
92 }
93
94 /* Exception Vector Table & Handlers */
95 /*----------------------------------------------------------------*/
Default_NMIException_Handler(void)96 void Default_NMIException_Handler(void)
97 {
98 __asm volatile(
99 "bkpt #10\n"
100 "B .\n"
101 );
102 }
103
Default_Fault_Handler(void)104 void Default_Fault_Handler(void)
105 {
106 __asm (
107 "MRS R0, CONTROL\n"
108 "TST R0, #2\n"
109 "ITE EQ\n"
110 "MRSEQ R0, MSP\n"
111 "MRSNE R0, PSP\n"
112 "B SysLib_FaultHandler\n"
113 );
114 }
115
116 /*----------------------------------------------------------------------------
117 Default Handler for Exceptions / Interrupts
118 *----------------------------------------------------------------------------*/
Default_Handler(void)119 void Default_Handler(void)
120 {
121 while(1);
122 }
123
124
125 /*******************************************************************************
126 * Function Name: Default_CM7_CpuIntr0_Handler
127 ****************************************************************************//**
128 *
129 * The Handler is called when the CPU interrupt0 occurs.
130 *
131 *******************************************************************************/
132 CY_SECTION_ITCM_BEGIN
Default_CpuIntr0_Handler(void)133 void Default_CpuIntr0_Handler(void)
134 {
135 CM7_CpuIntr_Handler(0);
136 }
137 CY_SECTION_ITCM_END
138
139
140 /*******************************************************************************
141 * Function Name: Default_CM7_CpuIntr1_Handler
142 ****************************************************************************//**
143 *
144 * The Handler is called when the CPU interrupt1 occurs.
145 *
146 *******************************************************************************/
147 CY_SECTION_ITCM_BEGIN
Default_CpuIntr1_Handler(void)148 void Default_CpuIntr1_Handler(void)
149 {
150 CM7_CpuIntr_Handler(1);
151 }
152 CY_SECTION_ITCM_END
153
154
155 /*******************************************************************************
156 * Function Name: Default_CM7_CpuIntr2_Handler
157 ****************************************************************************//**
158 *
159 * The Handler is called when the CPU interrupt2 occurs.
160 *
161 *******************************************************************************/
162 CY_SECTION_ITCM_BEGIN
Default_CpuIntr2_Handler(void)163 void Default_CpuIntr2_Handler(void)
164 {
165 CM7_CpuIntr_Handler(2);
166 }
167 CY_SECTION_ITCM_END
168
169
170 /*******************************************************************************
171 * Function Name: Default_CM7_CpuIntr3_Handler
172 ****************************************************************************//**
173 *
174 * The Handler is called when the CPU interrupt3 occurs.
175 *
176 *******************************************************************************/
177 CY_SECTION_ITCM_BEGIN
Default_CpuIntr3_Handler(void)178 void Default_CpuIntr3_Handler(void)
179 {
180 CM7_CpuIntr_Handler(3);
181 }
182 CY_SECTION_ITCM_END
183
184
185 /*******************************************************************************
186 * Function Name: Default_CM7_CpuIntr4_Handler
187 ****************************************************************************//**
188 *
189 * The Handler is called when the CPU interrupt4 occurs.
190 *
191 *******************************************************************************/
192 CY_SECTION_ITCM_BEGIN
Default_CpuIntr4_Handler(void)193 void Default_CpuIntr4_Handler(void)
194 {
195 CM7_CpuIntr_Handler(4);
196 }
197 CY_SECTION_ITCM_END
198
199
200 /*******************************************************************************
201 * Function Name: Default_CM7_CpuIntr5_Handler
202 ****************************************************************************//**
203 *
204 * The Handler is called when the CPU interrupt5 occurs.
205 *
206 *******************************************************************************/
207 CY_SECTION_ITCM_BEGIN
Default_CpuIntr5_Handler(void)208 void Default_CpuIntr5_Handler(void)
209 {
210 CM7_CpuIntr_Handler(5);
211 }
212 CY_SECTION_ITCM_END
213
214
215 /*******************************************************************************
216 * Function Name: Default_CM7_CpuIntr6_Handler
217 ****************************************************************************//**
218 *
219 * The Handler is called when the CPU interrupt6 occurs.
220 *
221 *******************************************************************************/
222 CY_SECTION_ITCM_BEGIN
Default_CpuIntr6_Handler(void)223 void Default_CpuIntr6_Handler(void)
224 {
225 CM7_CpuIntr_Handler(6);
226 }
227 CY_SECTION_ITCM_END
228
229
230 /*******************************************************************************
231 * Function Name: Default_CM7_CpuIntr7_Handler
232 ****************************************************************************//**
233 *
234 * The Handler is called when the CPU interrupt7 occurs.
235 *
236 *******************************************************************************/
237 CY_SECTION_ITCM_BEGIN
Default_CpuIntr7_Handler(void)238 void Default_CpuIntr7_Handler(void)
239 {
240 CM7_CpuIntr_Handler(7);
241 }
242 CY_SECTION_ITCM_END
243
244
245 void NMIException_Handler (void) __attribute__ ((weak, alias("Default_NMIException_Handler")));
246 void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Fault_Handler")));
247 void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Fault_Handler")));
248 void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Fault_Handler")));
249 void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Fault_Handler")));
250 void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
251 void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
252 void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
253 void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
254 void CM7_CpuIntr0_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr0_Handler")));
255 void CM7_CpuIntr1_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr1_Handler")));
256 void CM7_CpuIntr2_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr2_Handler")));
257 void CM7_CpuIntr3_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr3_Handler")));
258 void CM7_CpuIntr4_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr4_Handler")));
259 void CM7_CpuIntr5_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr5_Handler")));
260 void CM7_CpuIntr6_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr6_Handler")));
261 void CM7_CpuIntr7_Handler (void) __attribute__ ((weak, alias("Default_CpuIntr7_Handler")));
262
263 extern const cy_israddress __Vectors[VECTORTABLE_SIZE];
264 #if defined (__GNUC__)
265 _Pragma("GCC diagnostic push")
266 _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
267 #endif /* __GNUC__ */
268 const cy_israddress __Vectors[VECTORTABLE_SIZE] __VECTOR_TABLE_ATTRIBUTE = {
269 (cy_israddress)&__INITIAL_SP,
270 (cy_israddress)Reset_Handler, /* initial PC/Reset */
271 (cy_israddress)NMIException_Handler, /* NMI */
272 (cy_israddress)HardFault_Handler, /* Hard Fault*/
273 (cy_israddress)MemManage_Handler, /* Memory Manage Fault */
274 (cy_israddress)BusFault_Handler, /* Bus Fault */
275 (cy_israddress)UsageFault_Handler, /* Usage Fault */
276 0, /* RESERVED */
277 0, /* RESERVED */
278 0, /* RESERVED */
279 0, /* RESERVED */
280 (cy_israddress)SVC_Handler, /* SVC */
281 (cy_israddress)DebugMon_Handler, /* debug */
282 0, /* RESERVED */
283 (cy_israddress)PendSV_Handler, /* Pend SV */
284 (cy_israddress)SysTick_Handler, /* systick */
285 /* External interrupts */
286 (cy_israddress)CM7_CpuIntr0_Handler,
287 (cy_israddress)CM7_CpuIntr1_Handler,
288 (cy_israddress)CM7_CpuIntr2_Handler,
289 (cy_israddress)CM7_CpuIntr3_Handler,
290 (cy_israddress)CM7_CpuIntr4_Handler,
291 (cy_israddress)CM7_CpuIntr5_Handler,
292 (cy_israddress)CM7_CpuIntr6_Handler,
293 (cy_israddress)CM7_CpuIntr7_Handler,
294 /* Internal interrupts */
295 (cy_israddress)Default_Handler,
296 (cy_israddress)Default_Handler,
297 (cy_israddress)Default_Handler,
298 (cy_israddress)Default_Handler,
299 (cy_israddress)Default_Handler,
300 (cy_israddress)Default_Handler,
301 (cy_israddress)Default_Handler,
302 (cy_israddress)Default_Handler
303 };
304 #if defined (__GNUC__)
305 _Pragma("GCC diagnostic pop")
306 #endif /* __GNUC__ */
307
308 /* Provide empty __WEAK implementation for the low-level initialization
309 routine required by the RTOS-enabled applications.
310 clib-support library provides FreeRTOS-specific implementation:
311 https://github.com/Infineon/clib-support */
312 void cy_toolchain_init(void);
cy_toolchain_init(void)313 __WEAK void cy_toolchain_init(void)
314 {
315 }
316
317 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
318 /* GCC: newlib crt0 _start executes software_init_hook.
319 The cy_toolchain_init hook provided by clib-support library must execute
320 after static data initialization and before static constructors. */
321 void software_init_hook();
software_init_hook()322 void software_init_hook()
323 {
324 cy_toolchain_init();
325 }
326 #elif defined(__ICCARM__)
327 /* Initialize data section */
328 void __iar_data_init3(void);
329
330 /* Call the constructors of all global objects */
331 void __iar_dynamic_initialization(void);
332
333 /* Define strong version to return zero for __iar_program_start
334 to skip data sections initialization (__iar_data_init3). */
335 int __low_level_init(void);
__low_level_init(void)336 int __low_level_init(void)
337 {
338 return 0;
339 }
340 #else
341 /**/
342 #endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */
343
344
345 // Reset Handler
Reset_Handler(void)346 void Reset_Handler(void)
347 {
348 /* disable global interrupt */
349 __disable_irq();
350
351 /* Allow write access to Vector Table Offset Register and ITCM/DTCM configuration register
352 * (CPUSS_CM7_X_CTL.PPB_LOCK[3] and CPUSS_CM7_X_CTL.PPB_LOCK[1:0]) */
353 #ifdef CORE_NAME_CM7_1
354 CPUSS->CM7_1_CTL &= ~(0xB);
355 #elif CORE_NAME_CM7_0
356 CPUSS->CM7_0_CTL &= ~(0xB);
357 #else
358 #error "Not valid"
359 #endif
360
361 __DSB();
362 __ISB();
363
364 /* Enable ITCM and DTCM */
365 SCB->ITCMCR = SCB->ITCMCR | 0x7; /* Set ITCMCR.EN, .RMW and .RETEN fields */
366 SCB->DTCMCR = SCB->DTCMCR | 0x7; /* Set DTCMCR.EN, .RMW and .RETEN fields */
367
368 #ifdef CORE_NAME_CM7_0
369 CPUSS_CM7_0_CTL |= (0x1 << CPUSS_CM7_0_CTL_INIT_TCM_EN_Pos);
370 CPUSS_CM7_0_CTL |= (0x2 << CPUSS_CM7_0_CTL_INIT_TCM_EN_Pos);
371 CPUSS_CM7_0_CTL |= (0x1 << CPUSS_CM7_0_CTL_INIT_RMW_EN_Pos);
372 CPUSS_CM7_0_CTL |= (0x2 << CPUSS_CM7_0_CTL_INIT_RMW_EN_Pos);
373 #elif CORE_NAME_CM7_0
374 CPUSS_CM7_1_CTL |= (0x1 << CPUSS_CM7_1_CTL_INIT_TCM_EN_Pos);
375 CPUSS_CM7_1_CTL |= (0x2 << CPUSS_CM7_1_CTL_INIT_TCM_EN_Pos);
376 CPUSS_CM7_1_CTL |= (0x1 << CPUSS_CM7_1_CTL_INIT_RMW_EN_Pos);
377 CPUSS_CM7_1_CTL |= (0x2 << CPUSS_CM7_1_CTL_INIT_RMW_EN_Pos);
378 #endif
379
380 // ITCMCR EN/RMW/RETEN enabled to access ITCM
381 __UNALIGNED_UINT32_WRITE(((void const *)0xE000EF90), 0x2F);
382 // DTCMCR EN/RMW/RETEN enabled to access DTCM
383 __UNALIGNED_UINT32_WRITE(((void const *)0xE000EF94), 0x2F);
384
385 /* Enable FPU if present */
386 FpuEnable();
387
388 /* copy vector table */
389 for (uint32_t count = 0; count < VECTORTABLE_SIZE; count++)
390 {
391 __ramVectors[count] =__Vectors[count];
392 }
393
394 SCB->VTOR = (uint32_t)__ramVectors;
395
396 __DSB();
397 __ISB();
398
399 #ifdef ENABLE_CM7_INSTRUCTION_CACHE
400 SCB_EnableICache();
401 #endif /* ENABLE_CM7_INSTRUCTION_CACHE */
402 #ifdef ENABLE_CM7_DATA_CACHE
403 SCB_EnableDCache();
404 #else
405 // Ensure that the undefined valid bits in the cache RAM are set to invalid if cache is disabled, because the application
406 // may call further cache maintenance functions (e.g. SCB_CleanInvalidateDCache) independent of the "cache enabled" state.
407 SCB_InvalidateDCache();
408 #endif /* ENABLE_CM7_DATA_CACHE */
409
410 SystemInit();
411
412 #if defined(__ICCARM__)
413 /* Initialize data section */
414 __iar_data_init3();
415
416 /* Initialization hook for RTOS environment */
417 cy_toolchain_init();
418
419 /* Call the constructors of all global objects */
420 __iar_dynamic_initialization();
421 #endif
422
423 /* c-runtime */
424 __PROGRAM_START();
425 }
426
427
428 #if defined(__cplusplus)
429 }
430 #endif
431
432
433 /* [] END OF FILE */
434