1 /***************************************************************************//**
2 * \file system_cm0plus.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 * Function Name: SystemInit
27 ****************************************************************************//**
28 *
29 * Initializes the system:
30 * - Unlocks and disables WDT.
31 * - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
32 * - Calls \ref SystemCoreClockUpdate().
33 *
34 *******************************************************************************/
35 
36 
37 #include <stdbool.h>
38 #include "system_cat1c.h"
39 #include "cy_device.h"
40 #include "cy_device_headers.h"
41 #include "cy_syslib.h"
42 #include "cy_sysclk.h"
43 #include "cy_wdt.h"
44 #include "cmsis_compiler.h"
45 
46 #define CY_SYS_CM7_PWR_CTL_KEY_OPEN  (0x05FAUL)
47 #define CY_SYS_CM7_PWR_CTL_KEY_CLOSE (0xFA05UL)
48 
49 void Cy_DefaultUserHandler(void);
50 static void CopyVectorTable(void);
51 static void InitMemoryEccClearArea(uint32_t u32StartAddr, uint32_t u32EndAddr);
52 static void InitMemoryEcc(void);
53 static void EnableEcc(void);
54 static void PrepareSystemCallInfrastructure(void);
55 
56 #define DEFAULT_HANDLER_NAME                            Cy_DefaultUserHandler
57 
58 CY_NOINIT cy_israddress Cy_SystemIrqUserTable[CPUSS_SYSTEM_INT_NR] ;
59 
60 CY_NOINIT cy_israddress * Cy_SysInt_SystemIrqUserTableRamPointer ;
61 
62 extern uint32_t Cy_u32StartupStackStartAddress;
63 extern uint32_t Cy_u32StartupStackEndAddress;
64 extern void * __Vectors;
65 extern void * __Vectors_Size;
66 extern cy_israddress __ramVectors[];
67 
68 /*******************************************************************************
69 * SystemCoreClockUpdate()
70 *******************************************************************************/
71 
72 /** Default HFClk frequency in Hz */
73 #define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT       (8000000UL)
74 
75 /** Default PeriClk frequency in Hz */
76 #define CY_CLK_PERICLK_FREQ_HZ_DEFAULT      (8000000UL)
77 
78 /** Default system core frequency in Hz */
79 #define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT       (100000000UL)
80 
81 /** Holds the CLK_SLOW(Cortex-M0+) or CLK_FAST0(Cortex-M7_0) or CLK_FAST(Cortex-M7_1) system core clock */
82 CY_NOINIT uint32_t SystemCoreClock ;
83 
84 /** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
85 CY_NOINIT uint32_t cy_Hfclk0FreqHz ;
86 
87 /** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
88 CY_NOINIT uint32_t cy_PeriClkFreqHz ;
89 
90 /** Holds the AHB frequency. Updated by \ref SystemCoreClockUpdate(). */
91 CY_NOINIT uint32_t cy_AhbFreqHz ;
92 
93 /*******************************************************************************
94 * SystemCoreClockUpdate (void)
95 *******************************************************************************/
96 
97 /* Do not use these definitions directly in your application */
98 #define CY_DELAY_MS_OVERFLOW_THRESHOLD  (0x8000u)
99 #define CY_DELAY_1K_THRESHOLD           (1000u)
100 #define CY_DELAY_1K_MINUS_1_THRESHOLD   (CY_DELAY_1K_THRESHOLD - 1u)
101 #define CY_DELAY_1M_THRESHOLD           (1000000u)
102 #define CY_DELAY_1M_MINUS_1_THRESHOLD   (CY_DELAY_1M_THRESHOLD - 1u)
103 
104 CY_NOINIT uint32_t cy_delayFreqHz ;
105 
106 CY_NOINIT uint32_t cy_delayFreqKhz ;
107 
108 CY_NOINIT uint32_t cy_delayFreqMhz ;
109 
110 
111 /*****************************************************************************
112 * Global variable definitions (declared in header file with 'extern')
113 *****************************************************************************/
114 // CAUTION: Static or global initialized and non-const variables will not have their init value yet!
115 
116 
117 #define SRAM_BEGIN_ADDR                     (BASE_SRAM_CM0P)
118 #define SRAM_END_ADDR                       (CY_SRAM_BASE + CY_SRAM_SIZE)
119 #define STARTUP_STACK_OFFSEST               (0x100) /* 32 2-words are cleaned by startup */
120 
121 #define ECC_INIT_WIDTH_BYTES                8
122 #define SROM_VECTOR_TABLE_BASE_ADDRESS      0x00000000
123 #define VECTOR_TABLE_OFFSET_IRQ0            0x40
124 #define VECTOR_TABLE_OFFSET_IRQ1            0x44
125 
126 #if defined(__ARMCC_VERSION)
127 extern unsigned int Image$$ARM_LIB_STACK$$ZI$$Limit;            /* for (default) One Region model */
128 extern void __main(void);
129 #elif defined (__GNUC__)
130 extern unsigned int __StackTop;
131 #elif defined (__ICCARM__)
132 extern unsigned int CSTACK$$Limit;                      /* for (default) One Region model */
133 #endif
134 
135 /******************************************************************************/
136 
137 /** Define an abstract type for the chosen ECC initialization granularity */
138 typedef uint64_t  ecc_init_width_t;
139 
140 /* Provide empty __WEAK implementation for the low-level initialization
141    routine required by the RTOS-enabled applications.
142    clib-support library provides FreeRTOS-specific implementation:
143    https://github.com/Infineon/clib-support */
144 void cy_toolchain_init(void);
cy_toolchain_init(void)145 __WEAK void cy_toolchain_init(void)
146 {
147 }
148 
149 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
150 /* GCC: newlib crt0 _start executes software_init_hook.
151    The cy_toolchain_init hook provided by clib-support library must execute
152    after static data initialization and before static constructors. */
153 void software_init_hook();
software_init_hook()154 void software_init_hook()
155 {
156     cy_toolchain_init();
157 }
158 #elif defined(__ICCARM__)
159 /* Initialize data section */
160 void __iar_data_init3(void);
161 
162 /* Call the constructors of all global objects */
163 void __iar_dynamic_initialization(void);
164 
165 /* Define strong version to return zero for __iar_program_start
166    to skip data sections initialization (__iar_data_init3). */
167 int __low_level_init(void);
__low_level_init(void)168 int __low_level_init(void)
169 {
170     return 0;
171 }
172 #else
173 /**/
174 #endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */
175 
176 
CyMain(void)177 void CyMain(void)
178 {
179 #if defined(__ICCARM__)
180     /* Initialize data section */
181     __iar_data_init3();
182 
183     /* Initialization hook for RTOS environment  */
184     cy_toolchain_init();
185 
186     /* Call the constructors of all global objects */
187     __iar_dynamic_initialization();
188 #endif
189 
190     __PROGRAM_START();
191 }
192 
193 
SystemInit(void)194 void SystemInit(void)
195 {
196     /* startup Init */
197     InitMemoryEcc();
198     EnableEcc();
199     CopyVectorTable();
200     PrepareSystemCallInfrastructure();
201     /* startup Init done */
202 
203     SystemIrqInit();
204 
205     Cy_WDT_Unlock();
206     Cy_WDT_Disable();
207 
208     Cy_SystemInit();
209     SystemCoreClockUpdate();
210 
211 }
212 
213 
214 /*******************************************************************************
215 * Function Name: EnableEcc
216 ****************************************************************************//**
217 *
218 * The function is called during device startup.
219 *
220 *******************************************************************************/
EnableEcc(void)221 static void EnableEcc(void)
222 {
223     /* Enable ECC checking in SRAM controllers again (had been switched off by assembly startup code) */
224     CPUSS->RAM0_CTL0 &= ~(0x80000); /* set bit 19 to 0 */
225 #if (CPUSS_RAMC1_PRESENT == 1u)
226     CPUSS->RAM1_CTL0 &= ~(0x80000); /* set bit 19 to 0 */
227 #endif
228 #if (CPUSS_RAMC2_PRESENT == 1u)
229     CPUSS->RAM2_CTL0 &= ~(0x80000); /* set bit 19 to 0 */
230 #endif
231 }
232 
233 
234 /*******************************************************************************
235 * Function Name: InitMemoryEcc
236 ****************************************************************************//**
237 *
238 * The function is called during device startup.
239 *
240 *******************************************************************************/
InitMemoryEcc(void)241 static void InitMemoryEcc(void)
242 {
243     uint32_t *sp = (uint32_t*)&__INITIAL_SP;
244     uint32_t u32StckLow = (uint32_t)sp - STARTUP_STACK_OFFSEST;
245     uint32_t u32StackHigh = (uint32_t)sp;
246 
247     InitMemoryEccClearArea(SRAM_BEGIN_ADDR, u32StckLow);
248     InitMemoryEccClearArea(u32StackHigh, SRAM_END_ADDR);
249 }
250 
251 
252 /**
253  *****************************************************************************
254  ** Clears an area by writing '0' using a pointer of type #ecc_init_width_t
255  **
256  ** \param u32StartAddr    Start address of area to be cleared,
257  **                        must be aligned to #ECC_INIT_WIDTH_BYTES
258  ** \param u32EndAddr      Last address within area to be cleared, (u32EndAddr+1)
259  **                        must be aligned to #ECC_INIT_WIDTH_BYTES
260  **
261  ** \return none
262  *****************************************************************************/
InitMemoryEccClearArea(uint32_t u32StartAddr,uint32_t u32EndAddr)263 static void InitMemoryEccClearArea(uint32_t u32StartAddr, uint32_t u32EndAddr)
264 {
265     volatile ecc_init_width_t * pRam = (volatile ecc_init_width_t *) u32StartAddr;
266     ecc_init_width_t Zero = 0;
267 
268     for(; (uint32_t)pRam < u32EndAddr; pRam++)
269     {
270         // Note: Even if ecc_init_width_t is uint64_t, this will be compiled as two 32-bit accesses
271         //       in case of CM0+, because there is no STRD instruction specified in ARMv6-M Thumb
272         *pRam = Zero;
273     }
274 }
275 
276 
277 /**
278  *****************************************************************************
279  ** Copies the vector table from ROM to RAM and updates the VTOR (CMx vector
280  ** table base register) accordingly
281  **
282  ** \return none
283  *****************************************************************************/
CopyVectorTable(void)284 static void CopyVectorTable(void)
285 {
286     const uint8_t    u8NrOfVectors = (uint8_t) ((uint32_t) &__Vectors_Size / 4);
287     uint32_t * const pu32RamTable  = (uint32_t *) __ramVectors;
288     uint32_t * const pu32RomTable  = (uint32_t *) (&__Vectors);
289 
290 
291     for(uint8_t u8Index = 0; u8Index < u8NrOfVectors; u8Index++)
292     {
293         pu32RamTable[u8Index] = pu32RomTable[u8Index];
294     }
295 
296     SCB->VTOR = (uint32_t) pu32RamTable;
297 }
298 
299 /**
300  *****************************************************************************
301  ** Prepares necessary settings to get SROM system calls working
302  **
303  ** \return none
304  *****************************************************************************/
PrepareSystemCallInfrastructure(void)305 static void PrepareSystemCallInfrastructure(void)
306 {
307     const uint8_t u8Irq0Index = (uint8_t) (VECTOR_TABLE_OFFSET_IRQ0 / 4);
308     const uint8_t u8Irq1Index = (uint8_t) (VECTOR_TABLE_OFFSET_IRQ1 / 4);
309     uint32_t * const pu32RamTable   = (uint32_t *) __ramVectors;
310     uint32_t * const pu32SromTable  = (uint32_t *) SROM_VECTOR_TABLE_BASE_ADDRESS;
311 
312     // Use IRQ0 and IRQ1 handlers from SROM vector table
313     pu32RamTable[u8Irq0Index] = pu32SromTable[u8Irq0Index];
314     pu32RamTable[u8Irq1Index] = pu32SromTable[u8Irq1Index];
315 
316     NVIC_SetPriority(NvicMux0_IRQn, 1);
317     NVIC_SetPriority(NvicMux1_IRQn, 0);
318     NVIC_EnableIRQ(NvicMux0_IRQn);
319     NVIC_EnableIRQ(NvicMux1_IRQn);
320 
321     // Only item left is clearing of PRIMASK:
322     // This should be done by the application at a later point in time (e.g. in main())
323 }
324 
325 /*******************************************************************************
326 * Function Name: SystemIrqInit
327 ****************************************************************************//**
328 *
329 * The function is called during device startup.
330 *
331 *******************************************************************************/
SystemIrqInit(void)332 void SystemIrqInit(void)
333 {
334     for (int i=0; i<(int)CPUSS_SYSTEM_INT_NR; i++)
335     {
336         Cy_SystemIrqUserTable[i] = DEFAULT_HANDLER_NAME;
337     }
338 
339     Cy_SysInt_SystemIrqUserTableRamPointer = Cy_SystemIrqUserTable;
340 }
341 
342 /*******************************************************************************
343 * Function Name: Cy_SystemInit
344 ****************************************************************************//**
345 *
346 * The function is called during device startup.
347 *
348 *******************************************************************************/
Cy_SystemInit(void)349 __WEAK void Cy_SystemInit(void)
350 {
351      /* Empty weak function. The actual implementation to be in the app
352       * generated strong function.
353      */
354 }
355 
356 /*******************************************************************************
357 * Function Name: SystemCoreClockUpdate
358 ****************************************************************************//**
359 *
360 * Gets core clock frequency and updates \ref SystemCoreClock.
361 *
362 * Updates global variables used by the \ref Cy_SysLib_Delay(), \ref
363 * Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles().
364 *
365 *******************************************************************************/
SystemCoreClockUpdate(void)366 void SystemCoreClockUpdate (void)
367 {
368     uint32_t pathFreqHz;
369     uint32_t clkHfPath;
370 
371     /* Get frequency for the high-frequency clock*/
372     clkHfPath = CY_SYSCLK_CLK_CORE_HF_PATH_NUM;
373 
374     pathFreqHz = Cy_SysClk_ClkHfGetFrequency(clkHfPath);
375 
376     SystemCoreClock = pathFreqHz;
377 
378     cy_Hfclk0FreqHz = SystemCoreClock;
379 
380     /* Get Peripheral clock Frequency*/
381     clkHfPath = CY_SYSCLK_CLK_PERI_HF_PATH_NUM;
382 
383     pathFreqHz = Cy_SysClk_ClkHfGetFrequency(clkHfPath);
384 
385     cy_PeriClkFreqHz = pathFreqHz;
386 
387     /* Sets clock frequency for Delay API */
388     cy_delayFreqHz = SystemCoreClock;
389     cy_delayFreqMhz = (uint32_t)((cy_delayFreqHz + CY_DELAY_1M_MINUS_1_THRESHOLD) / CY_DELAY_1M_THRESHOLD);
390     cy_delayFreqKhz = (cy_delayFreqHz + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD;
391 
392     /* Get the frequency of AHB source, CLK HF0 is the source for AHB*/
393     cy_AhbFreqHz = Cy_SysClk_ClkHfGetFrequency(0UL);
394 }
395 
396 
Cy_SysGetCM7Status(uint8_t core)397 uint32_t Cy_SysGetCM7Status(uint8_t core)
398 {
399     uint32_t regValue = 0u;
400 
401     CY_ASSERT(core < CORE_MAX);
402 
403     if(core == CORE_CM7_0)
404     {
405         /* Get current power mode */
406         regValue = _FLD2VAL(CPUSS_CM7_0_PWR_CTL_PWR_MODE, CPUSS->CM7_0_PWR_CTL);
407     }
408     else if(core == CORE_CM7_1)
409     {
410         /* Get current power mode */
411         regValue = _FLD2VAL(CPUSS_CM7_1_PWR_CTL_PWR_MODE, CPUSS->CM7_1_PWR_CTL);
412     }
413     else
414     {
415         /* */
416     }
417 
418     return (regValue);
419 }
420 
421 
Cy_SysEnableCM7(uint8_t core,uint32_t vectorTableOffset)422 void Cy_SysEnableCM7(uint8_t core, uint32_t vectorTableOffset)
423 {
424     uint32_t cmStatus;
425     uint32_t interruptState;
426     uint32_t regValue;
427 
428     CY_ASSERT(core < CORE_MAX);
429 
430     interruptState = Cy_SaveIRQ();
431 
432     cmStatus = Cy_SysGetCM7Status(core);
433     if(cmStatus == CY_SYS_CM7_STATUS_ENABLED)
434     {
435         // Set core into reset first, so that new settings can get effective
436         // This branch is e.g. entered if a debugger is connected that would power-up the CM7,
437         // but let it run in ROM boot or pause its execution by keeping CPU_WAIT bit set.
438         Cy_SysResetCM7(core);
439     }
440 
441     // CLK_HF1, by default is disabled for use by CM7_0/1, hence enable
442     SRSS->CLK_ROOT_SELECT[1] |= SRSS_CLK_ROOT_SELECT_ENABLE_Msk;
443 
444     if(core == CORE_CM7_0)
445     {
446         /* Adjust the vector address */
447         CPUSS->CM7_0_VECTOR_TABLE_BASE = vectorTableOffset;
448 
449         /* Enable the Power Control Key */
450         regValue = CPUSS->CM7_0_PWR_CTL & ~(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_0_PWR_CTL_PWR_MODE_Msk);
451         regValue |= _VAL2FLD(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
452         regValue |= CY_SYS_CM7_STATUS_ENABLED;
453         CPUSS->CM7_0_PWR_CTL = regValue;
454 
455         while((CPUSS->CM7_0_STATUS & CPUSS_CM7_0_STATUS_PWR_DONE_Msk) == 0UL)
456         {
457             /* Wait for the power mode to take effect */
458         }
459 
460         CPUSS->CM7_0_CTL &= ~(0x1 << CPUSS_CM7_0_CTL_CPU_WAIT_Pos);
461     }
462     else if(core == CORE_CM7_1)
463     {
464         /* Adjust the vector address */
465         CPUSS->CM7_1_VECTOR_TABLE_BASE = vectorTableOffset;
466 
467         /* Enable the Power Control Key */
468         regValue = CPUSS->CM7_1_PWR_CTL & ~(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_1_PWR_CTL_PWR_MODE_Msk);
469         regValue |= _VAL2FLD(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
470         regValue |= CY_SYS_CM7_STATUS_ENABLED;
471         CPUSS->CM7_1_PWR_CTL = regValue;
472 
473         while((CPUSS->CM7_1_STATUS & CPUSS_CM7_1_STATUS_PWR_DONE_Msk) == 0UL)
474         {
475             /* Wait for the power mode to take effect */
476         }
477 
478         CPUSS->CM7_1_CTL &= ~(0x1 << CPUSS_CM7_1_CTL_CPU_WAIT_Pos);
479     }
480 
481     Cy_RestoreIRQ(interruptState);
482 
483 }
484 
485 
Cy_SysDisableCM7(uint8_t core)486 void Cy_SysDisableCM7(uint8_t core)
487 {
488     uint32_t regValue;
489 
490     CY_ASSERT(core < CORE_MAX);
491 
492     if(core == CORE_CM7_0)
493     {
494         regValue = CPUSS->CM7_0_PWR_CTL & ~(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_0_PWR_CTL_PWR_MODE_Msk);
495         regValue |= _VAL2FLD(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
496         regValue |= CY_SYS_CM7_STATUS_DISABLED;
497         CPUSS->CM7_0_PWR_CTL = regValue;
498 
499         while((CPUSS->CM7_0_STATUS & CPUSS_CM7_0_STATUS_PWR_DONE_Msk) == 0UL)
500         {
501             /* Wait for the power mode to take effect */
502         }
503 
504     }
505     else if(core == CORE_CM7_1)
506     {
507         regValue = CPUSS->CM7_1_PWR_CTL & ~(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_1_PWR_CTL_PWR_MODE_Msk);
508         regValue |= _VAL2FLD(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
509         regValue |= CY_SYS_CM7_STATUS_DISABLED;
510         CPUSS->CM7_1_PWR_CTL = regValue;
511 
512         while((CPUSS->CM7_1_STATUS & CPUSS_CM7_0_STATUS_PWR_DONE_Msk) == 0UL)
513         {
514             /* Wait for the power mode to take effect */
515         }
516     }
517 }
518 
519 
Cy_SysRetainCM7(uint8_t core)520 void Cy_SysRetainCM7(uint8_t core)
521 {
522     uint32_t cmStatus;
523     uint32_t  interruptState;
524     uint32_t regValue;
525 
526     interruptState = Cy_SaveIRQ();
527 
528     cmStatus = Cy_SysGetCM7Status(core);
529     if(cmStatus == CY_SYS_CM7_STATUS_ENABLED)
530     {
531         if(core == CORE_CM7_0)
532         {
533             regValue = CPUSS->CM7_0_PWR_CTL & ~(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_0_PWR_CTL_PWR_MODE_Msk);
534             regValue |= _VAL2FLD(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
535             regValue |= CY_SYS_CM7_STATUS_RETAINED;
536             CPUSS->CM7_0_PWR_CTL = regValue;
537         }
538         else if(core == CORE_CM7_1)
539         {
540             regValue = CPUSS->CM7_1_PWR_CTL & ~(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_1_PWR_CTL_PWR_MODE_Msk);
541             regValue |= _VAL2FLD(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
542             regValue |= CY_SYS_CM7_STATUS_RETAINED;
543             CPUSS->CM7_1_PWR_CTL = regValue;
544         }
545     }
546 
547     Cy_RestoreIRQ(interruptState);
548 }
549 
550 
Cy_SysResetCM7(uint8_t core)551 void Cy_SysResetCM7(uint8_t core)
552 {
553     uint32_t regValue;
554 
555     CY_ASSERT(core < CORE_MAX);
556 
557     if(core == CORE_CM7_0)
558     {
559         regValue = CPUSS->CM7_0_PWR_CTL & ~(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_0_PWR_CTL_PWR_MODE_Msk);
560         regValue |= _VAL2FLD(CPUSS_CM7_0_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
561         regValue |= CY_SYS_CM7_STATUS_RESET;
562         CPUSS->CM7_0_PWR_CTL = regValue;
563 
564         while((CPUSS->CM7_0_STATUS & CPUSS_CM7_0_STATUS_PWR_DONE_Msk) == 0UL)
565         {
566             /* Wait for the power mode to take effect */
567         }
568     }
569     else if(core == CORE_CM7_1)
570     {
571         regValue = CPUSS->CM7_1_PWR_CTL & ~(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT_Msk | CPUSS_CM7_1_PWR_CTL_PWR_MODE_Msk);
572         regValue |= _VAL2FLD(CPUSS_CM7_1_PWR_CTL_VECTKEYSTAT, CY_SYS_CM7_PWR_CTL_KEY_OPEN);
573         regValue |= CY_SYS_CM7_STATUS_RESET;
574         CPUSS->CM7_1_PWR_CTL = regValue;
575 
576         while((CPUSS->CM7_1_STATUS & CPUSS_CM7_1_STATUS_PWR_DONE_Msk) == 0UL)
577         {
578             /* Wait for the power mode to take effect */
579         }
580     }
581 }
582 
583 
584 /*******************************************************************************
585 * Function Name: Cy_DefaultUserHandler
586 ****************************************************************************//**
587 *
588 * The Handler is called when the CPU attempts to call IRQ that has not been mapped to user functions.
589 *
590 *******************************************************************************/
Cy_DefaultUserHandler(void)591 void Cy_DefaultUserHandler(void)
592 {
593     // This IRQ occurred because CPU attempted to call IRQ that has not been mapped to user function
594     while(1);
595 }
596 
597 
598 /*******************************************************************************
599 * Function Name: CM0P_CpuIntr_HandlerInline
600 ****************************************************************************//**
601 *
602 * The Inline handler for CPU interrupt.
603 * The system interrupt mapped to CPU interrupt will be fetched and executed
604 *
605 *******************************************************************************/
CM0P_CpuIntr_HandlerInline(uint8_t intrNum)606 __STATIC_FORCEINLINE void CM0P_CpuIntr_HandlerInline(uint8_t intrNum)
607 {
608     uint32_t system_int_idx;
609     cy_israddress handler;
610 
611     if (_FLD2VAL(CPUSS_CM0_INT0_STATUS_SYSTEM_INT_VALID, CPUSS_CM0_INT_STATUS_BASE[intrNum]))
612     {
613         system_int_idx = _FLD2VAL(CPUSS_CM0_INT0_STATUS_SYSTEM_INT_IDX, CPUSS_CM0_INT_STATUS_BASE[intrNum]);
614         handler = Cy_SystemIrqUserTable[system_int_idx];
615         if(handler != NULL)
616         handler(); // jump to system interrupt handler
617     }
618     else
619     {
620         // Triggered by software or because of software cleared a peripheral interrupt flag but did not clear the pending flag at NVIC
621     }
622     NVIC_ClearPendingIRQ((IRQn_Type)intrNum);
623 }
624 
625 
626 /*******************************************************************************
627 * Function Name: CpuIntr2_Handler
628 ****************************************************************************//**
629 *
630 * The Handler is called when the CPU interrupt2 occurs.
631 *
632 *******************************************************************************/
CM0P_CpuIntr2_Handler(void)633 void CM0P_CpuIntr2_Handler(void)
634 {
635     CM0P_CpuIntr_HandlerInline(2);
636 }
637 
638 
639 /*******************************************************************************
640 * Function Name: CpuIntr3_Handler
641 ****************************************************************************//**
642 *
643 * The Handler is called when the CPU interrupt3 occurs.
644 *
645 *******************************************************************************/
CM0P_CpuIntr3_Handler(void)646 void CM0P_CpuIntr3_Handler(void)
647 {
648     CM0P_CpuIntr_HandlerInline(3);
649 }
650 
651 
652 /*******************************************************************************
653 * Function Name: CpuIntr4_Handler
654 ****************************************************************************//**
655 *
656 * The Handler is called when the CPU interrupt4 occurs.
657 *
658 *******************************************************************************/
CM0P_CpuIntr4_Handler(void)659 void CM0P_CpuIntr4_Handler(void)
660 {
661     CM0P_CpuIntr_HandlerInline(4);
662 }
663 
664 /*******************************************************************************
665 * Function Name: CpuIntr5_Handler
666 ****************************************************************************//**
667 *
668 * The Handler is called when the CPU interrupt5 occurs.
669 *
670 *******************************************************************************/
CM0P_CpuIntr5_Handler(void)671 void CM0P_CpuIntr5_Handler(void)
672 {
673     CM0P_CpuIntr_HandlerInline(5);
674 }
675 
676 
677 /*******************************************************************************
678 * Function Name: CpuIntr6_Handler
679 ****************************************************************************//**
680 *
681 * The Handler is called when the CPU interrupt6 occurs.
682 *
683 *******************************************************************************/
CM0P_CpuIntr6_Handler(void)684 void CM0P_CpuIntr6_Handler(void)
685 {
686     CM0P_CpuIntr_HandlerInline(6);
687 }
688 
689 
690 /*******************************************************************************
691 * Function Name: CpuIntr7_Handler
692 ****************************************************************************//**
693 *
694 * The Handler is called when the CPU interrupt7 occurs.
695 *
696 *******************************************************************************/
CM0P_CpuIntr7_Handler(void)697 void CM0P_CpuIntr7_Handler(void)
698 {
699     CM0P_CpuIntr_HandlerInline(7);
700 }
701 
702 
703