1 /***************************************************************************//**
2 * \file cy_pra.c
3 * \version 2.40.1
4 *
5 * \brief The source code file for the PRA driver. The API is not intended to
6 * be used directly by the user application.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation
11 * (an Infineon company) or an affiliate of Cypress Semiconductor Corporation.
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26
27 #include "cy_device.h"
28
29 #if defined (CY_IP_MXS40SRSS)
30
31 #include "cy_pra.h"
32 #include "cy_pra_cfg.h"
33 #include "cy_sysint.h"
34 #include "cy_ipc_drv.h"
35 #include "cy_device.h"
36 #include "cy_syspm.h"
37 #include "cy_ble_clk.h"
38 #include "cy_gpio.h"
39
40 #if defined (CY_DEVICE_SECURE) || defined (CY_DOXYGEN)
41
42 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 17.2', 4, \
43 'Checked manually. All the recursive cycles are handled properly.')
44
45 #define CY_PRA_REG_POLICY_WRITE_ALL (0x00000000UL)
46 #define CY_PRA_REG_POLICY_WRITE_NONE (0xFFFFFFFFUL)
47 #define CY_PRA_MS_NR (16U)
48
49 #define CY_PRA_GPIO_V2_PRT_REG_NR (21U) /* No of registers in GPIO PRT_V2 */
50 #define CY_PRA_HSIOM_PRT_REG_NR (2U) /* No of registers in GPIO PRT_V1 */
51
52 #define CY_PRA_CLK_EXT_PIN_INDEX (0UL)
53 #define CY_PRA_CLK_ECO_INPIN_INDEX (1UL)
54 #define CY_PRA_CLK_ECO_OUTPIN_INDEX (2UL)
55 #define CY_PRA_CLK_WCO_INPIN_INDEX (3UL)
56 #define CY_PRA_CLK_WCO_OUTPIN_INDEX (4UL)
57
58 #define CY_PRA_SKIP_SYS_CFG (0xFFUL)
59
60
61 /* The table to get a register address based on its index */
62 cy_stc_pra_reg_policy_t regIndexToAddr[CY_PRA_REG_INDEX_COUNT];
63
64 #if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
65 /* SRAM power mode configurations */
66 cy_pra_sram_pwr_mode_config_t sramPwrModeConfig[CY_PRA_SRAM_MAX_NR];
67 #endif
68
69 #if (CY_CPU_CORTEX_M4)
70 static IPC_STRUCT_Type *ipcPraBase = NULL;
71
72 /* External clock secure pin list */
73 cy_stc_pra_extclk_pin_t secExtclkPinList[CY_PRA_EXTCLK_PIN_NR];
74 #if defined(CY_DEVICE_PSOC6ABLE2)
75 cy_stc_pra_extclk_hsiom_t secExtClkAdjHsiomList[CY_PRA_EXTCLK_PIN_NR];
76 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
77 #endif /* (CY_CPU_CORTEX_M0P) */
78
79
80 /*******************************************************************************
81 * Internal Function Prototypes
82 *******************************************************************************/
83 #if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
84 static void Cy_PRA_Handler(void);
85 static void Cy_PRA_ProcessCmd(cy_stc_pra_msg_t *message);
86 static void Cy_PRA_PmHibernate(uint32_t funcProc);
87 static void Cy_PRA_PmCm4DpFlagSet(void);
88 static cy_en_pra_status_t Cy_PRA_ClkDSBeforeTransition(void);
89 static cy_en_pra_status_t Cy_PRA_ClkDSAfterTransition(void);
90 static bool Cy_PRA_RegAccessRangeValid(uint16_t index);
91 static cy_en_pra_status_t Cy_PRA_ClocksReset(void);
92 static cy_en_pra_status_t Cy_PRA_BackupReset(bool iloHibernateON);
93 static void Cy_PRA_InitGpioPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum);
94 static void Cy_PRA_InitHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum);
95 #if defined(CY_DEVICE_PSOC6ABLE2)
96 static void Cy_PRA_InitAdjHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *base);
97 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
98 static cy_en_pra_status_t Cy_PRA_ValidateSramPowerMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode);
99 static cy_en_pra_status_t Cy_PRA_ValidateEntireSramPowerMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode);
100 #endif /* (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN) */
101
102
103 /*******************************************************************************
104 * Function Name: Cy_PRA_Init
105 ****************************************************************************//**
106 *
107 * Initializes the PRA driver:
108 * - Initializes the register access array with the register addresses (Cortex-M0+)
109 * - Sets up the IPC communication between CPU cores
110 * - Checks that the driver versions match on the Cortex-M0+ and Cortex-M4 sides.
111 *
112 * Call the function before accessing any protected registers.
113 * It is called during a device startup from \ref SystemInit().
114 *
115 *******************************************************************************/
Cy_PRA_Init(void)116 void Cy_PRA_Init(void)
117 {
118
119 #if (CY_CPU_CORTEX_M0P)
120 for (uint32_t i = 0UL; i < CY_PRA_REG_INDEX_COUNT; i++)
121 {
122 regIndexToAddr[i].writeMask = CY_PRA_REG_POLICY_WRITE_ALL;
123 }
124 regIndexToAddr[CY_PRA_INDX_SRSS_PWR_LVD_CTL].addr = &SRSS_PWR_LVD_CTL;
125 regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR].addr = &SRSS_SRSS_INTR;
126 regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_SET].addr = &SRSS_SRSS_INTR_SET;
127 regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_MASK].addr = &SRSS_SRSS_INTR_MASK;
128 regIndexToAddr[CY_PRA_INDX_SRSS_SRSS_INTR_CFG].addr = &SRSS_SRSS_INTR_CFG;
129 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_1].addr = &SRSS_CLK_ROOT_SELECT[1U];
130 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_2].addr = &SRSS_CLK_ROOT_SELECT[2U];
131 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_3].addr = &SRSS_CLK_ROOT_SELECT[3U];
132 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_4].addr = &SRSS_CLK_ROOT_SELECT[4U];
133 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_5].addr = (CY_SRSS_NUM_HFROOT > 4U) ? &SRSS_CLK_ROOT_SELECT[5U] : NULL;
134 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_ROOT_SELECT_6].addr = (CY_SRSS_NUM_HFROOT > 5U) ? &SRSS_CLK_ROOT_SELECT[6U] : NULL;
135 regIndexToAddr[CY_PRA_INDX_FLASHC_FLASH_CMD].addr = &FLASHC_FLASH_CMD;
136 regIndexToAddr[CY_PRA_INDX_SRSS_PWR_HIBERNATE].addr = &SRSS_PWR_HIBERNATE;
137 regIndexToAddr[CY_PRA_INDX_SRSS_PWR_HIBERNATE].writeMask = (uint32_t) ~ (SRSS_PWR_HIBERNATE_TOKEN_Msk |
138 SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |
139 SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk |
140 SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |
141 SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk);
142 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_MFO_CONFIG].addr = &SRSS_CLK_MFO_CONFIG;
143 regIndexToAddr[CY_PRA_INDX_SRSS_CLK_MF_SELECT].addr = &SRSS_CLK_MF_SELECT;
144 regIndexToAddr[CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK].addr = &FLASHC_FM_CTL_BOOKMARK;
145 regIndexToAddr[CY_PRA_INDX_FLASHC_FM_CTL_BOOKMARK].writeMask= CY_PRA_REG_POLICY_WRITE_NONE;
146
147 /* There are up to 16 bus masters */
148 for (uint32_t i = 0UL; i < CY_PRA_MS_NR; i++)
149 {
150 #if defined(CY_DEVICE_PSOC6ABLE2)
151 regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].addr = &PROT_MPU_MS_CTL(i);
152 #else
153 regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].addr = (volatile uint32_t *) 0UL;
154 #endif /* (CY_DEVICE_PSOC6ABLE2) */
155
156 regIndexToAddr[CY_PRA_INDX_PROT_MPU_MS_CTL + i].writeMask= CY_PRA_REG_POLICY_WRITE_NONE;
157 }
158
159 /* Initialize SRAM power modes */
160 for (uint32_t i = 0UL; i < CY_PRA_SRAM_MAX_NR; i++)
161 {
162 sramPwrModeConfig[i].macroConfigCount = 0UL;
163 }
164
165 /* Configures the IPC interrupt handler. */
166 Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(CY_IPC_INTR_PRA), CY_PRA_IPC_NONE_INTR, CY_PRA_IPC_CHAN_INTR);
167 cy_stc_sysint_t intr = {
168 .intrSrc = (IRQn_Type)CY_SYSINT_CM0P_MUX4,
169 .cm0pSrc = (cy_en_intr_t)(int32_t) CY_IPC_INTR_NUM_TO_VECT((int32_t) CY_IPC_INTR_PRA),
170 .intrPriority = 0UL
171 };
172
173 if (CY_SYSINT_SUCCESS != Cy_SysInt_Init(&intr, &Cy_PRA_Handler))
174 {
175 CY_HALT();
176 }
177
178 NVIC_EnableIRQ(intr.intrSrc);
179 #else
180 /* Need to get this address in RAM, because there are use cases
181 * where this address is used but flash is not accessible
182 */
183 ipcPraBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA);
184
185 /* Check the version of the driver on the Cortex-M0+ side to match with this one */
186 if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_VERSION_CHECK,
187 (uint16_t) 0U,
188 (uint32_t) CY_PRA_DRV_VERSION_MAJOR,
189 (uint32_t) CY_PRA_DRV_VERSION_MINOR))
190 {
191 /* The PRA driver may not function as expected if different versions
192 * of the driver are on the Cortex-M0+ and Cortex-M4 sides, so halt device.
193 */
194 CY_HALT();
195 }
196
197 /* Fill the external clock ports */
198 if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_EXTCLK_PIN_LIST,
199 (uint16_t) 0U,
200 (uint32_t) secExtclkPinList,
201 (uint32_t) CY_PRA_EXTCLK_PIN_NR))
202 {
203 /* Initialize the List */
204 for (uint32_t index = 0UL; index<CY_PRA_EXTCLK_PIN_NR; index++)
205 {
206 secExtclkPinList[index].port = NULL;
207 }
208 }
209
210 #if defined(CY_DEVICE_PSOC6ABLE2)
211 /* Fill the external clock HSIOM ports */
212 if (CY_PRA_STATUS_SUCCESS != Cy_PRA_SendCmd(CY_PRA_MSG_TYPE_EXTCLK_ADJHSIOM_LIST,
213 (uint16_t) 0U,
214 (uint32_t) secExtClkAdjHsiomList,
215 (uint32_t) CY_PRA_EXTCLK_PIN_NR))
216 {
217 /* Initialize the List */
218 for (uint32_t index = 0UL; index<CY_PRA_EXTCLK_PIN_NR; index++)
219 {
220 secExtClkAdjHsiomList[index].port = NULL;
221 }
222 }
223 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
224
225 #endif /* (CY_CPU_CORTEX_M0P) */
226 }
227
228
229 #if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
230
231 /*******************************************************************************
232 * Function Name: Cy_PRA_UpdateExtClockRegIndex
233 ****************************************************************************//**
234 *
235 * Update Index-to-Addr Array with External clock addresses
236 *
237 *******************************************************************************/
Cy_PRA_UpdateExtClockRegIndex(void)238 void Cy_PRA_UpdateExtClockRegIndex(void)
239 {
240 if (NULL != extClkPolicyPtr)
241 {
242 if (extClkPolicyPtr->extClkEnable)
243 {
244 Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_EXTCLK_PRT, extClkPolicyPtr->extClkPort, extClkPolicyPtr->extClkPinNum);
245 Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_EXTCLK_PRT, extClkPolicyPtr->extClkPort, extClkPolicyPtr->extClkPinNum);
246 #if defined(CY_DEVICE_PSOC6ABLE2)
247 Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_EXTCLK_ADJ_PRT, extClkPolicyPtr->extClkPort);
248 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
249 }
250
251 if (extClkPolicyPtr->ecoEnable)
252 {
253 Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_ECO_IN_PRT, extClkPolicyPtr->ecoInPort, extClkPolicyPtr->ecoInPinNum);
254 Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_ECO_OUT_PRT, extClkPolicyPtr->ecoOutPort, extClkPolicyPtr->ecoOutPinNum);
255 Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_IN_PRT, extClkPolicyPtr->ecoInPort, extClkPolicyPtr->ecoInPinNum);
256 Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_OUT_PRT, extClkPolicyPtr->ecoOutPort, extClkPolicyPtr->ecoOutPinNum);
257 #if defined(CY_DEVICE_PSOC6ABLE2)
258 Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_IN_ADJ_PRT, extClkPolicyPtr->ecoInPort);
259 Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_ECO_OUT_ADJ_PRT, extClkPolicyPtr->ecoOutPort);
260 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
261 }
262
263 if (extClkPolicyPtr->wcoEnable)
264 {
265 Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_WCO_IN_PRT, extClkPolicyPtr->wcoInPort, extClkPolicyPtr->wcoInPinNum);
266 Cy_PRA_InitGpioPort(regIndexToAddr, CY_PRA_INDX_GPIO_WCO_OUT_PRT, extClkPolicyPtr->wcoOutPort, extClkPolicyPtr->wcoOutPinNum);
267 Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_IN_PRT, extClkPolicyPtr->wcoInPort, extClkPolicyPtr->wcoInPinNum);
268 Cy_PRA_InitHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_OUT_PRT, extClkPolicyPtr->wcoOutPort, extClkPolicyPtr->wcoOutPinNum);
269 #if defined(CY_DEVICE_PSOC6ABLE2)
270 Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_IN_ADJ_PRT, extClkPolicyPtr->wcoInPort);
271 Cy_PRA_InitAdjHsiomPort(regIndexToAddr, CY_PRA_INDEX_HSIOM_WCO_OUT_ADJ_PRT, extClkPolicyPtr->wcoOutPort);
272 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
273 }
274 }
275 }
276
277 /*******************************************************************************
278 * Function Name: Cy_PRA_InitGpioPort
279 ****************************************************************************//**
280 *
281 * Initializes all port register address and write mask
282 *
283 *******************************************************************************/
Cy_PRA_InitGpioPort(cy_stc_pra_reg_policy_t * regPolicy,uint16_t index,GPIO_PRT_Type * port,uint32_t pinNum)284 static void Cy_PRA_InitGpioPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum)
285 {
286 uint32_t pinLoc;
287 volatile uint32_t *portAddr;
288
289 if ((NULL != regPolicy) && (NULL != port) && CY_GPIO_IS_PIN_VALID(pinNum))
290 {
291 portAddr = (volatile uint32_t *)((void *)(port));
292 for (uint32_t i = 0UL; i < CY_PRA_GPIO_V2_PRT_REG_NR; i++)
293 {
294 regPolicy[index + i].addr = (portAddr + i);
295 }
296
297 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT */
298 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_CLR), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_CLR */
299 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_SET), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_SET */
300 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_INV), 4U)].writeMask = (CY_GPIO_OUT_MASK << pinNum); /* OUT_INV */
301 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, IN), 4U)].writeMask = (CY_GPIO_IN_MASK << pinNum); /* IN */
302 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR), 4U)].writeMask = (CY_GPIO_INTR_STATUS_MASK << pinNum); /* INTR */
303 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASK), 4U)].writeMask = (CY_GPIO_INTR_EN_MASK << pinNum); /* INTR_MASK */
304 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASKED), 4U)].writeMask = (CY_GPIO_INTR_MASKED_MASK << pinNum); /* INTR_MASKED */
305 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_SET), 4U)].writeMask = (CY_GPIO_INTR_SET_MASK << pinNum); /* INTR_SET */
306
307 pinLoc = pinNum << CY_GPIO_INTR_CFG_OFFSET;
308 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtIntrCfgOffset), 4U)].writeMask = (CY_GPIO_INTR_EDGE_MASK << pinLoc); /* INTR_CFG */
309
310 pinLoc = pinNum << CY_GPIO_DRIVE_MODE_OFFSET;
311 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOffset), 4U)].writeMask = (CY_GPIO_CFG_DM_MASK << pinLoc); /* CFG */
312
313 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgInOffset), 4U)].writeMask = (CY_GPIO_CFG_IN_VTRIP_SEL_MASK << pinNum); /* CFG_IN */
314
315 pinLoc = (uint32_t)(pinNum << 1u) + CY_GPIO_CFG_OUT_DRIVE_OFFSET;
316 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOutOffset), 4U)].writeMask = (CY_GPIO_CFG_OUT_DRIVE_SEL_MASK << pinLoc) |
317 (CY_GPIO_CFG_OUT_SLOW_MASK << pinNum); /* CFG_OUT */
318
319 pinLoc = (pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET;
320 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask = (CY_GPIO_VREG_EN_MASK << pinLoc);
321 pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_IBUF_SHIFT;
322 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_IBUF_MASK << pinLoc);
323 pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VTRIP_SEL_SHIFT;
324 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VTRIP_SEL_MASK << pinLoc);
325 pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VREF_SEL_SHIFT;
326 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VREF_SEL_MASK << pinLoc);
327 pinLoc = ((pinNum & CY_GPIO_SIO_ODD_PIN_MASK) << CY_GPIO_CFG_SIO_OFFSET) + CY_GPIO_VOH_SEL_SHIFT;
328 regPolicy[index + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U)].writeMask |= (CY_GPIO_VOH_SEL_MASK << pinLoc);
329 }
330 else if (NULL != regPolicy)
331 {
332 /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
333 for (uint32_t i = 0UL; i < CY_PRA_GPIO_V2_PRT_REG_NR; i++)
334 {
335 regPolicy[index + i].addr = NULL;
336 regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
337 }
338 }
339 else
340 {
341 /* Invalid parameters */
342 }
343 }
344
345 /*******************************************************************************
346 * Function Name: Cy_PRA_InitHsiomPort
347 ****************************************************************************//**
348 *
349 * Initializes all HSIOM port register address and write mask
350 *
351 *******************************************************************************/
Cy_PRA_InitHsiomPort(cy_stc_pra_reg_policy_t * regPolicy,uint16_t index,GPIO_PRT_Type * port,uint32_t pinNum)352 static void Cy_PRA_InitHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *port, uint32_t pinNum)
353 {
354 uint32_t portNum;
355 volatile uint32_t *portAddrHSIOM;
356
357 if ((NULL != regPolicy) && (NULL != port) && CY_GPIO_IS_PIN_VALID(pinNum))
358 {
359 /* calculate hsiom port */
360 portNum = ((uint32_t)(port) - CY_GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
361 portAddrHSIOM = (volatile uint32_t *)(CY_HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));
362
363 for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
364 {
365 regPolicy[index + i].addr = (portAddrHSIOM + i);
366 }
367
368 if (pinNum < CY_GPIO_PRT_HALF)
369 {
370 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U)].writeMask = (CY_GPIO_HSIOM_MASK << (pinNum << CY_GPIO_HSIOM_OFFSET));
371 }
372 else
373 {
374 pinNum -= CY_GPIO_PRT_HALF;
375 regPolicy[index + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U)].writeMask = (CY_GPIO_HSIOM_MASK << (pinNum << CY_GPIO_HSIOM_OFFSET));
376 }
377 }
378 else if (NULL != regPolicy)
379 {
380 /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
381 for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
382 {
383 regPolicy[index + i].addr = NULL;
384 regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
385 }
386 }
387 else
388 {
389 /* Invalid parameters */
390 }
391 }
392
393 #if defined(CY_DEVICE_PSOC6ABLE2)
394 /*******************************************************************************
395 * Function Name: Cy_PRA_InitAdjHsiomPort
396 ****************************************************************************//**
397 *
398 * Initializes all adjacent HSIOM port register address and write mask
399 *
400 *******************************************************************************/
Cy_PRA_InitAdjHsiomPort(cy_stc_pra_reg_policy_t * regPolicy,uint16_t index,GPIO_PRT_Type * base)401 static void Cy_PRA_InitAdjHsiomPort(cy_stc_pra_reg_policy_t *regPolicy, uint16_t index, GPIO_PRT_Type *base)
402 {
403 uint32_t portNum;
404 volatile uint32_t *portAddrHSIOM;
405 GPIO_PRT_Type *port;
406
407 if ((NULL != regPolicy) && (NULL != base))
408 {
409 /* calculate next port address */
410 port = base + 1UL;
411
412 /* calculate hsiom port */
413 portNum = ((uint32_t)(port) - CY_GPIO_BASE) / GPIO_PRT_SECTION_SIZE;
414 portAddrHSIOM = (volatile uint32_t *)(CY_HSIOM_BASE + (HSIOM_PRT_SECTION_SIZE * portNum));
415
416 for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
417 {
418 regPolicy[index + i].addr = (portAddrHSIOM + i);
419 regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_ALL;
420 }
421 }
422 else if (NULL != regPolicy)
423 {
424 /* regIndexToAddr Indexes are filled with NULL addresses. So don't allow to write in these indexes */
425 for (uint32_t i = 0UL; i < CY_PRA_HSIOM_PRT_REG_NR; i++)
426 {
427 regPolicy[index + i].addr = NULL;
428 regPolicy[index + i].writeMask = CY_PRA_REG_POLICY_WRITE_NONE;
429 }
430 }
431 else
432 {
433 /* Invalid parameters */
434 }
435 }
436 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
437
438 /*******************************************************************************
439 * Function Name: Cy_PRA_Handler
440 ****************************************************************************//**
441 *
442 * The IPC interrupt handler on Cortex-M0+ core is called after there is a
443 * request from the Cortex-M4 core.
444 *
445 *******************************************************************************/
Cy_PRA_Handler(void)446 static void Cy_PRA_Handler(void)
447 {
448 cy_stc_pra_msg_t msgLocal;
449 cy_stc_pra_msg_t* msgRemote;
450
451 /* Processes an internal command copy and updates the original value */
452 msgRemote = (cy_stc_pra_msg_t *)Cy_IPC_Drv_ReadDataValue(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA));
453
454 msgLocal = *msgRemote;
455 Cy_PRA_ProcessCmd(&msgLocal);
456 *msgRemote = msgLocal;
457
458 /* Clears the interrupt logic to detect a next interrupt */
459 Cy_IPC_Drv_ClearInterrupt(Cy_IPC_Drv_GetIntrBaseAddr(CY_IPC_INTR_PRA), CY_PRA_IPC_NONE_INTR, CY_PRA_IPC_CHAN_INTR);
460
461 (void) Cy_IPC_Drv_LockRelease(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_PRA), CY_PRA_IPC_NONE_INTR);
462 }
463
464
465 /*******************************************************************************
466 * Function Name: Cy_PRA_ProcessCmd
467 ****************************************************************************//**
468 *
469 * Processes and executes the command on Cortex-M0+ which was received from
470 * the Cortex-M4 application.
471 *
472 * \param message cy_stc_pra_msg_t
473 *
474 *******************************************************************************/
Cy_PRA_ProcessCmd(cy_stc_pra_msg_t * message)475 static void Cy_PRA_ProcessCmd(cy_stc_pra_msg_t *message)
476 {
477 static bool structInit = false;
478 static cy_stc_pra_system_config_t structCpy = {0UL};
479
480 CY_ASSERT_L1(NULL != message);
481
482
483 switch (message->praCommand)
484 {
485 case CY_PRA_MSG_TYPE_REG32_CLR_SET:
486 /* Reports an error if any of the following conditions is false:
487 * - A new value (message->praData2) has zeros in the write-protected fields
488 * - The register index is within the valid range.
489 */
490 if ((0U == (message->praData2 & regIndexToAddr[message->praIndex].writeMask)) &&
491 (CY_PRA_REG_POLICY_WRITE_NONE != regIndexToAddr[message->praIndex].writeMask) &&
492 (Cy_PRA_RegAccessRangeValid(message->praIndex)))
493 {
494 uint32_t tmp;
495
496 tmp = CY_GET_REG32(regIndexToAddr[message->praIndex].addr);
497
498 tmp &= (message->praData1 | regIndexToAddr[message->praIndex].writeMask);
499 tmp |= message->praData2;
500 CY_SET_REG32(regIndexToAddr[message->praIndex].addr, tmp);
501 message->praStatus = CY_PRA_STATUS_SUCCESS;
502 }
503 else
504 {
505 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
506 }
507 break;
508
509 case CY_PRA_MSG_TYPE_REG32_SET:
510 /* Reports an error if any of the following conditions is false:
511 * - A new value (message->praData1) has zeros or same value in the write-protected fields
512 * - The register index is within the valid range.
513 */
514 if ((CY_PRA_REG_POLICY_WRITE_NONE != regIndexToAddr[message->praIndex].writeMask) &&
515 (Cy_PRA_RegAccessRangeValid(message->praIndex)))
516 {
517 uint32_t tmp;
518
519 tmp = CY_GET_REG32(regIndexToAddr[message->praIndex].addr);
520
521 if ((0U == (message->praData1 & regIndexToAddr[message->praIndex].writeMask)) ||
522 ((tmp & regIndexToAddr[message->praIndex].writeMask) ==
523 (message->praData1 & regIndexToAddr[message->praIndex].writeMask)))
524 {
525 /* Clears the bits allowed to write */
526 tmp &= regIndexToAddr[message->praIndex].writeMask;
527
528 /* Sets the allowed bits based on the new value.
529 * The write-protected fields have zeros in the new value, so no additional checks needed
530 */
531 tmp |= message->praData1;
532 CY_SET_REG32(regIndexToAddr[message->praIndex].addr, tmp);
533 message->praStatus = CY_PRA_STATUS_SUCCESS;
534 }
535 else
536 {
537 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
538 }
539 }
540 else
541 {
542 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
543 }
544 break;
545
546 case CY_PRA_MSG_TYPE_REG32_GET:
547 if (Cy_PRA_RegAccessRangeValid(message->praIndex))
548 {
549 message->praData1 = CY_GET_REG32(regIndexToAddr[message->praIndex].addr);
550 message->praStatus = CY_PRA_STATUS_SUCCESS;
551 }
552 else
553 {
554 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
555 }
556 break;
557
558 case CY_PRA_MSG_TYPE_CM0_WAKEUP:
559 message->praStatus = CY_PRA_STATUS_SUCCESS;
560 break;
561
562 case CY_PRA_MSG_TYPE_VERSION_CHECK:
563 /* The PRA driver may not function as expected if different versions
564 * of the driver are on the Cortex-M0+ and Cortex-M4 sides.
565 */
566 if (((uint32_t) CY_PRA_DRV_VERSION_MAJOR == (message->praData1)) &&
567 ((uint32_t) CY_PRA_DRV_VERSION_MINOR == (message->praData2)))
568 {
569 message->praStatus = CY_PRA_STATUS_SUCCESS;
570 }
571 else
572 {
573 message->praStatus = CY_PRA_STATUS_ERROR_PRA_VERSION;
574 }
575 break;
576
577 case CY_PRA_MSG_TYPE_EXTCLK_PIN_LIST:
578
579 if ((NULL != (cy_stc_pra_extclk_pin_t *) (message->praData1)) && ((uint32_t) (message->praData2) <= CY_PRA_EXTCLK_PIN_NR))
580 {
581 cy_stc_pra_extclk_pin_t *pinList = (cy_stc_pra_extclk_pin_t *) message->praData1;
582 message->praStatus = CY_PRA_STATUS_SUCCESS;
583
584 /* when there is no policy input then initialize the pinList */
585 if (NULL == extClkPolicyPtr)
586 {
587 pinList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
588 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
589 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
590 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
591 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
592 }
593 else
594 {
595
596 if (extClkPolicyPtr->extClkEnable)
597 {
598 pinList[CY_PRA_CLK_EXT_PIN_INDEX].port = extClkPolicyPtr->extClkPort;
599 pinList[CY_PRA_CLK_EXT_PIN_INDEX].pinNum = extClkPolicyPtr->extClkPinNum;
600 pinList[CY_PRA_CLK_EXT_PIN_INDEX].index = CY_PRA_INDX_GPIO_EXTCLK_PRT;
601 pinList[CY_PRA_CLK_EXT_PIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_EXTCLK_PRT;
602 }
603 else
604 {
605 pinList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
606 }
607
608 if (extClkPolicyPtr->ecoEnable)
609 {
610 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].port = extClkPolicyPtr->ecoInPort;
611 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].pinNum = extClkPolicyPtr->ecoInPinNum;
612 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].index = CY_PRA_INDX_GPIO_ECO_IN_PRT;
613 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_IN_PRT;
614
615 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = extClkPolicyPtr->ecoOutPort;
616 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].pinNum = extClkPolicyPtr->ecoOutPinNum;
617 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].index = CY_PRA_INDX_GPIO_ECO_OUT_PRT;
618 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_OUT_PRT;
619 }
620 else
621 {
622 pinList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
623 pinList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
624 }
625
626 if (extClkPolicyPtr->wcoEnable)
627 {
628 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].port = extClkPolicyPtr->wcoInPort;
629 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].pinNum = extClkPolicyPtr->wcoInPinNum;
630 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].index = CY_PRA_INDX_GPIO_WCO_IN_PRT;
631 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_IN_PRT;
632
633 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = extClkPolicyPtr->wcoOutPort;
634 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].pinNum = extClkPolicyPtr->wcoOutPinNum;
635 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].index = CY_PRA_INDX_GPIO_WCO_OUT_PRT;
636 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_OUT_PRT;
637 }
638 else
639 {
640 pinList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
641 pinList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
642 }
643 } /* NULL == extClkPolicyPtr */
644 }
645 else
646 {
647 message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
648 }
649
650 break;
651 #if defined(CY_DEVICE_PSOC6ABLE2)
652 case CY_PRA_MSG_TYPE_EXTCLK_ADJHSIOM_LIST:
653 if ((NULL != (cy_stc_pra_extclk_hsiom_t *) (message->praData1)) && ((uint32_t) (message->praData2) <= CY_PRA_EXTCLK_PIN_NR))
654 {
655 cy_stc_pra_extclk_hsiom_t *hsiomList = (cy_stc_pra_extclk_hsiom_t *) message->praData1;
656
657 /* when there is no policy input then initialize the hsiomList */
658 if (NULL == extClkPolicyPtr)
659 {
660 hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
661 hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
662 hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
663 hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
664 hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
665 }
666 else
667 {
668
669 if (extClkPolicyPtr->extClkEnable)
670 {
671 hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].port = extClkPolicyPtr->extClkPort + 1; /* Fill adjacent GPIO port */
672 hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_EXTCLK_ADJ_PRT;
673 }
674 else
675 {
676 hsiomList[CY_PRA_CLK_EXT_PIN_INDEX].port = NULL;
677 }
678
679 if (extClkPolicyPtr->ecoEnable)
680 {
681 hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].port = extClkPolicyPtr->ecoInPort + 1; /* Fill adjacent GPIO port */
682 hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_IN_ADJ_PRT;
683 hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = extClkPolicyPtr->ecoOutPort + 1; /* Fill adjacent GPIO port */
684 hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_ECO_OUT_ADJ_PRT;
685 }
686 else
687 {
688 hsiomList[CY_PRA_CLK_ECO_INPIN_INDEX].port = NULL;
689 hsiomList[CY_PRA_CLK_ECO_OUTPIN_INDEX].port = NULL;
690 }
691
692 if (extClkPolicyPtr->wcoEnable)
693 {
694 hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].port = extClkPolicyPtr->wcoInPort + 1; /* Fill adjacent GPIO port */
695 hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_IN_ADJ_PRT;
696 hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = extClkPolicyPtr->wcoOutPort + 1; /* Fill adjacent GPIO port */
697 hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].hsiomIndex = CY_PRA_INDEX_HSIOM_WCO_OUT_ADJ_PRT;
698 }
699 else
700 {
701 hsiomList[CY_PRA_CLK_WCO_INPIN_INDEX].port = NULL;
702 hsiomList[CY_PRA_CLK_WCO_OUTPIN_INDEX].port = NULL;
703 }
704 } /* NULL == extClkPolicyPtr */
705
706 message->praStatus = CY_PRA_STATUS_SUCCESS;
707 }
708 break;
709 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
710 case CY_PRA_MSG_TYPE_SYS_CFG_FUNC:
711 CY_ASSERT_L1((cy_stc_pra_system_config_t *)(message->praData1) != NULL);
712
713 if( NULL != (cy_stc_pra_system_config_t *)(message->praData1))
714 {
715 bool structInitBak = structInit;
716 message->praStatus = CY_PRA_STATUS_SUCCESS;
717
718 structCpy = *((cy_stc_pra_system_config_t *)(message->praData1));
719
720 /* Resets clocks configuration to the default state during system reset - DRIVERS-495 */
721 if (0u != Cy_SysLib_GetResetReason())
722 {
723 message->praStatus = Cy_PRA_ClocksReset();
724 }
725 /* Resets clocks configuration and backup domain to default
726 * state during hardware reset (POR, XRES, BOD)
727 */
728 else if (!structInit)
729 {
730 /* Resets the Backup domain on POR, XRES, BOD only if Backup domain is supplied by VDDD */
731 if ((structCpy.vBackupVDDDEnable) && (structCpy.iloEnable))
732 {
733 message->praStatus = Cy_PRA_BackupReset(structCpy.iloHibernateON);
734 }
735 message->praStatus = Cy_PRA_ClocksReset();
736 }
737 else
738 {
739 /* Skip clock clocks configuration resetting */
740 }
741
742 if (CY_PRA_STATUS_SUCCESS == message->praStatus)
743 {
744 structInit = false; /* This makes sure not to allow any CY_PRA_MSG_TYPE_FUNC_POLICY \
745 operation during system configurations */
746 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
747
748 structInit = structInitBak;
749
750 if(CY_PRA_STATUS_SUCCESS == message->praStatus)
751 {
752 structInit = true;
753 }
754 }
755 else
756 {
757 /* Error PRA status */
758 }
759 }
760 else
761 {
762 message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
763 }
764 break;
765
766 case CY_PRA_MSG_TYPE_SECURE_ONLY:
767 switch (message->praIndex)
768 {
769 case CY_PRA_PM_FUNC_HIBERNATE:
770 Cy_PRA_PmHibernate(message->praData1);
771 message->praStatus = CY_PRA_STATUS_SUCCESS;
772 break;
773
774 case CY_PRA_PM_FUNC_CM4_DP_FLAG_SET:
775 Cy_PRA_PmCm4DpFlagSet();
776 message->praStatus = CY_PRA_STATUS_SUCCESS;
777 break;
778
779 case CY_PRA_CLK_FUNC_DS_BEFORE_TRANSITION:
780 message->praStatus = Cy_PRA_ClkDSBeforeTransition();
781 break;
782
783 case CY_PRA_CLK_FUNC_DS_AFTER_TRANSITION:
784 message->praStatus = Cy_PRA_ClkDSAfterTransition();
785 break;
786
787 case CY_PRA_PM_FUNC_BUCK_ENABLE_VOLTAGE2:
788 Cy_SysPm_BuckEnableVoltage2();
789 message->praStatus = CY_PRA_STATUS_SUCCESS;
790 break;
791
792 case CY_PRA_PM_FUNC_BUCK_DISABLE_VOLTAGE2:
793 Cy_SysPm_BuckDisableVoltage2();
794 message->praStatus = CY_PRA_STATUS_SUCCESS;
795 break;
796
797 case CY_PRA_PM_FUNC_BUCK_VOLTAGE2_HW_CTRL:
798 Cy_SysPm_BuckSetVoltage2HwControl((bool) message->praData1);
799 message->praStatus = CY_PRA_STATUS_SUCCESS;
800 break;
801
802 case CY_PRA_PM_FUNC_BUCK_SET_VOLTAGE2:
803 if (CY_SYSPM_IS_BUCK_VOLTAGE2_VALID(((cy_stc_pra_voltage2_t *) message->praData1)->praVoltage))
804 {
805 Cy_SysPm_BuckSetVoltage2(((cy_stc_pra_voltage2_t *) message->praData1)->praVoltage,
806 ((cy_stc_pra_voltage2_t *) message->praData1)->praWaitToSettle);
807 message->praStatus = CY_PRA_STATUS_SUCCESS;
808 }
809 else
810 {
811 message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
812 }
813 break;
814
815 case CY_PRA_PM_FUNC_SRAM_MACRO_PWR_MODE:
816 {
817 cy_en_syspm_sram_index_t sramNum;
818 uint32_t sramMacroNum;
819 cy_en_syspm_sram_pwr_mode_t sramPwrMode;
820
821 sramNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramNum;
822 sramMacroNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramMacroNum;
823 sramPwrMode = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramPwrMode;
824
825 message->praStatus = Cy_PRA_ValidateSramPowerMode(sramNum, sramMacroNum, sramPwrMode);
826
827 if (message->praStatus == CY_PRA_STATUS_SUCCESS)
828 {
829 if (CY_SYSPM_SUCCESS != Cy_SysPm_SetSRAMMacroPwrMode(sramNum, sramMacroNum, sramPwrMode))
830 {
831 message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
832 }
833 }
834 else
835 {
836 /* Not allowed to modify sram power mode */
837 }
838 }
839 break;
840
841 case CY_PRA_PM_FUNC_SRAM_PWR_MODE:
842 {
843 cy_en_syspm_sram_index_t sramNum;
844 cy_en_syspm_sram_pwr_mode_t sramPwrMode;
845
846 sramNum = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramNum;
847 sramPwrMode = ((cy_stc_pra_sram_power_mode_config_t *) message->praData1)->sramPwrMode;
848
849 message->praStatus = Cy_PRA_ValidateEntireSramPowerMode(sramNum, sramPwrMode);
850
851 if (message->praStatus == CY_PRA_STATUS_SUCCESS)
852 {
853 if (CY_SYSPM_SUCCESS != Cy_SysPm_SetSRAMPwrMode(sramNum, sramPwrMode))
854 {
855 message->praStatus = CY_PRA_STATUS_INVALID_PARAM;
856 }
857 }
858 else
859 {
860 /* Not allowed to modify sram power mode */
861 }
862 }
863 break;
864
865 #ifdef CY_IP_MXBLESS
866 case CY_PRA_CLK_FUNC_PILO_INITIAL_TRIM:
867 Cy_SysClk_PiloInitialTrim();
868 message->praStatus = CY_PRA_STATUS_SUCCESS;
869 break;
870
871 case CY_PRA_CLK_FUNC_UPDATE_PILO_TRIM_STEP:
872 Cy_SysClk_PiloUpdateTrimStep();
873 message->praStatus = CY_PRA_STATUS_SUCCESS;
874 break;
875 #endif /* CY_IP_MXBLESS */
876
877 case CY_PRA_CLK_FUNC_START_MEASUREMENT:
878 {
879 cy_en_meas_clks_t clockVal1, clockVal2;
880 uint32_t countVal1;
881 clockVal1 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->clock1;
882 clockVal2 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->clock2;
883 countVal1 = ((cy_stc_pra_start_clk_measurement_t *) message->praData1)->count1;
884 message->praStatus = (cy_en_pra_status_t)Cy_SysClk_StartClkMeasurementCounters(clockVal1, countVal1, clockVal2);
885 }
886 break;
887
888 case CY_PRA_CLK_FUNC_ILO_TRIM:
889 message->praStatus = (cy_en_pra_status_t)Cy_SysClk_IloTrim(message->praData1);
890 break;
891
892 case CY_PRA_CLK_FUNC_SET_PILO_TRIM:
893 Cy_SysClk_PiloSetTrim(message->praData1);
894 message->praStatus = CY_PRA_STATUS_SUCCESS;
895 break;
896
897 #if defined(CY_IP_MXBLESS)
898 case CY_PRA_BLE_CLK_FUNC_ECO_CONFIGURE:
899 structCpy.altHFcLoad = ((cy_stc_pra_ble_eco_config_t *) message->praData1)->cLoad;
900 structCpy.altHFxtalStartUpTime = ((cy_stc_pra_ble_eco_config_t *) message->praData1)->xtalStartUpTime;
901 structCpy.altHFclkFreq = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->freq;
902 structCpy.altHFsysClkDiv = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->sysClkDiv;
903 structCpy.altHFvoltageReg = (uint32_t)((cy_stc_pra_ble_eco_config_t *) message->praData1)->voltageReg;
904 structCpy.clkAltHfEnable = true;
905
906 message->praStatus = (cy_en_pra_status_t)Cy_BLE_EcoConfigure(
907 (cy_en_ble_eco_freq_t)structCpy.altHFclkFreq,
908 (cy_en_ble_eco_sys_clk_div_t)structCpy.altHFsysClkDiv,
909 structCpy.altHFcLoad,
910 structCpy.altHFxtalStartUpTime,
911 (cy_en_ble_eco_voltage_reg_t)structCpy.altHFvoltageReg);
912 break;
913
914 case CY_PRA_BLE_CLK_FUNC_ECO_RESET:
915 Cy_BLE_EcoReset();
916 message->praStatus = CY_PRA_STATUS_SUCCESS;
917 break;
918 #endif /* CY_IP_MXBLESS */
919
920 default:
921 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
922 break;
923 }
924 break;
925
926 case CY_PRA_MSG_TYPE_FUNC_POLICY:
927 if(structInit)
928 {
929 switch (message->praIndex)
930 {
931 case CY_PRA_PM_FUNC_LDO_SET_VOLTAGE:
932 {
933 bool powerEnableTmp, ldoEnableTmp, ulpEnableTmp;
934 powerEnableTmp = structCpy.powerEnable; /* old value backup */
935 ldoEnableTmp = structCpy.ldoEnable; /* old value backup */
936 ulpEnableTmp = structCpy.ulpEnable; /* old value backup */
937 structCpy.powerEnable = true;
938 structCpy.ldoEnable = true;
939 structCpy.ldoVoltage = (cy_en_syspm_ldo_voltage_t)message->praData1;
940 if (structCpy.ldoVoltage == CY_SYSPM_LDO_VOLTAGE_0_9V)
941 {
942 structCpy.ulpEnable = true;
943 }
944 else
945 {
946 structCpy.ulpEnable = false;
947 }
948 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
949 {
950 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
951 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
952 {
953 /* On failure, previous values are restored */
954 structCpy.powerEnable = powerEnableTmp;
955 structCpy.ldoEnable = ldoEnableTmp;
956 structCpy.ulpEnable = ulpEnableTmp;
957 }
958 }
959 else
960 {
961 message->praStatus = CY_PRA_STATUS_SUCCESS;
962 }
963 }
964 break;
965
966 case CY_PRA_PM_FUNC_BUCK_ENABLE:
967 {
968 bool powerEnableTmp, ldoEnableTmp, ulpEnableTmp;
969 powerEnableTmp = structCpy.powerEnable; /* Old value backup */
970 ldoEnableTmp = structCpy.ldoEnable; /* Old value backup */
971 ulpEnableTmp = structCpy.ulpEnable; /* Old value backup */
972 structCpy.powerEnable = true;
973 structCpy.ldoEnable = false;
974 structCpy.buckVoltage = (cy_en_syspm_buck_voltage1_t)message->praData1;
975 if (structCpy.buckVoltage == CY_SYSPM_BUCK_OUT1_VOLTAGE_0_9V)
976 {
977 structCpy.ulpEnable = true;
978 }
979 else
980 {
981 structCpy.ulpEnable = false;
982 }
983 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
984 {
985 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
986 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
987 {
988 /* On failure, previous values are restored */
989 structCpy.powerEnable = powerEnableTmp;
990 structCpy.ldoEnable = ldoEnableTmp;
991 structCpy.ulpEnable = ulpEnableTmp;
992 }
993 }
994 else
995 {
996 message->praStatus = CY_PRA_STATUS_SUCCESS;
997 }
998 }
999 break;
1000
1001 case CY_PRA_PM_FUNC_SET_MIN_CURRENT:
1002 {
1003 bool powerEnableTmp, pwrCurrentModeMinTmp;
1004 /* Backups old values */
1005 powerEnableTmp = structCpy.powerEnable;
1006 pwrCurrentModeMinTmp = structCpy.pwrCurrentModeMin;
1007 structCpy.powerEnable = true;
1008 structCpy.pwrCurrentModeMin = true;
1009 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1010 {
1011 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1012 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1013 {
1014 /* On failure, previous values are restored */
1015 structCpy.powerEnable = powerEnableTmp;
1016 structCpy.pwrCurrentModeMin = pwrCurrentModeMinTmp;
1017 }
1018 }
1019 else
1020 {
1021 message->praStatus = CY_PRA_STATUS_SUCCESS;
1022 }
1023 }
1024 break;
1025
1026 case CY_PRA_PM_FUNC_SET_NORMAL_CURRENT:
1027 {
1028 bool powerEnableTmp, pwrCurrentModeMinTmp;
1029 /* Backups old values */
1030 powerEnableTmp = structCpy.powerEnable;
1031 pwrCurrentModeMinTmp = structCpy.pwrCurrentModeMin;
1032 structCpy.powerEnable = true;
1033 structCpy.pwrCurrentModeMin = false;
1034 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1035 {
1036 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1037 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1038 {
1039 /* On failure, previous values are restored */
1040 structCpy.powerEnable = powerEnableTmp;
1041 structCpy.pwrCurrentModeMin = pwrCurrentModeMinTmp;
1042 }
1043 }
1044 else
1045 {
1046 message->praStatus = CY_PRA_STATUS_SUCCESS;
1047 }
1048 }
1049 break;
1050
1051 case CY_PRA_CLK_FUNC_ECO_DISABLE:
1052 {
1053 bool ecoEnableTmp;
1054 /* Backups old values */
1055 ecoEnableTmp = structCpy.ecoEnable;
1056 structCpy.ecoEnable = false;
1057 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1058 {
1059 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1060 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1061 {
1062 /* On failure, previous values are restored */
1063 structCpy.ecoEnable = ecoEnableTmp;
1064 }
1065 }
1066 else
1067 {
1068 message->praStatus = CY_PRA_STATUS_SUCCESS;
1069 }
1070 }
1071 break;
1072
1073 case CY_PRA_CLK_FUNC_FLL_DISABLE:
1074 {
1075 bool fllEnableTmp;
1076 uint32_t fllOutFreqHzTmp;
1077 /* Backups old values */
1078 fllOutFreqHzTmp = structCpy.fllOutFreqHz;
1079 fllEnableTmp = structCpy.fllEnable;
1080 structCpy.fllEnable = false;
1081 structCpy.fllOutFreqHz = CY_PRA_DEFAULT_ZERO;
1082 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1083 {
1084 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1085 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1086 {
1087 /* On failure, previous values are restored */
1088 structCpy.fllEnable = fllEnableTmp;
1089 structCpy.fllOutFreqHz = fllOutFreqHzTmp;
1090 }
1091 }
1092 else
1093 {
1094 message->praStatus = CY_PRA_STATUS_SUCCESS;
1095 }
1096 }
1097 break;
1098
1099 case CY_PRA_CLK_FUNC_PLL_DISABLE:
1100 {
1101 bool pllEnable;
1102 if (((message->praData1) > CY_PRA_CLKPATH_0) && ((message->praData1) <= CY_SRSS_NUM_PLL)) /* 0 is invalid pll number */
1103 {
1104 /* Backups old values */
1105 ((message->praData1) == CY_PRA_CLKPLL_1) ? (pllEnable = structCpy.pll0Enable) : (pllEnable = structCpy.pll1Enable);
1106
1107 ((message->praData1) == CY_PRA_CLKPLL_1) ? (structCpy.pll0Enable = false) : (structCpy.pll1Enable = false);
1108 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1109 {
1110 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1111
1112 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1113 {
1114 /* On failure, previous values are restored */
1115 ((message->praData1) == CY_PRA_CLKPLL_1) ? (structCpy.pll0Enable = pllEnable) : (structCpy.pll1Enable = pllEnable);
1116 }
1117 }
1118 else
1119 {
1120 message->praStatus = CY_PRA_STATUS_SUCCESS;
1121 }
1122 }
1123 else
1124 {
1125 message->praStatus = CY_PRA_STATUS_INVALID_PARAM_PLL_NUM;
1126 }
1127 }
1128 break;
1129
1130 case CY_PRA_CLK_FUNC_ILO_ENABLE:
1131 {
1132 bool iloEnableTmp;
1133 /* Backups old values */
1134 iloEnableTmp = structCpy.iloEnable;
1135 structCpy.iloEnable = true;
1136 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1137 {
1138 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1139 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1140 {
1141 /* On failure, previous values are restored */
1142 structCpy.iloEnable = iloEnableTmp;
1143 }
1144 }
1145 else
1146 {
1147 message->praStatus = CY_PRA_STATUS_SUCCESS;
1148 }
1149 }
1150 break;
1151
1152 case CY_PRA_CLK_FUNC_ILO_DISABLE:
1153 {
1154 bool iloEnableTmp;
1155 /* Backups old values */
1156 iloEnableTmp = structCpy.iloEnable;
1157 structCpy.iloEnable = false;
1158 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1159 {
1160 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1161 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1162 {
1163 /* On failure, previous values are restored */
1164 structCpy.iloEnable = iloEnableTmp;
1165 }
1166 }
1167 else
1168 {
1169 message->praStatus = CY_PRA_STATUS_SUCCESS;
1170 }
1171 }
1172 break;
1173
1174 case CY_PRA_CLK_FUNC_ILO_HIBERNATE_ON:
1175 {
1176 bool iloHibernateOnTmp;
1177 /* Backups old values */
1178 iloHibernateOnTmp = structCpy.iloHibernateON;
1179 structCpy.iloHibernateON = (CY_PRA_DATA_DISABLE != message->praData1);
1180 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1181 {
1182 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1183 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1184 {
1185 /* On failure, previous values are restored */
1186 structCpy.iloHibernateON = iloHibernateOnTmp;
1187 }
1188 }
1189 else
1190 {
1191 message->praStatus = CY_PRA_STATUS_SUCCESS;
1192 }
1193 }
1194 break;
1195
1196 case CY_PRA_CLK_FUNC_PILO_ENABLE:
1197 {
1198 bool piloEnableTmp;
1199 /* Backups old values */
1200 piloEnableTmp = structCpy.piloEnable;
1201 structCpy.piloEnable = true;
1202 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1203 {
1204 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1205 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1206 {
1207 /* On failure, previous values are restored */
1208 structCpy.piloEnable = piloEnableTmp;
1209 }
1210 }
1211 else
1212 {
1213 message->praStatus = CY_PRA_STATUS_SUCCESS;
1214 }
1215 }
1216 break;
1217
1218 case CY_PRA_CLK_FUNC_PILO_DISABLE:
1219 {
1220 bool piloEnableTmp;
1221 /* Backups old values */
1222 piloEnableTmp = structCpy.piloEnable;
1223 structCpy.piloEnable = false;
1224 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1225 {
1226 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1227 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1228 {
1229 /* On failure, previous values are restored */
1230 structCpy.piloEnable = piloEnableTmp;
1231 }
1232 }
1233 else
1234 {
1235 message->praStatus = CY_PRA_STATUS_SUCCESS;
1236 }
1237 }
1238 break;
1239
1240 case CY_PRA_CLK_FUNC_WCO_ENABLE:
1241 {
1242 bool wcoEnableTmp;
1243 /* Backups old values */
1244 wcoEnableTmp = structCpy.wcoEnable;
1245 structCpy.wcoEnable = true;
1246 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1247 {
1248 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1249 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1250 {
1251 /* On failure, previous values are restored */
1252 structCpy.wcoEnable = wcoEnableTmp;
1253 }
1254 }
1255 else
1256 {
1257 message->praStatus = CY_PRA_STATUS_SUCCESS;
1258 }
1259 }
1260 break;
1261
1262 case CY_PRA_CLK_FUNC_WCO_DISABLE:
1263 {
1264 bool wcoEnableTmp;
1265 /* Backups old values */
1266 wcoEnableTmp = structCpy.wcoEnable;
1267 structCpy.wcoEnable = false;
1268 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1269 {
1270 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1271 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1272 {
1273 /* On failure, previous values are restored */
1274 structCpy.wcoEnable = wcoEnableTmp;
1275 }
1276 }
1277 else
1278 {
1279 message->praStatus = CY_PRA_STATUS_SUCCESS;
1280 }
1281 }
1282 break;
1283
1284 case CY_PRA_CLK_FUNC_WCO_BYPASS:
1285 {
1286 bool bypassEnableTmp;
1287 /* Backups old values */
1288 bypassEnableTmp = structCpy.bypassEnable;
1289 structCpy.bypassEnable = ((cy_en_wco_bypass_modes_t) message->praData1 == CY_SYSCLK_WCO_BYPASSED) ? true : false;
1290 message->praStatus = CY_PRA_STATUS_SUCCESS;
1291 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1292 {
1293 /* The bypass value will be written to the register only when WCO is enabled */
1294 if (structCpy.wcoEnable)
1295 {
1296 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1297 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1298 {
1299 /* On failure, previous values are restored */
1300 structCpy.bypassEnable = bypassEnableTmp;
1301 }
1302 }
1303 }
1304 }
1305 break;
1306
1307 case CY_PRA_CLK_FUNC_HF_ENABLE:
1308 {
1309 bool clkHFEnable;
1310 message->praStatus = CY_PRA_STATUS_SUCCESS;
1311 /* Backups old values */
1312 switch (message->praData1)
1313 {
1314 case CY_PRA_CLKHF_0:
1315 clkHFEnable = structCpy.clkHF0Enable;
1316 structCpy.clkHF0Enable = true;
1317 break;
1318
1319 case CY_PRA_CLKHF_1:
1320 clkHFEnable = structCpy.clkHF1Enable;
1321 structCpy.clkHF1Enable = true;
1322 break;
1323
1324 case CY_PRA_CLKHF_2:
1325 clkHFEnable = structCpy.clkHF2Enable;
1326 structCpy.clkHF2Enable = true;
1327 break;
1328
1329 case CY_PRA_CLKHF_3:
1330 clkHFEnable = structCpy.clkHF3Enable;
1331 structCpy.clkHF3Enable = true;
1332 break;
1333
1334 case CY_PRA_CLKHF_4:
1335 clkHFEnable = structCpy.clkHF4Enable;
1336 structCpy.clkHF4Enable = true;
1337 break;
1338
1339 case CY_PRA_CLKHF_5:
1340 clkHFEnable = structCpy.clkHF5Enable;
1341 structCpy.clkHF5Enable = true;
1342 break;
1343
1344 default:
1345 clkHFEnable = false;
1346 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
1347 break;
1348
1349 }
1350 if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1351 {
1352 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1353 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1354 {
1355 /* On failure, previous values are restored */
1356 switch (message->praData1)
1357 {
1358 case CY_PRA_CLKHF_0:
1359 structCpy.clkHF0Enable = clkHFEnable;
1360 break;
1361
1362 case CY_PRA_CLKHF_1:
1363 structCpy.clkHF1Enable = clkHFEnable;
1364 break;
1365
1366 case CY_PRA_CLKHF_2:
1367 structCpy.clkHF2Enable = clkHFEnable;
1368 break;
1369
1370 case CY_PRA_CLKHF_3:
1371 structCpy.clkHF3Enable = clkHFEnable;
1372 break;
1373
1374 case CY_PRA_CLKHF_4:
1375 structCpy.clkHF4Enable = clkHFEnable;
1376 break;
1377
1378 case CY_PRA_CLKHF_5:
1379 structCpy.clkHF5Enable = clkHFEnable;
1380 break;
1381
1382 default:
1383 /* Unknown Clock HF source */
1384 break;
1385 }
1386 }
1387 }
1388 }
1389 break;
1390
1391 case CY_PRA_CLK_FUNC_HF_DISABLE:
1392 {
1393 bool clkHFEnable;
1394 message->praStatus = CY_PRA_STATUS_SUCCESS;
1395 /* Backups old values */
1396 switch (message->praData1)
1397 {
1398 case CY_PRA_CLKHF_0:
1399 clkHFEnable = structCpy.clkHF0Enable;
1400 structCpy.clkHF0Enable = false;
1401 break;
1402
1403 case CY_PRA_CLKHF_1:
1404 clkHFEnable = structCpy.clkHF1Enable;
1405 structCpy.clkHF1Enable = false;
1406 break;
1407
1408 case CY_PRA_CLKHF_2:
1409 clkHFEnable = structCpy.clkHF2Enable;
1410 structCpy.clkHF2Enable = false;
1411 break;
1412
1413 case CY_PRA_CLKHF_3:
1414 clkHFEnable = structCpy.clkHF3Enable;
1415 structCpy.clkHF3Enable = false;
1416 break;
1417
1418 case CY_PRA_CLKHF_4:
1419 clkHFEnable = structCpy.clkHF4Enable;
1420 structCpy.clkHF4Enable = false;
1421 break;
1422
1423 case CY_PRA_CLKHF_5:
1424 clkHFEnable = structCpy.clkHF5Enable;
1425 structCpy.clkHF5Enable = false;
1426 break;
1427
1428 default:
1429 clkHFEnable = false;
1430 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
1431 break;
1432
1433 }
1434 if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1435 {
1436 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1437 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1438 {
1439 /* On failure, previous values are restored */
1440 switch (message->praData1)
1441 {
1442 case CY_PRA_CLKHF_0:
1443 structCpy.clkHF0Enable = clkHFEnable;
1444 break;
1445
1446 case CY_PRA_CLKHF_1:
1447 structCpy.clkHF1Enable = clkHFEnable;
1448 break;
1449
1450 case CY_PRA_CLKHF_2:
1451 structCpy.clkHF2Enable = clkHFEnable;
1452 break;
1453
1454 case CY_PRA_CLKHF_3:
1455 structCpy.clkHF3Enable = clkHFEnable;
1456 break;
1457
1458 case CY_PRA_CLKHF_4:
1459 structCpy.clkHF4Enable = clkHFEnable;
1460 break;
1461
1462 case CY_PRA_CLKHF_5:
1463 structCpy.clkHF5Enable = clkHFEnable;
1464 break;
1465
1466 default:
1467 /* Unknown Clock HF source */
1468 break;
1469 }
1470 }
1471 }
1472 }
1473 break;
1474
1475 case CY_PRA_CLK_FUNC_HF_SET_SOURCE:
1476 {
1477 cy_en_clkhf_in_sources_t hfSource;
1478 uint32_t hfOutFreqMHz;
1479 bool hfEnabled;
1480 message->praStatus = CY_PRA_STATUS_SUCCESS;
1481 /* Backups old values */
1482 switch (((cy_stc_pra_clkhfsetsource_t *) message->praData1)->clkHf)
1483 {
1484 case CY_PRA_CLKHF_0:
1485 hfSource = structCpy.hf0Source;
1486 structCpy.hf0Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1487 hfOutFreqMHz = structCpy.hf0OutFreqMHz;
1488 hfEnabled = structCpy.clkHF0Enable;
1489 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1490 structCpy.hf0OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source)/(1UL << (uint32_t)structCpy.hf0Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1491 break;
1492
1493 case CY_PRA_CLKHF_1:
1494 hfSource = structCpy.hf1Source;
1495 structCpy.hf1Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1496 hfOutFreqMHz = structCpy.hf1OutFreqMHz;
1497 hfEnabled = structCpy.clkHF1Enable;
1498 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1499 structCpy.hf1OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf1Source)/(1UL << (uint32_t)structCpy.hf1Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1500 break;
1501
1502 case CY_PRA_CLKHF_2:
1503 hfSource = structCpy.hf2Source;
1504 structCpy.hf2Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1505 hfOutFreqMHz = structCpy.hf2OutFreqMHz;
1506 hfEnabled = structCpy.clkHF2Enable;
1507 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1508 structCpy.hf2OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf2Source)/(1UL << (uint32_t)structCpy.hf2Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1509 break;
1510
1511 case CY_PRA_CLKHF_3:
1512 hfSource = structCpy.hf3Source;
1513 structCpy.hf3Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1514 hfOutFreqMHz = structCpy.hf3OutFreqMHz;
1515 hfEnabled = structCpy.clkHF3Enable;
1516 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1517 structCpy.hf3OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf3Source)/(1UL << (uint32_t)structCpy.hf3Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1518 break;
1519
1520 case CY_PRA_CLKHF_4:
1521 hfSource = structCpy.hf4Source;
1522 structCpy.hf4Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1523 hfOutFreqMHz = structCpy.hf4OutFreqMHz;
1524 hfEnabled = structCpy.clkHF4Enable;
1525 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1526 structCpy.hf4OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf4Source)/(1UL << (uint32_t)structCpy.hf4Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1527 break;
1528
1529 case CY_PRA_CLKHF_5:
1530 hfSource = structCpy.hf5Source;
1531 structCpy.hf5Source = ((cy_stc_pra_clkhfsetsource_t *) message->praData1)->source;
1532 hfOutFreqMHz = structCpy.hf5OutFreqMHz;
1533 hfEnabled = structCpy.clkHF5Enable;
1534 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1535 structCpy.hf5OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf5Source)/(1UL << (uint32_t)structCpy.hf5Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1536 break;
1537
1538 default:
1539 hfEnabled = false;
1540 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
1541 break;
1542 }
1543 /* The HF source value is updated in the register only when
1544 * that particular HF is enabled. Otherwise, it is stored in
1545 * the system config structure
1546 */
1547 if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (hfEnabled) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1548 {
1549 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1550 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1551 {
1552 /* On failure, previous values are restored */
1553 switch (((cy_stc_pra_clkhfsetsource_t *) message->praData1)->clkHf)
1554 {
1555 case CY_PRA_CLKHF_0:
1556 structCpy.hf0Source = hfSource;
1557 structCpy.hf0OutFreqMHz = hfOutFreqMHz;
1558 break;
1559
1560 case CY_PRA_CLKHF_1:
1561 structCpy.hf1Source = hfSource;
1562 structCpy.hf1OutFreqMHz = hfOutFreqMHz;
1563 break;
1564
1565 case CY_PRA_CLKHF_2:
1566 structCpy.hf2Source = hfSource;
1567 structCpy.hf2OutFreqMHz = hfOutFreqMHz;
1568 break;
1569
1570 case CY_PRA_CLKHF_3:
1571 structCpy.hf3Source = hfSource;
1572 structCpy.hf3OutFreqMHz = hfOutFreqMHz;
1573 break;
1574
1575 case CY_PRA_CLKHF_4:
1576 structCpy.hf4Source = hfSource;
1577 structCpy.hf4OutFreqMHz = hfOutFreqMHz;
1578 break;
1579
1580 case CY_PRA_CLKHF_5:
1581 structCpy.hf5Source = hfSource;
1582 structCpy.hf5OutFreqMHz = hfOutFreqMHz;
1583 break;
1584
1585 default:
1586 /* Unknown Clock HF source */
1587 break;
1588 }
1589 }
1590 }
1591 }
1592 break;
1593
1594 case CY_PRA_CLK_FUNC_HF_SET_DIVIDER:
1595 {
1596 cy_en_clkhf_dividers_t hfDivider;
1597 uint32_t hfOutFreqMHz;
1598 bool hfEnabled;
1599 message->praStatus = CY_PRA_STATUS_SUCCESS;
1600 /* Backups old values */
1601 switch (((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->clkHf)
1602 {
1603 case CY_PRA_CLKHF_0:
1604 hfDivider = structCpy.hf0Divider;
1605 structCpy.hf0Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1606 hfOutFreqMHz = structCpy.hf0OutFreqMHz;
1607 hfEnabled = structCpy.clkHF0Enable;
1608 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1609 structCpy.hf0OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source)/(1UL << (uint32_t)structCpy.hf0Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1610 break;
1611
1612 case CY_PRA_CLKHF_1:
1613 hfDivider = structCpy.hf1Divider;
1614 structCpy.hf1Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1615 hfOutFreqMHz = structCpy.hf1OutFreqMHz;
1616 hfEnabled = structCpy.clkHF1Enable;
1617 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1618 structCpy.hf1OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf1Source)/(1UL << (uint32_t)structCpy.hf1Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1619 break;
1620
1621 case CY_PRA_CLKHF_2:
1622 hfDivider = structCpy.hf2Divider;
1623 structCpy.hf2Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1624 hfOutFreqMHz = structCpy.hf2OutFreqMHz;
1625 hfEnabled = structCpy.clkHF2Enable;
1626 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1627 structCpy.hf2OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf2Source)/(1UL << (uint32_t)structCpy.hf2Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1628 break;
1629
1630 case CY_PRA_CLKHF_3:
1631 hfDivider = structCpy.hf3Divider;
1632 structCpy.hf3Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1633 hfOutFreqMHz = structCpy.hf3OutFreqMHz;
1634 hfEnabled = structCpy.clkHF3Enable;
1635 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1636 structCpy.hf3OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf3Source)/(1UL << (uint32_t)structCpy.hf3Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1637 break;
1638
1639 case CY_PRA_CLKHF_4:
1640 hfDivider = structCpy.hf4Divider;
1641 structCpy.hf4Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1642 hfOutFreqMHz = structCpy.hf4OutFreqMHz;
1643 hfEnabled = structCpy.clkHF4Enable;
1644 /* The HF output frequency is not present in the PDL API argument. Update the system config structure with the current HF output frequency value */
1645 structCpy.hf4OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf4Source)/(1UL << (uint32_t)structCpy.hf4Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1646 break;
1647
1648 case CY_PRA_CLKHF_5:
1649 hfDivider = structCpy.hf5Divider;
1650 structCpy.hf5Divider = ((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->divider;
1651 hfOutFreqMHz = structCpy.hf5OutFreqMHz;
1652 hfEnabled = structCpy.clkHF5Enable;
1653 /* The HF output frequency is not present in PDL API argument. So updated the system config structure with current HF output frequency value */
1654 structCpy.hf5OutFreqMHz = (Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf5Source)/(1UL << (uint32_t)structCpy.hf5Divider))/CY_PRA_FREQUENCY_HZ_CONVERSION;
1655 break;
1656
1657 default:
1658 hfEnabled = false;
1659 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
1660 break;
1661 }
1662 /* The HF divider value is updated in the register only when
1663 * that particular HF is enabled. Otherwise, it is stored in
1664 * the system config structure
1665 */
1666 if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (hfEnabled) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1667 {
1668 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1669 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1670 {
1671 /* On failure, previous values are restored */
1672 switch (((cy_stc_pra_clkhfsetdivider_t *) message->praData1)->clkHf)
1673 {
1674 case CY_PRA_CLKHF_0:
1675 structCpy.hf0Divider = hfDivider;
1676 structCpy.hf0OutFreqMHz = hfOutFreqMHz;
1677 break;
1678
1679 case CY_PRA_CLKHF_1:
1680 structCpy.hf1Divider = hfDivider;
1681 structCpy.hf1OutFreqMHz = hfOutFreqMHz;
1682 break;
1683
1684 case CY_PRA_CLKHF_2:
1685 structCpy.hf2Divider = hfDivider;
1686 structCpy.hf2OutFreqMHz = hfOutFreqMHz;
1687 break;
1688
1689 case CY_PRA_CLKHF_3:
1690 structCpy.hf3Divider = hfDivider;
1691 structCpy.hf3OutFreqMHz = hfOutFreqMHz;
1692 break;
1693
1694 case CY_PRA_CLKHF_4:
1695 structCpy.hf4Divider = hfDivider;
1696 structCpy.hf4OutFreqMHz = hfOutFreqMHz;
1697 break;
1698
1699 case CY_PRA_CLKHF_5:
1700 structCpy.hf5Divider = hfDivider;
1701 structCpy.hf5OutFreqMHz = hfOutFreqMHz;
1702 break;
1703
1704 default:
1705 /* Invalid Clock HF Source */
1706 break;
1707 }
1708 }
1709 }
1710 }
1711 break;
1712
1713 case CY_PRA_CLK_FUNC_FAST_SET_DIVIDER:
1714 {
1715 uint8_t clkFastDivTmp;
1716 bool clkFastEnableTmp;
1717 /* Backups old values */
1718 clkFastEnableTmp = structCpy.clkFastEnable;
1719 clkFastDivTmp = structCpy.clkFastDiv;
1720 structCpy.clkFastEnable = true;
1721 structCpy.clkFastDiv = (uint8_t)(message->praData1);
1722 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1723 {
1724 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1725 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1726 {
1727 /* On failure, previous values are restored */
1728 structCpy.clkFastDiv = clkFastDivTmp;
1729 structCpy.clkFastEnable = clkFastEnableTmp;
1730 }
1731 }
1732 else
1733 {
1734 message->praStatus = CY_PRA_STATUS_SUCCESS;
1735 }
1736 }
1737 break;
1738
1739 case CY_PRA_CLK_FUNC_PERI_SET_DIVIDER:
1740 {
1741 uint8_t clkPeriDivTmp;
1742 bool clkPeriEnableTmp;
1743 /* Backups old values */
1744 clkPeriDivTmp = structCpy.clkPeriDiv;
1745 clkPeriEnableTmp = structCpy.clkPeriEnable;
1746 structCpy.clkPeriEnable = true;
1747 structCpy.clkPeriDiv = (uint8_t)(message->praData1);
1748 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1749 {
1750 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1751 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1752 {
1753 /* On failure, previous values are restored */
1754 structCpy.clkPeriDiv = clkPeriDivTmp;
1755 structCpy.clkPeriEnable = clkPeriEnableTmp;
1756 }
1757 }
1758 else
1759 {
1760 message->praStatus = CY_PRA_STATUS_SUCCESS;
1761 }
1762 }
1763 break;
1764
1765 case CY_PRA_CLK_FUNC_LF_SET_SOURCE:
1766 {
1767 cy_en_clklf_in_sources_t clkLfSourceTmp;
1768 bool clkLFEnableTmp;
1769 /* Backups old values */
1770 clkLFEnableTmp = structCpy.clkLFEnable;
1771 clkLfSourceTmp = structCpy.clkLfSource;
1772 structCpy.clkLFEnable = true;
1773 structCpy.clkLfSource = (cy_en_clklf_in_sources_t)message->praData1;
1774 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1775 {
1776 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1777 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1778 {
1779 /* On failure, previous values are restored */
1780 structCpy.clkLfSource = clkLfSourceTmp;
1781 structCpy.clkLFEnable = clkLFEnableTmp;
1782 }
1783 }
1784 else
1785 {
1786 message->praStatus = CY_PRA_STATUS_SUCCESS;
1787 }
1788 }
1789 break;
1790
1791 case CY_PRA_CLK_FUNC_TIMER_SET_SOURCE:
1792 {
1793 cy_en_clktimer_in_sources_t clkTimerSourceTmp;
1794 /* Backups old values */
1795 clkTimerSourceTmp = structCpy.clkTimerSource;
1796 structCpy.clkTimerSource = (cy_en_clktimer_in_sources_t)message->praData1;
1797 message->praStatus = CY_PRA_STATUS_SUCCESS;
1798 if ((structCpy.clkTimerEnable) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1799 {
1800 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1801 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1802 {
1803 /* On failure, previous values are restored */
1804 structCpy.clkTimerSource = clkTimerSourceTmp;
1805 }
1806 }
1807 }
1808 break;
1809
1810 case CY_PRA_CLK_FUNC_TIMER_SET_DIVIDER:
1811 {
1812 uint8_t clkTimerDividerTmp;
1813 /* Backups old values */
1814 clkTimerDividerTmp = structCpy.clkTimerDivider;
1815 structCpy.clkTimerDivider = (uint8_t)(message->praData1);
1816 message->praStatus = CY_PRA_STATUS_SUCCESS;
1817 /* The timer divider value is updated in the register only
1818 * when CLK_TIMER is enabled. Otherwise, it is only
1819 * stored in the system config structure
1820 */
1821 if ((structCpy.clkTimerEnable) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1822 {
1823 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1824 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1825 {
1826 /* On failure, previous values are restored */
1827 structCpy.clkTimerDivider = clkTimerDividerTmp;
1828 }
1829 }
1830 }
1831 break;
1832
1833 case CY_PRA_CLK_FUNC_TIMER_ENABLE:
1834 {
1835 bool clkTimerEnableTmp;
1836 /* Backups old values */
1837 clkTimerEnableTmp = structCpy.clkTimerEnable;
1838 structCpy.clkTimerEnable = true;
1839 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1840 {
1841 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1842 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1843 {
1844 /* On failure, previous values are restored */
1845 structCpy.clkTimerEnable = clkTimerEnableTmp;
1846 }
1847 }
1848 else
1849 {
1850 message->praStatus = CY_PRA_STATUS_SUCCESS;
1851 }
1852 }
1853 break;
1854
1855 case CY_PRA_CLK_FUNC_TIMER_DISABLE:
1856 {
1857 bool clkTimerEnableTmp;
1858 /* Backups old values */
1859 clkTimerEnableTmp = structCpy.clkTimerEnable;
1860 structCpy.clkTimerEnable = false;
1861 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1862 {
1863 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1864 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1865 {
1866 /* On failure, previous values are restored */
1867 structCpy.clkTimerEnable = clkTimerEnableTmp;
1868 }
1869 }
1870 else
1871 {
1872 message->praStatus = CY_PRA_STATUS_SUCCESS;
1873 }
1874 }
1875 break;
1876
1877 case CY_PRA_CLK_FUNC_PUMP_SET_SOURCE:
1878 {
1879 cy_en_clkpump_in_sources_t pumpSourceTmp;
1880 /* Backups old values */
1881 pumpSourceTmp = structCpy.pumpSource;
1882 structCpy.pumpSource = (cy_en_clkpump_in_sources_t)message->praData1;
1883 message->praStatus = CY_PRA_STATUS_SUCCESS;
1884 /* The PUMP source value is updated in the register only
1885 * when PUMP is enabled. Otherwise, it is only
1886 * stored in the system config structure
1887 */
1888 if ((structCpy.clkPumpEnable) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1889 {
1890 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1891 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1892 {
1893 /* On failure, previous values are restored */
1894 structCpy.pumpSource = pumpSourceTmp;
1895 }
1896 }
1897 }
1898 break;
1899
1900 case CY_PRA_CLK_FUNC_PUMP_SET_DIVIDER:
1901 {
1902 cy_en_clkpump_divide_t pumpDividerTmp;
1903 /* Backups old values */
1904 pumpDividerTmp = structCpy.pumpDivider;
1905 structCpy.pumpDivider = (cy_en_clkpump_divide_t)message->praData1;
1906 message->praStatus = CY_PRA_STATUS_SUCCESS;
1907 /* The PUMP divider value is updated in the register only
1908 * when PUMP is enabled. Otherwise, it is only
1909 * stored in the system config structure
1910 */
1911 if ((structCpy.clkPumpEnable) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
1912 {
1913 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1914 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1915 {
1916 /* On failure, previous values are restored */
1917 structCpy.pumpDivider = pumpDividerTmp;
1918 }
1919 }
1920 }
1921 break;
1922
1923 case CY_PRA_CLK_FUNC_PUMP_ENABLE:
1924 {
1925 bool clkPumpEnableTmp;
1926 /* Backups old values */
1927 clkPumpEnableTmp = structCpy.clkPumpEnable;
1928 structCpy.clkPumpEnable = true;
1929 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1930 {
1931 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1932 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1933 {
1934 /* On failure, previous values are restored */
1935 structCpy.clkPumpEnable = clkPumpEnableTmp;
1936 }
1937 }
1938 else
1939 {
1940 message->praStatus = CY_PRA_STATUS_SUCCESS;
1941 }
1942 }
1943 break;
1944
1945 case CY_PRA_CLK_FUNC_PUMP_DISABLE:
1946 {
1947 bool clkPumpEnableTmp;
1948 /* Backups old values */
1949 clkPumpEnableTmp = structCpy.clkPumpEnable;
1950 structCpy.clkPumpEnable = false;
1951 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1952 {
1953 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1954 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1955 {
1956 /* On failure, previous values are restored */
1957 structCpy.clkPumpEnable = clkPumpEnableTmp;
1958 }
1959 }
1960 else
1961 {
1962 message->praStatus = CY_PRA_STATUS_SUCCESS;
1963 }
1964 }
1965 break;
1966
1967 case CY_PRA_CLK_FUNC_BAK_SET_SOURCE:
1968 {
1969 cy_en_clkbak_in_sources_t clkBakSourceTmp;
1970 bool clkBakEnableTmp;
1971 /* Backups old values */
1972 clkBakEnableTmp = structCpy.clkBakEnable;
1973 clkBakSourceTmp = structCpy.clkBakSource;
1974 structCpy.clkBakEnable = true;
1975 structCpy.clkBakSource = (cy_en_clkbak_in_sources_t)message->praData1;
1976 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
1977 {
1978 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
1979 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
1980 {
1981 /* On failure, previous values are restored */
1982 structCpy.clkBakSource = clkBakSourceTmp;
1983 structCpy.clkBakEnable = clkBakEnableTmp;
1984 }
1985 }
1986 else
1987 {
1988 message->praStatus = CY_PRA_STATUS_SUCCESS;
1989 }
1990 }
1991 break;
1992
1993 case CY_PRA_CLK_FUNC_ECO_CONFIGURE:
1994 {
1995 /* ECO configuration is not allowed if ECO is already enabled.
1996 * The correct sequence is ECO_DISABLE -> ECO_CONFIGURE -> ECO_ENABLE
1997 */
1998 if (structCpy.ecoEnable)
1999 {
2000 message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_ECO_ENABLED;
2001 }
2002 else
2003 {
2004 /* Stored the ECO config values into the system config structure.
2005 * These values are applied to the register after a call from ECO_ENABLE.
2006 */
2007 structCpy.ecoFreqHz = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praClkEcofreq;
2008 structCpy.ecoLoad = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praCsum;
2009 structCpy.ecoEsr = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praEsr;
2010 structCpy.ecoDriveLevel = ((cy_stc_pra_clk_eco_configure_t *) message->praData1)->praDriveLevel;
2011 message->praStatus = CY_PRA_STATUS_SUCCESS;
2012 }
2013 }
2014 break;
2015
2016 case CY_PRA_CLK_FUNC_ECO_ENABLE:
2017 {
2018 bool ecoEnableTmp;
2019 /* Backups old values */
2020 ecoEnableTmp = structCpy.ecoEnable;
2021 structCpy.ecoEnable = true;
2022 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
2023 {
2024 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
2025 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
2026 {
2027 /* On failure, previous values are restored */
2028 structCpy.ecoEnable = ecoEnableTmp;
2029 }
2030 }
2031 else
2032 {
2033 message->praStatus = CY_PRA_STATUS_SUCCESS;
2034 }
2035 }
2036 break;
2037
2038 case CY_PRA_CLK_FUNC_PATH_SET_SOURCE:
2039 {
2040 bool pathEnable = false;
2041 cy_en_clkpath_in_sources_t pathSrc = CY_SYSCLK_CLKPATH_IN_IMO;
2042 message->praStatus = CY_PRA_STATUS_SUCCESS;
2043 /* Backups old values */
2044 switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
2045 {
2046 case CY_PRA_CLKPATH_0:
2047 pathEnable = structCpy.path0Enable;
2048 pathSrc = structCpy.path0Src;
2049 structCpy.path0Enable = true;
2050 structCpy.path0Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2051 break;
2052
2053 case CY_PRA_CLKPATH_1:
2054 pathEnable = structCpy.path1Enable;
2055 pathSrc = structCpy.path1Src;
2056 structCpy.path1Enable = true;
2057 structCpy.path1Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2058 break;
2059
2060 case CY_PRA_CLKPATH_2:
2061 pathEnable = structCpy.path2Enable;
2062 pathSrc = structCpy.path2Src;
2063 structCpy.path2Enable = true;
2064 structCpy.path2Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2065 break;
2066
2067 case CY_PRA_CLKPATH_3:
2068 pathEnable = structCpy.path3Enable;
2069 pathSrc = structCpy.path3Src;
2070 structCpy.path3Enable = true;
2071 structCpy.path3Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2072 break;
2073
2074 case CY_PRA_CLKPATH_4:
2075 pathEnable = structCpy.path4Enable;
2076 pathSrc = structCpy.path4Src;
2077 structCpy.path4Enable = true;
2078 structCpy.path4Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2079 break;
2080
2081 case CY_PRA_CLKPATH_5:
2082 pathEnable = structCpy.path5Enable;
2083 pathSrc = structCpy.path5Src;
2084 structCpy.path5Enable = true;
2085 structCpy.path5Src = ((cy_stc_pra_clkpathsetsource_t *) message->praData1)->source;
2086 break;
2087
2088 default:
2089 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
2090 break;
2091 }
2092 if ((message->praStatus == CY_PRA_STATUS_SUCCESS) && (CY_PRA_SKIP_SYS_CFG != message->praData2))
2093 {
2094 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
2095 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
2096 {
2097 /* On failure, previous path values are restored */
2098 switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
2099 {
2100 case CY_PRA_CLKPATH_0:
2101 structCpy.path0Enable = pathEnable;
2102 structCpy.path0Src = pathSrc;
2103 break;
2104
2105 case CY_PRA_CLKPATH_1:
2106 structCpy.path1Enable = pathEnable;
2107 structCpy.path1Src = pathSrc;
2108 break;
2109
2110 case CY_PRA_CLKPATH_2:
2111 structCpy.path2Enable = pathEnable;
2112 structCpy.path2Src = pathSrc;
2113 break;
2114
2115 case CY_PRA_CLKPATH_3:
2116 structCpy.path3Enable = pathEnable;
2117 structCpy.path3Src = pathSrc;
2118 break;
2119
2120 case CY_PRA_CLKPATH_4:
2121 structCpy.path4Enable = pathEnable;
2122 structCpy.path4Src = pathSrc;
2123 break;
2124
2125 case CY_PRA_CLKPATH_5:
2126 structCpy.path5Enable = pathEnable;
2127 structCpy.path5Src = pathSrc;
2128 break;
2129
2130 default:
2131 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
2132 break;
2133 }
2134 }
2135 else
2136 {
2137 switch (((cy_stc_pra_clkpathsetsource_t *) message->praData1)->clk_path)
2138 {
2139 case CY_PRA_CLKPATH_0:
2140 {
2141 if (structCpy.fllEnable)
2142 {
2143 /* Update FLL output frequency */
2144 structCpy.fllOutFreqHz = Cy_PRA_CalculateFLLOutFreq(&structCpy);
2145 }
2146 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH0)
2147 {
2148 /* Update HF0 output frequency */
2149 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2150 }
2151 }
2152 break;
2153
2154 case CY_PRA_CLKPATH_1:
2155 {
2156 if (structCpy.pll0Enable)
2157 {
2158 /* Update PLL0 output frequency */
2159 structCpy.pll0OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_1, &structCpy);
2160 }
2161 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH1)
2162 {
2163 /* Update HF0 output frequency */
2164 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2165 }
2166 }
2167 break;
2168
2169 case CY_PRA_CLKPATH_2:
2170 {
2171 if (structCpy.pll1Enable)
2172 {
2173 /* Update PLL1 output frequency */
2174 structCpy.pll1OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_2, &structCpy);
2175 }
2176 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH2)
2177 {
2178 /* Update HF0 output frequency */
2179 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2180 }
2181 }
2182 break;
2183
2184 case CY_PRA_CLKPATH_3:
2185 {
2186 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH3)
2187 {
2188 /* Update HF0 output frequency */
2189 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2190 }
2191 }
2192 break;
2193
2194 case CY_PRA_CLKPATH_4:
2195 {
2196 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH4)
2197 {
2198 /* Update HF0 output frequency */
2199 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2200 }
2201 }
2202 break;
2203
2204 case CY_PRA_CLKPATH_5:
2205 {
2206 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH5)
2207 {
2208 /* Update HF0 output frequency */
2209 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2210 }
2211 }
2212 break;
2213
2214 default:
2215 /* Unknown clock path */
2216 break;
2217 }
2218 }
2219 }
2220 }
2221 break;
2222
2223 case CY_PRA_CLK_FUNC_FLL_MANCONFIG:
2224 {
2225 /* FLL manual configuration values are not written to the
2226 * register but stored in the system config structure.
2227 * These values are applied to the register
2228 * after a call from CY_PRA_CLK_FUNC_FLL_ENABLE */
2229 structCpy.fllMult = ((cy_stc_fll_manual_config_t *) message->praData1)->fllMult;
2230 structCpy.fllRefDiv = ((cy_stc_fll_manual_config_t *) message->praData1)->refDiv;
2231 structCpy.fllCcoRange = ((cy_stc_fll_manual_config_t *) message->praData1)->ccoRange;
2232 structCpy.enableOutputDiv = ((cy_stc_fll_manual_config_t *) message->praData1)->enableOutputDiv;
2233 structCpy.lockTolerance = ((cy_stc_fll_manual_config_t *) message->praData1)->lockTolerance;
2234 structCpy.igain = ((cy_stc_fll_manual_config_t *) message->praData1)->igain;
2235 structCpy.pgain = ((cy_stc_fll_manual_config_t *) message->praData1)->pgain;
2236 structCpy.settlingCount = ((cy_stc_fll_manual_config_t *) message->praData1)->settlingCount;
2237 structCpy.outputMode = ((cy_stc_fll_manual_config_t *) message->praData1)->outputMode;
2238 structCpy.ccoFreq = ((cy_stc_fll_manual_config_t *) message->praData1)->cco_Freq;
2239 message->praStatus = CY_PRA_STATUS_SUCCESS;
2240 }
2241 break;
2242
2243 case CY_PRA_CLK_FUNC_FLL_ENABLE:
2244 {
2245 /* FLL Enable is not allowed if it is already enabled */
2246 if (structCpy.fllEnable == true) /* FLL is already enabled */
2247 {
2248 message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_FLL0_ENABLED;
2249 }
2250 else
2251 {
2252 structCpy.fllEnable = true;
2253 /* FLL Enable API does not contain the FLL output value
2254 * as the argument. So, calculate and update the FLL output value */
2255 structCpy.fllOutFreqHz = Cy_PRA_CalculateFLLOutFreq(&structCpy);
2256 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
2257 {
2258 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
2259 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
2260 {
2261 structCpy.fllOutFreqHz = CY_PRA_DEFAULT_ZERO;
2262 structCpy.fllEnable = false;
2263 }
2264 else
2265 {
2266 /* Check if FLL is source to HF0 */
2267 if (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH0)
2268 {
2269 /* Update HF0 output frequency */
2270 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2271 }
2272 }
2273 } /* (CY_PRA_SKIP_SYS_CFG != message->praData2) */
2274 else
2275 {
2276 message->praStatus = CY_PRA_STATUS_SUCCESS;
2277 }
2278 }
2279 }
2280 break;
2281
2282 case CY_PRA_CLK_FUNC_PLL_MANCONFIG:
2283 {
2284 /* Checks for the valid PLL number */
2285 if((((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath == CY_PRA_CLKPATH_0) ||
2286 (((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath > CY_SRSS_NUM_PLL))
2287 {
2288 message->praStatus = CY_PRA_STATUS_INVALID_PARAM_PLL_NUM;
2289 }
2290 else
2291 {
2292 /* PLL manual configuration values are not written to
2293 * the register but stored in the system config structure.
2294 * These values are applied to the register
2295 * after a call from CY_PRA_CLK_FUNC_PLL_ENABLE. */
2296 if(((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->clkPath == CY_PRA_CLKPATH_1)
2297 {
2298 structCpy.pll0FeedbackDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->feedbackDiv;
2299 structCpy.pll0ReferenceDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->referenceDiv;
2300 structCpy.pll0OutputDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputDiv;
2301 structCpy.pll0LfMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->lfMode;
2302 structCpy.pll0OutputMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputMode;
2303 }
2304 else
2305 {
2306 structCpy.pll1FeedbackDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->feedbackDiv;
2307 structCpy.pll1ReferenceDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->referenceDiv;
2308 structCpy.pll1OutputDiv = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputDiv;
2309 structCpy.pll1LfMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->lfMode;
2310 structCpy.pll1OutputMode = ((cy_stc_pra_clk_pll_manconfigure_t *) message->praData1)->praConfig->outputMode;
2311 }
2312 message->praStatus = CY_PRA_STATUS_SUCCESS;
2313 }
2314 }
2315 break;
2316
2317 case CY_PRA_CLK_FUNC_PLL_ENABLE:
2318 {
2319 if ((((message->praData1) == CY_PRA_CLKPLL_1) && (structCpy.pll0Enable == true))
2320 || (((message->praData1) == CY_PRA_CLKPLL_2) && (structCpy.pll1Enable == true))
2321 || (message->praData1 > CY_SRSS_NUM_PLL) || (message->praData1 == 0UL))
2322 {
2323 message->praStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL_ENABLED;
2324 }
2325 else
2326 {
2327 /* PLL Enable API does not contain the PLL output value
2328 * as the argument. So, calculate and update the PLL output value */
2329 if ((message->praData1) == CY_PRA_CLKPLL_1)
2330 {
2331 structCpy.pll0OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_1, &structCpy);
2332 structCpy.pll0Enable = true;
2333 }
2334 else
2335 {
2336 structCpy.pll1OutFreqHz = Cy_PRA_CalculatePLLOutFreq(CY_PRA_CLKPLL_2, &structCpy);
2337 structCpy.pll1Enable = true;
2338 }
2339 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
2340 {
2341 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
2342
2343 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
2344 {
2345 if ((message->praData1) == CY_PRA_CLKPLL_1)
2346 {
2347 structCpy.pll0OutFreqHz = CY_PRA_DEFAULT_ZERO;
2348 structCpy.pll0Enable = false;
2349 }
2350 else
2351 {
2352 structCpy.pll1OutFreqHz = CY_PRA_DEFAULT_ZERO;
2353 structCpy.pll1Enable = false;
2354 }
2355 }
2356 else /* PLL is enabled successfully */
2357 {
2358 /* Check if PLL0 or PLL1 is source to HF0 */
2359 if ((structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH1) || (structCpy.hf0Source == CY_SYSCLK_CLKHF_IN_CLKPATH2))
2360 {
2361 /* Update HF0 output frequency */
2362 structCpy.hf0OutFreqMHz = CY_SYSLIB_DIV_ROUND(Cy_SysClk_ClkPathGetFrequency((uint32_t) structCpy.hf0Source), ((1UL << (uint32_t)structCpy.hf0Divider) * CY_PRA_FREQUENCY_HZ_CONVERSION));
2363 }
2364 }
2365 } /* (CY_PRA_SKIP_SYS_CFG != message->praData2) */
2366 else
2367 {
2368 message->praStatus = CY_PRA_STATUS_SUCCESS;
2369 }
2370
2371 }
2372 }
2373 break;
2374
2375 case CY_PRA_CLK_FUNC_SLOW_SET_DIVIDER:
2376 {
2377 uint8_t clkSlowDivTmp;
2378 bool clkSlowEnableTmp;
2379 /* Backups old values */
2380 clkSlowEnableTmp = structCpy.clkSlowEnable;
2381 clkSlowDivTmp = structCpy.clkSlowDiv;
2382 structCpy.clkSlowEnable = true;
2383 structCpy.clkSlowDiv = (uint8_t)(message->praData1);
2384 if (CY_PRA_SKIP_SYS_CFG != message->praData2)
2385 {
2386 message->praStatus = Cy_PRA_SystemConfig(&structCpy);
2387 if (message->praStatus != CY_PRA_STATUS_SUCCESS)
2388 {
2389 /* On failure, previous path values are restored */
2390 structCpy.clkSlowDiv = clkSlowDivTmp;
2391 structCpy.clkSlowEnable = clkSlowEnableTmp;
2392 }
2393 }
2394 else
2395 {
2396 message->praStatus = CY_PRA_STATUS_SUCCESS;
2397 }
2398 }
2399 break;
2400
2401 case CY_PRA_CLK_FUNC_EXT_CLK_SET_FREQUENCY:
2402 {
2403 structCpy.extClkEnable = true;
2404 structCpy.extClkFreqHz = (uint32_t)(message->praData1);
2405 message->praStatus = CY_PRA_STATUS_SUCCESS;
2406 }
2407 break;
2408
2409 default:
2410 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
2411 break;
2412 }
2413 }
2414 else
2415 {
2416 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
2417 }
2418 break;
2419
2420 default:
2421 message->praStatus = CY_PRA_STATUS_ACCESS_DENIED;
2422 break;
2423 }
2424
2425 }
2426 #endif /* (CY_CPU_CORTEX_M0P) */
2427
2428
2429
2430 /*******************************************************************************
2431 * Function Name: Cy_PRA_SendCmd
2432 ****************************************************************************//**
2433 *
2434 * Takes the parameters, passes them to the secure Cortex-M0+ via IPC, waits for
2435 * Cortex-M0+ to finish and reports the status.
2436 *
2437 * \param cmd The command to execute on the secure side. The macros for this
2438 * parameter are defined in the cy_pra.h file with the CY_PRA_MSG_TYPE_ prefix.
2439 * \param regIndex The index of the function or register depending on the command
2440 * parameter. The macros for this parameter are defined in the cy_pra.h file with
2441 * the CY_PRA_INDX_ prefix.
2442 * \param clearMask Data sent to secure the core.
2443 * \param setMask Additional data send to secure the core.
2444 *
2445 * \return The command execution status. For the register read command, the read
2446 * value is returned.
2447 *
2448 *******************************************************************************/
2449 #if defined(CY_DEVICE_PSOC6ABLE2)
2450
2451 CY_SECTION_RAMFUNC_BEGIN
2452 #if !defined (__ICCARM__)
2453 CY_NOINLINE
2454 #endif
2455 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
Cy_PRA_SendCmd(uint16_t cmd,uint16_t regIndex,uint32_t clearMask,uint32_t setMask)2456 cy_en_pra_status_t Cy_PRA_SendCmd(uint16_t cmd, uint16_t regIndex, uint32_t clearMask, uint32_t setMask)
2457 {
2458 cy_en_pra_status_t status;
2459 #if (CY_CPU_CORTEX_M0P)
2460 /* update structCpy variable */
2461 CY_ALIGN(4UL)cy_stc_pra_msg_t msgLocal;
2462
2463 msgLocal.praCommand = cmd;
2464 msgLocal.praStatus = CY_PRA_STATUS_REQUEST_SENT;
2465 msgLocal.praIndex = regIndex;
2466 msgLocal.praData1 = clearMask;
2467
2468 if (cmd == CY_PRA_MSG_TYPE_FUNC_POLICY)
2469 {
2470 msgLocal.praData2 = CY_PRA_SKIP_SYS_CFG;
2471 Cy_PRA_ProcessCmd(&msgLocal);
2472 status = CY_PRA_STATUS_SUCCESS;
2473 (void)setMask;
2474 }
2475 else if ((cmd == CY_PRA_MSG_TYPE_SYS_CFG_FUNC) && (regIndex == CY_PRA_FUNC_INIT_CYCFG_DEVICE))
2476 {
2477 msgLocal.praData2 = setMask;
2478 Cy_PRA_ProcessCmd(&msgLocal);
2479 status = (cy_en_pra_status_t) msgLocal.praStatus;
2480 }
2481 else
2482 {
2483 status = CY_PRA_STATUS_ACCESS_DENIED;
2484 (void)cmd;
2485 (void)regIndex;
2486 (void)clearMask;
2487 (void)setMask;
2488 }
2489 #else
2490 CY_ASSERT_L1(NULL != ipcPraBase);
2491
2492
2493 CY_ALIGN(4UL) cy_stc_pra_msg_t ipcMsg;
2494 uint32_t interruptState;
2495
2496 ipcMsg.praCommand = cmd;
2497 ipcMsg.praStatus = CY_PRA_STATUS_REQUEST_SENT;
2498 ipcMsg.praIndex = regIndex;
2499 ipcMsg.praData1 = clearMask;
2500 ipcMsg.praData2 = setMask;
2501
2502 interruptState = Cy_SysLib_EnterCriticalSection();
2503
2504 while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(ipcPraBase)))
2505 {
2506 /* Waits until the PRA IPC structure is acquired */
2507 }
2508
2509 /* Sends the message */
2510 REG_IPC_STRUCT_DATA(ipcPraBase) = (uint32_t) &ipcMsg;
2511
2512 /* Generates an acquire notification event by the PRA IPC interrupt structure */
2513 REG_IPC_STRUCT_NOTIFY(ipcPraBase) = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, CY_PRA_IPC_NOTIFY_INTR);
2514
2515 while (0U != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_LOCK_STATUS(ipcPraBase)))
2516 {
2517 /* Waits until the PRA IPC structure is released */
2518 }
2519
2520 Cy_SysLib_ExitCriticalSection(interruptState);
2521
2522 /* Cortex-M0+ has an updated ipcMsg variable */
2523
2524 status = (cy_en_pra_status_t) ipcMsg.praStatus;
2525
2526 if (CY_PRA_STATUS_ACCESS_DENIED == status)
2527 {
2528 CY_HALT();
2529 }
2530
2531 if (CY_PRA_MSG_TYPE_SYS_CFG_FUNC == ipcMsg.praCommand)
2532 {
2533 #if defined(CY_IP_MXBLESS)
2534 /* Update cy_BleEcoClockFreqHz for the proper Cy_SysLib_Delay functionality */
2535 if(((cy_stc_pra_system_config_t *) clearMask)->altHFclkFreq == CY_BLE_BLESS_ECO_FREQ_32MHZ)
2536 {
2537 cy_BleEcoClockFreqHz = CY_PRA_ALTHF_FREQ_32MHZ / (1UL << ((cy_stc_pra_system_config_t *) clearMask)->altHFsysClkDiv);
2538 }
2539 else
2540 {
2541 cy_BleEcoClockFreqHz = CY_PRA_ALTHF_FREQ_16MHZ / (1UL << ((cy_stc_pra_system_config_t *) clearMask)->altHFsysClkDiv);
2542 }
2543
2544 if(((cy_stc_pra_system_config_t *) clearMask)->clkAltHfEnable == false)
2545 {
2546 cy_BleEcoClockFreqHz = 0UL;
2547 }
2548 #endif /* defined(CY_IP_MXBLESS) */
2549
2550 cySysClkExtFreq = ((cy_stc_pra_system_config_t *) clearMask)->extClkFreqHz;
2551
2552 SystemCoreClockUpdate();
2553 }
2554
2555 if (CY_PRA_MSG_TYPE_REG32_GET == ipcMsg.praCommand)
2556 {
2557 status = (cy_en_pra_status_t)ipcMsg.praData1;
2558 }
2559
2560 #endif /* (CY_CPU_CORTEX_M0P) */
2561
2562 return status;
2563 }
2564 #if defined(CY_DEVICE_PSOC6ABLE2)
2565 CY_SECTION_RAMFUNC_END
2566 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
2567
2568 #if (CY_CPU_CORTEX_M4) || defined (CY_DOXYGEN)
2569 /*******************************************************************************
2570 * Function Name: Cy_PRA_GetPinProtType
2571 ****************************************************************************//**
2572 *
2573 * Find the matching PORT and PIN number from External clock secure PIN list and
2574 * returns protection status of the PIN.
2575 *
2576 *******************************************************************************/
Cy_PRA_GetPinProtType(GPIO_PRT_Type * base,uint32_t pinNum)2577 cy_en_pra_pin_prot_type_t Cy_PRA_GetPinProtType(GPIO_PRT_Type *base, uint32_t pinNum)
2578 {
2579 uint32_t index;
2580 cy_en_pra_pin_prot_type_t pinType = CY_PRA_PIN_SECURE_NONE;
2581
2582 if ((NULL != base) && (CY_GPIO_IS_PIN_VALID(pinNum)))
2583 {
2584 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2585 {
2586 if (secExtclkPinList[index].port == base)
2587 {
2588 pinType = CY_PRA_PIN_SECURE_UNCONSTRAINED;
2589
2590 if (secExtclkPinList[index].pinNum == pinNum)
2591 {
2592 pinType = CY_PRA_PIN_SECURE;
2593 break;
2594 }
2595 }
2596 }
2597 }
2598
2599 return pinType;
2600 }
2601
2602 /*******************************************************************************
2603 * Function Name: Cy_PRA_IsPortSecure
2604 ****************************************************************************//**
2605 *
2606 * Find the matching PORT from External clock secure PIN list and returns
2607 * protection status of the PORT.
2608 *
2609 *******************************************************************************/
Cy_PRA_IsPortSecure(GPIO_PRT_Type * base)2610 bool Cy_PRA_IsPortSecure(GPIO_PRT_Type *base)
2611 {
2612 uint32_t index;
2613 bool retPort = false;
2614 if (NULL != base)
2615 {
2616 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2617 {
2618 if (secExtclkPinList[index].port == base)
2619 {
2620 retPort = true;
2621 break;
2622 }
2623 }
2624 }
2625
2626 return retPort;
2627 }
2628
2629 #if defined(CY_DEVICE_PSOC6ABLE2)
2630 /*******************************************************************************
2631 * Function Name: Cy_PRA_IsHsiomSecure
2632 ****************************************************************************//**
2633 *
2634 * Find the matching PORT from External clock adjacent HSIOM list and returns
2635 * protection status of the PORT.
2636 *
2637 *******************************************************************************/
Cy_PRA_IsHsiomSecure(GPIO_PRT_Type * base)2638 bool Cy_PRA_IsHsiomSecure(GPIO_PRT_Type *base)
2639 {
2640 uint32_t index;
2641 bool retPort = false;
2642 if (NULL != base)
2643 {
2644 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2645 {
2646 if (secExtClkAdjHsiomList[index].port == base)
2647 {
2648 retPort = true;
2649 break;
2650 }
2651 }
2652 }
2653
2654 return retPort;
2655 }
2656
2657 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
2658
2659 /*******************************************************************************
2660 * Function Name: Cy_PRA_GetPortRegIndex
2661 ****************************************************************************//**
2662 *
2663 * Find the matching PORT and PIN number from External clock secure PIN list and
2664 * returns port address index
2665 *
2666 *******************************************************************************/
Cy_PRA_GetPortRegIndex(GPIO_PRT_Type * base,uint16_t subIndex)2667 uint16_t Cy_PRA_GetPortRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
2668 {
2669 uint32_t index;
2670 uint16_t portIndex;
2671 uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */
2672
2673 if (NULL != base)
2674 {
2675 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2676 {
2677 if (secExtclkPinList[index].port == base)
2678 {
2679 portIndex = secExtclkPinList[index].index;
2680
2681 switch (subIndex)
2682 {
2683 case CY_PRA_SUB_INDEX_PORT_OUT:
2684 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT), 4U);
2685 break;
2686 case CY_PRA_SUB_INDEX_PORT_OUT_CLR:
2687 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_CLR), 4U);
2688 break;
2689 case CY_PRA_SUB_INDEX_PORT_OUT_SET:
2690 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_SET), 4U);
2691 break;
2692 case CY_PRA_SUB_INDEX_PORT_OUT_INV:
2693 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, OUT_INV), 4U);
2694 break;
2695 case CY_PRA_SUB_INDEX_PORT_IN:
2696 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, IN), 4U);
2697 break;
2698 case CY_PRA_SUB_INDEX_PORT_INTR:
2699 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR), 4U);
2700 break;
2701 case CY_PRA_SUB_INDEX_PORT_INTR_MASK:
2702 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASK), 4U);
2703 break;
2704 case CY_PRA_SUB_INDEX_PORT_INTR_MASKED:
2705 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_MASKED), 4U);
2706 break;
2707 case CY_PRA_SUB_INDEX_PORT_INTR_SET:
2708 retIndex = portIndex + CY_SYSLIB_DIV_ROUND(offsetof(GPIO_PRT_Type, INTR_SET), 4U);
2709 break;
2710 case CY_PRA_SUB_INDEX_PORT_INTR_CFG:
2711 retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtIntrCfgOffset), 4U);
2712 break;
2713 case CY_PRA_SUB_INDEX_PORT_CFG:
2714 retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOffset), 4U);
2715 break;
2716 case CY_PRA_SUB_INDEX_PORT_CFG_IN:
2717 retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgInOffset), 4U);
2718 break;
2719 case CY_PRA_SUB_INDEX_PORT_CFG_OUT:
2720 retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgOutOffset), 4U);
2721 break;
2722 case CY_PRA_SUB_INDEX_PORT_CFG_SIO:
2723 retIndex = portIndex + CY_SYSLIB_DIV_ROUND((uint16_t)(cy_device->gpioPrtCfgSioOffset), 4U);
2724 break;
2725 default:
2726 retIndex = CY_PRA_REG_INDEX_COUNT;
2727 break;
2728 }
2729
2730 break;
2731 }
2732 }
2733 }
2734 return retIndex;
2735 }
2736
2737 /*******************************************************************************
2738 * Function Name: Cy_PRA_GetHsiomRegIndex
2739 ****************************************************************************//**
2740 *
2741 * Find the matching PORT address from External clock secure PIN list and
2742 * returns HSIOM port address index
2743 *
2744 *******************************************************************************/
Cy_PRA_GetHsiomRegIndex(GPIO_PRT_Type * base,uint16_t subIndex)2745 uint16_t Cy_PRA_GetHsiomRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
2746 {
2747 uint32_t index;
2748 uint16_t hsiomIndex;
2749 uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */
2750
2751 if (NULL != base)
2752 {
2753 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2754 {
2755 if (secExtclkPinList[index].port == base)
2756 {
2757 hsiomIndex = secExtclkPinList[index].hsiomIndex;
2758
2759 switch (subIndex)
2760 {
2761 case CY_PRA_SUB_INDEX_HSIOM_PORT0:
2762 retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U);
2763 break;
2764 case CY_PRA_SUB_INDEX_HSIOM_PORT1:
2765 retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U);
2766 break;
2767 default:
2768 retIndex = CY_PRA_REG_INDEX_COUNT;
2769 break;
2770 }
2771 break;
2772 }
2773 }
2774 }
2775 return retIndex;
2776 }
2777
2778 #if defined(CY_DEVICE_PSOC6ABLE2)
2779 /*******************************************************************************
2780 * Function Name: Cy_PRA_GetAdjHsiomRegIndex
2781 ****************************************************************************//**
2782 *
2783 * Find the matching PORT address from External clock adjacent hsiom list and
2784 * returns HSIOM port address index
2785 *
2786 *******************************************************************************/
Cy_PRA_GetAdjHsiomRegIndex(GPIO_PRT_Type * base,uint16_t subIndex)2787 uint16_t Cy_PRA_GetAdjHsiomRegIndex(GPIO_PRT_Type *base, uint16_t subIndex)
2788 {
2789 uint32_t index;
2790 uint16_t hsiomIndex;
2791 uint16_t retIndex = CY_PRA_REG_INDEX_COUNT; /* assigned with invalid index */
2792
2793 if (NULL != base)
2794 {
2795 for (index=0; index<CY_PRA_EXTCLK_PIN_NR; index++)
2796 {
2797 if (secExtClkAdjHsiomList[index].port == base)
2798 {
2799 hsiomIndex = secExtClkAdjHsiomList[index].hsiomIndex;
2800
2801 switch (subIndex)
2802 {
2803 case CY_PRA_SUB_INDEX_HSIOM_PORT0:
2804 retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL0), 4U);
2805 break;
2806 case CY_PRA_SUB_INDEX_HSIOM_PORT1:
2807 retIndex = hsiomIndex + CY_SYSLIB_DIV_ROUND(offsetof(HSIOM_PRT_V1_Type, PORT_SEL1), 4U);
2808 break;
2809 default:
2810 retIndex = CY_PRA_REG_INDEX_COUNT;
2811 break;
2812 }
2813 break;
2814 }
2815 }
2816 }
2817 return retIndex;
2818 }
2819 #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
2820
2821 #endif /* (CY_CPU_CORTEX_M4) */
2822
2823
2824 #if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
2825
2826 /* The mask to unlock Hibernate power mode */
2827 #define HIBERNATE_UNLOCK_VAL ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)
2828
2829 /* The mask to set Hibernate power mode */
2830 #define SET_HIBERNATE_MODE ((HIBERNATE_UNLOCK_VAL |\
2831 SRSS_PWR_HIBERNATE_FREEZE_Msk |\
2832 SRSS_PWR_HIBERNATE_HIBERNATE_Msk))
2833
2834 /* The mask to retain Hibernate power mode status */
2835 #define HIBERNATE_RETAIN_STATUS_MASK ((SRSS_PWR_HIBERNATE_TOKEN_Msk |\
2836 SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
2837 SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
2838 SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
2839 SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
2840
2841 /** The mask for Hibernate wakeup sources */
2842 #define HIBERNATE_WAKEUP_MASK ((SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
2843 SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
2844 SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
2845 SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
2846
2847 /** The define to update the token to indicate the transition into Hibernate */
2848 #define HIBERNATE_TOKEN ((uint32_t) 0x1BU << SRSS_PWR_HIBERNATE_TOKEN_Pos)
2849
2850
2851 /*******************************************************************************
2852 * Function Name: Cy_PRA_PmHibernate
2853 ****************************************************************************//**
2854 *
2855 * Updates the SRSS_PWR_HIBERNATE register for the Cy_SysPm_SystemEnterHibernate and
2856 * Cy_SysPm_IoUnfreeze functions.
2857 *
2858 *******************************************************************************/
Cy_PRA_PmHibernate(uint32_t funcProc)2859 static void Cy_PRA_PmHibernate(uint32_t funcProc)
2860 {
2861
2862 if(0UL == funcProc)
2863 {
2864 /* Saves the token to be retained through a wakeup sequence.
2865 * This could be used by Cy_SysLib_GetResetReason() to differentiate
2866 * Wakeup from a general reset event.
2867 * Saves the wakeup source(s) configuration.
2868 */
2869 SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_WAKEUP_MASK) | HIBERNATE_TOKEN;
2870
2871 /* Disables the overriding the next pin-freeze command by the peripherals */
2872 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
2873
2874 /* The second write causes freezing of I/O cells to save the I/O-cell state */
2875 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
2876
2877 /* The third write cause system to enter Hibernate */
2878 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
2879 }
2880 else
2881 {
2882 /* Saves the last reset reason and wakeup polarity. Then, unfreeze I/O:
2883 * writes PWR_HIBERNATE.FREEZE=0, .UNLOCK=0x3A, .HIBERANTE=0
2884 */
2885 SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_RETAIN_STATUS_MASK) | HIBERNATE_UNLOCK_VAL;
2886
2887 /* Locks Hibernate mode:
2888 * write PWR_HIBERNATE.HIBERNATE=0, UNLOCK=0x00, HIBERANTE=0
2889 */
2890 SRSS_PWR_HIBERNATE &= HIBERNATE_RETAIN_STATUS_MASK;
2891 }
2892 }
2893
2894
2895 /*******************************************************************************
2896 * Function Name: Cy_PRA_PmCm4DpFlagSet
2897 ****************************************************************************//**
2898 *
2899 * Sets Deep Sleep Flag for the CM4 core.
2900 *
2901 *******************************************************************************/
Cy_PRA_PmCm4DpFlagSet(void)2902 static void Cy_PRA_PmCm4DpFlagSet(void)
2903 {
2904 uint32_t ddftStructData;
2905
2906 /* Acquires the IPC to prevent the changing of the shared resources at the same time */
2907 while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
2908 {
2909 /* Waits until the IPC structure is released by another CPU */
2910 }
2911
2912 ddftStructData = REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
2913
2914 /* Updates the CM4 core Deep Sleep mask */
2915 ddftStructData |= (0x01UL << 28u);
2916
2917 /* Updates the pointer to the latest saved structure */
2918 REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = ddftStructData;
2919
2920 /* Releases the IPC */
2921 REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
2922
2923 /* Reads the release value to make sure it is set */
2924 (void) REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
2925 }
2926
2927 /* The timeout count for function Cy_PRA_ClkDeepSleepCallback() is sufficiently large for ~1 second */
2928 #define CY_PRA_TIMEOUT (1000000UL)
2929 /* These variables act as locks to prevent collisions between clock measurement and entry into
2930 Deep Sleep mode. See Cy_SysClk_DeepSleep(). */
2931 static uint16_t changedSourcePaths = CY_PRA_DEFAULT_ZERO;
2932 static uint16_t pllAutoModes = CY_PRA_DEFAULT_ZERO;
2933
2934
2935 /*******************************************************************************
2936 * Function Name: Cy_PRA_ClkDSBeforeTransition
2937 ****************************************************************************//**
2938 *
2939 * SysClock before deep sleep transition.
2940 *
2941 *******************************************************************************/
Cy_PRA_ClkDSBeforeTransition(void)2942 static cy_en_pra_status_t Cy_PRA_ClkDSBeforeTransition(void)
2943 {
2944 uint32_t fllPll; /* 0 = FLL, all other values = a PLL */
2945
2946 /* Initializes the storage of changed paths */
2947 changedSourcePaths = CY_PRA_DEFAULT_ZERO;
2948 pllAutoModes = CY_PRA_DEFAULT_ZERO;
2949
2950 /* For FLL and each PLL */
2951 for (fllPll = 0UL; fllPll <= CY_SRSS_NUM_PLL; fllPll++)
2952 {
2953 /* If FLL or PLL is enabled */
2954 if ((0UL == fllPll) ? Cy_SysClk_FllIsEnabled() : Cy_SysClk_PllIsEnabled(fllPll))
2955 {
2956 /* And the FLL/PLL has ECO as a source */
2957 if (Cy_SysClk_ClkPathGetSource(fllPll) == CY_SYSCLK_CLKPATH_IN_ECO)
2958 {
2959 /* Bypasses the FLL/PLL */
2960 if (0UL == fllPll)
2961 {
2962 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2963 }
2964 else
2965 {
2966 if (((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllPll - 1UL])) ||
2967 ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO1 == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllPll - 1UL])))
2968 {
2969 pllAutoModes |= (uint16_t)(1UL << fllPll);
2970 }
2971
2972 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2973 }
2974
2975 /* Changes this path source to IMO */
2976 (void)Cy_SysClk_ClkPathSetSource(fllPll, CY_SYSCLK_CLKPATH_IN_IMO);
2977
2978 /* Stores a record that this path source was changed from ECO */
2979 changedSourcePaths |= (uint16_t)(1UL << fllPll);
2980 }
2981 else if (0UL == fllPll)
2982 {
2983 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2984 }
2985 else
2986 {
2987 /* Does nothing */
2988 }
2989 }
2990 }
2991
2992 return CY_PRA_STATUS_SUCCESS;
2993 }
2994
2995 /*******************************************************************************
2996 * Function Name: Cy_PRA_ClkDSAfterTransition
2997 ****************************************************************************//**
2998 *
2999 * SysClock after Deep Sleep transition.
3000 *
3001 *******************************************************************************/
Cy_PRA_ClkDSAfterTransition(void)3002 static cy_en_pra_status_t Cy_PRA_ClkDSAfterTransition(void)
3003 {
3004 /* Bit-mapped paths with enabled FLL/PLL sourced by ECO */
3005 uint32_t timeout = CY_PRA_TIMEOUT;
3006 cy_en_pra_status_t retVal = CY_PRA_STATUS_ERROR_SYSPM_TIMEOUT;
3007
3008 /* After return from Deep Sleep, for each FLL/PLL, if needed, restore the source to ECO.
3009 * And block until the FLL/PLL has regained its frequency lock.
3010 */
3011 if (0U != changedSourcePaths)
3012 {
3013 /* If any FLL/PLL was sourced by the ECO, the timeout waits for the ECO to become fully stabilized again */
3014 while ((CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeout))
3015 {
3016 timeout--;
3017 }
3018
3019 if (0UL != timeout)
3020 {
3021 uint32_t fllPll; /* 0 = FLL, all other values = PLL */
3022
3023 for (fllPll = 0UL; fllPll <= CY_SRSS_NUM_PLL; fllPll++)
3024 {
3025 /* If there is a correspondent record about a changed clock source */
3026 if (0U != (changedSourcePaths & (uint16_t)(1UL << fllPll)))
3027 {
3028 /* Changes this path source back to ECO */
3029 (void)Cy_SysClk_ClkPathSetSource(fllPll, CY_SYSCLK_CLKPATH_IN_ECO);
3030
3031 /* The timeout waits for FLL/PLL to regain a lock.
3032 * Split FLL and PLL lock polling loops into two separate threads to minimize one polling loop duration.
3033 */
3034 if (0UL == fllPll)
3035 {
3036 while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
3037 {
3038 timeout--;
3039 }
3040 }
3041 else
3042 {
3043 while ((!Cy_SysClk_PllLocked(fllPll)) && (0UL != timeout))
3044 {
3045 timeout--;
3046 }
3047 }
3048
3049 if (0UL != timeout)
3050 {
3051 /* Undoes the bypass for FLL/PLL */
3052 if (0UL == fllPll)
3053 {
3054 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
3055 }
3056 else
3057 {
3058 if (0U != (pllAutoModes & (uint16_t)(1UL << fllPll)))
3059 {
3060 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_AUTO);
3061 }
3062 else
3063 {
3064 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllPll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
3065 }
3066 }
3067
3068 retVal = CY_PRA_STATUS_SUCCESS;
3069 }
3070 }
3071 }
3072 }
3073 }
3074 else if (Cy_SysClk_FllIsEnabled())
3075 {
3076 /* The timeout waits for FLL to regain a lock */
3077 while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
3078 {
3079 timeout--;
3080 }
3081
3082 if (0UL != timeout)
3083 {
3084 /* Undoes the bypass for FLL */
3085 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
3086 retVal = CY_PRA_STATUS_SUCCESS;
3087 }
3088 }
3089 else
3090 {
3091 retVal = CY_PRA_STATUS_SUCCESS;
3092 }
3093
3094 return (retVal);
3095 }
3096
3097 /*******************************************************************************
3098 * Function Name: Cy_PRA_RegAccessRangeValid
3099 ****************************************************************************//**
3100 *
3101 * Checks if the access is within the valid range and the access address is non-zero.
3102 *
3103 * \param index The index of the accessed register.
3104 *
3105 * \return Returns true for the valid access.
3106 *
3107 *******************************************************************************/
Cy_PRA_RegAccessRangeValid(uint16_t index)3108 static bool Cy_PRA_RegAccessRangeValid(uint16_t index)
3109 {
3110 bool accessValid = true;
3111
3112 /* Checks if access is within the array range */
3113 if (index >= CY_PRA_REG_INDEX_COUNT)
3114 {
3115 accessValid = false;
3116 }
3117 else
3118 {
3119 /* Some registers do not exist for some families */
3120 if (regIndexToAddr[index].addr == (const volatile uint32_t *) 0U)
3121 {
3122 accessValid = false;
3123 }
3124 }
3125
3126 return accessValid;
3127 }
3128
3129
3130 /*******************************************************************************
3131 * Function Name: Cy_PRA_ClocksReset
3132 ****************************************************************************//**
3133 *
3134 * Initializes system clocks and dividers to the default state after reset.
3135 *
3136 *******************************************************************************/
Cy_PRA_ClocksReset(void)3137 static cy_en_pra_status_t Cy_PRA_ClocksReset(void)
3138 {
3139 cy_en_pra_status_t returnStatus = CY_PRA_STATUS_SUCCESS;
3140 cy_en_sysclk_status_t sysClkStatus = CY_SYSCLK_SUCCESS;
3141
3142 /* Sets the worst case memory wait states (! ultra low power, 150 MHz) */
3143 Cy_SysLib_SetWaitStates(false, CY_PRA_150MHZ_FREQUENCY);
3144
3145 /* Resets the core clock path to default and disable all the FLLs/PLLs after Reset or Software reset */
3146 sysClkStatus = Cy_SysClk_ClkHfSetDivider(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_NO_DIVIDE);
3147 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3148 {
3149 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
3150 }
3151
3152 /* Sets the default divider for FAST, PERI and SLOW clocks */
3153 Cy_SysClk_ClkFastSetDivider(CY_PRA_DIVIDER_0);
3154 Cy_SysClk_ClkPeriSetDivider(CY_PRA_DIVIDER_1);
3155 Cy_SysClk_ClkSlowSetDivider(CY_PRA_DIVIDER_0);
3156
3157 SystemCoreClockUpdate();
3158
3159 /* Disables All PLLs */
3160 if (CY_SRSS_NUM_PLL >= CY_PRA_CLKPLL_1)
3161 {
3162 sysClkStatus = Cy_SysClk_PllDisable(CY_PRA_CLKPLL_1);
3163 }
3164
3165 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3166 {
3167 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL0;
3168 }
3169
3170 if (CY_SRSS_NUM_PLL >= CY_PRA_CLKPLL_2)
3171 {
3172 sysClkStatus = Cy_SysClk_PllDisable(CY_PRA_CLKPLL_2);
3173 }
3174
3175 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3176 {
3177 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PLL1;
3178 }
3179
3180 /* Sets the CLK_PATH1 source to IMO */
3181 sysClkStatus = Cy_SysClk_ClkPathSetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH1, CY_SYSCLK_CLKPATH_IN_IMO);
3182 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3183 {
3184 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PATHMUX1;
3185 }
3186
3187 /* Set the HF0 source to IMO if it is sourced from WCO */
3188 if (CY_SYSCLK_CLKHF_IN_CLKPATH0 == Cy_SysClk_ClkHfGetSource(CY_PRA_CLKHF_0))
3189 {
3190 if (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH0))
3191 {
3192 sysClkStatus = Cy_SysClk_ClkHfSetSource(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_IN_CLKPATH1);
3193 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3194 {
3195 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
3196 }
3197 SystemCoreClockUpdate();
3198 }
3199 }
3200
3201 sysClkStatus = Cy_SysClk_FllDisable();
3202 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3203 {
3204 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_FLL0;
3205 }
3206
3207 /* Sets the CLK_PATH0 source to IMO */
3208 sysClkStatus = Cy_SysClk_ClkPathSetSource((uint32_t) CY_SYSCLK_CLKHF_IN_CLKPATH0, CY_SYSCLK_CLKPATH_IN_IMO);
3209 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3210 {
3211 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PATHMUX0;
3212 }
3213
3214 /* Sets the HF0 source to IMO via CLK_PATH0 */
3215 sysClkStatus = Cy_SysClk_ClkHfSetSource(CY_PRA_CLKHF_0, CY_SYSCLK_CLKHF_IN_CLKPATH0);
3216 if (CY_SYSCLK_SUCCESS != sysClkStatus)
3217 {
3218 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_CLKHF0;
3219 }
3220
3221 #ifdef CY_IP_MXBLESS
3222 Cy_BLE_EcoReset();
3223 #endif
3224
3225 return returnStatus;
3226 }
3227
3228
3229 /*******************************************************************************
3230 * Function Name: Cy_PRA_BackupReset
3231 ****************************************************************************//**
3232 *
3233 * Resets the Backup domain and system clocks after System reset.
3234 *
3235 *******************************************************************************/
Cy_PRA_BackupReset(bool iloHibernateON)3236 static cy_en_pra_status_t Cy_PRA_BackupReset(bool iloHibernateON)
3237 {
3238 cy_en_pra_status_t returnStatus = CY_PRA_STATUS_SUCCESS;
3239
3240 if (CY_SYSLIB_SUCCESS != Cy_SysLib_ResetBackupDomain())
3241 {
3242 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PWR;
3243 }
3244 else
3245 {
3246 if (Cy_SysClk_IloIsEnabled())
3247 {
3248 if (CY_SYSCLK_SUCCESS != Cy_SysClk_IloDisable())
3249 {
3250 returnStatus = CY_PRA_STATUS_ERROR_PROCESSING_PWR;
3251 }
3252 }
3253
3254 if (CY_PRA_STATUS_SUCCESS == returnStatus)
3255 {
3256 Cy_SysClk_IloEnable();
3257 Cy_SysClk_IloHibernateOn(iloHibernateON);
3258 }
3259 }
3260
3261 return returnStatus;
3262 }
3263
3264 /*******************************************************************************
3265 * Function Name: Cy_PRA_ValidateSramPowerMode
3266 ****************************************************************************//**
3267 *
3268 * Validate SRAM power mode for a particular macro.
3269 *
3270 *******************************************************************************/
Cy_PRA_ValidateSramPowerMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)3271 static cy_en_pra_status_t Cy_PRA_ValidateSramPowerMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
3272 {
3273 uint32_t macroConfigIndex;
3274 cy_en_pra_status_t praStatus = CY_PRA_STATUS_SUCCESS;
3275
3276 if (((uint8_t)sramNum < CY_PRA_SRAM_MAX_NR) && ((uint8_t)sramMacroNum < CY_PRA_SRAM_MACRO_MAX_NR))
3277 {
3278 /* find the sram macro */
3279 for (macroConfigIndex=0UL; macroConfigIndex<sramPwrModeConfig[sramNum].macroConfigCount; macroConfigIndex++)
3280 {
3281 if (0UL != (sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramMacros & (1UL<<sramMacroNum)))
3282 {
3283 switch(sramPwrMode)
3284 {
3285 case CY_SYSPM_SRAM_PWR_MODE_OFF:
3286 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_OFF, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3287 {
3288 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3289 }
3290 break;
3291 case CY_SYSPM_SRAM_PWR_MODE_RET:
3292 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_RETAIN, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3293 {
3294 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3295 }
3296 break;
3297 case CY_SYSPM_SRAM_PWR_MODE_ON:
3298 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_ON, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3299 {
3300 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3301 }
3302 break;
3303 default:
3304 /* invalid power mode */
3305 break;
3306 }
3307 break; /* found the macro number */
3308 }
3309 }
3310
3311 /* if configuration is not present in policy, then all power modes are allowed */
3312 }
3313 else
3314 {
3315 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3316 }
3317
3318 return praStatus;
3319 }
3320
3321 /*******************************************************************************
3322 * Function Name: Cy_PRA_ValidateEntireSramPowerMode
3323 ****************************************************************************//**
3324 *
3325 * Validate SRAM power mode for all macros.
3326 *
3327 *******************************************************************************/
Cy_PRA_ValidateEntireSramPowerMode(cy_en_syspm_sram_index_t sramNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)3328 static cy_en_pra_status_t Cy_PRA_ValidateEntireSramPowerMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
3329 {
3330 uint32_t macroConfigIndex;
3331 cy_en_pra_status_t praStatus = CY_PRA_STATUS_SUCCESS;
3332
3333 if ((uint8_t)sramNum < CY_PRA_SRAM_MAX_NR)
3334 {
3335 /* find the sram macro */
3336 for (macroConfigIndex=0UL; macroConfigIndex<sramPwrModeConfig[sramNum].macroConfigCount; macroConfigIndex++)
3337 {
3338 switch(sramPwrMode)
3339 {
3340 case CY_SYSPM_SRAM_PWR_MODE_OFF:
3341 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_OFF, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3342 {
3343 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3344 }
3345 break;
3346 case CY_SYSPM_SRAM_PWR_MODE_RET:
3347 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_RETAIN, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3348 {
3349 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3350 }
3351 break;
3352 case CY_SYSPM_SRAM_PWR_MODE_ON:
3353 if (0U == _FLD2VAL(CY_PRA_PM_SRAM_PWR_MODE_ON, sramPwrModeConfig[sramNum].macroConfigs[macroConfigIndex].sramPwrMode))
3354 {
3355 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3356 }
3357 break;
3358 default:
3359 /* invalid power mode */
3360 break;
3361 }
3362 if (praStatus == CY_PRA_STATUS_INVALID_PARAM)
3363 {
3364 break;
3365 }
3366 }
3367
3368 /* if configuration is not present in policy, then all power modes are allowed */
3369 }
3370 else
3371 {
3372 praStatus = CY_PRA_STATUS_INVALID_PARAM;
3373 }
3374
3375 return praStatus;
3376 }
3377
3378 #endif /* (CY_CPU_CORTEX_M0P) */
3379
3380 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 17.2')
3381
3382 #endif /* (CY_DEVICE_SECURE) */
3383
3384 #endif /* CY_IP_M4CPUSS */
3385
3386 /* [] END OF FILE */
3387