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