1 /***************************************************************************//**
2 * \file cy_sysclk.c
3 * \version 3.70
4 *
5 * Provides an API implementation of the sysclk driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright (c) (2016-2022), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation.
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION < 3)
29 
30 #include "cy_sysclk.h"
31 #include "cy_syslib.h"
32 #include <stdlib.h>
33 
34 #if defined (CY_DEVICE_SECURE)
35 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 17.2', 24, \
36 'Checked manually. All the recursive cycles are handled properly.')
37 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 18.6', 6, \
38 'Checked manually. Assignment of Local to global variable does not create any issue.')
39 #endif
40 
41 cy_en_sysclk_status_t
Cy_SysClk_PeriphSetDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerValue)42                 Cy_SysClk_PeriphSetDivider(cy_en_divider_types_t dividerType,
43                                            uint32_t dividerNum, uint32_t dividerValue)
44 {
45     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
46     if (dividerType == CY_SYSCLK_DIV_8_BIT)
47     {
48         if ((dividerNum < PERI_DIV_8_NR) &&
49             (dividerValue <= (PERI_DIV_8_CTL_INT8_DIV_Msk >> PERI_DIV_8_CTL_INT8_DIV_Pos)))
50         {
51             CY_REG32_CLR_SET(PERI_DIV_8_CTL[dividerNum], PERI_DIV_8_CTL_INT8_DIV, dividerValue);
52             retVal = CY_SYSCLK_SUCCESS;
53         }
54     }
55     else if (dividerType == CY_SYSCLK_DIV_16_BIT)
56     {
57         if ((dividerNum < PERI_DIV_16_NR) &&
58             (dividerValue <= (PERI_DIV_16_CTL_INT16_DIV_Msk >> PERI_DIV_16_CTL_INT16_DIV_Pos)))
59         {
60             CY_REG32_CLR_SET(PERI_DIV_16_CTL[dividerNum], PERI_DIV_16_CTL_INT16_DIV, dividerValue);
61             retVal = CY_SYSCLK_SUCCESS;
62         }
63     }
64     else
65     { /* return bad parameter */
66     }
67     return (retVal);
68 }
69 
70 
Cy_SysClk_PeriphGetDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)71 uint32_t Cy_SysClk_PeriphGetDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
72 {
73     uint32_t retVal;
74 
75     CY_ASSERT_L1(dividerType <= CY_SYSCLK_DIV_16_BIT);
76 
77     if (dividerType == CY_SYSCLK_DIV_8_BIT)
78     {
79         CY_ASSERT_L1(dividerNum < PERI_DIV_8_NR);
80         retVal = _FLD2VAL(PERI_DIV_8_CTL_INT8_DIV, PERI_DIV_8_CTL[dividerNum]);
81     }
82     else
83     { /* 16-bit divider */
84         CY_ASSERT_L1(dividerNum < PERI_DIV_16_NR);
85         retVal = _FLD2VAL(PERI_DIV_16_CTL_INT16_DIV, PERI_DIV_16_CTL[dividerNum]);
86     }
87     return (retVal);
88 }
89 
90 
91 cy_en_sysclk_status_t
Cy_SysClk_PeriphSetFracDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerIntValue,uint32_t dividerFracValue)92                 Cy_SysClk_PeriphSetFracDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
93                                                uint32_t dividerIntValue, uint32_t dividerFracValue)
94 {
95     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
96     if (dividerType == CY_SYSCLK_DIV_16_5_BIT)
97     {
98         if ((dividerNum < PERI_DIV_16_5_NR) &&
99             (dividerIntValue <= (PERI_DIV_16_5_CTL_INT16_DIV_Msk >> PERI_DIV_16_5_CTL_INT16_DIV_Pos)) &&
100             (dividerFracValue <= (PERI_DIV_16_5_CTL_FRAC5_DIV_Msk >> PERI_DIV_16_5_CTL_FRAC5_DIV_Pos)))
101         {
102             CY_REG32_CLR_SET(PERI_DIV_16_5_CTL[dividerNum], PERI_DIV_16_5_CTL_INT16_DIV, dividerIntValue);
103             CY_REG32_CLR_SET(PERI_DIV_16_5_CTL[dividerNum], PERI_DIV_16_5_CTL_FRAC5_DIV, dividerFracValue);
104             retVal = CY_SYSCLK_SUCCESS;
105         }
106     }
107     else if (dividerType == CY_SYSCLK_DIV_24_5_BIT)
108     {
109         if ((dividerNum < PERI_DIV_24_5_NR) &&
110             (dividerIntValue <= (PERI_DIV_24_5_CTL_INT24_DIV_Msk >> PERI_DIV_24_5_CTL_INT24_DIV_Pos)) &&
111             (dividerFracValue <= (PERI_DIV_24_5_CTL_FRAC5_DIV_Msk >> PERI_DIV_24_5_CTL_FRAC5_DIV_Pos)))
112         {
113             CY_REG32_CLR_SET(PERI_DIV_24_5_CTL[dividerNum], PERI_DIV_24_5_CTL_INT24_DIV, dividerIntValue);
114             CY_REG32_CLR_SET(PERI_DIV_24_5_CTL[dividerNum], PERI_DIV_24_5_CTL_FRAC5_DIV, dividerFracValue);
115             retVal = CY_SYSCLK_SUCCESS;
116         }
117     }
118     else
119     { /* return bad parameter */
120     }
121     return (retVal);
122 }
123 
124 
Cy_SysClk_PeriphGetFracDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t * dividerIntValue,uint32_t * dividerFracValue)125 void Cy_SysClk_PeriphGetFracDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
126                                                     uint32_t *dividerIntValue, uint32_t *dividerFracValue)
127 {
128     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_16_5_BIT) || (dividerType == CY_SYSCLK_DIV_24_5_BIT)) && \
129                  (dividerIntValue != NULL) && (dividerFracValue != NULL));
130 
131     if (dividerType == CY_SYSCLK_DIV_16_5_BIT)
132     {
133         CY_ASSERT_L1(dividerNum < PERI_DIV_16_5_NR);
134         *dividerIntValue  = _FLD2VAL(PERI_DIV_16_5_CTL_INT16_DIV, PERI_DIV_16_5_CTL[dividerNum]);
135         *dividerFracValue = _FLD2VAL(PERI_DIV_16_5_CTL_FRAC5_DIV, PERI_DIV_16_5_CTL[dividerNum]);
136     }
137     else
138     { /* 24.5-bit divider */
139         CY_ASSERT_L1(dividerNum < PERI_DIV_24_5_NR);
140         *dividerIntValue  = _FLD2VAL(PERI_DIV_24_5_CTL_INT24_DIV, PERI_DIV_24_5_CTL[dividerNum]);
141         *dividerFracValue = _FLD2VAL(PERI_DIV_24_5_CTL_FRAC5_DIV, PERI_DIV_24_5_CTL[dividerNum]);
142     }
143 }
144 
145 
146 cy_en_sysclk_status_t
Cy_SysClk_PeriphAssignDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)147                 Cy_SysClk_PeriphAssignDivider(en_clk_dst_t ipBlock,
148                                               cy_en_divider_types_t dividerType, uint32_t dividerNum)
149 {
150     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
151     if ((CY_PERI_CLOCK_NR > (uint32_t)ipBlock) && (CY_SYSCLK_DIV_24_5_BIT >= dividerType))
152     {
153         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    ||
154             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   ||
155             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) ||
156             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)))
157         {
158             PERI_CLOCK_CTL[ipBlock] = _VAL2FLD(CY_PERI_CLOCK_CTL_TYPE_SEL, dividerType) |
159                                       _VAL2FLD(CY_PERI_CLOCK_CTL_DIV_SEL, dividerNum);
160             retVal = CY_SYSCLK_SUCCESS;
161         }
162     }
163     return (retVal);
164 }
165 
166 
Cy_SysClk_PeriphGetAssignedDivider(en_clk_dst_t ipBlock)167 uint32_t Cy_SysClk_PeriphGetAssignedDivider(en_clk_dst_t ipBlock)
168 {
169     CY_ASSERT_L1(CY_PERI_CLOCK_NR > (uint32_t)ipBlock);
170     return (PERI_CLOCK_CTL[ipBlock] & (CY_PERI_CLOCK_CTL_DIV_SEL_Msk | CY_PERI_CLOCK_CTL_TYPE_SEL_Msk));
171 }
172 
173 
174 cy_en_sysclk_status_t
Cy_SysClk_PeriphEnableDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)175                 Cy_SysClk_PeriphEnableDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
176 {
177     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
178     if (dividerType <= CY_SYSCLK_DIV_24_5_BIT)
179     {
180         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    ||
181             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   ||
182             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) ||
183             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)))
184         {
185             /* specify the divider, make the reference = clk_peri, and enable the divider */
186             PERI_DIV_CMD = PERI_DIV_CMD_ENABLE_Msk                         |
187                            CY_PERI_DIV_CMD_PA_TYPE_SEL_Msk                 |
188                            CY_PERI_DIV_CMD_PA_DIV_SEL_Msk                  |
189                            _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType) |
190                            _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
191             (void)PERI_DIV_CMD; /* dummy read to handle buffered writes */
192             retVal = CY_SYSCLK_SUCCESS;
193         }
194     }
195     return (retVal);
196 }
197 
198 
199 cy_en_sysclk_status_t
Cy_SysClk_PeriphDisableDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)200                 Cy_SysClk_PeriphDisableDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
201 {
202     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
203     if (dividerType <= CY_SYSCLK_DIV_24_5_BIT)
204     {
205         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    ||
206             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   ||
207             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) ||
208             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)))
209         {
210             /* specify the divider and disable it */
211             PERI_DIV_CMD = PERI_DIV_CMD_DISABLE_Msk          |
212              _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType) |
213              _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
214             retVal = CY_SYSCLK_SUCCESS;
215         }
216     }
217     return (retVal);
218 }
219 
220 
221 cy_en_sysclk_status_t
Cy_SysClk_PeriphEnablePhaseAlignDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,cy_en_divider_types_t dividerTypePA,uint32_t dividerNumPA)222                 Cy_SysClk_PeriphEnablePhaseAlignDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
223                                                         cy_en_divider_types_t dividerTypePA, uint32_t dividerNumPA)
224 {
225     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
226     if (dividerTypePA <= CY_SYSCLK_DIV_24_5_BIT)
227     {
228         if (((dividerTypePA == CY_SYSCLK_DIV_8_BIT)    && (dividerNumPA < PERI_DIV_8_NR))    ||
229             ((dividerTypePA == CY_SYSCLK_DIV_16_BIT)   && (dividerNumPA < PERI_DIV_16_NR))   ||
230             ((dividerTypePA == CY_SYSCLK_DIV_16_5_BIT) && (dividerNumPA < PERI_DIV_16_5_NR)) ||
231             ((dividerTypePA == CY_SYSCLK_DIV_24_5_BIT) && ((dividerNumPA < PERI_DIV_24_5_NR) || (dividerNumPA == 63u))))
232         {
233             /* First, disable the divider that is to be phase-aligned.
234                The other two parameters are checked in that function;
235                if they're not valid, the divider is not disabled. */
236             retVal = Cy_SysClk_PeriphDisableDivider(dividerType, dividerNum);
237             if (retVal == CY_SYSCLK_SUCCESS)
238             {
239                 /* Then, specify the reference divider, and the divider, and enable the divider */
240                 PERI_DIV_CMD = PERI_DIV_CMD_ENABLE_Msk             |
241                  _VAL2FLD(CY_PERI_DIV_CMD_PA_TYPE_SEL, dividerTypePA) |
242                  _VAL2FLD(CY_PERI_DIV_CMD_PA_DIV_SEL,  dividerNumPA)  |
243                  _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType)   |
244                  _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
245             }
246         }
247     }
248     return (retVal);
249 }
250 
251 
Cy_SysClk_PeriphGetDividerEnabled(cy_en_divider_types_t dividerType,uint32_t dividerNum)252 bool Cy_SysClk_PeriphGetDividerEnabled(cy_en_divider_types_t dividerType, uint32_t dividerNum)
253 {
254     bool retVal = false;
255 
256     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    || \
257                  ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   || \
258                  ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) || \
259                  ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)));
260 
261     switch(dividerType)
262     {
263         case CY_SYSCLK_DIV_8_BIT:
264             retVal = _FLD2BOOL(PERI_DIV_8_CTL_EN, PERI_DIV_8_CTL[dividerNum]);
265             break;
266         case CY_SYSCLK_DIV_16_BIT:
267             retVal = _FLD2BOOL(PERI_DIV_16_CTL_EN, PERI_DIV_16_CTL[dividerNum]);
268             break;
269         case CY_SYSCLK_DIV_16_5_BIT:
270             retVal = _FLD2BOOL(PERI_DIV_16_5_CTL_EN, PERI_DIV_16_5_CTL[dividerNum]);
271             break;
272         case CY_SYSCLK_DIV_24_5_BIT:
273             retVal = _FLD2BOOL(PERI_DIV_24_5_CTL_EN, PERI_DIV_24_5_CTL[dividerNum]);
274             break;
275         default:
276             /* Unknown Divider */
277             break;
278     }
279     return (retVal);
280 }
281 
282 
283 /* ========================================================================== */
284 /* =========================    clk_slow SECTION    ========================= */
285 /* ========================================================================== */
286 
287 
Cy_SysClk_ClkSlowGetFrequency(void)288 uint32_t Cy_SysClk_ClkSlowGetFrequency(void)
289 {
290     uint32_t locFreq = Cy_SysClk_ClkPeriGetFrequency(); /* Get Peri frequency */
291     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkSlowGetDivider(); /* peri prescaler (1-256) */
292 
293     /* Divide the path input frequency down and return the result */
294     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
295 }
296 
297 
Cy_SysClk_ClkSlowSetDivider(uint8_t divider)298 void Cy_SysClk_ClkSlowSetDivider(uint8_t divider)
299 {
300 #if defined (CY_DEVICE_SECURE)
301     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_SLOW_SET_DIVIDER, divider);
302 #endif /* defined (CY_DEVICE_SECURE) */
303 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
304     CY_REG32_CLR_SET(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, divider);
305 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
306 }
307 
308 
Cy_SysClk_ClkSlowGetDivider(void)309 uint8_t Cy_SysClk_ClkSlowGetDivider(void)
310 {
311     return ((uint8_t)_FLD2VAL(CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, CPUSS_CM0_CLOCK_CTL));
312 }
313 
314 
Cy_SysClk_ClkPumpSetSource(cy_en_clkpump_in_sources_t source)315 void Cy_SysClk_ClkPumpSetSource(cy_en_clkpump_in_sources_t source)
316 {
317 #if defined (CY_DEVICE_SECURE)
318     cy_en_pra_status_t retStatus;
319     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PUMP_SET_SOURCE, source);
320 
321     if (retStatus != CY_PRA_STATUS_SUCCESS)
322     {
323         CY_ASSERT_L1(false);
324     }
325 #endif /* defined (CY_DEVICE_SECURE) */
326 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
327     CY_ASSERT_L3(source <= CY_SYSCLK_PUMP_IN_CLKPATH15);
328     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_PUMP_SEL, source);
329 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
330 }
331 
332 
Cy_SysClk_ClkPumpGetSource(void)333 cy_en_clkpump_in_sources_t Cy_SysClk_ClkPumpGetSource(void)
334 {
335     return ((cy_en_clkpump_in_sources_t)((uint32_t)_FLD2VAL(SRSS_CLK_SELECT_PUMP_SEL, SRSS_CLK_SELECT)));
336 }
337 
338 
Cy_SysClk_ClkPumpSetDivider(cy_en_clkpump_divide_t divider)339 void Cy_SysClk_ClkPumpSetDivider(cy_en_clkpump_divide_t divider)
340 {
341 #if defined (CY_DEVICE_SECURE)
342     cy_en_pra_status_t retStatus;
343     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PUMP_SET_DIVIDER, divider);
344 
345     if (retStatus != CY_PRA_STATUS_SUCCESS)
346     {
347         CY_ASSERT_L1(false);
348     }
349 #endif /* defined (CY_DEVICE_SECURE) */
350 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
351     CY_ASSERT_L3(CY_SYSCLK_FLL_IS_DIVIDER_VALID(divider));
352     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_PUMP_DIV, divider);
353 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
354 }
355 
356 
Cy_SysClk_ClkPumpGetDivider(void)357 cy_en_clkpump_divide_t Cy_SysClk_ClkPumpGetDivider(void)
358 {
359     return ((cy_en_clkpump_divide_t)((uint32_t)_FLD2VAL(SRSS_CLK_SELECT_PUMP_DIV, SRSS_CLK_SELECT)));
360 }
361 
362 
Cy_SysClk_ClkPumpEnable(void)363 void Cy_SysClk_ClkPumpEnable(void)
364 {
365 #if defined (CY_DEVICE_SECURE)
366     cy_en_pra_status_t retStatus;
367     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PUMP_ENABLE, 1UL);
368 
369     if (retStatus != CY_PRA_STATUS_SUCCESS)
370     {
371         CY_ASSERT_L1(false);
372     }
373 #endif /* defined (CY_DEVICE_SECURE) */
374 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
375     SRSS_CLK_SELECT |= SRSS_CLK_SELECT_PUMP_ENABLE_Msk;
376 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
377 }
378 
379 
Cy_SysClk_ClkPumpIsEnabled(void)380 bool Cy_SysClk_ClkPumpIsEnabled(void)
381 {
382     return (_FLD2BOOL(SRSS_CLK_SELECT_PUMP_ENABLE, SRSS_CLK_SELECT));
383 }
384 
385 
Cy_SysClk_ClkPumpDisable(void)386 void Cy_SysClk_ClkPumpDisable(void)
387 {
388 #if defined (CY_DEVICE_SECURE)
389     cy_en_pra_status_t retStatus;
390     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PUMP_DISABLE, 0UL);
391 
392     if (retStatus != CY_PRA_STATUS_SUCCESS)
393     {
394         CY_ASSERT_L1(false);
395     }
396 #endif /* defined (CY_DEVICE_SECURE) */
397 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
398     SRSS_CLK_SELECT &= ~SRSS_CLK_SELECT_PUMP_ENABLE_Msk;
399 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
400 }
401 
402 
Cy_SysClk_ClkPumpGetFrequency(void)403 uint32_t Cy_SysClk_ClkPumpGetFrequency(void)
404 {
405     /* Divide the input frequency down and return the result */
406     return (Cy_SysClk_ClkPumpIsEnabled() ?
407             (Cy_SysClk_ClkPathGetFrequency((uint32_t)Cy_SysClk_ClkPumpGetSource()) /
408              (1UL << (uint32_t)Cy_SysClk_ClkPumpGetDivider())) : 0UL);
409 }
410 
411 
Cy_SysClk_ClkBakSetSource(cy_en_clkbak_in_sources_t source)412 void Cy_SysClk_ClkBakSetSource(cy_en_clkbak_in_sources_t source)
413 {
414 #if defined (CY_DEVICE_SECURE)
415     cy_en_pra_status_t retStatus;
416     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_BAK_SET_SOURCE, source);
417 
418     if (retStatus != CY_PRA_STATUS_SUCCESS)
419     {
420         CY_ASSERT_L1(false);
421     }
422 #endif /* defined (CY_DEVICE_SECURE) */
423 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
424     CY_ASSERT_L3(source <= CY_SYSCLK_BAK_IN_CLKLF);
425     CY_REG32_CLR_SET(BACKUP_CTL, BACKUP_CTL_CLK_SEL, source);
426 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
427 }
428 
429 
Cy_SysClk_ClkBakGetSource(void)430 cy_en_clkbak_in_sources_t Cy_SysClk_ClkBakGetSource(void)
431 {
432     return ((cy_en_clkbak_in_sources_t)((uint32_t)_FLD2VAL(BACKUP_CTL_CLK_SEL, BACKUP_CTL)));
433 }
434 
435 
Cy_SysClk_ClkTimerSetSource(cy_en_clktimer_in_sources_t source)436 void Cy_SysClk_ClkTimerSetSource(cy_en_clktimer_in_sources_t source)
437 {
438 #if defined (CY_DEVICE_SECURE)
439     cy_en_pra_status_t retStatus;
440     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_TIMER_SET_SOURCE, source);
441 
442     if (retStatus != CY_PRA_STATUS_SUCCESS)
443     {
444         CY_ASSERT_L1(false);
445     }
446 #endif /* defined (CY_DEVICE_SECURE) */
447 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
448     CY_ASSERT_L3(source <= CY_SYSCLK_CLKTIMER_IN_HF0_DIV8);
449     /* set both fields TIMER_SEL and TIMER_HF0_DIV with the same input value */
450     CY_REG32_CLR_SET(SRSS_CLK_TIMER_CTL, CY_SRSS_CLK_TIMER_CTL_TIMER, source);
451 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
452 }
453 
454 
Cy_SysClk_ClkTimerGetSource(void)455 cy_en_clktimer_in_sources_t Cy_SysClk_ClkTimerGetSource(void)
456 {
457     /* return both fields TIMER_SEL and TIMER_HF0_DIV as a single combined value */
458     return ((cy_en_clktimer_in_sources_t)((uint32_t)(SRSS_CLK_TIMER_CTL & CY_SRSS_CLK_TIMER_CTL_TIMER_Msk)));
459 }
460 
461 
Cy_SysClk_ClkTimerSetDivider(uint8_t divider)462 void Cy_SysClk_ClkTimerSetDivider(uint8_t divider)
463 {
464 #if defined (CY_DEVICE_SECURE)
465     cy_en_pra_status_t retStatus;
466     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_TIMER_SET_DIVIDER, divider);
467 
468     if (retStatus != CY_PRA_STATUS_SUCCESS)
469     {
470         CY_ASSERT_L1(false);
471     }
472 #endif /* defined (CY_DEVICE_SECURE) */
473 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
474     CY_REG32_CLR_SET(SRSS_CLK_TIMER_CTL, SRSS_CLK_TIMER_CTL_TIMER_DIV, divider);
475 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
476 }
477 
478 
Cy_SysClk_ClkTimerGetDivider(void)479 uint8_t Cy_SysClk_ClkTimerGetDivider(void)
480 {
481     return ((uint8_t)_FLD2VAL(SRSS_CLK_TIMER_CTL_TIMER_DIV, SRSS_CLK_TIMER_CTL));
482 }
483 
484 
Cy_SysClk_ClkTimerEnable(void)485 void Cy_SysClk_ClkTimerEnable(void)
486 {
487 #if defined (CY_DEVICE_SECURE)
488     cy_en_pra_status_t retStatus;
489     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_TIMER_ENABLE, 1UL);
490 
491     if (retStatus != CY_PRA_STATUS_SUCCESS)
492     {
493         CY_ASSERT_L1(false);
494     }
495 #endif /* defined (CY_DEVICE_SECURE) */
496 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
497     SRSS_CLK_TIMER_CTL |= SRSS_CLK_TIMER_CTL_ENABLE_Msk;
498 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
499 }
500 
501 
Cy_SysClk_ClkTimerIsEnabled(void)502 bool Cy_SysClk_ClkTimerIsEnabled(void)
503 {
504     return (_FLD2BOOL(SRSS_CLK_TIMER_CTL_ENABLE, SRSS_CLK_TIMER_CTL));
505 }
506 
507 
Cy_SysClk_ClkTimerDisable(void)508 void Cy_SysClk_ClkTimerDisable(void)
509 {
510 #if defined (CY_DEVICE_SECURE)
511     cy_en_pra_status_t retStatus;
512     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_TIMER_DISABLE, 0UL);
513 
514     if (retStatus != CY_PRA_STATUS_SUCCESS)
515     {
516         CY_ASSERT_L1(false);
517     }
518 #endif /* defined (CY_DEVICE_SECURE) */
519 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
520     SRSS_CLK_TIMER_CTL &= ~SRSS_CLK_TIMER_CTL_ENABLE_Msk;
521 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
522 }
523 
524 
Cy_SysClk_ClkLfSetSource(cy_en_clklf_in_sources_t source)525 void Cy_SysClk_ClkLfSetSource(cy_en_clklf_in_sources_t source)
526 {
527 #if defined (CY_DEVICE_SECURE)
528     cy_en_pra_status_t retStatus;
529     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_LF_SET_SOURCE, source);
530 
531     if (retStatus != CY_PRA_STATUS_SUCCESS)
532     {
533         CY_ASSERT_L1(false);
534     }
535 #endif /* defined (CY_DEVICE_SECURE) */
536 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
537     CY_ASSERT_L3(source <= CY_SYSCLK_CLKLF_IN_PILO);
538     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_LFCLK_SEL, source);
539 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
540 }
541 
542 
Cy_SysClk_ClkLfGetSource(void)543 cy_en_clklf_in_sources_t Cy_SysClk_ClkLfGetSource(void)
544 {
545     return ((cy_en_clklf_in_sources_t)(((uint32_t)_FLD2VAL(SRSS_CLK_SELECT_LFCLK_SEL, SRSS_CLK_SELECT))));
546 }
547 
548 
Cy_SysClk_ClkPeriGetFrequency(void)549 uint32_t Cy_SysClk_ClkPeriGetFrequency(void)
550 {
551     uint32_t locFreq = Cy_SysClk_ClkHfGetFrequency(0UL); /* Get root frequency */
552     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider(); /* peri prescaler (1-256) */
553 
554     /* Divide the path input frequency down and return the result */
555     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
556 }
557 
558 
Cy_SysClk_ClkPeriSetDivider(uint8_t divider)559 void Cy_SysClk_ClkPeriSetDivider(uint8_t divider)
560 {
561 #if defined (CY_DEVICE_SECURE)
562     cy_en_pra_status_t retStatus;
563     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PERI_SET_DIVIDER, divider);
564 
565     if (retStatus != CY_PRA_STATUS_SUCCESS)
566     {
567         CY_ASSERT_L1(false);
568     }
569 #endif /* defined (CY_DEVICE_SECURE) */
570 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
571     CY_REG32_CLR_SET(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, divider);
572 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
573 }
574 
575 
Cy_SysClk_ClkPeriGetDivider(void)576 uint8_t Cy_SysClk_ClkPeriGetDivider(void)
577 {
578     return ((uint8_t)_FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS_CM0_CLOCK_CTL));
579 }
580 
581 
582 /* ========================================================================== */
583 /* =========================    clk_fast SECTION    ========================= */
584 /* ========================================================================== */
585 
586 
Cy_SysClk_ClkFastGetFrequency(void)587 uint32_t Cy_SysClk_ClkFastGetFrequency(void)
588 {
589     uint32_t locFreq = Cy_SysClk_ClkHfGetFrequency(0UL); /* Get root frequency */
590     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkFastGetDivider(); /* fast prescaler (1-256) */
591 
592     /* Divide the path input frequency down and return the result */
593     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
594 }
595 
596 
Cy_SysClk_ClkFastSetDivider(uint8_t divider)597 void Cy_SysClk_ClkFastSetDivider(uint8_t divider)
598 {
599 #if defined (CY_DEVICE_SECURE)
600     cy_en_pra_status_t retStatus;
601     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_FAST_SET_DIVIDER, divider);
602 
603     if (retStatus != CY_PRA_STATUS_SUCCESS)
604     {
605         CY_ASSERT_L1(false);
606     }
607 #endif /* defined (CY_DEVICE_SECURE) */
608 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
609     CY_REG32_CLR_SET(CPUSS_CM4_CLOCK_CTL, CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, divider);
610 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
611 }
612 
613 
Cy_SysClk_ClkFastGetDivider(void)614 uint8_t Cy_SysClk_ClkFastGetDivider(void)
615 {
616     return ((uint8_t)_FLD2VAL(CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, CPUSS_CM4_CLOCK_CTL));
617 }
618 
619 
Cy_SysClk_ClkHfEnable(uint32_t clkHf)620 cy_en_sysclk_status_t Cy_SysClk_ClkHfEnable(uint32_t clkHf)
621 {
622     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
623     if (clkHf < CY_SRSS_NUM_HFROOT)
624     {
625 #if defined (CY_DEVICE_SECURE)
626         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_HF_ENABLE, clkHf);
627 #endif /* defined (CY_DEVICE_SECURE) */
628 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
629         SRSS_CLK_ROOT_SELECT[clkHf] |= SRSS_CLK_ROOT_SELECT_ENABLE_Msk;
630         retVal = CY_SYSCLK_SUCCESS;
631 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
632     }
633     return (retVal);
634 }
635 
636 
Cy_SysClk_ClkHfIsEnabled(uint32_t clkHf)637 bool Cy_SysClk_ClkHfIsEnabled(uint32_t clkHf)
638 {
639     bool retVal = false;
640     if (clkHf < CY_SRSS_NUM_HFROOT)
641     {
642         retVal = _FLD2BOOL(SRSS_CLK_ROOT_SELECT_ENABLE, SRSS_CLK_ROOT_SELECT[clkHf]);
643     }
644     return (retVal);
645 }
646 
647 
Cy_SysClk_ClkHfDisable(uint32_t clkHf)648 cy_en_sysclk_status_t Cy_SysClk_ClkHfDisable(uint32_t clkHf)
649 {
650     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
651     if ((0UL < clkHf) /* prevent CLK_HF0 disabling */
652            && (clkHf < CY_SRSS_NUM_HFROOT))
653     {
654 #if defined (CY_DEVICE_SECURE)
655         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_HF_DISABLE, clkHf);
656 #endif /* defined (CY_DEVICE_SECURE) */
657 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
658         SRSS_CLK_ROOT_SELECT[clkHf] &= ~SRSS_CLK_ROOT_SELECT_ENABLE_Msk;
659         retVal = CY_SYSCLK_SUCCESS;
660 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
661     }
662     return (retVal);
663 }
664 
665 
Cy_SysClk_ClkHfSetSource(uint32_t clkHf,cy_en_clkhf_in_sources_t source)666 cy_en_sysclk_status_t Cy_SysClk_ClkHfSetSource(uint32_t clkHf, cy_en_clkhf_in_sources_t source)
667 {
668     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
669     if ((clkHf < CY_SRSS_NUM_HFROOT) && (source <= CY_SYSCLK_CLKHF_IN_CLKPATH15))
670     {
671 #if defined (CY_DEVICE_SECURE)
672         cy_stc_pra_clkhfsetsource_t set_source;
673         set_source.clkHf = clkHf;
674         set_source.source = source;
675         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_HF_SET_SOURCE, &set_source);
676 #endif /* defined (CY_DEVICE_SECURE) */
677 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
678         CY_REG32_CLR_SET(SRSS_CLK_ROOT_SELECT[clkHf], SRSS_CLK_ROOT_SELECT_ROOT_MUX, source);
679         retVal = CY_SYSCLK_SUCCESS;
680 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
681     }
682     return (retVal);
683 }
684 
685 
Cy_SysClk_ClkHfGetSource(uint32_t clkHf)686 cy_en_clkhf_in_sources_t Cy_SysClk_ClkHfGetSource(uint32_t clkHf)
687 {
688     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
689     return ((cy_en_clkhf_in_sources_t)((uint32_t)(_FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_MUX, SRSS_CLK_ROOT_SELECT[clkHf]))));
690 }
691 
692 
Cy_SysClk_ClkHfSetDivider(uint32_t clkHf,cy_en_clkhf_dividers_t divider)693 cy_en_sysclk_status_t Cy_SysClk_ClkHfSetDivider(uint32_t clkHf, cy_en_clkhf_dividers_t divider)
694 {
695     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
696     if ((clkHf < CY_SRSS_NUM_HFROOT) && (divider <= CY_SYSCLK_CLKHF_DIVIDE_BY_8))
697     {
698 #if defined (CY_DEVICE_SECURE)
699         cy_stc_pra_clkhfsetdivider_t set_divider;
700         set_divider.clkHf = clkHf;
701         set_divider.divider = divider;
702         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_HF_SET_DIVIDER, &set_divider);
703 #endif /* defined (CY_DEVICE_SECURE) */
704 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
705         CY_REG32_CLR_SET(SRSS_CLK_ROOT_SELECT[clkHf], SRSS_CLK_ROOT_SELECT_ROOT_DIV, divider);
706         retVal = CY_SYSCLK_SUCCESS;
707 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
708     }
709     return (retVal);
710 }
711 
712 
Cy_SysClk_ClkHfGetDivider(uint32_t clkHf)713 cy_en_clkhf_dividers_t Cy_SysClk_ClkHfGetDivider(uint32_t clkHf)
714 {
715     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
716     return ((cy_en_clkhf_dividers_t)(((uint32_t)_FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV, SRSS_CLK_ROOT_SELECT[clkHf]))));
717 }
718 
719 
720 /* ========================================================================== */
721 /* ============================    MF SECTION    ============================ */
722 /* ========================================================================== */
723 
724 
Cy_SysClk_MfoEnable(bool deepSleepEnable)725 void Cy_SysClk_MfoEnable(bool deepSleepEnable)
726 {
727     if (CY_SRSS_MFO_PRESENT)
728     {
729     #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
730         CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_CLK_MFO_CONFIG, (SRSS_CLK_MFO_CONFIG_ENABLE_Msk | (deepSleepEnable ? SRSS_CLK_MFO_CONFIG_DPSLP_ENABLE_Msk : 0UL)));
731     #else
732         SRSS_CLK_MFO_CONFIG = SRSS_CLK_MFO_CONFIG_ENABLE_Msk | (deepSleepEnable ? SRSS_CLK_MFO_CONFIG_DPSLP_ENABLE_Msk : 0UL);
733     #endif /* CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE) */
734     }
735 }
736 
737 
Cy_SysClk_MfoIsEnabled(void)738 bool Cy_SysClk_MfoIsEnabled(void)
739 {
740     return (CY_SRSS_MFO_PRESENT && (0UL != (SRSS_CLK_MFO_CONFIG & SRSS_CLK_MFO_CONFIG_ENABLE_Msk)));
741 }
742 
743 
Cy_SysClk_MfoDisable(void)744 void Cy_SysClk_MfoDisable(void)
745 {
746     if (CY_SRSS_MFO_PRESENT)
747     {
748     #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
749         CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_CLK_MFO_CONFIG, 0UL);
750     #else
751         SRSS_CLK_MFO_CONFIG = 0UL;
752     #endif /* CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE) */
753     }
754 }
755 
756 
Cy_SysClk_ClkMfEnable(void)757 void Cy_SysClk_ClkMfEnable(void)
758 {
759     if (CY_SRSS_MFO_PRESENT)
760     {
761     #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
762         CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_ENABLE, 1U);
763     #else
764         SRSS_CLK_MF_SELECT |= SRSS_CLK_MF_SELECT_ENABLE_Msk;
765     #endif /* CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE) */
766     }
767 }
768 
769 
Cy_SysClk_ClkMfIsEnabled(void)770 bool Cy_SysClk_ClkMfIsEnabled(void)
771 {
772     return ((CY_SRSS_MFO_PRESENT) && (0UL != (SRSS_CLK_MF_SELECT & SRSS_CLK_MF_SELECT_ENABLE_Msk)));
773 }
774 
775 
Cy_SysClk_ClkMfDisable(void)776 void Cy_SysClk_ClkMfDisable(void)
777 {
778     if (CY_SRSS_MFO_PRESENT)
779     {
780     #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
781         CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_ENABLE, 0U);
782     #else
783         SRSS_CLK_MF_SELECT &= ~SRSS_CLK_MF_SELECT_ENABLE_Msk;
784     #endif /* CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE) */
785     }
786 }
787 
788 
Cy_SysClk_ClkMfSetDivider(uint32_t divider)789 void Cy_SysClk_ClkMfSetDivider(uint32_t divider)
790 {
791     if ((CY_SRSS_MFO_PRESENT) && CY_SYSCLK_IS_MF_DIVIDER_VALID(divider))
792     {
793         if (!Cy_SysClk_ClkMfIsEnabled())
794         {
795         #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
796             CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_MFCLK_DIV, divider - 1UL);
797         #else
798             CY_REG32_CLR_SET(SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_MFCLK_DIV, divider - 1UL);
799         #endif /* CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE) */
800         }
801     }
802 }
803 
804 
Cy_SysClk_ClkMfGetDivider(void)805 uint32_t Cy_SysClk_ClkMfGetDivider(void)
806 {
807     return ((CY_SRSS_MFO_PRESENT) ? (1UL + _FLD2VAL(SRSS_CLK_MF_SELECT_MFCLK_DIV, SRSS_CLK_MF_SELECT)) : 1UL);
808 }
809 
810 
Cy_SysClk_ClkMfGetFrequency(void)811 uint32_t Cy_SysClk_ClkMfGetFrequency(void)
812 {
813     uint32_t locFreq = (Cy_SysClk_MfoIsEnabled()) ? CY_SYSCLK_MFO_FREQ : 0UL; /* Get root frequency */
814     uint32_t locDiv = Cy_SysClk_ClkMfGetDivider(); /* clkMf prescaler (1-256) */
815 
816     /* Divide the path input frequency down and return the result */
817     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
818 }
819 
820 
Cy_SysClk_WcoEnable(uint32_t timeoutus)821 cy_en_sysclk_status_t Cy_SysClk_WcoEnable(uint32_t timeoutus)
822 {
823     cy_en_sysclk_status_t retVal;
824 #if defined (CY_DEVICE_SECURE)
825     retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_WCO_ENABLE, timeoutus);
826 #endif /* defined (CY_DEVICE_SECURE) */
827 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
828     retVal = CY_SYSCLK_TIMEOUT;
829 
830     /* first set the WCO enable bit */
831     BACKUP_CTL |= BACKUP_CTL_WCO_EN_Msk;
832 
833     /* now do the timeout wait for STATUS, bit WCO_OK */
834     for (; (Cy_SysClk_WcoOkay() == false) && (0UL != timeoutus); timeoutus--)
835     {
836         Cy_SysLib_DelayUs(1U);
837     }
838 
839     if (0UL != timeoutus)
840     {
841         retVal = CY_SYSCLK_SUCCESS;
842     }
843 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
844     return (retVal);
845 }
846 
847 
Cy_SysClk_WcoOkay(void)848 bool Cy_SysClk_WcoOkay(void)
849 {
850     return (_FLD2BOOL(BACKUP_STATUS_WCO_OK, BACKUP_STATUS));
851 }
852 
853 
Cy_SysClk_WcoDisable(void)854 void Cy_SysClk_WcoDisable(void)
855 {
856 #if defined (CY_DEVICE_SECURE)
857     cy_en_pra_status_t retStatus;
858     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_WCO_DISABLE, 0UL);
859 
860     if (retStatus != CY_PRA_STATUS_SUCCESS)
861     {
862         CY_ASSERT_L1(false);
863     }
864 #endif /* defined (CY_DEVICE_SECURE) */
865 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
866     BACKUP_CTL &= (uint32_t)~BACKUP_CTL_WCO_EN_Msk;
867 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
868 }
869 
870 
Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)871 void Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)
872 {
873 #if defined (CY_DEVICE_SECURE)
874     cy_en_pra_status_t retStatus;
875     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_WCO_BYPASS, bypass);
876 
877     if (retStatus != CY_PRA_STATUS_SUCCESS)
878     {
879         CY_ASSERT_L1(false);
880     }
881 #endif /* defined (CY_DEVICE_SECURE) */
882 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
883     CY_REG32_CLR_SET(BACKUP_CTL, BACKUP_CTL_WCO_BYPASS, bypass);
884 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
885 }
886 
887 
888 /* ========================================================================== */
889 /* ===========================    PILO SECTION    =========================== */
890 /* ========================================================================== */
891 
892 
Cy_SysClk_PiloEnable(void)893 void Cy_SysClk_PiloEnable(void)
894 {
895 #if defined (CY_DEVICE_SECURE)
896     cy_en_pra_status_t retStatus;
897     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PILO_ENABLE, 1UL);
898 
899     if (retStatus != CY_PRA_STATUS_SUCCESS)
900     {
901         CY_ASSERT_L1(false);
902     }
903 #endif /* defined (CY_DEVICE_SECURE) */
904 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
905     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_EN_Msk; /* 1 = enable */
906     Cy_SysLib_Delay(1U/*msec*/);
907     /* release the reset and enable clock output */
908     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_RESET_N_Msk |
909                             SRSS_CLK_PILO_CONFIG_PILO_CLK_EN_Msk;
910 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
911 }
912 
913 
Cy_SysClk_PiloIsEnabled(void)914 bool Cy_SysClk_PiloIsEnabled(void)
915 {
916     return (_FLD2BOOL(SRSS_CLK_PILO_CONFIG_PILO_CLK_EN, SRSS_CLK_PILO_CONFIG));
917 }
918 
919 
Cy_SysClk_PiloDisable(void)920 void Cy_SysClk_PiloDisable(void)
921 {
922 #if defined (CY_DEVICE_SECURE)
923     cy_en_pra_status_t retStatus;
924     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PILO_DISABLE, 0UL);
925 
926     if (retStatus != CY_PRA_STATUS_SUCCESS)
927     {
928         CY_ASSERT_L1(false);
929     }
930 #endif /* defined (CY_DEVICE_SECURE) */
931 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
932     /* Clear PILO_EN, PILO_RESET_N, and PILO_CLK_EN bitfields. This disables the
933        PILO and holds the PILO in a reset state. */
934     SRSS_CLK_PILO_CONFIG &= (uint32_t)~(SRSS_CLK_PILO_CONFIG_PILO_EN_Msk      |
935                                         SRSS_CLK_PILO_CONFIG_PILO_RESET_N_Msk |
936                                         SRSS_CLK_PILO_CONFIG_PILO_CLK_EN_Msk);
937 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
938 }
939 
940 
Cy_SysClk_PiloSetTrim(uint32_t trimVal)941 void Cy_SysClk_PiloSetTrim(uint32_t trimVal)
942 {
943 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
944     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_SET_PILO_TRIM, trimVal);
945 #else
946     CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, trimVal);
947 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
948 }
949 
950 
Cy_SysClk_PiloGetTrim(void)951 uint32_t Cy_SysClk_PiloGetTrim(void)
952 {
953     return (_FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG));
954 }
955 
956 
957 /* ========================================================================== */
958 /* ==========================    ALTHF SECTION    =========================== */
959 /* ========================================================================== */
960 
961 
Cy_SysClk_AltHfGetFrequency(void)962 uint32_t Cy_SysClk_AltHfGetFrequency(void)
963 {
964     #if defined(CY_IP_MXBLESS)
965         return (cy_BleEcoClockFreqHz);
966     #else /* CY_IP_MXBLESS */
967         return (0UL);
968     #endif /* CY_IP_MXBLESS */
969 }
970 
971 
972 /* ========================================================================== */
973 /* ==========================    ALTLF SECTION    =========================== */
974 /* ========================================================================== */
975 
976 
Cy_SysClk_AltLfGetFrequency(void)977 uint32_t Cy_SysClk_AltLfGetFrequency(void)
978 {
979     return (0UL);
980 }
981 
982 
Cy_SysClk_AltLfIsEnabled(void)983 bool Cy_SysClk_AltLfIsEnabled(void)
984 {
985     return (false);
986 }
987 
988 
989 /* ========================================================================== */
990 /* ===========================    ILO SECTION    ============================ */
991 /* ========================================================================== */
992 
993 
Cy_SysClk_IloEnable(void)994 void Cy_SysClk_IloEnable(void)
995 {
996 #if defined (CY_DEVICE_SECURE)
997     cy_en_pra_status_t retStatus;
998     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ILO_ENABLE, 1UL);
999 
1000     if (retStatus != CY_PRA_STATUS_SUCCESS)
1001     {
1002         CY_ASSERT_L1(false);
1003     }
1004 #endif /* defined (CY_DEVICE_SECURE) */
1005 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1006     SRSS_CLK_ILO_CONFIG |= SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1007 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1008 }
1009 
1010 
Cy_SysClk_IloIsEnabled(void)1011 bool Cy_SysClk_IloIsEnabled(void)
1012 {
1013     return (_FLD2BOOL(SRSS_CLK_ILO_CONFIG_ENABLE, SRSS_CLK_ILO_CONFIG));
1014 }
1015 
1016 
Cy_SysClk_IloDisable(void)1017 cy_en_sysclk_status_t Cy_SysClk_IloDisable(void)
1018 {
1019     cy_en_sysclk_status_t retVal;
1020 #if defined (CY_DEVICE_SECURE)
1021     retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ILO_DISABLE, 0UL);
1022 
1023 #endif /* defined (CY_DEVICE_SECURE) */
1024 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1025     retVal = CY_SYSCLK_INVALID_STATE;
1026     if (!_FLD2BOOL(SRSS_WDT_CTL_WDT_EN, SRSS_WDT_CTL)) /* if disabled */
1027     {
1028         SRSS_CLK_ILO_CONFIG &= ~SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1029         retVal = CY_SYSCLK_SUCCESS;
1030     }
1031 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1032     return (retVal);
1033 }
1034 
1035 
Cy_SysClk_IloHibernateOn(bool on)1036 void Cy_SysClk_IloHibernateOn(bool on)
1037 {
1038 #if defined (CY_DEVICE_SECURE)
1039     cy_en_pra_status_t retStatus;
1040     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ILO_HIBERNATE_ON, on);
1041 
1042     if (retStatus != CY_PRA_STATUS_SUCCESS)
1043     {
1044         CY_ASSERT_L1(false);
1045     }
1046 #endif /* defined (CY_DEVICE_SECURE) */
1047 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1048     CY_REG32_CLR_SET(SRSS_CLK_ILO_CONFIG, SRSS_CLK_ILO_CONFIG_ILO_BACKUP, ((on) ? 1UL : 0UL));
1049 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1050 }
1051 
1052 
1053 /* ========================================================================== */
1054 /* =========================    EXTCLK SECTION    =========================== */
1055 /* ========================================================================== */
1056 
1057 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1058     uint32_t cySysClkExtFreq = 0UL;
1059 #else
1060     static uint32_t cySysClkExtFreq = 0UL;
1061 #endif
1062 
1063 #define CY_SYSCLK_EXTCLK_MAX_FREQ (100000000UL) /* 100 MHz */
1064 /** \endcond */
1065 
Cy_SysClk_ExtClkSetFrequency(uint32_t freq)1066 void Cy_SysClk_ExtClkSetFrequency(uint32_t freq)
1067 {
1068     if (freq <= CY_SYSCLK_EXTCLK_MAX_FREQ)
1069     {
1070 #if defined (CY_DEVICE_SECURE)
1071         CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_EXT_CLK_SET_FREQUENCY, freq);
1072 #endif
1073         cySysClkExtFreq = freq;
1074     }
1075 
1076 }
1077 
1078 
Cy_SysClk_ExtClkGetFrequency(void)1079 uint32_t Cy_SysClk_ExtClkGetFrequency(void)
1080 {
1081     return (cySysClkExtFreq);
1082 }
1083 
1084 
1085 /* ========================================================================== */
1086 /* ===========================    ECO SECTION    ============================ */
1087 /* ========================================================================== */
1088 /** \cond INTERNAL */
1089 #define CY_SYSCLK_TRIM_ECO_Pos  (SRSS_CLK_TRIM_ECO_CTL_WDTRIM_Pos)
1090 #define CY_SYSCLK_TRIM_ECO_Msk  (SRSS_CLK_TRIM_ECO_CTL_WDTRIM_Msk | \
1091                                  SRSS_CLK_TRIM_ECO_CTL_ATRIM_Msk  | \
1092                                  SRSS_CLK_TRIM_ECO_CTL_FTRIM_Msk  | \
1093                                  SRSS_CLK_TRIM_ECO_CTL_RTRIM_Msk  | \
1094                                  SRSS_CLK_TRIM_ECO_CTL_GTRIM_Msk)
1095 
1096 /** \cond *********************************************************************
1097 * Function Name: cy_sqrt
1098 * Calculates square root.
1099 * The input is 32-bit wide.
1100 * The result is 16-bit wide.
1101 *******************************************************************************/
1102 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1103 static uint32_t cy_sqrt(uint32_t x);
cy_sqrt(uint32_t x)1104 static uint32_t cy_sqrt(uint32_t x)
1105 {
1106     uint32_t i;
1107     uint32_t res = 0UL;
1108     uint32_t add = 0x8000UL;
1109 
1110     for(i = 0UL; i < 16UL; i++)
1111     {
1112         uint32_t tmp = res | add;
1113 
1114         if (x >= (tmp * tmp))
1115         {
1116             res = tmp;
1117         }
1118 
1119         add >>= 1U;
1120     }
1121 
1122     return (res);
1123 }
1124 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1125 
1126 static uint32_t ecoFrequency = 0UL; /* Internal storage for ECO frequency user setting */
1127 
1128 #define CY_SYSCLK_ECO_FREQ_MIN (16000000UL) /* 16 MHz */
1129 #define CY_SYSCLK_ECO_FREQ_MAX (35000000UL) /* 35 MHz */
1130 #define CY_SYSCLK_ECO_CSM_MAX  (100UL)      /* 100 pF */
1131 #define CY_SYSCLK_ECO_ESR_MAX  (1000UL)     /* 1000 Ohm */
1132 #define CY_SYSCLK_ECO_DRV_MAX  (2000UL)     /* 2 mW */
1133 
1134 #define CY_SYSCLK_ECO_IS_FREQ_VALID(freq) ((CY_SYSCLK_ECO_FREQ_MIN <= (freq)) && ((freq) <= CY_SYSCLK_ECO_FREQ_MAX))
1135 #define CY_SYSCLK_ECO_IS_CSM_VALID(csm)   ((0UL < (csm)) && ((csm) <= CY_SYSCLK_ECO_CSM_MAX))
1136 #define CY_SYSCLK_ECO_IS_ESR_VALID(esr)   ((0UL < (esr)) && ((esr) <= CY_SYSCLK_ECO_ESR_MAX))
1137 #define CY_SYSCLK_ECO_IS_DRV_VALID(drv)   ((0UL < (drv)) && ((drv) <= CY_SYSCLK_ECO_DRV_MAX))
1138 /** \endcond */
1139 
Cy_SysClk_EcoDisable(void)1140 void Cy_SysClk_EcoDisable(void)
1141 {
1142 #if defined (CY_DEVICE_SECURE)
1143     cy_en_pra_status_t retStatus;
1144     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ECO_DISABLE, 0UL);
1145 
1146     if (retStatus != CY_PRA_STATUS_SUCCESS)
1147     {
1148         CY_ASSERT_L1(false);
1149     }
1150 #endif /* defined (CY_DEVICE_SECURE) */
1151 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1152     SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1153 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1154 }
1155 
1156 
Cy_SysClk_EcoGetStatus(void)1157 uint32_t Cy_SysClk_EcoGetStatus(void)
1158 {
1159     /* if ECO is not ready, just report the ECO_OK bit. Otherwise report 2 = ECO ready */
1160     return ((SRSS_CLK_ECO_STATUS_Msk == (SRSS_CLK_ECO_STATUS_Msk & SRSS_CLK_ECO_STATUS)) ?
1161       CY_SYSCLK_ECOSTAT_STABLE : (SRSS_CLK_ECO_STATUS_ECO_OK_Msk & SRSS_CLK_ECO_STATUS));
1162 }
1163 
1164 #if (defined (CY_IP_MXS40SRSS)&& (CY_IP_MXS40SRSS_VERSION < 3))
Cy_SysClk_EcoSetFrequency(uint32_t freq)1165 void Cy_SysClk_EcoSetFrequency(uint32_t freq)
1166 {
1167     ecoFrequency = freq; /* Store the ECO frequency */
1168 }
1169 #endif /* (defined (CY_IP_MXS40SRSS)&& (CY_IP_MXS40SRSS_VERSION < 3)) */
1170 
Cy_SysClk_EcoConfigure(uint32_t freq,uint32_t cSum,uint32_t esr,uint32_t driveLevel)1171 cy_en_sysclk_status_t Cy_SysClk_EcoConfigure(uint32_t freq, uint32_t cSum, uint32_t esr, uint32_t driveLevel)
1172 {
1173     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1174 
1175 #if defined (CY_DEVICE_SECURE)
1176     cy_stc_pra_clk_eco_configure_t ecoConfig;
1177     ecoConfig.praClkEcofreq = freq;
1178     ecoConfig.praCsum = cSum;
1179     ecoConfig.praEsr = esr;
1180     ecoConfig.praDriveLevel = driveLevel;
1181     retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ECO_CONFIGURE, &ecoConfig);
1182     if(CY_SYSCLK_SUCCESS == retVal)
1183     {
1184         ecoFrequency = freq; /* Store the ECO frequency */
1185     }
1186 #endif /* defined (CY_DEVICE_SECURE) */
1187 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1188 
1189 
1190     if (0UL != (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
1191     {
1192         retVal = CY_SYSCLK_INVALID_STATE;
1193     }
1194     else if ((CY_SYSCLK_ECO_IS_FREQ_VALID(freq)) &&
1195              (CY_SYSCLK_ECO_IS_CSM_VALID(cSum)) &&
1196              (CY_SYSCLK_ECO_IS_ESR_VALID(esr)) &&
1197              (CY_SYSCLK_ECO_IS_DRV_VALID(driveLevel)))
1198     {
1199         /* Calculate intermediate values */
1200         uint32_t freqKhz = CY_SYSLIB_DIV_ROUND(freq, 1000UL);
1201 
1202         uint32_t maxAmpl = CY_SYSLIB_DIV_ROUND((159155UL * /* 5 * 100000 / PI */
1203                    cy_sqrt(CY_SYSLIB_DIV_ROUND(2000000UL * driveLevel, esr))), /* Scaled by 2 */
1204                                                (freqKhz * cSum)); /* The result is scaled by 10^3 */
1205 
1206         /* 10^9 / (5 * 4 * 4 * PI^2) = 1266514,7955292221430484932901216.. -> 126651, scaled by 10 */
1207         uint32_t ampSect = (CY_SYSLIB_DIV_ROUND(cSum * cSum *
1208                             CY_SYSLIB_DIV_ROUND(freqKhz * freqKhz, 126651UL), 100UL) * esr)/ 900000UL;
1209 
1210         if ((maxAmpl >= 650UL) && (ampSect <= 3UL))
1211         {
1212             uint32_t gtrim = (ampSect > 1UL) ? ampSect :
1213                             ((ampSect == 1UL) ? 0UL : 1UL);
1214 
1215             /* Update all fields of trim control register with one write, without changing the ITRIM field */
1216             uint32_t reg = _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_WDTRIM, 7UL) |
1217                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_ATRIM, 15UL) |
1218                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_FTRIM, 3UL)  |
1219                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_RTRIM, 0UL)  |
1220                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_GTRIM, gtrim);
1221 
1222             CY_REG32_CLR_SET(SRSS_CLK_TRIM_ECO_CTL, CY_SYSCLK_TRIM_ECO, reg);
1223 
1224             SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_AGC_EN_Msk;
1225 
1226             ecoFrequency = freq; /* Store the ECO frequency */
1227 
1228             retVal = CY_SYSCLK_SUCCESS;
1229         }
1230     }
1231     else
1232     {
1233         /* Return CY_SYSCLK_BAD_PARAM */
1234     }
1235 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1236     return (retVal);
1237 }
1238 
1239 
Cy_SysClk_EcoEnable(uint32_t timeoutus)1240 cy_en_sysclk_status_t Cy_SysClk_EcoEnable(uint32_t timeoutus)
1241 {
1242     cy_en_sysclk_status_t retVal;
1243 #if defined (CY_DEVICE_SECURE)
1244     retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ECO_ENABLE, timeoutus);
1245 #endif /* defined (CY_DEVICE_SECURE) */
1246 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1247 
1248     bool zeroTimeout = (0UL == timeoutus);
1249     retVal = CY_SYSCLK_INVALID_STATE;
1250 
1251     /* Invalid state error if ECO is already enabled */
1252     if (0UL == (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
1253     {
1254         /* Set ECO enable */
1255         SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1256 
1257         /* Wait for CY_SYSCLK_ECOSTAT_STABLE */
1258         for (; (CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeoutus); timeoutus--)
1259         {
1260             Cy_SysLib_DelayUs(1U);
1261         }
1262 
1263         if (zeroTimeout || (0UL != timeoutus))
1264         {
1265             retVal = CY_SYSCLK_SUCCESS;
1266         }
1267         else
1268         {
1269             /* If ECO doesn't start, then disable it */
1270             SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1271             retVal = CY_SYSCLK_TIMEOUT;
1272         }
1273     }
1274 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1275     return (retVal);
1276 }
1277 
1278 
Cy_SysClk_EcoGetFrequency(void)1279 uint32_t Cy_SysClk_EcoGetFrequency(void)
1280 {
1281     return ((CY_SYSCLK_ECOSTAT_STABLE == Cy_SysClk_EcoGetStatus()) ? ecoFrequency : 0UL);
1282 }
1283 
1284 
1285 /* ========================================================================== */
1286 /* ====================    INPUT MULTIPLEXER SECTION    ===================== */
1287 /* ========================================================================== */
1288 
1289 
Cy_SysClk_ClkPathSetSource(uint32_t clkPath,cy_en_clkpath_in_sources_t source)1290 cy_en_sysclk_status_t Cy_SysClk_ClkPathSetSource(uint32_t clkPath, cy_en_clkpath_in_sources_t source)
1291 {
1292     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1293     if ((clkPath < CY_SRSS_NUM_CLKPATH) &&
1294         ((source <= CY_SYSCLK_CLKPATH_IN_DSIMUX) ||
1295          ((CY_SYSCLK_CLKPATH_IN_DSI <= source) && (source <= CY_SYSCLK_CLKPATH_IN_PILO))))
1296     {
1297 #if defined (CY_DEVICE_SECURE)
1298         cy_stc_pra_clkpathsetsource_t clkpath_set_source;
1299         clkpath_set_source.clk_path = clkPath;
1300         clkpath_set_source.source   = source;
1301         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PATH_SET_SOURCE, &clkpath_set_source);
1302 #endif /* defined (CY_DEVICE_SECURE) */
1303 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1304 
1305         if (source >= CY_SYSCLK_CLKPATH_IN_DSI)
1306         {
1307             SRSS_CLK_DSI_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_DSI_SELECT_DSI_MUX, (uint32_t)source);
1308             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)CY_SYSCLK_CLKPATH_IN_DSIMUX);
1309         }
1310         else
1311         {
1312             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)source);
1313         }
1314         retVal = CY_SYSCLK_SUCCESS;
1315 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1316     }
1317     return (retVal);
1318 
1319 }
1320 
1321 
Cy_SysClk_ClkPathGetSource(uint32_t clkPath)1322 cy_en_clkpath_in_sources_t Cy_SysClk_ClkPathGetSource(uint32_t clkPath)
1323 {
1324     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1325     cy_en_clkpath_in_sources_t retVal =
1326         (cy_en_clkpath_in_sources_t )((uint32_t)_FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS_CLK_PATH_SELECT[clkPath]));
1327     if (retVal == CY_SYSCLK_CLKPATH_IN_DSIMUX)
1328     {
1329         retVal = (cy_en_clkpath_in_sources_t)((uint32_t)(((uint32_t)CY_SYSCLK_CLKPATH_IN_DSI) |
1330                     ((uint32_t)(_FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS_CLK_DSI_SELECT[clkPath])))));
1331     }
1332     return (retVal);
1333 }
1334 
1335 
Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)1336 uint32_t Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)
1337 {
1338     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1339 
1340     uint32_t freq = 0UL;    /* The path mux output frequency in Hz, 0 = an unknown frequency */
1341 
1342     /* Get the frequency of the source, i.e., the path mux input */
1343     switch(Cy_SysClk_ClkPathGetSource(clkPath))
1344     {
1345         case CY_SYSCLK_CLKPATH_IN_IMO: /* The IMO frequency is fixed at 8 MHz */
1346             freq = CY_SYSCLK_IMO_FREQ;
1347             break;
1348 
1349         case CY_SYSCLK_CLKPATH_IN_EXT:
1350             freq = Cy_SysClk_ExtClkGetFrequency();
1351             break;
1352 
1353         case CY_SYSCLK_CLKPATH_IN_ECO:
1354             freq = Cy_SysClk_EcoGetFrequency();
1355             break;
1356 
1357         case CY_SYSCLK_CLKPATH_IN_ALTHF:
1358             freq = Cy_SysClk_AltHfGetFrequency();
1359             break;
1360 
1361         case CY_SYSCLK_CLKPATH_IN_ILO:
1362             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
1363             break;
1364 
1365         case CY_SYSCLK_CLKPATH_IN_WCO:
1366             freq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
1367             break;
1368 
1369         case CY_SYSCLK_CLKPATH_IN_PILO:
1370             freq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
1371             break;
1372 
1373         case CY_SYSCLK_CLKPATH_IN_ALTLF:
1374             freq = Cy_SysClk_AltLfGetFrequency();
1375             break;
1376 
1377         default:
1378             /* Don't know the frequency of dsi_out, leave freq = 0UL */
1379             break;
1380     }
1381 
1382     return (freq);
1383 }
1384 
1385 
Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)1386 uint32_t Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)
1387 {
1388     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1389 
1390     uint32_t freq = 0UL;
1391 
1392     if (clkPath == (uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0) /* FLL? (always path 0) */
1393     {
1394         freq = Cy_SysClk_FllGetFrequency();
1395     }
1396     else if (clkPath <= CY_SRSS_NUM_PLL) /* PLL? (always path 1...N)*/
1397     {
1398         freq = Cy_SysClk_PllGetFrequency(clkPath);
1399     }
1400     else
1401     {
1402         /* Do nothing with the path mux frequency */
1403     }
1404 
1405     if(freq==0UL)
1406     {
1407         freq = Cy_SysClk_ClkPathMuxGetFrequency(clkPath);
1408     }
1409 
1410 return (freq);
1411 }
1412 
1413 
1414 /* ========================================================================== */
1415 /* ===========================    FLL SECTION    ============================ */
1416 /* ========================================================================== */
1417 
1418 
1419 #define  CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ (48000000UL)
1420 #define  CY_SYSCLK_FLL_MIN_OUTPUT_FREQ     (CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ / 2U)
1421 #define  CY_SYSCLK_FLL_MAX_OUTPUT_FREQ     (100000000UL)
1422 
1423 #define  CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(range) (((range) == CY_SYSCLK_FLL_CCO_RANGE0) || \
1424                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE1) || \
1425                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE2) || \
1426                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE3) || \
1427                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE4))
1428 /** \cond INTERNAL */
1429 #define  CY_SYSCLK_FLL_INT_COEF (327680000UL)
1430 #define  CY_SYSCLK_FLL_GAIN_IDX (11U)
1431 #define  CY_SYSCLK_FLL_GAIN_VAL (8UL * CY_SYSCLK_FLL_INT_COEF)
1432 
1433 #define TRIM_STEPS_SCALE        (100000000ULL) /* 10 ^ 8 */
1434 #define MARGIN_SCALE            (100000ULL) /* 10 ^ 5 */
1435 /** \endcond */
1436 
Cy_SysClk_FllIsEnabled(void)1437 bool Cy_SysClk_FllIsEnabled(void)
1438 {
1439     return (_FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_ENABLE, SRSS_CLK_FLL_CONFIG));
1440 }
1441 
1442 
Cy_SysClk_FllLocked(void)1443 bool Cy_SysClk_FllLocked(void)
1444 {
1445     return (_FLD2BOOL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS_CLK_FLL_STATUS));
1446 }
1447 
1448 
Cy_SysClk_FllDisable(void)1449 cy_en_sysclk_status_t Cy_SysClk_FllDisable(void)
1450 {
1451     cy_en_sysclk_status_t retStatus;
1452 #if defined (CY_DEVICE_SECURE)
1453     retStatus = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_FLL_DISABLE, 0UL);
1454 
1455 #endif /* defined (CY_DEVICE_SECURE) */
1456 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1457     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1458     SRSS_CLK_FLL_CONFIG  &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
1459     SRSS_CLK_FLL_CONFIG4 &= ~SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
1460     retStatus = (CY_SYSCLK_SUCCESS);
1461 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1462     return retStatus;
1463 }
1464 
1465 
Cy_SysClk_FllConfigure(uint32_t inputFreq,uint32_t outputFreq,cy_en_fll_pll_output_mode_t outputMode)1466 cy_en_sysclk_status_t Cy_SysClk_FllConfigure(uint32_t inputFreq, uint32_t outputFreq, cy_en_fll_pll_output_mode_t outputMode)
1467 {
1468     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1469 
1470     /* check for errors */
1471     if ((outputFreq < CY_SYSCLK_FLL_MIN_OUTPUT_FREQ) || (CY_SYSCLK_FLL_MAX_OUTPUT_FREQ < outputFreq) || /* invalid output frequency */
1472       (((outputFreq * 5UL) / inputFreq) < 11UL)) /* check output/input frequency ratio */
1473     {
1474         retVal = CY_SYSCLK_BAD_PARAM;
1475     }
1476     else /* no errors */
1477     {
1478         /* If output mode is bypass (input routed directly to output), then done.
1479            The output frequency equals the input frequency regardless of the
1480            frequency parameters. */
1481         if (outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1482         {
1483             cy_stc_fll_manual_config_t config;
1484             uint32_t ccoFreq;
1485             bool wcoSource = (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource(0UL/*FLL*/)) ? true : false;
1486 
1487             config.outputMode = outputMode;
1488             /* 1. Output division by 2 is always required */
1489             config.enableOutputDiv = true;
1490             /* 2. Compute the target CCO frequency from the target output frequency and output division */
1491             ccoFreq = outputFreq * 2UL;
1492             /* 3. Compute the CCO range value from the CCO frequency */
1493             config.ccoRange = ((ccoFreq >= 150339200UL) ? CY_SYSCLK_FLL_CCO_RANGE4 :
1494                                ((ccoFreq >= 113009380UL) ? CY_SYSCLK_FLL_CCO_RANGE3 :
1495                                 ((ccoFreq >=  84948700UL) ? CY_SYSCLK_FLL_CCO_RANGE2 :
1496                                  ((ccoFreq >=  63855600UL) ? CY_SYSCLK_FLL_CCO_RANGE1 : CY_SYSCLK_FLL_CCO_RANGE0))));
1497 
1498         /* 4. Compute the FLL reference divider value.
1499               refDiv is a constant if the WCO is the FLL source, otherwise the formula is
1500               refDiv = ROUNDUP((inputFreq / outputFreq) * 250) */
1501             config.refDiv = wcoSource ? 19U : (uint16_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)inputFreq * 250ULL, (uint64_t)outputFreq);
1502 
1503         /* 5. Compute the FLL multiplier value.
1504               Formula is fllMult = ccoFreq / (inputFreq / refDiv) */
1505             config.fllMult = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)ccoFreq * (uint64_t)config.refDiv, (uint64_t)inputFreq);
1506         /* 6. Compute the lock tolerance.
1507               Formula is lock tolerance = 1.5 * fllMult * (((1 + CCO accuracy) / (1 - source clock accuracy)) - 1)
1508               We assume CCO accuracy is 0.25%.
1509               We assume the source clock accuracy = 1%. This is the accuracy of the IMO.
1510               Therefore the formula is lock tolerance = 1.5 * fllMult * 0.012626 = 0.018939 * fllMult */
1511             config.lockTolerance = (uint16_t)CY_SYSLIB_DIV_ROUNDUP(config.fllMult * 18939UL, 1000000UL);
1512 
1513             {
1514                 /* constants indexed by ccoRange */
1515                 const uint32_t trimSteps[] = {110340UL, 110200UL, 110000UL, 110000UL, 117062UL}; /* Scaled by 10^8 */
1516                 const uint32_t margin[] = {436UL, 581UL, 772UL, 1030UL, 1320UL}; /* Scaled by 10^5 */
1517         /* 7. Compute the CCO igain and pgain */
1518                 {
1519                     /* intermediate parameters */
1520                     uint32_t kcco = (trimSteps[config.ccoRange] * margin[config.ccoRange]);
1521                     uint32_t ki_p = (uint32_t)CY_SYSLIB_DIV_ROUND(850ULL * CY_SYSCLK_FLL_INT_COEF * inputFreq, (uint64_t)kcco * (uint64_t)config.refDiv);
1522 
1523                     /* find the largest IGAIN value that is less than or equal to ki_p */
1524                     uint32_t locigain = CY_SYSCLK_FLL_GAIN_VAL;
1525                     uint32_t locpgain = CY_SYSCLK_FLL_GAIN_VAL;
1526 
1527                     /* find the largest IGAIN value that is less than or equal to ki_p */
1528                     for(config.igain = CY_SYSCLK_FLL_GAIN_IDX; config.igain != 0UL; config.igain--)
1529                     {
1530                        if(locigain <= ki_p)
1531                        {
1532                           break;
1533                        }
1534                        locigain >>= 1U;
1535                     }
1536                     /* decrement igain if the WCO is the FLL source */
1537                     if (wcoSource && (config.igain > 0U))
1538                     {
1539                         config.igain--;
1540                         locigain >>= 1U;
1541                     }
1542 
1543                     /* then find the largest PGAIN value that is less than or equal to ki_p - igain */
1544                     for(config.pgain = CY_SYSCLK_FLL_GAIN_IDX; config.pgain != 0UL; config.pgain--)
1545                     {
1546                       if(locpgain <= (ki_p - locigain))
1547                       {
1548                           break;
1549                       }
1550                       locpgain >>= 1U;
1551                     }
1552 
1553                     /* decrement pgain if the WCO is the FLL source */
1554                     if (wcoSource && (config.pgain > 0U))
1555                     {
1556                         config.pgain--;
1557                     }
1558                 }
1559 
1560         /* 8. Compute the CCO_FREQ bits in CLK_FLL_CONFIG4 register */
1561                 {
1562                     uint64_t cmp = CY_SYSLIB_DIV_ROUND(((TRIM_STEPS_SCALE / MARGIN_SCALE) * (uint64_t)ccoFreq), (uint64_t)margin[config.ccoRange]);
1563                     uint64_t mlt = TRIM_STEPS_SCALE + (uint64_t)trimSteps[config.ccoRange];
1564                     uint64_t res = mlt;
1565 
1566                     config.cco_Freq = 0U;
1567 
1568                     while(res < cmp)
1569                     {
1570                         res *= mlt;
1571                         res /= TRIM_STEPS_SCALE;
1572                         config.cco_Freq++;
1573                     }
1574                 }
1575             }
1576 
1577         /* 9. Compute the settling count, using a 1 usec settling time. Use a constant if the WCO is the FLL source */
1578             {
1579                 uint64_t fref = CY_SYSLIB_DIV_ROUND(6000ULL * (uint64_t)inputFreq, (uint64_t)config.refDiv);
1580                 uint32_t divval = CY_SYSLIB_DIV_ROUNDUP(inputFreq, 1000000UL);
1581                 uint32_t altval = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)divval * fref, 6000000ULL) + 1UL;
1582 
1583                 config.settlingCount = wcoSource ? 200U : (uint16_t)
1584                           ((outputFreq < fref) ? divval :
1585                             ((divval > altval) ? divval : altval));
1586             }
1587         /* Configure FLL based on calculated values */
1588             retVal = Cy_SysClk_FllManualConfigure(&config);
1589         }
1590         else /* if not, bypass output mode */
1591         {
1592             CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1593         }
1594     }
1595 
1596     return (retVal);
1597 }
1598 
1599 
Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t * config)1600 cy_en_sysclk_status_t Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t *config)
1601 {
1602     cy_en_sysclk_status_t retVal;
1603 #if defined (CY_DEVICE_SECURE)
1604     retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_FLL_MANCONFIG, config);
1605 #endif /* defined (CY_DEVICE_SECURE) */
1606 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1607     retVal = CY_SYSCLK_INVALID_STATE;
1608 
1609     /* Check for errors */
1610     CY_ASSERT_L1(config != NULL);
1611 
1612     if (!Cy_SysClk_FllIsEnabled()) /* If disabled */
1613     {
1614         /* update CLK_FLL_CONFIG register with 2 parameters; FLL_ENABLE is already 0 */
1615         /* asserts just check for bitfield overflow */
1616         CY_ASSERT_L1(config->fllMult <= (SRSS_CLK_FLL_CONFIG_FLL_MULT_Msk >> SRSS_CLK_FLL_CONFIG_FLL_MULT_Pos));
1617 
1618         SRSS_CLK_FLL_CONFIG = _VAL2FLD(SRSS_CLK_FLL_CONFIG_FLL_MULT, config->fllMult) |
1619                              _BOOL2FLD(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, config->enableOutputDiv);
1620 
1621         /* update CLK_FLL_CONFIG2 register with 2 parameters */
1622         /* asserts just check for bitfield overflow */
1623         CY_ASSERT_L1(config->refDiv <= (SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Msk >> SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Pos));
1624         CY_ASSERT_L1(config->lockTolerance <= (SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Msk >> SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Pos));
1625 
1626         SRSS_CLK_FLL_CONFIG2 = _VAL2FLD(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, config->refDiv) |
1627                                _VAL2FLD(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, config->lockTolerance);
1628 
1629         /* update CLK_FLL_CONFIG3 register with 4 parameters */
1630         /* asserts just check for bitfield overflow */
1631         CY_ASSERT_L1(config->igain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Pos));
1632         CY_ASSERT_L1(config->pgain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Pos));
1633         CY_ASSERT_L1(config->settlingCount <= (SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Msk >> SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Pos));
1634 
1635         SRSS_CLK_FLL_CONFIG3 = _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, config->igain) |
1636                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, config->pgain) |
1637                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, config->settlingCount) |
1638                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, config->outputMode);
1639 
1640         /* update CLK_FLL_CONFIG4 register with 1 parameter; preserve other bits */
1641         /* asserts just check for bitfield overflow */
1642         CY_ASSERT_L1(CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(config->ccoRange));
1643         CY_ASSERT_L1(config->cco_Freq <= (SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Msk >> SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Pos));
1644 
1645         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_RANGE, (uint32_t)(config->ccoRange));
1646         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_FREQ, (uint32_t)(config->cco_Freq));
1647 
1648         retVal = CY_SYSCLK_SUCCESS;
1649     }
1650 
1651 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1652     return (retVal);
1653 }
1654 
1655 
Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t * config)1656 void Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t *config)
1657 {
1658     CY_ASSERT_L1(config != NULL);
1659     /* read 2 parameters from CLK_FLL_CONFIG register */
1660     uint32_t tempReg = SRSS_CLK_FLL_CONFIG;
1661     config->fllMult         = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, tempReg);
1662     config->enableOutputDiv = _FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, tempReg);
1663     /* read 2 parameters from CLK_FLL_CONFIG2 register */
1664     tempReg = SRSS_CLK_FLL_CONFIG2;
1665     config->refDiv          = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, tempReg);
1666     config->lockTolerance   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, tempReg);
1667     /* read 4 parameters from CLK_FLL_CONFIG3 register */
1668     tempReg = SRSS_CLK_FLL_CONFIG3;
1669     config->igain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, tempReg);
1670     config->pgain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, tempReg);
1671     config->settlingCount   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, tempReg);
1672     config->outputMode      = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, tempReg));
1673     /* read 2 parameters from CLK_FLL_CONFIG4 register */
1674     tempReg = SRSS_CLK_FLL_CONFIG4;
1675     config->ccoRange        = (cy_en_fll_cco_ranges_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_RANGE, tempReg));
1676     config->cco_Freq        = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_FREQ, tempReg);
1677 }
1678 
1679 
Cy_SysClk_FllEnable(uint32_t timeoutus)1680 cy_en_sysclk_status_t Cy_SysClk_FllEnable(uint32_t timeoutus)
1681 {
1682     cy_en_sysclk_status_t retStatus;
1683 #if defined (CY_DEVICE_SECURE)
1684     retStatus = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_FLL_ENABLE, timeoutus);
1685 #endif /* defined (CY_DEVICE_SECURE) */
1686 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1687     bool zeroTimeout = (0UL == timeoutus);
1688 
1689     /* first set the CCO enable bit */
1690     SRSS_CLK_FLL_CONFIG4 |= SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
1691 
1692     /* Wait until CCO is ready */
1693     for (; (!_FLD2BOOL(SRSS_CLK_FLL_STATUS_CCO_READY, SRSS_CLK_FLL_STATUS)) && /* if cco_ready == 0 */
1694            (0UL != timeoutus);
1695          timeoutus--)
1696     {
1697         Cy_SysLib_DelayUs(1U);
1698     }
1699 
1700     /* Set the FLL bypass mode to FLL_REF */
1701     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1702 
1703     /* Set the FLL enable bit, if CCO is ready */
1704     if (zeroTimeout || (0UL != timeoutus))
1705     {
1706         SRSS_CLK_FLL_CONFIG |= SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
1707     }
1708 
1709     /* now do the timeout wait for FLL_STATUS, bit LOCKED */
1710     for (; (!Cy_SysClk_FllLocked()) && /* if locked == 0 */
1711            (0UL != timeoutus);
1712          timeoutus--)
1713     {
1714         Cy_SysLib_DelayUs(1U);
1715     }
1716 
1717     if (zeroTimeout || (0UL != timeoutus))
1718     {
1719         /* Set the FLL bypass mode to FLL_OUT (ignoring lock indicator) */
1720         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
1721     }
1722     else
1723     {
1724         /* If lock doesn't occur, FLL is stopped */
1725         (void)Cy_SysClk_FllDisable();
1726     }
1727 
1728     retStatus = ((zeroTimeout || (0UL != timeoutus)) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_TIMEOUT);
1729 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1730     return retStatus;
1731 }
1732 
1733 
1734 /* ========================================================================== */
1735 /* ===========================    PLL SECTION    ============================ */
1736 /* ========================================================================== */
1737 
1738 /* PLL OUTPUT_DIV bitfield allowable range */
1739 #define CY_SYSCLK_PLL_MIN_OUTPUT_DIV   (2UL)
1740 #define CY_SYSCLK_PLL_MAX_OUTPUT_DIV   (16UL)
1741 
1742 /* PLL REFERENCE_DIV bitfield allowable range */
1743 #define CY_SYSCLK_PLL_MIN_REF_DIV      (1UL)
1744 #define CY_SYSCLK_PLL_MAX_REF_DIV      (18UL)
1745 
1746 /* PLL FEEDBACK_DIV bitfield allowable ranges, LF and normal modes */
1747 #define CY_SYSCLK_PLL_MIN_FB_DIV_LF    (19UL)
1748 #define CY_SYSCLK_PLL_MAX_FB_DIV_LF    (56UL)
1749 #define CY_SYSCLK_PLL_MIN_FB_DIV_NORM  (22UL)
1750 #define CY_SYSCLK_PLL_MAX_FB_DIV_NORM  (112UL)
1751 
1752 /* PLL FEEDBACK_DIV bitfield allowable range selection */
1753 #define CY_SYSCLK_PLL_MIN_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FB_DIV_LF : CY_SYSCLK_PLL_MIN_FB_DIV_NORM)
1754 #define CY_SYSCLK_PLL_MAX_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FB_DIV_LF : CY_SYSCLK_PLL_MAX_FB_DIV_NORM)
1755 
1756 /* PLL Fvco range allowable ranges, LF and normal modes */
1757 #define CY_SYSCLK_PLL_MIN_FVCO_LF      (170000000UL)
1758 #define CY_SYSCLK_PLL_MAX_FVCO_LF      (200000000UL)
1759 #define CY_SYSCLK_PLL_MIN_FVCO_NORM    (200000000UL)
1760 #define CY_SYSCLK_PLL_MAX_FVCO_NORM    (400000000UL)
1761 /* PLL Fvco range selection */
1762 #define CY_SYSCLK_PLL_MIN_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FVCO_LF : CY_SYSCLK_PLL_MIN_FVCO_NORM)
1763 #define CY_SYSCLK_PLL_MAX_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FVCO_LF : CY_SYSCLK_PLL_MAX_FVCO_NORM)
1764 
1765 /* PLL input and output frequency limits */
1766 #define CY_SYSCLK_PLL_MIN_IN_FREQ  (4000000UL)
1767 #define CY_SYSCLK_PLL_MAX_IN_FREQ  (64000000UL)
1768 #define CY_SYSCLK_PLL_MIN_OUT_FREQ (CY_SYSCLK_PLL_MIN_FVCO / CY_SYSCLK_PLL_MAX_OUTPUT_DIV)
1769 #define CY_SYSCLK_PLL_MAX_OUT_FREQ (150000000UL)
1770 
1771 
Cy_SysClk_PllIsEnabled(uint32_t clkPath)1772 bool Cy_SysClk_PllIsEnabled(uint32_t clkPath)
1773 {
1774     clkPath--; /* to correctly access PLL config and status registers structures */
1775     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1776     return (_FLD2BOOL(SRSS_CLK_PLL_CONFIG_ENABLE, SRSS_CLK_PLL_CONFIG[clkPath]));
1777 }
1778 
1779 
Cy_SysClk_PllLocked(uint32_t clkPath)1780 bool Cy_SysClk_PllLocked(uint32_t clkPath)
1781 {
1782     clkPath--; /* to correctly access PLL config and status registers structures */
1783     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1784     return (_FLD2BOOL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS_CLK_PLL_STATUS[clkPath]));
1785 }
1786 
1787 
Cy_SysClk_PllLostLock(uint32_t clkPath)1788 bool Cy_SysClk_PllLostLock(uint32_t clkPath)
1789 {
1790 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1791     (void) clkPath;
1792     return false;
1793 
1794 #else
1795     clkPath--; /* to correctly access PLL config and status registers structures */
1796     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1797     bool retVal = _FLD2BOOL(SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED, SRSS_CLK_PLL_STATUS[clkPath]);
1798     /* write a 1 to clear the unlock occurred bit */
1799     SRSS_CLK_PLL_STATUS[clkPath] = SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED_Msk;
1800     return (retVal);
1801 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1802 }
1803 
1804 
Cy_SysClk_PllDisable(uint32_t clkPath)1805 cy_en_sysclk_status_t Cy_SysClk_PllDisable(uint32_t clkPath)
1806 {
1807     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1808     clkPath--; /* to correctly access PLL config and status registers structures */
1809     if (clkPath < CY_SRSS_NUM_PLL)
1810     {
1811 #if defined (CY_DEVICE_SECURE)
1812         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PLL_DISABLE, (clkPath + 1U));
1813 #endif /* defined (CY_DEVICE_SECURE) */
1814 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1815         /* First bypass PLL */
1816         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1817         /* Wait at least 6 PLL clock cycles */
1818         Cy_SysLib_DelayUs(1U);
1819         /* And now disable the PLL itself */
1820         SRSS_CLK_PLL_CONFIG[clkPath] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
1821         retVal = CY_SYSCLK_SUCCESS;
1822 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1823     }
1824     return (retVal);
1825 }
1826 
1827 
Cy_SysClk_PllConfigure(uint32_t clkPath,const cy_stc_pll_config_t * config)1828 cy_en_sysclk_status_t Cy_SysClk_PllConfigure(uint32_t clkPath, const cy_stc_pll_config_t *config)
1829 {
1830     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1831 
1832     if (((config->inputFreq)  < CY_SYSCLK_PLL_MIN_IN_FREQ)  || (CY_SYSCLK_PLL_MAX_IN_FREQ  < (config->inputFreq)) ||
1833         ((config->outputFreq) < CY_SYSCLK_PLL_MIN_OUT_FREQ) || (CY_SYSCLK_PLL_MAX_OUT_FREQ < (config->outputFreq)))
1834     {
1835         retVal = CY_SYSCLK_BAD_PARAM;
1836     }
1837     else
1838     {
1839         cy_stc_pll_manual_config_t manualConfig = {0U, 0U, 0U, false, CY_SYSCLK_FLLPLL_OUTPUT_AUTO};
1840 
1841         /* If output mode is not bypass (input routed directly to output), then
1842            calculate new parameters. */
1843         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1844         {
1845             /* for each possible value of OUTPUT_DIV and REFERENCE_DIV (Q), try
1846                to find a value for FEEDBACK_DIV (P) that gives an output frequency
1847                as close as possible to the desired output frequency. */
1848             uint32_t p, q, out;
1849             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
1850 
1851             /* REFERENCE_DIV (Q) selection */
1852             for (q = CY_SYSCLK_PLL_MIN_REF_DIV; q <= CY_SYSCLK_PLL_MAX_REF_DIV; q++)
1853             {
1854                 /* FEEDBACK_DIV (P) selection */
1855                 for (p = CY_SYSCLK_PLL_MIN_FB_DIV; p <= CY_SYSCLK_PLL_MAX_FB_DIV; p++)
1856                 {
1857                     /* Calculate the intermediate Fvco, and make sure that it's in range */
1858                     uint32_t fvco = (uint32_t)(((uint64_t)(config->inputFreq) * (uint64_t)p) / (uint64_t)q);
1859                     if ((CY_SYSCLK_PLL_MIN_FVCO <= fvco) && (fvco <= CY_SYSCLK_PLL_MAX_FVCO))
1860                     {
1861                         /* OUTPUT_DIV selection */
1862                         for (out = CY_SYSCLK_PLL_MIN_OUTPUT_DIV; out <= CY_SYSCLK_PLL_MAX_OUTPUT_DIV; out++)
1863                         {
1864                             /* Calculate what output frequency will actually be produced.
1865                                If it's closer to the target than what we have so far, then save it. */
1866                             uint32_t fout = ((p * config->inputFreq) / q) / out;
1867                             if ((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
1868                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq)))
1869                             {
1870                                 if (foutBest == (config->outputFreq))
1871                                 {
1872                                    break;
1873                                 }
1874 
1875                                 foutBest = fout;
1876                                 manualConfig.feedbackDiv  = (uint8_t)p;
1877                                 manualConfig.referenceDiv = (uint8_t)q;
1878                                 manualConfig.outputDiv    = (uint8_t)out;
1879                             }
1880                         }
1881                     }
1882                 }
1883             }
1884             /* exit loops if foutBest equals outputFreq */
1885 
1886             manualConfig.lfMode = config->lfMode;
1887         } /* if not, bypass output mode */
1888 
1889         /* If output mode is bypass (input routed directly to output), then
1890            use old parameters. */
1891         else
1892         {
1893             (void)Cy_SysClk_PllGetConfiguration(clkPath, &manualConfig);
1894         }
1895         /* configure PLL based on calculated values */
1896 
1897         manualConfig.outputMode = config->outputMode;
1898         retVal = Cy_SysClk_PllManualConfigure(clkPath, &manualConfig);
1899 
1900     } /* if no error */
1901 
1902     return (retVal);
1903 }
1904 
1905 
Cy_SysClk_PllManualConfigure(uint32_t clkPath,const cy_stc_pll_manual_config_t * config)1906 cy_en_sysclk_status_t Cy_SysClk_PllManualConfigure(uint32_t clkPath, const cy_stc_pll_manual_config_t *config)
1907 {
1908     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1909 
1910     /* check for errors */
1911     if (clkPath > CY_SRSS_NUM_PLL) /* invalid clock path number */
1912     {
1913         retVal = CY_SYSCLK_BAD_PARAM;
1914     }
1915     else if (Cy_SysClk_PllIsEnabled(clkPath))
1916     {
1917         retVal = CY_SYSCLK_INVALID_STATE;
1918     }
1919     /* valid divider bitfield values */
1920     else if ((config->outputDiv    < CY_SYSCLK_PLL_MIN_OUTPUT_DIV) || (CY_SYSCLK_PLL_MAX_OUTPUT_DIV < config->outputDiv)    ||
1921              (config->referenceDiv < CY_SYSCLK_PLL_MIN_REF_DIV)    || (CY_SYSCLK_PLL_MAX_REF_DIV    < config->referenceDiv) ||
1922              (config->feedbackDiv  < CY_SYSCLK_PLL_MIN_FB_DIV)     || (CY_SYSCLK_PLL_MAX_FB_DIV     < config->feedbackDiv))
1923     {
1924          retVal = CY_SYSCLK_BAD_PARAM;
1925     }
1926     else /* no errors */
1927     {
1928 #if defined (CY_DEVICE_SECURE)
1929         cy_stc_pra_clk_pll_manconfigure_t pll_config;
1930         pll_config.clkPath   = clkPath;
1931         pll_config.praConfig    = (cy_stc_pll_manual_config_t *)config;
1932         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PLL_MANCONFIG, &pll_config);
1933 #endif /* defined (CY_DEVICE_SECURE) */
1934 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1935         clkPath--; /* to correctly access PLL config registers structure */
1936         /* If output mode is bypass (input routed directly to output), then done.
1937            The output frequency equals the input frequency regardless of the frequency parameters. */
1938         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1939         {
1940             SRSS_CLK_PLL_CONFIG[clkPath] =
1941                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  config->feedbackDiv)  |
1942                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, config->referenceDiv) |
1943                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    config->outputDiv)    |
1944                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   config->lfMode);
1945         }
1946 
1947         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, (uint32_t)config->outputMode);
1948 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1949     }
1950 
1951     return (retVal);
1952 }
1953 
1954 
Cy_SysClk_PllGetConfiguration(uint32_t clkPath,cy_stc_pll_manual_config_t * config)1955 cy_en_sysclk_status_t Cy_SysClk_PllGetConfiguration(uint32_t clkPath, cy_stc_pll_manual_config_t *config)
1956 {
1957     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1958     clkPath--; /* to correctly access PLL config and status register structures */
1959     if (clkPath < CY_SRSS_NUM_PLL)
1960     {
1961         uint32_t tempReg = SRSS_CLK_PLL_CONFIG[clkPath];
1962         config->feedbackDiv  = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  tempReg);
1963         config->referenceDiv = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, tempReg);
1964         config->outputDiv    = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    tempReg);
1965         config->lfMode       =         _FLD2BOOL(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   tempReg);
1966         config->outputMode   = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, tempReg));
1967         retVal = CY_SYSCLK_SUCCESS;
1968     }
1969     return (retVal);
1970 }
1971 
1972 
Cy_SysClk_PllEnable(uint32_t clkPath,uint32_t timeoutus)1973 cy_en_sysclk_status_t Cy_SysClk_PllEnable(uint32_t clkPath, uint32_t timeoutus)
1974 {
1975     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1976     bool zeroTimeout = (timeoutus == 0UL);
1977     clkPath--; /* to correctly access PLL config and status registers structures */
1978     if (clkPath < CY_SRSS_NUM_PLL)
1979     {
1980 #if defined (CY_DEVICE_SECURE)
1981         (void)timeoutus;
1982         (void)zeroTimeout;
1983         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PLL_ENABLE, (clkPath + 1U));
1984 #endif /* defined (CY_DEVICE_SECURE) */
1985 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1986         /* first set the PLL enable bit */
1987         SRSS_CLK_PLL_CONFIG[clkPath] |= SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
1988 
1989         /* now do the timeout wait for PLL_STATUS, bit LOCKED */
1990         for (; (0UL == (SRSS_CLK_PLL_STATUS_LOCKED_Msk & SRSS_CLK_PLL_STATUS[clkPath])) &&
1991                (0UL != timeoutus);
1992              timeoutus--)
1993         {
1994             Cy_SysLib_DelayUs(1U);
1995         }
1996 
1997         if (zeroTimeout || (0UL != timeoutus))
1998         {
1999             /* Unbypass PLL, if it is not in AUTO mode */
2000             if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[clkPath]))
2001             {
2002                 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2003             }
2004 
2005             retVal = CY_SYSCLK_SUCCESS;
2006         }
2007         else
2008         {
2009             /* If lock doesn't occur, then bypass PLL */
2010             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2011             /* Wait at least 6 PLL clock cycles */
2012             Cy_SysLib_DelayUs(1U);
2013             /* And now disable the PLL itself */
2014             SRSS_CLK_PLL_CONFIG[clkPath] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
2015             retVal = CY_SYSCLK_TIMEOUT;
2016         }
2017 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
2018     }
2019     return (retVal);
2020 }
2021 
2022 
2023 /* ========================================================================== */
2024 /* ====================    Clock Measurement section    ===================== */
2025 /* ========================================================================== */
2026 /* Slow control register default value */
2027 #define TST_DDFT_SLOW_CTL_DEFAULT_VAL      (0x00001F1FUL)
2028 
2029 /* Fast control register */
2030 #define TST_DDFT_FAST_CTL_REG              (*(volatile uint32_t *) 0x40260104U)
2031 
2032 /* Slow control register default value */
2033 #define TST_DDFT_FAST_CTL_DEFAULT_VAL      (0x00003D3DUL)
2034 
2035 /* Define for select signal outputs in slow clock */
2036 #define SRSS_CLK_OUTPUT_SLOW_MASK  ((uint32_t) SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk | \
2037                                                SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk)
2038 
2039 /* Define for select signal outputs in fast clock */
2040 #define SRSS_CLK_OUTPUT_FAST_MASK  ((uint32_t) SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk  | \
2041                                                SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk  | \
2042                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk  | \
2043                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk  | \
2044                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk | \
2045                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk)
2046 
2047 /* Cy_SysClk_StartClkMeasurementCounters() input parameter saved for use later in other functions */
2048 static uint32_t clk1Count1;
2049 
2050 /* These variables act as locks to prevent collisions between clock measurement and entry into
2051    Deep Sleep mode. See Cy_SysClk_DeepSleep(). */
2052 static bool clkCounting = false;
2053 static bool preventCounting = false;
2054 
2055 
Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock,uint32_t refClkFreq)2056 uint32_t Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock, uint32_t refClkFreq)
2057 {
2058     uint32_t retVal = 0UL;
2059     bool isMeasurementValid = false;
2060 
2061     /* Done counting; allow entry into Deep Sleep mode */
2062     clkCounting = false;
2063 
2064     /* Acquire the IPC to prevent changing of the shared resources at the same time */
2065     while(0U == (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
2066     {
2067         /* Wait until the IPC structure is released by another process */
2068     }
2069 
2070     /* Check whether the device was in the Deep Sleep mode or the flash partially blocked while the
2071     *  operation was done
2072     */
2073     if(SRSS_TST_DDFT_SLOW_CTL_REG == TST_DDFT_SLOW_CTL_DEFAULT_VAL)
2074     {
2075        if(SRSS_TST_DDFT_FAST_CTL_REG == TST_DDFT_FAST_CTL_DEFAULT_VAL)
2076        {
2077            isMeasurementValid = true;
2078        }
2079     }
2080 
2081     retVal = _FLD2VAL(SRSS_CLK_CAL_CNT2_CAL_COUNTER2, SRSS_CLK_CAL_CNT2);
2082     /* Release the IPC */
2083     REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
2084 
2085     if (isMeasurementValid && (0UL != retVal))
2086     {
2087         if (!measuredClock)
2088         {   /* clock1 is the measured clock */
2089             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)clk1Count1 * (uint64_t)refClkFreq, (uint64_t)retVal);
2090         }
2091         else
2092         {   /* clock2 is the measured clock */
2093             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)retVal * (uint64_t)refClkFreq, (uint64_t)clk1Count1);
2094         }
2095     }
2096     else
2097     {
2098         /* Return zero value to indicate invalid measurement */
2099         retVal = 0UL;
2100     }
2101 
2102     return (retVal);
2103 }
2104 
2105 
Cy_SysClk_ClkMeasurementCountersDone(void)2106 bool Cy_SysClk_ClkMeasurementCountersDone(void)
2107 {
2108     return (_FLD2BOOL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1));
2109 }
2110 
2111 
Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1,uint32_t count1,cy_en_meas_clks_t clock2)2112 cy_en_sysclk_status_t Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1, uint32_t count1, cy_en_meas_clks_t clock2)
2113 {
2114     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
2115 
2116 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2117 
2118     cy_stc_pra_start_clk_measurement_t clkMeasurement;
2119     clkMeasurement.clock1 = clock1;
2120     clkMeasurement.count1 = count1;
2121     clkMeasurement.clock2 = clock2;
2122 
2123     /* Don't start a measurement if about to enter Deep Sleep mode */
2124     if (!preventCounting)
2125     {
2126         retVal = (cy_en_sysclk_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_START_MEASUREMENT, &clkMeasurement);
2127     }
2128 
2129     if (CY_SYSCLK_SUCCESS == retVal)
2130     {
2131         /* Disallow entry into Deep Sleep mode while counting */
2132         clkCounting = true;
2133 
2134         /* Save this input parameter for use later, in other functions */
2135         clk1Count1 = count1;
2136     }
2137 #else
2138 
2139     uint32_t clkOutputSlowVal = 0UL;
2140     uint32_t clkOutputFastVal = 0UL;
2141 
2142     uint32_t clkOutputSlowMask = 0UL;
2143     uint32_t clkOutputFastMask = 0UL;
2144 
2145     /* Prepare values for measurement control registers */
2146 
2147     /* Connect the indicated clocks to the respective counters:
2148 
2149        if clock1 is a slow clock,
2150          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL0, and SRSS_CLK_OUTPUT_FAST.FAST_SEL0 = SLOW_SEL0
2151        else if clock1 is a fast clock,
2152          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL0,
2153        else error, do nothing and return.
2154 
2155        if clock2 is a slow clock,
2156          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL1, and SRSS_CLK_OUTPUT_FAST.FAST_SEL1 = SLOW_SEL1
2157        else if clock2 is a fast clock,
2158          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL1,
2159        else error, do nothing and return.
2160     */
2161     if ((clock1 < CY_SYSCLK_MEAS_CLK_LAST_CLK) && (clock2 < CY_SYSCLK_MEAS_CLK_LAST_CLK) &&
2162         (count1 <= (SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Msk >> SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Pos)))
2163     {
2164         /* Disallow entry into Deep Sleep mode while counting */
2165         clkCounting = true;
2166 
2167         if (clock1 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
2168         { /* slow clock */
2169             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0, (uint32_t)clock1);
2170             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, 7UL/*slow_sel0 output*/);
2171 
2172             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk;
2173             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2174         }
2175         else
2176         { /* fast clock */
2177             if (clock1 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
2178             { /* ECO, EXT, ALTHF */
2179                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (uint32_t)clock1);
2180                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2181             }
2182             else
2183             { /* PATH or CLKHF */
2184                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (((uint32_t)clock1 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
2185                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2186 
2187                 if (clock1 < CY_SYSCLK_MEAS_CLK_CLKHFS)
2188                 { /* PATH select */
2189                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
2190                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk;
2191                 }
2192                 else
2193                 { /* CLKHF select */
2194                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
2195                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk;
2196                 }
2197             }
2198         } /* clock1 fast clock */
2199 
2200         if (clock2 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
2201         { /* slow clock */
2202             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1, (uint32_t)clock2);
2203             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, 7UL/*slow_sel1 output*/);
2204 
2205             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk;
2206             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2207         }
2208         else
2209         { /* fast clock */
2210             if (clock2 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
2211             { /* ECO, EXT, ALTHF */
2212                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (uint32_t)clock2);
2213                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2214             }
2215             else
2216             { /* PATH or CLKHF */
2217                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (((uint32_t)clock2 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
2218                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2219 
2220                 if (clock2 < CY_SYSCLK_MEAS_CLK_CLKHFS)
2221                 { /* PATH select */
2222                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
2223                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk;
2224                 }
2225                 else
2226                 { /* CLKHF select */
2227                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
2228                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk;
2229                 }
2230             }
2231         } /* clock2 fast clock */
2232 
2233         /* Acquire the IPC to prevent changing of the shared resources at the same time */
2234         while(0U == (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
2235         {
2236             /* Wait until the IPC structure is released by another process */
2237         }
2238 
2239         if ((!preventCounting) /* don't start a measurement if about to enter Deep Sleep mode */  ||
2240             (_FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1) != 0UL/*1 = done*/))
2241         {
2242             /* Set default values for counters measurement control registers */
2243             SRSS_TST_DDFT_SLOW_CTL_REG = TST_DDFT_SLOW_CTL_DEFAULT_VAL;
2244             SRSS_TST_DDFT_FAST_CTL_REG = TST_DDFT_FAST_CTL_DEFAULT_VAL;
2245 
2246             SRSS_CLK_OUTPUT_SLOW = ((SRSS_CLK_OUTPUT_SLOW & ((uint32_t) ~clkOutputSlowMask)) | clkOutputSlowVal);
2247             SRSS_CLK_OUTPUT_FAST = ((SRSS_CLK_OUTPUT_FAST & ((uint32_t) ~clkOutputFastMask)) | clkOutputFastVal);
2248 
2249             /* Save this input parameter for use later, in other functions.
2250                No error checking is done on this parameter */
2251             clk1Count1 = count1;
2252 
2253             /* Counting starts when counter1 is written with a nonzero value */
2254             SRSS_CLK_CAL_CNT1 = clk1Count1;
2255 
2256             retVal = CY_SYSCLK_SUCCESS;
2257         }
2258 
2259         /* Release the IPC */
2260         REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
2261     }
2262 
2263 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2264 
2265     return (retVal);
2266 }
2267 
2268 /* ========================================================================== */
2269 /* ==========================    TRIM SECTION    ============================ */
2270 /* ========================================================================== */
2271 
2272 
2273 /** \cond INTERNAL */
2274 #define CY_SYSCLK_ILO_TARGET_FREQ  (32768UL)
2275 /* Nominal trim step size is 1.5% of "the frequency". Using the target frequency */
2276 #define CY_SYSCLK_ILO_TRIM_STEP    (CY_SYSLIB_DIV_ROUND(CY_SYSCLK_ILO_TARGET_FREQ * 15UL, 1000UL))
2277 
2278 /* The step size to be used by Cy_SysClk_PiloTrim function */
2279 static uint32_t stepSize = CY_SYSCLK_PILO_TRIM_STEP;
2280 /** \endcond */
2281 
Cy_SysClk_IloTrim(uint32_t iloFreq)2282 int32_t Cy_SysClk_IloTrim(uint32_t iloFreq)
2283 {
2284     int32_t changeInTrim;
2285 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2286     (void) iloFreq;
2287     changeInTrim = (int32_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_ILO_TRIM, iloFreq);
2288 #else
2289     uint32_t diff;
2290     bool sign = false;
2291 
2292     if(iloFreq > (CY_SYSCLK_ILO_TARGET_FREQ + CY_SYSCLK_ILO_TRIM_STEP))
2293     {
2294         diff = iloFreq - CY_SYSCLK_ILO_TARGET_FREQ;
2295     }
2296     else if (iloFreq < (CY_SYSCLK_ILO_TARGET_FREQ - CY_SYSCLK_ILO_TRIM_STEP))
2297     {
2298         diff = CY_SYSCLK_ILO_TARGET_FREQ - iloFreq;
2299         sign = true;
2300     }
2301     else
2302     {
2303         diff = 0UL;
2304     }
2305 
2306     /* Do nothing if iloFreq is already within one trim step from the target */
2307     if(0UL != diff)
2308     {
2309         /* Get current trim value */
2310         uint32_t trim = _FLD2VAL(SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, SRSS_CLK_TRIM_ILO_CTL);
2311 
2312         diff = CY_SYSLIB_DIV_ROUND(diff, CY_SYSCLK_ILO_TRIM_STEP);
2313 
2314         if(sign)
2315         {
2316             trim += diff;
2317         }
2318         else
2319         {
2320             trim -= diff;
2321         }
2322 
2323         /* Update the trim value */
2324         CY_REG32_CLR_SET(SRSS_CLK_TRIM_ILO_CTL, SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, trim);
2325     }
2326 
2327     changeInTrim = (sign ? (int32_t)diff : (0L - (int32_t)diff));
2328 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2329 
2330     return changeInTrim;
2331 }
2332 
2333 
2334 /** \cond INTERNAL */
2335 #define CY_SYSCLK_PILO_TARGET_FREQ  (32768UL)
2336 /* nominal trim step size */
2337 #define CY_SYSCLK_PILO_TRIM_STEP        (5UL)
2338 /** \endcond */
2339 
Cy_SysClk_PiloTrim(uint32_t piloFreq)2340 int32_t Cy_SysClk_PiloTrim(uint32_t piloFreq)
2341 {
2342     int32_t changeInTrim;
2343     uint32_t diff;
2344     bool sign = false;
2345 
2346     if(piloFreq > (CY_SYSCLK_PILO_TARGET_FREQ + stepSize))
2347     {
2348         diff = piloFreq - CY_SYSCLK_PILO_TARGET_FREQ;
2349     }
2350     else if (piloFreq < (CY_SYSCLK_PILO_TARGET_FREQ - stepSize))
2351     {
2352         diff = CY_SYSCLK_PILO_TARGET_FREQ - piloFreq;
2353         sign = true;
2354     }
2355     else
2356     {
2357         diff = 0UL;
2358     }
2359 
2360     /* Do nothing if piloFreq is already within one trim step from the target */
2361     if(0UL != diff)
2362     {
2363         /* Get current trim value */
2364         uint32_t trim = Cy_SysClk_PiloGetTrim();
2365 
2366         diff = CY_SYSLIB_DIV_ROUND(diff, stepSize);
2367 
2368         if(sign)
2369         {/* piloFreq too low. Increase the trim value */
2370             trim += diff;
2371             if (trim >= SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk) /* limit overflow */
2372             {
2373                 trim = SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk;
2374             }
2375         }
2376         else
2377         {/* piloFreq too high. Decrease the trim value */
2378             trim -= diff;
2379             if ((int32_t)trim < 0) /* limit underflow */
2380             {
2381                 trim = 0UL;
2382             }
2383         }
2384 
2385         /* Update the trim value */
2386         Cy_SysClk_PiloSetTrim(trim);
2387     }
2388 
2389     changeInTrim = ((int32_t)(sign ? (int32_t)diff : (0L - (int32_t)diff)));
2390 return changeInTrim;
2391 }
2392 /** \cond INTERNAL */
2393 #define LF_COUNT          (64u)
2394 #define REF_COUNT         (212u)
2395 #define FREQ_REF          (31250u)
2396 #define TRIM_DELAY        (2000u)
2397 #define STEP_SIZE_ITER    (8u)
2398 /** \endcond */
2399 
2400 
2401 
Cy_SysClk_PiloInitialTrim(void)2402 void Cy_SysClk_PiloInitialTrim(void)
2403 {
2404 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2405     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_PILO_INITIAL_TRIM);
2406 #else
2407     uint32_t measuredCnt  = 0xFFFFFFFFUL;
2408     uint32_t trimVal      = 0UL;
2409     int32_t  bitPos       = 9;
2410 
2411     do
2412     {
2413         SRSS_CLK_PILO_CONFIG &= ~(SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk);
2414 
2415         /* Set 1 at BitPos in FTRIM*/
2416         SRSS_CLK_PILO_CONFIG |= (trimVal | ((uint32_t) 1U  << (uint32_t) bitPos));
2417 
2418         /* Wait for 2 ms after setting FTRIM */
2419         Cy_SysLib_DelayUs(TRIM_DELAY);
2420         /* Start frequency measurement of PILO for
2421          * 64 PILO clock counts with BLE ECO ALTHF(configured to 16MHz) as reference clock */
2422         (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, LF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2423         while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2424         {
2425             /* Wait for the measurement to complete */
2426         }
2427         /* Read the number of reference clock cycles for 64 PILO clock cycles */
2428         measuredCnt = (uint32_t)_FLD2VAL(SRSS_CLK_CAL_CNT2_CAL_COUNTER2, SRSS_CLK_CAL_CNT2);
2429         /* If the measured clock cycles are greater than expected 31250 cycles, retain the bitPos as 1 in FTRIM */
2430         if (measuredCnt > FREQ_REF)
2431         {
2432             trimVal |= ((uint32_t) 1U << (uint32_t) bitPos);
2433         }
2434         /* Repeat until this is done for all 10 bits of FTRIM */
2435         bitPos--;
2436 
2437     } while (bitPos >= 0);
2438     SRSS_CLK_PILO_CONFIG &= ~(SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk);
2439     SRSS_CLK_PILO_CONFIG |= (trimVal);
2440 #endif
2441 }
2442 
2443 
Cy_SysClk_PiloUpdateTrimStep(void)2444 void Cy_SysClk_PiloUpdateTrimStep(void)
2445 {
2446 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2447     (void)stepSize;
2448     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_UPDATE_PILO_TRIM_STEP);
2449 #else
2450     uint32_t iteration    = 0u;
2451     uint32_t fTrim        = 0u;
2452     uint32_t newFreq      = 0u;
2453     uint32_t oldFreq      = 0u;
2454     uint32_t initialFtrim = _FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG);
2455     uint32_t refClkFreq   = Cy_SysClk_AltHfGetFrequency();
2456 
2457     stepSize = 8U;
2458 
2459     (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, REF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2460     while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2461     {
2462         /* Wait for the measurement to complete */
2463     }
2464 
2465     oldFreq = Cy_SysClk_ClkMeasurementCountersGetFreq(false, refClkFreq);
2466     do
2467     {
2468         fTrim = _FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG);
2469         /* Update the fine trim value */
2470         CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, fTrim + 1u);
2471         /* Wait for 2 ms after setting FTRIM */
2472         Cy_SysLib_DelayUs(TRIM_DELAY);
2473         (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, REF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2474         while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2475         {
2476             /* Wait for the measurement to complete */
2477         }
2478         newFreq = Cy_SysClk_ClkMeasurementCountersGetFreq(false, refClkFreq);
2479         stepSize += (newFreq - oldFreq);
2480         oldFreq = newFreq;
2481         iteration++;
2482 
2483     } while (iteration < STEP_SIZE_ITER);
2484     stepSize = (stepSize/STEP_SIZE_ITER);
2485     /* Restore the fine trim value */
2486     CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, initialFtrim);
2487     /* Wait for 2 ms after setting FTRIM */
2488     Cy_SysLib_DelayUs(TRIM_DELAY);
2489 #endif
2490 }
2491 
2492 
2493 /* ========================================================================== */
2494 /* ======================    POWER MANAGEMENT SECTION    ==================== */
2495 /* ========================================================================== */
2496 
2497 
2498 /** \cond INTERNAL */
2499 /* Timeout count for use in function Cy_SysClk_DeepSleepCallback() is sufficiently large for ~1 second */
2500 #define TIMEOUT (1000000UL)
2501 /** \endcond */
2502 
Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)2503 cy_en_syspm_status_t Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams, cy_en_syspm_callback_mode_t mode)
2504 {
2505 
2506     /* Bitmapped paths with enabled FLL/PLL sourced by ECO */
2507     static uint16_t changedSourcePaths;
2508     static uint16_t pllAutoModes;
2509 
2510     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
2511 
2512     (void)callbackParams; /* Suppress "not used" warning */
2513     (void)changedSourcePaths;
2514     (void)pllAutoModes;
2515 
2516     switch (mode)
2517     {
2518         case CY_SYSPM_CHECK_READY:
2519             /* Don't allow entry into Deep Sleep mode if currently measuring a frequency */
2520             if (!clkCounting)
2521             {
2522                 /* Indicating that we can go into Deep Sleep.
2523                  * Prevent starting a new clock measurement until
2524                  * after we've come back from Deep Sleep.
2525                  */
2526                 preventCounting = true;
2527                 retVal = CY_SYSPM_SUCCESS;
2528             }
2529             break;
2530 
2531         case CY_SYSPM_CHECK_FAIL:
2532             /* Cancellation of going into Deep Sleep, therefore allow a new clock measurement */
2533             preventCounting = false;
2534             retVal = CY_SYSPM_SUCCESS;
2535             break;
2536 
2537         case CY_SYSPM_BEFORE_TRANSITION:
2538             {
2539 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2540                 retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_DS_BEFORE_TRANSITION);
2541 #else
2542                 uint32_t fllpll; /* 0 = FLL, all other values = a PLL */
2543 
2544                 /* Initialize the storage of changed paths */
2545                 changedSourcePaths = 0U;
2546                 pllAutoModes = 0U;
2547 
2548                 /* For FLL and each PLL */
2549                 for (fllpll = 0UL; fllpll <= CY_SRSS_NUM_PLL; fllpll++)
2550                 {
2551                     /* If FLL or PLL is enabled */
2552                     if ((0UL == fllpll) ? Cy_SysClk_FllIsEnabled() : Cy_SysClk_PllIsEnabled(fllpll))
2553                     {
2554                         /* And the FLL/PLL has ECO as a source */
2555                         if (Cy_SysClk_ClkPathGetSource(fllpll) == CY_SYSCLK_CLKPATH_IN_ECO)
2556                         {
2557                             /* Bypass the FLL/PLL */
2558                             if (0UL == fllpll)
2559                             {
2560                                 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2561                             }
2562                             else
2563                             {
2564                                 if (((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO  == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllpll - 1UL])) ||
2565                                     ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO1 == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllpll - 1UL])))
2566                                 {
2567                                     pllAutoModes |= (uint16_t)(1UL << fllpll);
2568                                 }
2569 
2570                                 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2571                             }
2572 
2573                             /* Change this path source to IMO */
2574                             (void)Cy_SysClk_ClkPathSetSource(fllpll, CY_SYSCLK_CLKPATH_IN_IMO);
2575 
2576                             /* Store a record that this path source was changed from ECO */
2577                             changedSourcePaths |= (uint16_t)(1UL << fllpll);
2578                         }
2579                         else if (0UL == fllpll)
2580                         {
2581                             CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2582                         }
2583                         else
2584                         {
2585                             /* Do nothing */
2586                         }
2587                     }
2588                 }
2589 
2590                 retVal = CY_SYSPM_SUCCESS;
2591 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))  */
2592             }
2593             break;
2594 
2595         case CY_SYSPM_AFTER_TRANSITION:
2596             {
2597 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2598                 retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_DS_AFTER_TRANSITION);
2599 #else
2600                 /* After return from Deep Sleep, for each FLL/PLL, if needed, restore the source to ECO.
2601                  * And block until the FLL/PLL has regained its frequency lock.
2602                  */
2603                 uint32_t timeout = TIMEOUT;
2604                 retVal = CY_SYSPM_TIMEOUT;
2605 
2606                 if (0U != changedSourcePaths)
2607                 {
2608                     /* If any FLL/PLL was sourced by the ECO, timeout wait for the ECO to become fully stabilized again */
2609                     while ((CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeout))
2610                     {
2611                         timeout--;
2612                     }
2613 
2614                     if (0UL != timeout)
2615                     {
2616                         uint32_t fllpll; /* 0 = FLL, all other values = PLL */
2617 
2618                         for (fllpll = 0UL; fllpll <= CY_SRSS_NUM_PLL; fllpll++)
2619                         {
2620                             /* If there is a correspondent record about a changed clock source */
2621                             if (0U != (changedSourcePaths & (uint16_t)(1UL << fllpll)))
2622                             {
2623                                 /* Change this path source back to ECO */
2624                                 (void)Cy_SysClk_ClkPathSetSource(fllpll, CY_SYSCLK_CLKPATH_IN_ECO);
2625 
2626                                 /* Timeout wait for FLL/PLL to regain lock.
2627                                  * Split FLL and PLL lock polling loops into two separate threads to minimize one polling loop duration.
2628                                  */
2629                                 if (0UL == fllpll)
2630                                 {
2631                                     while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
2632                                     {
2633                                         timeout--;
2634                                     }
2635                                 }
2636                                 else
2637                                 {
2638                                     while ((!Cy_SysClk_PllLocked(fllpll)) && (0UL != timeout))
2639                                     {
2640                                         timeout--;
2641                                     }
2642                                 }
2643 
2644                                 if (0UL != timeout)
2645                                 {
2646                                     /* Undo bypass the FLL/PLL */
2647                                     if (0UL == fllpll)
2648                                     {
2649                                         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2650                                     }
2651                                     else
2652                                     {
2653                                         if (0U != (pllAutoModes & (uint16_t)(1UL << fllpll)))
2654                                         {
2655                                             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_AUTO);
2656                                         }
2657                                         else
2658                                         {
2659                                             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2660                                         }
2661                                     }
2662 
2663                                     retVal = CY_SYSPM_SUCCESS;
2664                                 }
2665                             }
2666                         }
2667                     }
2668                 }
2669                 else if (Cy_SysClk_FllIsEnabled())
2670                 {
2671                     /* Timeout wait for FLL to regain lock */
2672                     while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
2673                     {
2674                         timeout--;
2675                     }
2676 
2677                     if (0UL != timeout)
2678                     {
2679                         /* Undo bypass the FLL */
2680                         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2681                         retVal = CY_SYSPM_SUCCESS;
2682                     }
2683                 }
2684                 else
2685                 {
2686                     retVal = CY_SYSPM_SUCCESS;
2687                 }
2688 
2689                 preventCounting = false; /* Allow clock measurement */
2690 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2691             }
2692             break;
2693 
2694         default: /* Unsupported mode, return CY_SYSPM_FAIL */
2695             break;
2696     }
2697 
2698     return (retVal);
2699 
2700 }
2701 
2702 
2703 /* ========================================================================== */
2704 /* =========================    clkHf[n] SECTION    ========================= */
2705 /* ========================================================================== */
2706 
2707 
Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)2708 uint32_t Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)
2709 {
2710     /* variables holding intermediate clock frequencies, dividers and FLL/PLL settings */
2711     uint32_t pDiv = 1UL << (uint32_t)Cy_SysClk_ClkHfGetDivider(clkHf); /* root prescaler (1/2/4/8) */
2712     uint32_t path = (uint32_t) Cy_SysClk_ClkHfGetSource(clkHf); /* path input for root 0 (clkHf[0]) */
2713     uint32_t freq = Cy_SysClk_ClkPathGetFrequency(path);
2714 
2715     /* Divide the path input frequency down and return the result */
2716     return (CY_SYSLIB_DIV_ROUND(freq, pDiv));
2717 }
2718 
2719 
2720 /* ========================================================================== */
2721 /* =====================    clk_peripherals SECTION    ====================== */
2722 /* ========================================================================== */
2723 
2724 
Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType,uint32_t dividerNum)2725 uint32_t Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType, uint32_t dividerNum)
2726 {
2727     uint32_t integer = 0UL;        /* Integer part of peripheral divider */
2728     uint32_t freq = Cy_SysClk_ClkPeriGetFrequency(); /* Get Peri frequency */
2729 
2730     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    || \
2731                  ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   || \
2732                  ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) || \
2733                  ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)));
2734 
2735     /* get the divider value for clk_peri to the selected peripheral clock */
2736     switch(dividerType)
2737     {
2738         case CY_SYSCLK_DIV_8_BIT:
2739         case CY_SYSCLK_DIV_16_BIT:
2740             integer = 1UL + Cy_SysClk_PeriphGetDivider(dividerType, dividerNum);
2741             freq = CY_SYSLIB_DIV_ROUND(freq, integer);
2742             break;
2743 
2744         case CY_SYSCLK_DIV_16_5_BIT:
2745         case CY_SYSCLK_DIV_24_5_BIT:
2746             {
2747                 uint32_t locFrac;
2748                 uint32_t locDiv;
2749                 uint64_t locFreq = freq * 32ULL;
2750                 Cy_SysClk_PeriphGetFracDivider(dividerType, dividerNum, &integer, &locFrac);
2751                 /* For fractional dividers, the divider is (int + 1) + frac/32 */
2752                 locDiv = ((1UL + integer) * 32UL) + locFrac;
2753                 freq = (uint32_t) CY_SYSLIB_DIV_ROUND(locFreq, (uint64_t)locDiv);
2754             }
2755             break;
2756 
2757         default:
2758             /* Unknown divider */
2759             break;
2760     }
2761 
2762     return (freq);
2763 }
2764 
2765 
Cy_SysClk_ClkTimerGetFrequency(void)2766 uint32_t Cy_SysClk_ClkTimerGetFrequency(void)
2767 {
2768     uint32_t freq = 0UL;
2769 
2770     if (Cy_SysClk_ClkTimerIsEnabled())
2771     {
2772         freq = Cy_SysClk_ClkHfGetFrequency(0UL);
2773 
2774         switch (Cy_SysClk_ClkTimerGetSource())
2775         {
2776             case CY_SYSCLK_CLKTIMER_IN_IMO:
2777                 freq = CY_SYSCLK_IMO_FREQ;
2778                 break;
2779 
2780             case CY_SYSCLK_CLKTIMER_IN_HF0_NODIV:
2781                 break;
2782 
2783             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV2:
2784                 freq /= 2UL;
2785                 break;
2786 
2787             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV4:
2788                 freq /= 4UL;
2789                 break;
2790 
2791             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV8:
2792                 freq /= 8UL;
2793                 break;
2794 
2795             default:
2796                 freq = 0UL;
2797                 break;
2798         }
2799     }
2800 
2801     /* Divide the input frequency down and return the result */
2802     return (CY_SYSLIB_DIV_ROUND(freq, 1UL + (uint32_t)Cy_SysClk_ClkTimerGetDivider()));
2803 }
2804 
2805 
Cy_SysClk_FllGetFrequency(void)2806 uint32_t Cy_SysClk_FllGetFrequency(void)
2807 {
2808     uint32_t fDiv ;    /* FLL multiplier/feedback divider */
2809     uint32_t rDiv;    /* FLL reference divider */
2810     uint32_t oDiv;    /* FLL output divider */
2811     bool  enabled;    /* FLL enable status; n/a for direct */
2812     uint32_t freq = 0UL;    /* FLL Frequency */
2813 
2814     cy_stc_fll_manual_config_t fllCfg;
2815     Cy_SysClk_FllGetConfiguration(&fllCfg);
2816     enabled = (Cy_SysClk_FllIsEnabled()) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != fllCfg.outputMode);
2817     fDiv = fllCfg.fllMult;
2818     rDiv = fllCfg.refDiv;
2819     oDiv = (fllCfg.enableOutputDiv) ? 2UL : 1UL;
2820 
2821     if (enabled && /* If FLL is enabled and not bypassed */
2822         (0UL != rDiv)) /* to avoid division by zero */
2823     {
2824         freq = Cy_SysClk_ClkPathMuxGetFrequency(0UL); /* FLL mapped always to path 0 */
2825         freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
2826                                              ((uint64_t)rDiv * (uint64_t)oDiv));
2827     }
2828 
2829     return (freq);
2830 }
2831 
Cy_SysClk_PllGetFrequency(uint32_t clkPath)2832 uint32_t Cy_SysClk_PllGetFrequency(uint32_t clkPath)
2833 {
2834     uint32_t fDiv = 0UL;    /* PLL multiplier/feedback divider */
2835     uint32_t rDiv = 0UL;    /* PLL reference divider */
2836     uint32_t oDiv = 0UL;    /* PLL output divider */
2837     bool  enabled = false;    /* PLL enable status; n/a for direct */
2838     uint32_t freq=0UL;    /* PLL Frequency */
2839 
2840     if((CY_SRSS_NUM_PLL > 0UL) && (clkPath > 0UL))
2841     {
2842         CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
2843 
2844         if (clkPath <= CY_SRSS_NUM_PLL)
2845         {
2846             cy_stc_pll_manual_config_t pllcfg;
2847             if (CY_SYSCLK_SUCCESS == Cy_SysClk_PllGetConfiguration(clkPath, &pllcfg))
2848             {
2849                 enabled = (Cy_SysClk_PllIsEnabled(clkPath)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.outputMode);
2850                 fDiv = pllcfg.feedbackDiv;
2851                 rDiv = pllcfg.referenceDiv;
2852                 oDiv = pllcfg.outputDiv;
2853             }
2854 
2855             if (enabled && /* If PLL is enabled and not bypassed */
2856             (0UL != rDiv) && (0UL != oDiv)) /* to avoid division by zero */
2857             {
2858                 freq = Cy_SysClk_ClkPathMuxGetFrequency(clkPath);
2859                 freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
2860                                                      ((uint64_t)rDiv * (uint64_t)oDiv));
2861             }
2862         }
2863     }
2864 
2865     return (freq);
2866 }
2867 
2868 #if defined (CY_DEVICE_SECURE)
2869 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 17.2')
2870 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.6')
2871 #endif
2872 
2873 #endif
2874 
2875 /* [] END OF FILE */
2876