1 /***************************************************************************//**
2 * \file system_psoc6_cm4.c
3 * \version 2.90.1
4 *
5 * The device system-source file.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2016-2020 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 #include <stdbool.h>
26 #include "system_psoc6.h"
27 #include "cy_device.h"
28 #include "cy_device_headers.h"
29 #include "cy_syslib.h"
30 #include "cy_sysclk.h"
31 #include "cy_wdt.h"
32 
33 #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
34     #include "cy_ipc_sema.h"
35     #include "cy_ipc_pipe.h"
36     #include "cy_ipc_drv.h"
37 
38     #if defined(CY_DEVICE_PSOC6ABLE2)
39         #include "cy_flash.h"
40     #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
41 #endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
42 
43 #if defined(CY_DEVICE_SECURE)
44     #include "cy_pra.h"
45 #endif /* defined(CY_DEVICE_SECURE) */
46 
47 
48 /*******************************************************************************
49 * SystemCoreClockUpdate()
50 *******************************************************************************/
51 
52 /** Default HFClk frequency in Hz */
53 #define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT       (8000000UL)
54 
55 /** Default PeriClk frequency in Hz */
56 #define CY_CLK_PERICLK_FREQ_HZ_DEFAULT      (4000000UL)
57 
58 /** Default FastClk system core frequency in Hz */
59 #define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT       (8000000UL)
60 
61 
62 /**
63 * Holds the SlowClk (Cortex-M0+) or FastClk (Cortex-M4) system core clock,
64 * which is the system clock frequency supplied to the SysTick timer and the
65 * processor core clock.
66 * This variable implements CMSIS Core global variable.
67 * Refer to the [CMSIS documentation]
68 * (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration")
69 * for more details.
70 * This variable can be used by debuggers to query the frequency
71 * of the debug timer or to configure the trace clock speed.
72 *
73 * \attention Compilers must be configured to avoid removing this variable in case
74 * the application program is not using it. Debugging systems require the variable
75 * to be physically present in memory so that it can be examined to configure the debugger. */
76 uint32_t SystemCoreClock = CY_CLK_SYSTEM_FREQ_HZ_DEFAULT;
77 
78 /** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
79 uint32_t cy_Hfclk0FreqHz  = CY_CLK_HFCLK0_FREQ_HZ_DEFAULT;
80 
81 /** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
82 uint32_t cy_PeriClkFreqHz = CY_CLK_PERICLK_FREQ_HZ_DEFAULT;
83 
84 /** Holds the Alternate high frequency clock in Hz. Updated by \ref Cy_BLE_EcoConfigure(). */
85 uint32_t cy_BleEcoClockFreqHz = 0UL;
86 
87 /* SCB->CPACR */
88 #define SCB_CPACR_CP10_CP11_ENABLE      (0xFUL << 20u)
89 
90 
91 /*******************************************************************************
92 * SystemInit()
93 *******************************************************************************/
94 
95 /* CLK_FLL_CONFIG default values */
96 #define CY_FB_CLK_FLL_CONFIG_VALUE      (0x01000000u)
97 #define CY_FB_CLK_FLL_CONFIG2_VALUE     (0x00020001u)
98 #define CY_FB_CLK_FLL_CONFIG3_VALUE     (0x00002800u)
99 #define CY_FB_CLK_FLL_CONFIG4_VALUE     (0x000000FFu)
100 
101 /* IPC_STRUCT7->DATA configuration */
102 #define CY_STARTUP_CM0_DP_STATE         (0x2uL)
103 #define CY_STARTUP_IPC7_DP_OFFSET       (0x28u)
104 
105 
106 /*******************************************************************************
107 * SystemCoreClockUpdate (void)
108 *******************************************************************************/
109 
110 /* Do not use these definitions directly in your application */
111 #define CY_DELAY_MS_OVERFLOW_THRESHOLD  (0x8000u)
112 #define CY_DELAY_1K_THRESHOLD           (1000u)
113 #define CY_DELAY_1M_THRESHOLD           (1000000u)
114 
115 uint32_t cy_delayFreqKhz  = CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1K_THRESHOLD);
116 
117 uint8_t cy_delayFreqMhz  = (uint8_t)CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1M_THRESHOLD);
118 
119 uint32_t cy_delay32kMs    = CY_DELAY_MS_OVERFLOW_THRESHOLD *
120                             CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1K_THRESHOLD);
121 
122 
123 /*******************************************************************************
124 * Function Name: SystemInit
125 ****************************************************************************//**
126 * \cond
127 * Initializes the system:
128 * - Restores FLL registers to the default state for single core devices.
129 * - Unlocks and disables WDT.
130 * - Calls Cy_PDL_Init() function to define the driver library.
131 * - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
132 * - Calls \ref Cy_PRA_Init() for PSoC 64 devices.
133 * - Calls \ref SystemCoreClockUpdate().
134 * \endcond
135 *******************************************************************************/
SystemInit(void)136 void SystemInit(void)
137 {
138     Cy_PDL_Init(CY_DEVICE_CFG);
139 
140 #ifdef __CM0P_PRESENT
141     #if (__CM0P_PRESENT == 0)
142         /* Restore FLL registers to the default state as they are not restored by the ROM code */
143         uint32_t copy = SRSS->CLK_FLL_CONFIG;
144         copy &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
145         SRSS->CLK_FLL_CONFIG = copy;
146 
147         copy = SRSS->CLK_ROOT_SELECT[0u];
148         copy &= ~SRSS_CLK_ROOT_SELECT_ROOT_DIV_Msk; /* Set ROOT_DIV = 0*/
149         SRSS->CLK_ROOT_SELECT[0u] = copy;
150 
151         SRSS->CLK_FLL_CONFIG  = CY_FB_CLK_FLL_CONFIG_VALUE;
152         SRSS->CLK_FLL_CONFIG2 = CY_FB_CLK_FLL_CONFIG2_VALUE;
153         SRSS->CLK_FLL_CONFIG3 = CY_FB_CLK_FLL_CONFIG3_VALUE;
154         SRSS->CLK_FLL_CONFIG4 = CY_FB_CLK_FLL_CONFIG4_VALUE;
155 
156         /* Unlock and disable WDT */
157         Cy_WDT_Unlock();
158         Cy_WDT_Disable();
159     #endif /* (__CM0P_PRESENT == 0) */
160 #endif /* __CM0P_PRESENT */
161 
162     Cy_SystemInit();
163     SystemCoreClockUpdate();
164 
165 #ifdef __CM0P_PRESENT
166     #if (__CM0P_PRESENT == 0)
167         /* Configure data register (as CM0p in deep sleep state) of IPC structure #7, reserved for the Deep-Sleep operations. */
168         REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = (CY_STARTUP_CM0_DP_STATE <<
169                                                                     CY_STARTUP_IPC7_DP_OFFSET);
170 
171         /* Release IPC structure #7 to avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering. */
172         REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0UL;
173     #endif /* (__CM0P_PRESENT == 0) */
174 #endif /* __CM0P_PRESENT */
175 
176 #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
177 
178 #ifdef __CM0P_PRESENT
179     #if (__CM0P_PRESENT == 0)
180         /* Allocate and initialize semaphores for the system operations. */
181         static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD];
182         (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray);
183     #else
184         (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
185     #endif /* (__CM0P_PRESENT) */
186 #else
187     (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
188 #endif /* __CM0P_PRESENT */
189 
190 
191     /********************************************************************************
192     *
193     * Initializes the system pipes. The system pipes are used by BLE and Flash.
194     *
195     * If the default startup file is not used, or SystemInit() is not called in your
196     * project, call the following three functions prior to executing any flash or
197     * EmEEPROM write or erase operation:
198     *  -# Cy_IPC_Sema_Init()
199     *  -# Cy_IPC_Pipe_Config()
200     *  -# Cy_IPC_Pipe_Init()
201     *  -# Cy_Flash_Init()
202     *
203     *******************************************************************************/
204     /* Create an array of endpoint structures */
205     static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS];
206 
207     Cy_IPC_Pipe_Config(systemIpcPipeEpArray);
208 
209     static cy_ipc_pipe_callback_ptr_t systemIpcPipeSysCbArray[CY_SYS_CYPIPE_CLIENT_CNT];
210 
211     static const cy_stc_ipc_pipe_config_t systemIpcPipeConfigCm4 =
212     {
213     /* .ep0ConfigData */
214         {
215             /* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP0,
216             /* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP0,
217             /* .ipcNotifierMuxNumber */  CY_SYS_INTR_CYPIPE_MUX_EP0,
218             /* .epAddress            */  CY_IPC_EP_CYPIPE_CM0_ADDR,
219             /* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP0
220         },
221     /* .ep1ConfigData */
222         {
223             /* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP1,
224             /* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP1,
225             /* .ipcNotifierMuxNumber */  0u,
226             /* .epAddress            */  CY_IPC_EP_CYPIPE_CM4_ADDR,
227             /* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP1
228         },
229     /* .endpointClientsCount     */  CY_SYS_CYPIPE_CLIENT_CNT,
230     /* .endpointsCallbacksArray  */  systemIpcPipeSysCbArray,
231     /* .userPipeIsrHandler       */  &Cy_SysIpcPipeIsrCm4
232     };
233 
234     Cy_IPC_Pipe_Init(&systemIpcPipeConfigCm4);
235 
236 #if defined(CY_DEVICE_PSOC6ABLE2)
237     Cy_Flash_Init();
238 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
239 
240 #endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
241 
242 #if defined(CY_DEVICE_SECURE)
243     /* Initialize Protected Register Access driver */
244     Cy_PRA_Init();
245 #endif /* defined(CY_DEVICE_SECURE) */
246 }
247 
248 
249 /*******************************************************************************
250 * Function Name: Cy_SystemInit
251 ****************************************************************************//**
252 *
253 * The function is called during device startup. Once project compiled as part of
254 * the PSoC Creator project, the Cy_SystemInit() function is generated by the
255 * PSoC Creator.
256 *
257 * The function generated by PSoC Creator performs all of the necessary device
258 * configuration based on the design settings.  This includes settings from the
259 * Design Wide Resources (DWR) such as Clocks and Pins as well as any component
260 * configuration that is necessary.
261 *
262 *******************************************************************************/
Cy_SystemInit(void)263 __WEAK void Cy_SystemInit(void)
264 {
265      /* Empty weak function. The actual implementation to be in the PSoC Creator
266       * generated strong function.
267      */
268 }
269 
270 
271 /*******************************************************************************
272 * Function Name: SystemCoreClockUpdate
273 ****************************************************************************//**
274 *
275 * Gets core clock frequency and updates \ref SystemCoreClock, \ref
276 * cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz.
277 *
278 * Updates global variables used by the \ref Cy_SysLib_Delay(), \ref
279 * Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles().
280 *
281 *******************************************************************************/
SystemCoreClockUpdate(void)282 void SystemCoreClockUpdate (void)
283 {
284     uint32 locHf0Clock = Cy_SysClk_ClkHfGetFrequency(0UL);
285 
286     if (0UL != locHf0Clock)
287     {
288         cy_Hfclk0FreqHz = locHf0Clock;
289         cy_PeriClkFreqHz = locHf0Clock / (1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider());
290         SystemCoreClock = locHf0Clock / (1UL + (uint32_t)Cy_SysClk_ClkFastGetDivider());
291 
292         /* Sets clock frequency for Delay API */
293         cy_delayFreqMhz = (uint8_t)CY_SYSLIB_DIV_ROUNDUP(SystemCoreClock, CY_DELAY_1M_THRESHOLD);
294         cy_delayFreqKhz = CY_SYSLIB_DIV_ROUNDUP(SystemCoreClock, CY_DELAY_1K_THRESHOLD);
295         cy_delay32kMs   = CY_DELAY_MS_OVERFLOW_THRESHOLD * cy_delayFreqKhz;
296     }
297 }
298 
299 
300 /*******************************************************************************
301 * Function Name: Cy_SystemInitFpuEnable
302 ****************************************************************************//**
303 *
304 * Enables the FPU if it is used. The function is called from the startup file.
305 *
306 *******************************************************************************/
Cy_SystemInitFpuEnable(void)307 void Cy_SystemInitFpuEnable(void)
308 {
309     #if defined (__FPU_USED) && (__FPU_USED == 1U)
310         uint32_t  interruptState;
311         interruptState = Cy_SysLib_EnterCriticalSection();
312         SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE;
313         __DSB();
314         __ISB();
315         Cy_SysLib_ExitCriticalSection(interruptState);
316     #endif /* (__FPU_USED) && (__FPU_USED == 1U) */
317 }
318 
319 
320 #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
321 /*******************************************************************************
322 * Function Name: Cy_SysIpcPipeIsrCm4
323 ****************************************************************************//**
324 *
325 * This is the interrupt service routine for the system pipe.
326 *
327 *******************************************************************************/
Cy_SysIpcPipeIsrCm4(void)328 void Cy_SysIpcPipeIsrCm4(void)
329 {
330     Cy_IPC_Pipe_ExecuteCallback(CY_IPC_EP_CYPIPE_CM4_ADDR);
331 }
332 #endif
333 
334 
335 /*******************************************************************************
336 * Function Name: Cy_MemorySymbols
337 ****************************************************************************//**
338 *
339 * The intention of the function is to declare boundaries of the memories for the
340 * MDK compilers. For the rest of the supported compilers, this is done using
341 * linker configuration files. The following symbols used by the cymcuelftool.
342 *
343 *******************************************************************************/
344 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050)
Cy_MemorySymbols(void)345 __asm void Cy_MemorySymbols(void)
346 {
347     /* Flash */
348     EXPORT __cy_memory_0_start
349     EXPORT __cy_memory_0_length
350     EXPORT __cy_memory_0_row_size
351 
352     /* Working Flash */
353     EXPORT __cy_memory_1_start
354     EXPORT __cy_memory_1_length
355     EXPORT __cy_memory_1_row_size
356 
357     /* Supervisory Flash */
358     EXPORT __cy_memory_2_start
359     EXPORT __cy_memory_2_length
360     EXPORT __cy_memory_2_row_size
361 
362     /* XIP */
363     EXPORT __cy_memory_3_start
364     EXPORT __cy_memory_3_length
365     EXPORT __cy_memory_3_row_size
366 
367     /* eFuse */
368     EXPORT __cy_memory_4_start
369     EXPORT __cy_memory_4_length
370     EXPORT __cy_memory_4_row_size
371 
372     /* Flash */
373 __cy_memory_0_start     EQU __cpp(CY_FLASH_BASE)
374 __cy_memory_0_length    EQU __cpp(CY_FLASH_SIZE)
375 __cy_memory_0_row_size  EQU 0x200
376 
377     /* Flash region for EEPROM emulation */
378 __cy_memory_1_start     EQU __cpp(CY_EM_EEPROM_BASE)
379 __cy_memory_1_length    EQU __cpp(CY_EM_EEPROM_SIZE)
380 __cy_memory_1_row_size  EQU 0x200
381 
382     /* Supervisory Flash */
383 __cy_memory_2_start     EQU __cpp(CY_SFLASH_BASE)
384 __cy_memory_2_length    EQU __cpp(CY_SFLASH_SIZE)
385 __cy_memory_2_row_size  EQU 0x200
386 
387     /* XIP */
388 __cy_memory_3_start     EQU __cpp(CY_XIP_BASE)
389 __cy_memory_3_length    EQU __cpp(CY_XIP_SIZE)
390 __cy_memory_3_row_size  EQU 0x200
391 
392     /* eFuse */
393 __cy_memory_4_start     EQU __cpp(0x90700000)
394 __cy_memory_4_length    EQU __cpp(0x100000)
395 __cy_memory_4_row_size  EQU __cpp(1)
396 }
397 #endif /* defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) */
398 
399 
400 /* [] END OF FILE */
401