1 /***************************************************************************//**
2 * \file cy_sysclk.c
3 * \version 3.110
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 < 2)
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     while((Cy_SysClk_WcoOkay() == false) && (0UL != timeoutus))
835     {
836         Cy_SysLib_DelayUs(1U);
837         timeoutus--;
838     }
839 
840     if (0UL != timeoutus)
841     {
842         retVal = CY_SYSCLK_SUCCESS;
843     }
844 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
845     return (retVal);
846 }
847 
848 
Cy_SysClk_WcoOkay(void)849 bool Cy_SysClk_WcoOkay(void)
850 {
851     return (_FLD2BOOL(BACKUP_STATUS_WCO_OK, BACKUP_STATUS));
852 }
853 
854 
Cy_SysClk_WcoDisable(void)855 void Cy_SysClk_WcoDisable(void)
856 {
857 #if defined (CY_DEVICE_SECURE)
858     cy_en_pra_status_t retStatus;
859     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_WCO_DISABLE, 0UL);
860 
861     if (retStatus != CY_PRA_STATUS_SUCCESS)
862     {
863         CY_ASSERT_L1(false);
864     }
865 #endif /* defined (CY_DEVICE_SECURE) */
866 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
867     BACKUP_CTL &= (uint32_t)~BACKUP_CTL_WCO_EN_Msk;
868 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
869 }
870 
871 
Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)872 void Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)
873 {
874 #if defined (CY_DEVICE_SECURE)
875     cy_en_pra_status_t retStatus;
876     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_WCO_BYPASS, bypass);
877 
878     if (retStatus != CY_PRA_STATUS_SUCCESS)
879     {
880         CY_ASSERT_L1(false);
881     }
882 #endif /* defined (CY_DEVICE_SECURE) */
883 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
884     CY_REG32_CLR_SET(BACKUP_CTL, BACKUP_CTL_WCO_BYPASS, bypass);
885 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
886 }
887 
888 
889 /* ========================================================================== */
890 /* ===========================    PILO SECTION    =========================== */
891 /* ========================================================================== */
892 
893 
Cy_SysClk_PiloEnable(void)894 void Cy_SysClk_PiloEnable(void)
895 {
896 #if defined (CY_DEVICE_SECURE)
897     cy_en_pra_status_t retStatus;
898     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PILO_ENABLE, 1UL);
899 
900     if (retStatus != CY_PRA_STATUS_SUCCESS)
901     {
902         CY_ASSERT_L1(false);
903     }
904 #endif /* defined (CY_DEVICE_SECURE) */
905 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
906     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_EN_Msk; /* 1 = enable */
907     Cy_SysLib_Delay(1U/*msec*/);
908     /* release the reset and enable clock output */
909     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_RESET_N_Msk |
910                             SRSS_CLK_PILO_CONFIG_PILO_CLK_EN_Msk;
911 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
912 }
913 
914 
Cy_SysClk_PiloIsEnabled(void)915 bool Cy_SysClk_PiloIsEnabled(void)
916 {
917     return (_FLD2BOOL(SRSS_CLK_PILO_CONFIG_PILO_CLK_EN, SRSS_CLK_PILO_CONFIG));
918 }
919 
920 
Cy_SysClk_PiloDisable(void)921 void Cy_SysClk_PiloDisable(void)
922 {
923 #if defined (CY_DEVICE_SECURE)
924     cy_en_pra_status_t retStatus;
925     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_PILO_DISABLE, 0UL);
926 
927     if (retStatus != CY_PRA_STATUS_SUCCESS)
928     {
929         CY_ASSERT_L1(false);
930     }
931 #endif /* defined (CY_DEVICE_SECURE) */
932 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
933     /* Clear PILO_EN, PILO_RESET_N, and PILO_CLK_EN bitfields. This disables the
934        PILO and holds the PILO in a reset state. */
935     SRSS_CLK_PILO_CONFIG &= (uint32_t)~(SRSS_CLK_PILO_CONFIG_PILO_EN_Msk      |
936                                         SRSS_CLK_PILO_CONFIG_PILO_RESET_N_Msk |
937                                         SRSS_CLK_PILO_CONFIG_PILO_CLK_EN_Msk);
938 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
939 }
940 
941 
Cy_SysClk_PiloSetTrim(uint32_t trimVal)942 void Cy_SysClk_PiloSetTrim(uint32_t trimVal)
943 {
944 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
945     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_SET_PILO_TRIM, trimVal);
946 #else
947     CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, trimVal);
948 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
949 }
950 
951 
Cy_SysClk_PiloGetTrim(void)952 uint32_t Cy_SysClk_PiloGetTrim(void)
953 {
954     return (_FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG));
955 }
956 
957 
958 /* ========================================================================== */
959 /* ==========================    ALTHF SECTION    =========================== */
960 /* ========================================================================== */
961 
962 
Cy_SysClk_AltHfGetFrequency(void)963 uint32_t Cy_SysClk_AltHfGetFrequency(void)
964 {
965     #if defined(CY_IP_MXBLESS)
966         return (cy_BleEcoClockFreqHz);
967     #else /* CY_IP_MXBLESS */
968         return (0UL);
969     #endif /* CY_IP_MXBLESS */
970 }
971 
972 
973 /* ========================================================================== */
974 /* ==========================    ALTLF SECTION    =========================== */
975 /* ========================================================================== */
976 
977 
Cy_SysClk_AltLfGetFrequency(void)978 uint32_t Cy_SysClk_AltLfGetFrequency(void)
979 {
980     return (0UL);
981 }
982 
983 
Cy_SysClk_AltLfIsEnabled(void)984 bool Cy_SysClk_AltLfIsEnabled(void)
985 {
986     return (false);
987 }
988 
989 
990 /* ========================================================================== */
991 /* ===========================    ILO SECTION    ============================ */
992 /* ========================================================================== */
993 
994 
Cy_SysClk_IloEnable(void)995 void Cy_SysClk_IloEnable(void)
996 {
997 #if defined (CY_DEVICE_SECURE)
998     cy_en_pra_status_t retStatus;
999     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ILO_ENABLE, 1UL);
1000 
1001     if (retStatus != CY_PRA_STATUS_SUCCESS)
1002     {
1003         CY_ASSERT_L1(false);
1004     }
1005 #endif /* defined (CY_DEVICE_SECURE) */
1006 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1007     SRSS_CLK_ILO_CONFIG |= SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1008 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1009 }
1010 
1011 
Cy_SysClk_IloIsEnabled(void)1012 bool Cy_SysClk_IloIsEnabled(void)
1013 {
1014     return (_FLD2BOOL(SRSS_CLK_ILO_CONFIG_ENABLE, SRSS_CLK_ILO_CONFIG));
1015 }
1016 
1017 
Cy_SysClk_IloDisable(void)1018 cy_en_sysclk_status_t Cy_SysClk_IloDisable(void)
1019 {
1020     cy_en_sysclk_status_t retVal;
1021 #if defined (CY_DEVICE_SECURE)
1022     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);
1023 
1024 #endif /* defined (CY_DEVICE_SECURE) */
1025 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1026     retVal = CY_SYSCLK_INVALID_STATE;
1027     if (!_FLD2BOOL(SRSS_WDT_CTL_WDT_EN, SRSS_WDT_CTL)) /* if disabled */
1028     {
1029         SRSS_CLK_ILO_CONFIG &= ~SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1030         retVal = CY_SYSCLK_SUCCESS;
1031     }
1032 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1033     return (retVal);
1034 }
1035 
1036 
Cy_SysClk_IloHibernateOn(bool on)1037 void Cy_SysClk_IloHibernateOn(bool on)
1038 {
1039 #if defined (CY_DEVICE_SECURE)
1040     cy_en_pra_status_t retStatus;
1041     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ILO_HIBERNATE_ON, on);
1042 
1043     if (retStatus != CY_PRA_STATUS_SUCCESS)
1044     {
1045         CY_ASSERT_L1(false);
1046     }
1047 #endif /* defined (CY_DEVICE_SECURE) */
1048 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1049     CY_REG32_CLR_SET(SRSS_CLK_ILO_CONFIG, SRSS_CLK_ILO_CONFIG_ILO_BACKUP, ((on) ? 1UL : 0UL));
1050 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1051 }
1052 
1053 
1054 /* ========================================================================== */
1055 /* =========================    EXTCLK SECTION    =========================== */
1056 /* ========================================================================== */
1057 
1058 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1059     uint32_t cySysClkExtFreq = 0UL;
1060 #else
1061     static uint32_t cySysClkExtFreq = 0UL;
1062 #endif
1063 
1064 #define CY_SYSCLK_EXTCLK_MAX_FREQ (100000000UL) /* 100 MHz */
1065 /** \endcond */
1066 
Cy_SysClk_ExtClkSetFrequency(uint32_t freq)1067 void Cy_SysClk_ExtClkSetFrequency(uint32_t freq)
1068 {
1069     if (freq <= CY_SYSCLK_EXTCLK_MAX_FREQ)
1070     {
1071 #if defined (CY_DEVICE_SECURE)
1072         CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_EXT_CLK_SET_FREQUENCY, freq);
1073 #endif
1074         cySysClkExtFreq = freq;
1075     }
1076 
1077 }
1078 
1079 
Cy_SysClk_ExtClkGetFrequency(void)1080 uint32_t Cy_SysClk_ExtClkGetFrequency(void)
1081 {
1082     return (cySysClkExtFreq);
1083 }
1084 
1085 
1086 /* ========================================================================== */
1087 /* ===========================    ECO SECTION    ============================ */
1088 /* ========================================================================== */
1089 /** \cond INTERNAL */
1090 #define CY_SYSCLK_TRIM_ECO_Pos  (SRSS_CLK_TRIM_ECO_CTL_WDTRIM_Pos)
1091 #define CY_SYSCLK_TRIM_ECO_Msk  (SRSS_CLK_TRIM_ECO_CTL_WDTRIM_Msk | \
1092                                  SRSS_CLK_TRIM_ECO_CTL_ATRIM_Msk  | \
1093                                  SRSS_CLK_TRIM_ECO_CTL_FTRIM_Msk  | \
1094                                  SRSS_CLK_TRIM_ECO_CTL_RTRIM_Msk  | \
1095                                  SRSS_CLK_TRIM_ECO_CTL_GTRIM_Msk)
1096 
1097 /** \cond *********************************************************************
1098 * Function Name: cy_sqrt
1099 * Calculates square root.
1100 * The input is 32-bit wide.
1101 * The result is 16-bit wide.
1102 *******************************************************************************/
1103 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1104 static uint32_t cy_sqrt(uint32_t x);
cy_sqrt(uint32_t x)1105 static uint32_t cy_sqrt(uint32_t x)
1106 {
1107     uint32_t i;
1108     uint32_t res = 0UL;
1109     uint32_t add = 0x8000UL;
1110 
1111     for(i = 0UL; i < 16UL; i++)
1112     {
1113         uint32_t tmp = res | add;
1114 
1115         if (x >= (tmp * tmp))
1116         {
1117             res = tmp;
1118         }
1119 
1120         add >>= 1U;
1121     }
1122 
1123     return (res);
1124 }
1125 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1126 
1127 static uint32_t ecoFrequency = 0UL; /* Internal storage for ECO frequency user setting */
1128 
1129 #define CY_SYSCLK_ECO_FREQ_MIN (16000000UL) /* 16 MHz */
1130 #define CY_SYSCLK_ECO_FREQ_MAX (35000000UL) /* 35 MHz */
1131 #define CY_SYSCLK_ECO_CSM_MAX  (100UL)      /* 100 pF */
1132 #define CY_SYSCLK_ECO_ESR_MAX  (1000UL)     /* 1000 Ohm */
1133 #define CY_SYSCLK_ECO_DRV_MAX  (2000UL)     /* 2 mW */
1134 
1135 #define CY_SYSCLK_ECO_IS_FREQ_VALID(freq) ((CY_SYSCLK_ECO_FREQ_MIN <= (freq)) && ((freq) <= CY_SYSCLK_ECO_FREQ_MAX))
1136 #define CY_SYSCLK_ECO_IS_CSM_VALID(csm)   ((0UL < (csm)) && ((csm) <= CY_SYSCLK_ECO_CSM_MAX))
1137 #define CY_SYSCLK_ECO_IS_ESR_VALID(esr)   ((0UL < (esr)) && ((esr) <= CY_SYSCLK_ECO_ESR_MAX))
1138 #define CY_SYSCLK_ECO_IS_DRV_VALID(drv)   ((0UL < (drv)) && ((drv) <= CY_SYSCLK_ECO_DRV_MAX))
1139 /** \endcond */
1140 
Cy_SysClk_EcoDisable(void)1141 void Cy_SysClk_EcoDisable(void)
1142 {
1143 #if defined (CY_DEVICE_SECURE)
1144     cy_en_pra_status_t retStatus;
1145     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_ECO_DISABLE, 0UL);
1146 
1147     if (retStatus != CY_PRA_STATUS_SUCCESS)
1148     {
1149         CY_ASSERT_L1(false);
1150     }
1151 #endif /* defined (CY_DEVICE_SECURE) */
1152 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1153     SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1154 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1155 }
1156 
1157 
Cy_SysClk_EcoGetStatus(void)1158 uint32_t Cy_SysClk_EcoGetStatus(void)
1159 {
1160     /* if ECO is not ready, just report the ECO_OK bit. Otherwise report 2 = ECO ready */
1161     return ((SRSS_CLK_ECO_STATUS_Msk == (SRSS_CLK_ECO_STATUS_Msk & SRSS_CLK_ECO_STATUS)) ?
1162       CY_SYSCLK_ECOSTAT_STABLE : (SRSS_CLK_ECO_STATUS_ECO_OK_Msk & SRSS_CLK_ECO_STATUS));
1163 }
1164 
1165 #if (defined (CY_IP_MXS40SRSS)&& (CY_IP_MXS40SRSS_VERSION < 2))
Cy_SysClk_EcoSetFrequency(uint32_t freq)1166 void Cy_SysClk_EcoSetFrequency(uint32_t freq)
1167 {
1168     ecoFrequency = freq; /* Store the ECO frequency */
1169 }
1170 #endif /* (defined (CY_IP_MXS40SRSS)&& (CY_IP_MXS40SRSS_VERSION < 2)) */
1171 
Cy_SysClk_EcoConfigure(uint32_t freq,uint32_t cSum,uint32_t esr,uint32_t driveLevel)1172 cy_en_sysclk_status_t Cy_SysClk_EcoConfigure(uint32_t freq, uint32_t cSum, uint32_t esr, uint32_t driveLevel)
1173 {
1174     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1175 
1176 #if defined (CY_DEVICE_SECURE)
1177     cy_stc_pra_clk_eco_configure_t ecoConfig;
1178     ecoConfig.praClkEcofreq = freq;
1179     ecoConfig.praCsum = cSum;
1180     ecoConfig.praEsr = esr;
1181     ecoConfig.praDriveLevel = driveLevel;
1182     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);
1183     if(CY_SYSCLK_SUCCESS == retVal)
1184     {
1185         ecoFrequency = freq; /* Store the ECO frequency */
1186     }
1187 #endif /* defined (CY_DEVICE_SECURE) */
1188 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1189 
1190 
1191     if (0UL != (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
1192     {
1193         retVal = CY_SYSCLK_INVALID_STATE;
1194     }
1195     else if ((CY_SYSCLK_ECO_IS_FREQ_VALID(freq)) &&
1196              (CY_SYSCLK_ECO_IS_CSM_VALID(cSum)) &&
1197              (CY_SYSCLK_ECO_IS_ESR_VALID(esr)) &&
1198              (CY_SYSCLK_ECO_IS_DRV_VALID(driveLevel)))
1199     {
1200         /* Calculate intermediate values */
1201         uint32_t freqKhz = CY_SYSLIB_DIV_ROUND(freq, 1000UL);
1202 
1203         uint32_t maxAmpl = CY_SYSLIB_DIV_ROUND((159155UL * /* 5 * 100000 / PI */
1204                    cy_sqrt(CY_SYSLIB_DIV_ROUND(2000000UL * driveLevel, esr))), /* Scaled by 2 */
1205                                                (freqKhz * cSum)); /* The result is scaled by 10^3 */
1206 
1207         /* 10^9 / (5 * 4 * 4 * PI^2) = 1266514,7955292221430484932901216.. -> 126651, scaled by 10 */
1208         uint32_t ampSect = (CY_SYSLIB_DIV_ROUND(cSum * cSum *
1209                             CY_SYSLIB_DIV_ROUND(freqKhz * freqKhz, 126651UL), 100UL) * esr)/ 900000UL;
1210 
1211         if ((maxAmpl >= 650UL) && (ampSect <= 3UL))
1212         {
1213             uint32_t gtrim = (ampSect > 1UL) ? ampSect :
1214                             ((ampSect == 1UL) ? 0UL : 1UL);
1215 
1216             /* Update all fields of trim control register with one write, without changing the ITRIM field */
1217             uint32_t reg = _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_WDTRIM, 7UL) |
1218                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_ATRIM, 15UL) |
1219                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_FTRIM, 3UL)  |
1220                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_RTRIM, 0UL)  |
1221                            _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_GTRIM, gtrim);
1222 
1223             CY_REG32_CLR_SET(SRSS_CLK_TRIM_ECO_CTL, CY_SYSCLK_TRIM_ECO, reg);
1224 
1225             SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_AGC_EN_Msk;
1226 
1227             ecoFrequency = freq; /* Store the ECO frequency */
1228 
1229             retVal = CY_SYSCLK_SUCCESS;
1230         }
1231     }
1232     else
1233     {
1234         /* Return CY_SYSCLK_BAD_PARAM */
1235     }
1236 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1237     return (retVal);
1238 }
1239 
1240 
Cy_SysClk_EcoEnable(uint32_t timeoutus)1241 cy_en_sysclk_status_t Cy_SysClk_EcoEnable(uint32_t timeoutus)
1242 {
1243     cy_en_sysclk_status_t retVal;
1244 #if defined (CY_DEVICE_SECURE)
1245     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);
1246 #endif /* defined (CY_DEVICE_SECURE) */
1247 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1248 
1249     bool zeroTimeout = (0UL == timeoutus);
1250     retVal = CY_SYSCLK_INVALID_STATE;
1251 
1252     /* Invalid state error if ECO is already enabled */
1253     if (0UL == (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
1254     {
1255         /* Set ECO enable */
1256         SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1257 
1258         /* Wait for CY_SYSCLK_ECOSTAT_STABLE */
1259         while((CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeoutus))
1260         {
1261             Cy_SysLib_DelayUs(1U);
1262             timeoutus--;
1263         }
1264 
1265         if (zeroTimeout || (0UL != timeoutus))
1266         {
1267             retVal = CY_SYSCLK_SUCCESS;
1268         }
1269         else
1270         {
1271             /* If ECO doesn't start, then disable it */
1272             SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
1273             retVal = CY_SYSCLK_TIMEOUT;
1274         }
1275     }
1276 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1277     return (retVal);
1278 }
1279 
1280 
Cy_SysClk_EcoGetFrequency(void)1281 uint32_t Cy_SysClk_EcoGetFrequency(void)
1282 {
1283     return ((CY_SYSCLK_ECOSTAT_STABLE == Cy_SysClk_EcoGetStatus()) ? ecoFrequency : 0UL);
1284 }
1285 
1286 
1287 /* ========================================================================== */
1288 /* ====================    INPUT MULTIPLEXER SECTION    ===================== */
1289 /* ========================================================================== */
1290 
1291 
Cy_SysClk_ClkPathSetSource(uint32_t clkPath,cy_en_clkpath_in_sources_t source)1292 cy_en_sysclk_status_t Cy_SysClk_ClkPathSetSource(uint32_t clkPath, cy_en_clkpath_in_sources_t source)
1293 {
1294     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1295     if ((clkPath < CY_SRSS_NUM_CLKPATH) &&
1296         ((source <= CY_SYSCLK_CLKPATH_IN_DSIMUX) ||
1297          ((CY_SYSCLK_CLKPATH_IN_DSI <= source) && (source <= CY_SYSCLK_CLKPATH_IN_PILO))))
1298     {
1299 #if defined (CY_DEVICE_SECURE)
1300         cy_stc_pra_clkpathsetsource_t clkpath_set_source;
1301         clkpath_set_source.clk_path = clkPath;
1302         clkpath_set_source.source   = source;
1303         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);
1304 #endif /* defined (CY_DEVICE_SECURE) */
1305 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1306 
1307         if (source >= CY_SYSCLK_CLKPATH_IN_DSI)
1308         {
1309             SRSS_CLK_DSI_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_DSI_SELECT_DSI_MUX, (uint32_t)source);
1310             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)CY_SYSCLK_CLKPATH_IN_DSIMUX);
1311         }
1312         else
1313         {
1314             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)source);
1315         }
1316         retVal = CY_SYSCLK_SUCCESS;
1317 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1318     }
1319     return (retVal);
1320 
1321 }
1322 
1323 
Cy_SysClk_ClkPathGetSource(uint32_t clkPath)1324 cy_en_clkpath_in_sources_t Cy_SysClk_ClkPathGetSource(uint32_t clkPath)
1325 {
1326     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1327     cy_en_clkpath_in_sources_t retVal =
1328         (cy_en_clkpath_in_sources_t )((uint32_t)_FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS_CLK_PATH_SELECT[clkPath]));
1329     if (retVal == CY_SYSCLK_CLKPATH_IN_DSIMUX)
1330     {
1331         retVal = (cy_en_clkpath_in_sources_t)((uint32_t)(((uint32_t)CY_SYSCLK_CLKPATH_IN_DSI) |
1332                     ((uint32_t)(_FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS_CLK_DSI_SELECT[clkPath])))));
1333     }
1334     return (retVal);
1335 }
1336 
1337 
Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)1338 uint32_t Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)
1339 {
1340     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1341 
1342     uint32_t freq = 0UL;    /* The path mux output frequency in Hz, 0 = an unknown frequency */
1343 
1344     /* Get the frequency of the source, i.e., the path mux input */
1345     switch(Cy_SysClk_ClkPathGetSource(clkPath))
1346     {
1347         case CY_SYSCLK_CLKPATH_IN_IMO: /* The IMO frequency is fixed at 8 MHz */
1348             freq = CY_SYSCLK_IMO_FREQ;
1349             break;
1350 
1351         case CY_SYSCLK_CLKPATH_IN_EXT:
1352             freq = Cy_SysClk_ExtClkGetFrequency();
1353             break;
1354 
1355         case CY_SYSCLK_CLKPATH_IN_ECO:
1356             freq = Cy_SysClk_EcoGetFrequency();
1357             break;
1358 
1359         case CY_SYSCLK_CLKPATH_IN_ALTHF:
1360             freq = Cy_SysClk_AltHfGetFrequency();
1361             break;
1362 
1363         case CY_SYSCLK_CLKPATH_IN_ILO:
1364             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
1365             break;
1366 
1367         case CY_SYSCLK_CLKPATH_IN_WCO:
1368             freq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
1369             break;
1370 
1371         case CY_SYSCLK_CLKPATH_IN_PILO:
1372             freq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
1373             break;
1374 
1375         case CY_SYSCLK_CLKPATH_IN_ALTLF:
1376             freq = Cy_SysClk_AltLfGetFrequency();
1377             break;
1378 
1379         default:
1380             /* Don't know the frequency of dsi_out, leave freq = 0UL */
1381             break;
1382     }
1383 
1384     return (freq);
1385 }
1386 
1387 
Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)1388 uint32_t Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)
1389 {
1390     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
1391 
1392     uint32_t freq = 0UL;
1393 
1394     if (clkPath == (uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0) /* FLL? (always path 0) */
1395     {
1396         freq = Cy_SysClk_FllGetFrequency();
1397     }
1398     else if (clkPath <= CY_SRSS_NUM_PLL) /* PLL? (always path 1...N)*/
1399     {
1400         freq = Cy_SysClk_PllGetFrequency(clkPath);
1401     }
1402     else
1403     {
1404         /* Do nothing with the path mux frequency */
1405     }
1406 
1407     if(freq==0UL)
1408     {
1409         freq = Cy_SysClk_ClkPathMuxGetFrequency(clkPath);
1410     }
1411 
1412 return (freq);
1413 }
1414 
1415 
1416 /* ========================================================================== */
1417 /* ===========================    FLL SECTION    ============================ */
1418 /* ========================================================================== */
1419 
1420 
1421 #define  CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ (48000000UL)
1422 #define  CY_SYSCLK_FLL_MIN_OUTPUT_FREQ     (CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ / 2U)
1423 #define  CY_SYSCLK_FLL_MAX_OUTPUT_FREQ     (100000000UL)
1424 
1425 #define  CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(range) (((range) == CY_SYSCLK_FLL_CCO_RANGE0) || \
1426                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE1) || \
1427                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE2) || \
1428                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE3) || \
1429                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE4))
1430 /** \cond INTERNAL */
1431 #define  CY_SYSCLK_FLL_INT_COEF (327680000UL)
1432 #define  CY_SYSCLK_FLL_GAIN_IDX (11U)
1433 #define  CY_SYSCLK_FLL_GAIN_VAL (8UL * CY_SYSCLK_FLL_INT_COEF)
1434 
1435 #define TRIM_STEPS_SCALE        (100000000ULL) /* 10 ^ 8 */
1436 #define MARGIN_SCALE            (100000ULL) /* 10 ^ 5 */
1437 /** \endcond */
1438 
Cy_SysClk_FllIsEnabled(void)1439 bool Cy_SysClk_FllIsEnabled(void)
1440 {
1441     return (_FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_ENABLE, SRSS_CLK_FLL_CONFIG));
1442 }
1443 
1444 
Cy_SysClk_FllLocked(void)1445 bool Cy_SysClk_FllLocked(void)
1446 {
1447     return (_FLD2BOOL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS_CLK_FLL_STATUS));
1448 }
1449 
1450 
Cy_SysClk_FllDisable(void)1451 cy_en_sysclk_status_t Cy_SysClk_FllDisable(void)
1452 {
1453     cy_en_sysclk_status_t retStatus;
1454 #if defined (CY_DEVICE_SECURE)
1455     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);
1456 
1457 #endif /* defined (CY_DEVICE_SECURE) */
1458 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1459     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1460     SRSS_CLK_FLL_CONFIG  &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
1461     SRSS_CLK_FLL_CONFIG4 &= ~SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
1462     retStatus = (CY_SYSCLK_SUCCESS);
1463 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1464     return retStatus;
1465 }
1466 
1467 
Cy_SysClk_FllConfigure(uint32_t inputFreq,uint32_t outputFreq,cy_en_fll_pll_output_mode_t outputMode)1468 cy_en_sysclk_status_t Cy_SysClk_FllConfigure(uint32_t inputFreq, uint32_t outputFreq, cy_en_fll_pll_output_mode_t outputMode)
1469 {
1470     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1471 
1472     /* check for errors */
1473     if ((outputFreq < CY_SYSCLK_FLL_MIN_OUTPUT_FREQ) || (CY_SYSCLK_FLL_MAX_OUTPUT_FREQ < outputFreq) || /* invalid output frequency */
1474       (((outputFreq * 5UL) / inputFreq) < 11UL)) /* check output/input frequency ratio */
1475     {
1476         retVal = CY_SYSCLK_BAD_PARAM;
1477     }
1478     else /* no errors */
1479     {
1480         /* If output mode is bypass (input routed directly to output), then done.
1481            The output frequency equals the input frequency regardless of the
1482            frequency parameters. */
1483         if (outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1484         {
1485             cy_stc_fll_manual_config_t config;
1486             uint32_t ccoFreq;
1487             bool wcoSource = (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource(0UL/*FLL*/)) ? true : false;
1488 
1489             config.outputMode = outputMode;
1490             /* 1. Output division by 2 is always required */
1491             config.enableOutputDiv = true;
1492             /* 2. Compute the target CCO frequency from the target output frequency and output division */
1493             ccoFreq = outputFreq * 2UL;
1494             /* 3. Compute the CCO range value from the CCO frequency */
1495             config.ccoRange = ((ccoFreq >= 150339200UL) ? CY_SYSCLK_FLL_CCO_RANGE4 :
1496                                ((ccoFreq >= 113009380UL) ? CY_SYSCLK_FLL_CCO_RANGE3 :
1497                                 ((ccoFreq >=  84948700UL) ? CY_SYSCLK_FLL_CCO_RANGE2 :
1498                                  ((ccoFreq >=  63855600UL) ? CY_SYSCLK_FLL_CCO_RANGE1 : CY_SYSCLK_FLL_CCO_RANGE0))));
1499 
1500         /* 4. Compute the FLL reference divider value.
1501               refDiv is a constant if the WCO is the FLL source, otherwise the formula is
1502               refDiv = ROUNDUP((inputFreq / outputFreq) * 250) */
1503             config.refDiv = wcoSource ? 19U : (uint16_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)inputFreq * 250ULL, (uint64_t)outputFreq);
1504 
1505         /* 5. Compute the FLL multiplier value.
1506               Formula is fllMult = ccoFreq / (inputFreq / refDiv) */
1507             config.fllMult = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)ccoFreq * (uint64_t)config.refDiv, (uint64_t)inputFreq);
1508         /* 6. Compute the lock tolerance.
1509               Formula is lock tolerance = 1.5 * fllMult * (((1 + CCO accuracy) / (1 - source clock accuracy)) - 1)
1510               We assume CCO accuracy is 0.25%.
1511               We assume the source clock accuracy = 1%. This is the accuracy of the IMO.
1512               Therefore the formula is lock tolerance = 1.5 * fllMult * 0.012626 = 0.018939 * fllMult */
1513             config.lockTolerance = (uint16_t)CY_SYSLIB_DIV_ROUNDUP(config.fllMult * 18939UL, 1000000UL);
1514 
1515             {
1516                 /* constants indexed by ccoRange */
1517                 const uint32_t trimSteps[] = {110340UL, 110200UL, 110000UL, 110000UL, 117062UL}; /* Scaled by 10^8 */
1518                 const uint32_t margin[] = {436UL, 581UL, 772UL, 1030UL, 1320UL}; /* Scaled by 10^5 */
1519         /* 7. Compute the CCO igain and pgain */
1520                 {
1521                     /* intermediate parameters */
1522                     uint32_t kcco = (trimSteps[config.ccoRange] * margin[config.ccoRange]);
1523                     uint32_t ki_p = (uint32_t)CY_SYSLIB_DIV_ROUND(850ULL * CY_SYSCLK_FLL_INT_COEF * inputFreq, (uint64_t)kcco * (uint64_t)config.refDiv);
1524 
1525                     /* find the largest IGAIN value that is less than or equal to ki_p */
1526                     uint32_t locigain = CY_SYSCLK_FLL_GAIN_VAL;
1527                     uint32_t locpgain = CY_SYSCLK_FLL_GAIN_VAL;
1528 
1529                     /* find the largest IGAIN value that is less than or equal to ki_p */
1530                     config.igain = CY_SYSCLK_FLL_GAIN_IDX;
1531                     while(config.igain != 0UL)
1532                     {
1533                        if(locigain <= ki_p)
1534                        {
1535                           break;
1536                        }
1537                        locigain >>= 1U;
1538                        config.igain--;
1539                     }
1540                     /* decrement igain if the WCO is the FLL source */
1541                     if (wcoSource && (config.igain > 0U))
1542                     {
1543                         config.igain--;
1544                         locigain >>= 1U;
1545                     }
1546 
1547                     /* then find the largest PGAIN value that is less than or equal to ki_p - igain */
1548                     config.pgain = CY_SYSCLK_FLL_GAIN_IDX;
1549                     while(config.pgain != 0UL)
1550                     {
1551                       if(locpgain <= (ki_p - locigain))
1552                       {
1553                           break;
1554                       }
1555                       locpgain >>= 1U;
1556                       config.pgain--;
1557                     }
1558 
1559                     /* decrement pgain if the WCO is the FLL source */
1560                     if (wcoSource && (config.pgain > 0U))
1561                     {
1562                         config.pgain--;
1563                     }
1564                 }
1565 
1566         /* 8. Compute the CCO_FREQ bits in CLK_FLL_CONFIG4 register */
1567                 {
1568                     uint64_t cmp = CY_SYSLIB_DIV_ROUND(((TRIM_STEPS_SCALE / MARGIN_SCALE) * (uint64_t)ccoFreq), (uint64_t)margin[config.ccoRange]);
1569                     uint64_t mlt = TRIM_STEPS_SCALE + (uint64_t)trimSteps[config.ccoRange];
1570                     uint64_t res = mlt;
1571 
1572                     config.cco_Freq = 0U;
1573 
1574                     while(res < cmp)
1575                     {
1576                         res *= mlt;
1577                         res /= TRIM_STEPS_SCALE;
1578                         config.cco_Freq++;
1579                     }
1580                 }
1581             }
1582 
1583         /* 9. Compute the settling count, using a 1 usec settling time. Use a constant if the WCO is the FLL source */
1584             {
1585                 uint64_t fref = CY_SYSLIB_DIV_ROUND(6000ULL * (uint64_t)inputFreq, (uint64_t)config.refDiv);
1586                 uint32_t divval = CY_SYSLIB_DIV_ROUNDUP(inputFreq, 1000000UL);
1587                 uint32_t altval = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)divval * fref, 6000000ULL) + 1UL;
1588 
1589                 config.settlingCount = wcoSource ? 200U : (uint16_t)
1590                           ((outputFreq < fref) ? divval :
1591                             ((divval > altval) ? divval : altval));
1592             }
1593         /* Configure FLL based on calculated values */
1594             retVal = Cy_SysClk_FllManualConfigure(&config);
1595         }
1596         else /* if not, bypass output mode */
1597         {
1598             CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1599         }
1600     }
1601 
1602     return (retVal);
1603 }
1604 
1605 
Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t * config)1606 cy_en_sysclk_status_t Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t *config)
1607 {
1608     cy_en_sysclk_status_t retVal;
1609 #if defined (CY_DEVICE_SECURE)
1610     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);
1611 #endif /* defined (CY_DEVICE_SECURE) */
1612 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1613     retVal = CY_SYSCLK_INVALID_STATE;
1614 
1615     /* Check for errors */
1616     CY_ASSERT_L1(config != NULL);
1617 
1618     if (!Cy_SysClk_FllIsEnabled()) /* If disabled */
1619     {
1620         /* update CLK_FLL_CONFIG register with 2 parameters; FLL_ENABLE is already 0 */
1621         /* asserts just check for bitfield overflow */
1622         CY_ASSERT_L1(config->fllMult <= (SRSS_CLK_FLL_CONFIG_FLL_MULT_Msk >> SRSS_CLK_FLL_CONFIG_FLL_MULT_Pos));
1623 
1624         SRSS_CLK_FLL_CONFIG = _VAL2FLD(SRSS_CLK_FLL_CONFIG_FLL_MULT, config->fllMult) |
1625                              _BOOL2FLD(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, config->enableOutputDiv);
1626 
1627         /* update CLK_FLL_CONFIG2 register with 2 parameters */
1628         /* asserts just check for bitfield overflow */
1629         CY_ASSERT_L1(config->refDiv <= (SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Msk >> SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Pos));
1630         CY_ASSERT_L1(config->lockTolerance <= (SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Msk >> SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Pos));
1631 
1632         SRSS_CLK_FLL_CONFIG2 = _VAL2FLD(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, config->refDiv) |
1633                                _VAL2FLD(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, config->lockTolerance);
1634 
1635         /* update CLK_FLL_CONFIG3 register with 4 parameters */
1636         /* asserts just check for bitfield overflow */
1637         CY_ASSERT_L1(config->igain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Pos));
1638         CY_ASSERT_L1(config->pgain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Pos));
1639         CY_ASSERT_L1(config->settlingCount <= (SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Msk >> SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Pos));
1640 
1641         SRSS_CLK_FLL_CONFIG3 = _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, config->igain) |
1642                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, config->pgain) |
1643                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, config->settlingCount) |
1644                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, config->outputMode);
1645 
1646         /* update CLK_FLL_CONFIG4 register with 1 parameter; preserve other bits */
1647         /* asserts just check for bitfield overflow */
1648         CY_ASSERT_L1(CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(config->ccoRange));
1649         CY_ASSERT_L1(config->cco_Freq <= (SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Msk >> SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Pos));
1650 
1651         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_RANGE, (uint32_t)(config->ccoRange));
1652         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_FREQ, (uint32_t)(config->cco_Freq));
1653 
1654         retVal = CY_SYSCLK_SUCCESS;
1655     }
1656 
1657 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1658     return (retVal);
1659 }
1660 
1661 
Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t * config)1662 void Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t *config)
1663 {
1664     CY_ASSERT_L1(config != NULL);
1665     /* read 2 parameters from CLK_FLL_CONFIG register */
1666     uint32_t tempReg = SRSS_CLK_FLL_CONFIG;
1667     config->fllMult         = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, tempReg);
1668     config->enableOutputDiv = _FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, tempReg);
1669     /* read 2 parameters from CLK_FLL_CONFIG2 register */
1670     tempReg = SRSS_CLK_FLL_CONFIG2;
1671     config->refDiv          = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, tempReg);
1672     config->lockTolerance   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, tempReg);
1673     /* read 4 parameters from CLK_FLL_CONFIG3 register */
1674     tempReg = SRSS_CLK_FLL_CONFIG3;
1675     config->igain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, tempReg);
1676     config->pgain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, tempReg);
1677     config->settlingCount   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, tempReg);
1678     config->outputMode      = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, tempReg));
1679     /* read 2 parameters from CLK_FLL_CONFIG4 register */
1680     tempReg = SRSS_CLK_FLL_CONFIG4;
1681     config->ccoRange        = (cy_en_fll_cco_ranges_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_RANGE, tempReg));
1682     config->cco_Freq        = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_FREQ, tempReg);
1683 }
1684 
1685 
Cy_SysClk_FllEnable(uint32_t timeoutus)1686 cy_en_sysclk_status_t Cy_SysClk_FllEnable(uint32_t timeoutus)
1687 {
1688     cy_en_sysclk_status_t retStatus;
1689 #if defined (CY_DEVICE_SECURE)
1690     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);
1691 #endif /* defined (CY_DEVICE_SECURE) */
1692 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1693     bool zeroTimeout = (0UL == timeoutus);
1694 
1695     /* first set the CCO enable bit */
1696     SRSS_CLK_FLL_CONFIG4 |= SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
1697 
1698     /* Wait until CCO is ready */
1699     while((!_FLD2BOOL(SRSS_CLK_FLL_STATUS_CCO_READY, SRSS_CLK_FLL_STATUS)) && /* if cco_ready == 0 */ (0UL != timeoutus))
1700     {
1701         Cy_SysLib_DelayUs(1U);
1702          timeoutus--;
1703     }
1704 
1705     /* Set the FLL bypass mode to FLL_REF */
1706     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1707 
1708     /* Set the FLL enable bit, if CCO is ready */
1709     if (zeroTimeout || (0UL != timeoutus))
1710     {
1711         SRSS_CLK_FLL_CONFIG |= SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
1712     }
1713 
1714     /* now do the timeout wait for FLL_STATUS, bit LOCKED */
1715     while((!Cy_SysClk_FllLocked()) && /* if locked == 0 */(0UL != timeoutus))
1716     {
1717         Cy_SysLib_DelayUs(1U);
1718         timeoutus--;
1719     }
1720 
1721     if (zeroTimeout || (0UL != timeoutus))
1722     {
1723         /* Set the FLL bypass mode to FLL_OUT (ignoring lock indicator) */
1724         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
1725     }
1726     else
1727     {
1728         /* If lock doesn't occur, FLL is stopped */
1729         (void)Cy_SysClk_FllDisable();
1730     }
1731 
1732     retStatus = ((zeroTimeout || (0UL != timeoutus)) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_TIMEOUT);
1733 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1734     return retStatus;
1735 }
1736 
1737 
1738 /* ========================================================================== */
1739 /* ===========================    PLL SECTION    ============================ */
1740 /* ========================================================================== */
1741 
1742 /* PLL OUTPUT_DIV bitfield allowable range */
1743 #define CY_SYSCLK_PLL_MIN_OUTPUT_DIV   (2UL)
1744 #define CY_SYSCLK_PLL_MAX_OUTPUT_DIV   (16UL)
1745 
1746 /* PLL REFERENCE_DIV bitfield allowable range */
1747 #define CY_SYSCLK_PLL_MIN_REF_DIV      (1UL)
1748 #define CY_SYSCLK_PLL_MAX_REF_DIV      (18UL)
1749 
1750 /* PLL FEEDBACK_DIV bitfield allowable ranges, LF and normal modes */
1751 #define CY_SYSCLK_PLL_MIN_FB_DIV_LF    (19UL)
1752 #define CY_SYSCLK_PLL_MAX_FB_DIV_LF    (56UL)
1753 #define CY_SYSCLK_PLL_MIN_FB_DIV_NORM  (22UL)
1754 #define CY_SYSCLK_PLL_MAX_FB_DIV_NORM  (112UL)
1755 
1756 /* PLL FEEDBACK_DIV bitfield allowable range selection */
1757 #define CY_SYSCLK_PLL_MIN_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FB_DIV_LF : CY_SYSCLK_PLL_MIN_FB_DIV_NORM)
1758 #define CY_SYSCLK_PLL_MAX_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FB_DIV_LF : CY_SYSCLK_PLL_MAX_FB_DIV_NORM)
1759 
1760 /* PLL Fvco range allowable ranges, LF and normal modes */
1761 #define CY_SYSCLK_PLL_MIN_FVCO_LF      (170000000UL)
1762 #define CY_SYSCLK_PLL_MAX_FVCO_LF      (200000000UL)
1763 #define CY_SYSCLK_PLL_MIN_FVCO_NORM    (200000000UL)
1764 #define CY_SYSCLK_PLL_MAX_FVCO_NORM    (400000000UL)
1765 /* PLL Fvco range selection */
1766 #define CY_SYSCLK_PLL_MIN_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FVCO_LF : CY_SYSCLK_PLL_MIN_FVCO_NORM)
1767 #define CY_SYSCLK_PLL_MAX_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FVCO_LF : CY_SYSCLK_PLL_MAX_FVCO_NORM)
1768 
1769 /* PLL input and output frequency limits */
1770 #define CY_SYSCLK_PLL_MIN_IN_FREQ  (4000000UL)
1771 #define CY_SYSCLK_PLL_MAX_IN_FREQ  (64000000UL)
1772 #define CY_SYSCLK_PLL_MIN_OUT_FREQ (CY_SYSCLK_PLL_MIN_FVCO / CY_SYSCLK_PLL_MAX_OUTPUT_DIV)
1773 #define CY_SYSCLK_PLL_MAX_OUT_FREQ (150000000UL)
1774 
1775 
Cy_SysClk_PllIsEnabled(uint32_t clkPath)1776 bool Cy_SysClk_PllIsEnabled(uint32_t clkPath)
1777 {
1778     clkPath--; /* to correctly access PLL config and status registers structures */
1779     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1780     return (_FLD2BOOL(SRSS_CLK_PLL_CONFIG_ENABLE, SRSS_CLK_PLL_CONFIG[clkPath]));
1781 }
1782 
1783 
Cy_SysClk_PllLocked(uint32_t clkPath)1784 bool Cy_SysClk_PllLocked(uint32_t clkPath)
1785 {
1786     clkPath--; /* to correctly access PLL config and status registers structures */
1787     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1788     return (_FLD2BOOL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS_CLK_PLL_STATUS[clkPath]));
1789 }
1790 
1791 
Cy_SysClk_PllLostLock(uint32_t clkPath)1792 bool Cy_SysClk_PllLostLock(uint32_t clkPath)
1793 {
1794 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1795     (void) clkPath;
1796     return false;
1797 
1798 #else
1799     clkPath--; /* to correctly access PLL config and status registers structures */
1800     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_PLL);
1801     bool retVal = _FLD2BOOL(SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED, SRSS_CLK_PLL_STATUS[clkPath]);
1802     /* write a 1 to clear the unlock occurred bit */
1803     SRSS_CLK_PLL_STATUS[clkPath] = SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED_Msk;
1804     return (retVal);
1805 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1806 }
1807 
1808 
Cy_SysClk_PllDisable(uint32_t clkPath)1809 cy_en_sysclk_status_t Cy_SysClk_PllDisable(uint32_t clkPath)
1810 {
1811     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1812     clkPath--; /* to correctly access PLL config and status registers structures */
1813     if (clkPath < CY_SRSS_NUM_PLL)
1814     {
1815 #if defined (CY_DEVICE_SECURE)
1816         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));
1817 #endif /* defined (CY_DEVICE_SECURE) */
1818 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1819         /* First bypass PLL */
1820         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
1821         /* Wait at least 6 PLL clock cycles */
1822         Cy_SysLib_DelayUs(1U);
1823         /* And now disable the PLL itself */
1824         SRSS_CLK_PLL_CONFIG[clkPath] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
1825         retVal = CY_SYSCLK_SUCCESS;
1826 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1827     }
1828     return (retVal);
1829 }
1830 
1831 
Cy_SysClk_PllConfigure(uint32_t clkPath,const cy_stc_pll_config_t * config)1832 cy_en_sysclk_status_t Cy_SysClk_PllConfigure(uint32_t clkPath, const cy_stc_pll_config_t *config)
1833 {
1834     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1835 
1836     if (((config->inputFreq)  < CY_SYSCLK_PLL_MIN_IN_FREQ)  || (CY_SYSCLK_PLL_MAX_IN_FREQ  < (config->inputFreq)) ||
1837         ((config->outputFreq) < CY_SYSCLK_PLL_MIN_OUT_FREQ) || (CY_SYSCLK_PLL_MAX_OUT_FREQ < (config->outputFreq)))
1838     {
1839         retVal = CY_SYSCLK_BAD_PARAM;
1840     }
1841     else
1842     {
1843         cy_stc_pll_manual_config_t manualConfig = {0U, 0U, 0U, false, CY_SYSCLK_FLLPLL_OUTPUT_AUTO};
1844 
1845         /* If output mode is not bypass (input routed directly to output), then
1846            calculate new parameters. */
1847         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1848         {
1849             /* for each possible value of OUTPUT_DIV and REFERENCE_DIV (Q), try
1850                to find a value for FEEDBACK_DIV (P) that gives an output frequency
1851                as close as possible to the desired output frequency. */
1852             uint32_t p, q, out;
1853             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
1854 
1855             /* REFERENCE_DIV (Q) selection */
1856             for (q = CY_SYSCLK_PLL_MIN_REF_DIV; q <= CY_SYSCLK_PLL_MAX_REF_DIV; q++)
1857             {
1858                 /* FEEDBACK_DIV (P) selection */
1859                 for (p = CY_SYSCLK_PLL_MIN_FB_DIV; p <= CY_SYSCLK_PLL_MAX_FB_DIV; p++)
1860                 {
1861                     /* Calculate the intermediate Fvco, and make sure that it's in range */
1862                     uint32_t fvco = (uint32_t)(((uint64_t)(config->inputFreq) * (uint64_t)p) / (uint64_t)q);
1863                     if ((CY_SYSCLK_PLL_MIN_FVCO <= fvco) && (fvco <= CY_SYSCLK_PLL_MAX_FVCO))
1864                     {
1865                         /* OUTPUT_DIV selection */
1866                         for (out = CY_SYSCLK_PLL_MIN_OUTPUT_DIV; out <= CY_SYSCLK_PLL_MAX_OUTPUT_DIV; out++)
1867                         {
1868                             /* Calculate what output frequency will actually be produced.
1869                                If it's closer to the target than what we have so far, then save it. */
1870                             uint32_t fout = ((p * config->inputFreq) / q) / out;
1871                             if ((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
1872                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq)))
1873                             {
1874                                 if (foutBest == (config->outputFreq))
1875                                 {
1876                                    break;
1877                                 }
1878 
1879                                 foutBest = fout;
1880                                 manualConfig.feedbackDiv  = (uint8_t)p;
1881                                 manualConfig.referenceDiv = (uint8_t)q;
1882                                 manualConfig.outputDiv    = (uint8_t)out;
1883                             }
1884                         }
1885                     }
1886                 }
1887             }
1888             /* exit loops if foutBest equals outputFreq */
1889 
1890             manualConfig.lfMode = config->lfMode;
1891         } /* if not, bypass output mode */
1892 
1893         /* If output mode is bypass (input routed directly to output), then
1894            use old parameters. */
1895         else
1896         {
1897             (void)Cy_SysClk_PllGetConfiguration(clkPath, &manualConfig);
1898         }
1899         /* configure PLL based on calculated values */
1900 
1901         manualConfig.outputMode = config->outputMode;
1902         retVal = Cy_SysClk_PllManualConfigure(clkPath, &manualConfig);
1903 
1904     } /* if no error */
1905 
1906     return (retVal);
1907 }
1908 
1909 
Cy_SysClk_PllManualConfigure(uint32_t clkPath,const cy_stc_pll_manual_config_t * config)1910 cy_en_sysclk_status_t Cy_SysClk_PllManualConfigure(uint32_t clkPath, const cy_stc_pll_manual_config_t *config)
1911 {
1912     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
1913 
1914     /* check for errors */
1915     if (clkPath > CY_SRSS_NUM_PLL) /* invalid clock path number */
1916     {
1917         retVal = CY_SYSCLK_BAD_PARAM;
1918     }
1919     else if (Cy_SysClk_PllIsEnabled(clkPath))
1920     {
1921         retVal = CY_SYSCLK_INVALID_STATE;
1922     }
1923     /* valid divider bitfield values */
1924     else if ((config->outputDiv    < CY_SYSCLK_PLL_MIN_OUTPUT_DIV) || (CY_SYSCLK_PLL_MAX_OUTPUT_DIV < config->outputDiv)    ||
1925              (config->referenceDiv < CY_SYSCLK_PLL_MIN_REF_DIV)    || (CY_SYSCLK_PLL_MAX_REF_DIV    < config->referenceDiv) ||
1926              (config->feedbackDiv  < CY_SYSCLK_PLL_MIN_FB_DIV)     || (CY_SYSCLK_PLL_MAX_FB_DIV     < config->feedbackDiv))
1927     {
1928          retVal = CY_SYSCLK_BAD_PARAM;
1929     }
1930     else /* no errors */
1931     {
1932 #if defined (CY_DEVICE_SECURE)
1933         cy_stc_pra_clk_pll_manconfigure_t pll_config;
1934         pll_config.clkPath   = clkPath;
1935         pll_config.praConfig    = (cy_stc_pll_manual_config_t *)config;
1936         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);
1937 #endif /* defined (CY_DEVICE_SECURE) */
1938 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1939         clkPath--; /* to correctly access PLL config registers structure */
1940         /* If output mode is bypass (input routed directly to output), then done.
1941            The output frequency equals the input frequency regardless of the frequency parameters. */
1942         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
1943         {
1944             SRSS_CLK_PLL_CONFIG[clkPath] =
1945                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  config->feedbackDiv)  |
1946                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, config->referenceDiv) |
1947                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    config->outputDiv)    |
1948                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   config->lfMode);
1949         }
1950 
1951         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, (uint32_t)config->outputMode);
1952 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1953     }
1954 
1955     return (retVal);
1956 }
1957 
1958 
Cy_SysClk_PllGetConfiguration(uint32_t clkPath,cy_stc_pll_manual_config_t * config)1959 cy_en_sysclk_status_t Cy_SysClk_PllGetConfiguration(uint32_t clkPath, cy_stc_pll_manual_config_t *config)
1960 {
1961     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1962     clkPath--; /* to correctly access PLL config and status register structures */
1963     if (clkPath < CY_SRSS_NUM_PLL)
1964     {
1965         uint32_t tempReg = SRSS_CLK_PLL_CONFIG[clkPath];
1966         config->feedbackDiv  = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  tempReg);
1967         config->referenceDiv = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, tempReg);
1968         config->outputDiv    = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    tempReg);
1969         config->lfMode       =         _FLD2BOOL(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   tempReg);
1970         config->outputMode   = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, tempReg));
1971         retVal = CY_SYSCLK_SUCCESS;
1972     }
1973     return (retVal);
1974 }
1975 
1976 
Cy_SysClk_PllEnable(uint32_t clkPath,uint32_t timeoutus)1977 cy_en_sysclk_status_t Cy_SysClk_PllEnable(uint32_t clkPath, uint32_t timeoutus)
1978 {
1979     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1980     bool zeroTimeout = (timeoutus == 0UL);
1981     clkPath--; /* to correctly access PLL config and status registers structures */
1982     if (clkPath < CY_SRSS_NUM_PLL)
1983     {
1984 #if defined (CY_DEVICE_SECURE)
1985         (void)timeoutus;
1986         (void)zeroTimeout;
1987         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));
1988 #endif /* defined (CY_DEVICE_SECURE) */
1989 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1990         /* first set the PLL enable bit */
1991         SRSS_CLK_PLL_CONFIG[clkPath] |= SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
1992 
1993         /* now do the timeout wait for PLL_STATUS, bit LOCKED */
1994         while((0UL == (SRSS_CLK_PLL_STATUS_LOCKED_Msk & SRSS_CLK_PLL_STATUS[clkPath])) && (0UL != timeoutus))
1995         {
1996             Cy_SysLib_DelayUs(1U);
1997             timeoutus--;
1998         }
1999 
2000         if (zeroTimeout || (0UL != timeoutus))
2001         {
2002             /* Unbypass PLL, if it is not in AUTO mode */
2003             if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[clkPath]))
2004             {
2005                 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2006             }
2007 
2008             retVal = CY_SYSCLK_SUCCESS;
2009         }
2010         else
2011         {
2012             /* If lock doesn't occur, then bypass PLL */
2013             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[clkPath], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2014             /* Wait at least 6 PLL clock cycles */
2015             Cy_SysLib_DelayUs(1U);
2016             /* And now disable the PLL itself */
2017             SRSS_CLK_PLL_CONFIG[clkPath] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
2018             retVal = CY_SYSCLK_TIMEOUT;
2019         }
2020 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
2021     }
2022     return (retVal);
2023 }
2024 
2025 
2026 /* ========================================================================== */
2027 /* ====================    Clock Measurement section    ===================== */
2028 /* ========================================================================== */
2029 /* Slow control register default value */
2030 #define TST_DDFT_SLOW_CTL_DEFAULT_VAL      (0x00001F1FUL)
2031 
2032 /* Fast control register */
2033 #define TST_DDFT_FAST_CTL_REG              (*(volatile uint32_t *) 0x40260104U)
2034 
2035 /* Slow control register default value */
2036 #define TST_DDFT_FAST_CTL_DEFAULT_VAL      (0x00003D3DUL)
2037 
2038 /* Define for select signal outputs in slow clock */
2039 #define SRSS_CLK_OUTPUT_SLOW_MASK  ((uint32_t) SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk | \
2040                                                SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk)
2041 
2042 /* Define for select signal outputs in fast clock */
2043 #define SRSS_CLK_OUTPUT_FAST_MASK  ((uint32_t) SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk  | \
2044                                                SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk  | \
2045                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk  | \
2046                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk  | \
2047                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk | \
2048                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk)
2049 
2050 /* Cy_SysClk_StartClkMeasurementCounters() input parameter saved for use later in other functions */
2051 static uint32_t clk1Count1;
2052 
2053 /* These variables act as locks to prevent collisions between clock measurement and entry into
2054    Deep Sleep mode. See Cy_SysClk_DeepSleep(). */
2055 static bool clkCounting = false;
2056 static bool preventCounting = false;
2057 
2058 
Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock,uint32_t refClkFreq)2059 uint32_t Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock, uint32_t refClkFreq)
2060 {
2061     uint32_t retVal = 0UL;
2062     bool isMeasurementValid = false;
2063 
2064     /* Done counting; allow entry into Deep Sleep mode */
2065     clkCounting = false;
2066 
2067     /* Acquire the IPC to prevent changing of the shared resources at the same time */
2068     while(0U == (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
2069     {
2070         /* Wait until the IPC structure is released by another process */
2071     }
2072 
2073     /* Check whether the device was in the Deep Sleep mode or the flash partially blocked while the
2074     *  operation was done
2075     */
2076     if(SRSS_TST_DDFT_SLOW_CTL_REG == TST_DDFT_SLOW_CTL_DEFAULT_VAL)
2077     {
2078        if(SRSS_TST_DDFT_FAST_CTL_REG == TST_DDFT_FAST_CTL_DEFAULT_VAL)
2079        {
2080            isMeasurementValid = true;
2081        }
2082     }
2083 
2084     retVal = _FLD2VAL(SRSS_CLK_CAL_CNT2_CAL_COUNTER2, SRSS_CLK_CAL_CNT2);
2085     /* Release the IPC */
2086     REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
2087 
2088     if (isMeasurementValid && (0UL != retVal))
2089     {
2090         if (!measuredClock)
2091         {   /* clock1 is the measured clock */
2092             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)clk1Count1 * (uint64_t)refClkFreq, (uint64_t)retVal);
2093         }
2094         else
2095         {   /* clock2 is the measured clock */
2096             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)retVal * (uint64_t)refClkFreq, (uint64_t)clk1Count1);
2097         }
2098     }
2099     else
2100     {
2101         /* Return zero value to indicate invalid measurement */
2102         retVal = 0UL;
2103     }
2104 
2105     return (retVal);
2106 }
2107 
2108 
Cy_SysClk_ClkMeasurementCountersDone(void)2109 bool Cy_SysClk_ClkMeasurementCountersDone(void)
2110 {
2111     return (_FLD2BOOL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1));
2112 }
2113 
2114 
Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1,uint32_t count1,cy_en_meas_clks_t clock2)2115 cy_en_sysclk_status_t Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1, uint32_t count1, cy_en_meas_clks_t clock2)
2116 {
2117     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
2118 
2119 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2120 
2121     cy_stc_pra_start_clk_measurement_t clkMeasurement;
2122     clkMeasurement.clock1 = clock1;
2123     clkMeasurement.count1 = count1;
2124     clkMeasurement.clock2 = clock2;
2125 
2126     /* Don't start a measurement if about to enter Deep Sleep mode */
2127     if (!preventCounting)
2128     {
2129         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);
2130     }
2131 
2132     if (CY_SYSCLK_SUCCESS == retVal)
2133     {
2134         /* Disallow entry into Deep Sleep mode while counting */
2135         clkCounting = true;
2136 
2137         /* Save this input parameter for use later, in other functions */
2138         clk1Count1 = count1;
2139     }
2140 #else
2141 
2142     uint32_t clkOutputSlowVal = 0UL;
2143     uint32_t clkOutputFastVal = 0UL;
2144 
2145     uint32_t clkOutputSlowMask = 0UL;
2146     uint32_t clkOutputFastMask = 0UL;
2147 
2148     /* Prepare values for measurement control registers */
2149 
2150     /* Connect the indicated clocks to the respective counters:
2151 
2152        if clock1 is a slow clock,
2153          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL0, and SRSS_CLK_OUTPUT_FAST.FAST_SEL0 = SLOW_SEL0
2154        else if clock1 is a fast clock,
2155          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL0,
2156        else error, do nothing and return.
2157 
2158        if clock2 is a slow clock,
2159          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL1, and SRSS_CLK_OUTPUT_FAST.FAST_SEL1 = SLOW_SEL1
2160        else if clock2 is a fast clock,
2161          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL1,
2162        else error, do nothing and return.
2163     */
2164     if ((clock1 < CY_SYSCLK_MEAS_CLK_LAST_CLK) && (clock2 < CY_SYSCLK_MEAS_CLK_LAST_CLK) &&
2165         (count1 <= (SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Msk >> SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Pos)))
2166     {
2167         /* Disallow entry into Deep Sleep mode while counting */
2168         clkCounting = true;
2169 
2170         if (clock1 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
2171         { /* slow clock */
2172             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0, (uint32_t)clock1);
2173             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, 7UL/*slow_sel0 output*/);
2174 
2175             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk;
2176             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2177         }
2178         else
2179         { /* fast clock */
2180             if (clock1 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
2181             { /* ECO, EXT, ALTHF */
2182                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (uint32_t)clock1);
2183                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2184             }
2185             else
2186             { /* PATH or CLKHF */
2187                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (((uint32_t)clock1 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
2188                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
2189 
2190                 if (clock1 < CY_SYSCLK_MEAS_CLK_CLKHFS)
2191                 { /* PATH select */
2192                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
2193                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk;
2194                 }
2195                 else
2196                 { /* CLKHF select */
2197                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
2198                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk;
2199                 }
2200             }
2201         } /* clock1 fast clock */
2202 
2203         if (clock2 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
2204         { /* slow clock */
2205             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1, (uint32_t)clock2);
2206             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, 7UL/*slow_sel1 output*/);
2207 
2208             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk;
2209             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2210         }
2211         else
2212         { /* fast clock */
2213             if (clock2 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
2214             { /* ECO, EXT, ALTHF */
2215                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (uint32_t)clock2);
2216                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2217             }
2218             else
2219             { /* PATH or CLKHF */
2220                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (((uint32_t)clock2 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
2221                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
2222 
2223                 if (clock2 < CY_SYSCLK_MEAS_CLK_CLKHFS)
2224                 { /* PATH select */
2225                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
2226                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk;
2227                 }
2228                 else
2229                 { /* CLKHF select */
2230                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
2231                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk;
2232                 }
2233             }
2234         } /* clock2 fast clock */
2235 
2236         /* Acquire the IPC to prevent changing of the shared resources at the same time */
2237         while(0U == (IPC_STRUCT_ACQUIRE_SUCCESS_Msk & REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
2238         {
2239             /* Wait until the IPC structure is released by another process */
2240         }
2241 
2242         if ((!preventCounting) /* don't start a measurement if about to enter Deep Sleep mode */  ||
2243             (_FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1) != 0UL/*1 = done*/))
2244         {
2245             /* Set default values for counters measurement control registers */
2246             SRSS_TST_DDFT_SLOW_CTL_REG = TST_DDFT_SLOW_CTL_DEFAULT_VAL;
2247             SRSS_TST_DDFT_FAST_CTL_REG = TST_DDFT_FAST_CTL_DEFAULT_VAL;
2248 
2249             SRSS_CLK_OUTPUT_SLOW = ((SRSS_CLK_OUTPUT_SLOW & ((uint32_t) ~clkOutputSlowMask)) | clkOutputSlowVal);
2250             SRSS_CLK_OUTPUT_FAST = ((SRSS_CLK_OUTPUT_FAST & ((uint32_t) ~clkOutputFastMask)) | clkOutputFastVal);
2251 
2252             /* Save this input parameter for use later, in other functions.
2253                No error checking is done on this parameter */
2254             clk1Count1 = count1;
2255 
2256             /* Counting starts when counter1 is written with a nonzero value */
2257             SRSS_CLK_CAL_CNT1 = clk1Count1;
2258 
2259             retVal = CY_SYSCLK_SUCCESS;
2260         }
2261 
2262         /* Release the IPC */
2263         REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
2264     }
2265 
2266 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2267 
2268     return (retVal);
2269 }
2270 
2271 /* ========================================================================== */
2272 /* ==========================    TRIM SECTION    ============================ */
2273 /* ========================================================================== */
2274 
2275 
2276 /** \cond INTERNAL */
2277 #define CY_SYSCLK_ILO_TARGET_FREQ  (32768UL)
2278 /* Nominal trim step size is 1.5% of "the frequency". Using the target frequency */
2279 #define CY_SYSCLK_ILO_TRIM_STEP    (CY_SYSLIB_DIV_ROUND(CY_SYSCLK_ILO_TARGET_FREQ * 15UL, 1000UL))
2280 
2281 /* The step size to be used by Cy_SysClk_PiloTrim function */
2282 static uint32_t stepSize = CY_SYSCLK_PILO_TRIM_STEP;
2283 /** \endcond */
2284 
Cy_SysClk_IloTrim(uint32_t iloFreq)2285 int32_t Cy_SysClk_IloTrim(uint32_t iloFreq)
2286 {
2287     int32_t changeInTrim;
2288 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2289     (void) iloFreq;
2290     changeInTrim = (int32_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_ILO_TRIM, iloFreq);
2291 #else
2292     uint32_t diff;
2293     bool sign = false;
2294 
2295     if(iloFreq > (CY_SYSCLK_ILO_TARGET_FREQ + CY_SYSCLK_ILO_TRIM_STEP))
2296     {
2297         diff = iloFreq - CY_SYSCLK_ILO_TARGET_FREQ;
2298     }
2299     else if (iloFreq < (CY_SYSCLK_ILO_TARGET_FREQ - CY_SYSCLK_ILO_TRIM_STEP))
2300     {
2301         diff = CY_SYSCLK_ILO_TARGET_FREQ - iloFreq;
2302         sign = true;
2303     }
2304     else
2305     {
2306         diff = 0UL;
2307     }
2308 
2309     /* Do nothing if iloFreq is already within one trim step from the target */
2310     if(0UL != diff)
2311     {
2312         /* Get current trim value */
2313         uint32_t trim = _FLD2VAL(SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, SRSS_CLK_TRIM_ILO_CTL);
2314 
2315         diff = CY_SYSLIB_DIV_ROUND(diff, CY_SYSCLK_ILO_TRIM_STEP);
2316 
2317         if(sign)
2318         {
2319             trim += diff;
2320         }
2321         else
2322         {
2323             trim -= diff;
2324         }
2325 
2326         /* Update the trim value */
2327         CY_REG32_CLR_SET(SRSS_CLK_TRIM_ILO_CTL, SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, trim);
2328     }
2329 
2330     changeInTrim = (sign ? (int32_t)diff : (0L - (int32_t)diff));
2331 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2332 
2333     return changeInTrim;
2334 }
2335 
2336 
2337 /** \cond INTERNAL */
2338 #define CY_SYSCLK_PILO_TARGET_FREQ  (32768UL)
2339 /* nominal trim step size */
2340 #define CY_SYSCLK_PILO_TRIM_STEP        (5UL)
2341 /** \endcond */
2342 
Cy_SysClk_PiloTrim(uint32_t piloFreq)2343 int32_t Cy_SysClk_PiloTrim(uint32_t piloFreq)
2344 {
2345     int32_t changeInTrim;
2346     uint32_t diff;
2347     bool sign = false;
2348 
2349     if(piloFreq > (CY_SYSCLK_PILO_TARGET_FREQ + stepSize))
2350     {
2351         diff = piloFreq - CY_SYSCLK_PILO_TARGET_FREQ;
2352     }
2353     else if (piloFreq < (CY_SYSCLK_PILO_TARGET_FREQ - stepSize))
2354     {
2355         diff = CY_SYSCLK_PILO_TARGET_FREQ - piloFreq;
2356         sign = true;
2357     }
2358     else
2359     {
2360         diff = 0UL;
2361     }
2362 
2363     /* Do nothing if piloFreq is already within one trim step from the target */
2364     if(0UL != diff)
2365     {
2366         /* Get current trim value */
2367         uint32_t trim = Cy_SysClk_PiloGetTrim();
2368 
2369         diff = CY_SYSLIB_DIV_ROUND(diff, stepSize);
2370 
2371         if(sign)
2372         {/* piloFreq too low. Increase the trim value */
2373             trim += diff;
2374             if (trim >= SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk) /* limit overflow */
2375             {
2376                 trim = SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk;
2377             }
2378         }
2379         else
2380         {/* piloFreq too high. Decrease the trim value */
2381             trim -= diff;
2382             if ((int32_t)trim < 0) /* limit underflow */
2383             {
2384                 trim = 0UL;
2385             }
2386         }
2387 
2388         /* Update the trim value */
2389         Cy_SysClk_PiloSetTrim(trim);
2390     }
2391 
2392     changeInTrim = ((int32_t)(sign ? (int32_t)diff : (0L - (int32_t)diff)));
2393 return changeInTrim;
2394 }
2395 /** \cond INTERNAL */
2396 #define LF_COUNT          (64u)
2397 #define REF_COUNT         (212u)
2398 #define FREQ_REF          (31250u)
2399 #define TRIM_DELAY        (2000u)
2400 #define STEP_SIZE_ITER    (8u)
2401 /** \endcond */
2402 
2403 
2404 
Cy_SysClk_PiloInitialTrim(void)2405 void Cy_SysClk_PiloInitialTrim(void)
2406 {
2407 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2408     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_PILO_INITIAL_TRIM);
2409 #else
2410     uint32_t measuredCnt  = 0xFFFFFFFFUL;
2411     uint32_t trimVal      = 0UL;
2412     int32_t  bitPos       = 9;
2413 
2414     do
2415     {
2416         SRSS_CLK_PILO_CONFIG &= ~(SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk);
2417 
2418         /* Set 1 at BitPos in FTRIM*/
2419         SRSS_CLK_PILO_CONFIG |= (trimVal | ((uint32_t) 1U  << (uint32_t) bitPos));
2420 
2421         /* Wait for 2 ms after setting FTRIM */
2422         Cy_SysLib_DelayUs(TRIM_DELAY);
2423         /* Start frequency measurement of PILO for
2424          * 64 PILO clock counts with BLE ECO ALTHF(configured to 16MHz) as reference clock */
2425         (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, LF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2426         while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2427         {
2428             /* Wait for the measurement to complete */
2429         }
2430         /* Read the number of reference clock cycles for 64 PILO clock cycles */
2431         measuredCnt = (uint32_t)_FLD2VAL(SRSS_CLK_CAL_CNT2_CAL_COUNTER2, SRSS_CLK_CAL_CNT2);
2432         /* If the measured clock cycles are greater than expected 31250 cycles, retain the bitPos as 1 in FTRIM */
2433         if (measuredCnt > FREQ_REF)
2434         {
2435             trimVal |= ((uint32_t) 1U << (uint32_t) bitPos);
2436         }
2437         /* Repeat until this is done for all 10 bits of FTRIM */
2438         bitPos--;
2439 
2440     } while (bitPos >= 0);
2441     SRSS_CLK_PILO_CONFIG &= ~(SRSS_CLK_PILO_CONFIG_PILO_FFREQ_Msk);
2442     SRSS_CLK_PILO_CONFIG |= (trimVal);
2443 #endif
2444 }
2445 
2446 
Cy_SysClk_PiloUpdateTrimStep(void)2447 void Cy_SysClk_PiloUpdateTrimStep(void)
2448 {
2449 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2450     (void)stepSize;
2451     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_CLK_FUNC_UPDATE_PILO_TRIM_STEP);
2452 #else
2453     uint32_t iteration    = 0u;
2454     uint32_t fTrim        = 0u;
2455     uint32_t newFreq      = 0u;
2456     uint32_t oldFreq      = 0u;
2457     uint32_t initialFtrim = _FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG);
2458     uint32_t refClkFreq   = Cy_SysClk_AltHfGetFrequency();
2459 
2460     stepSize = 8U;
2461 
2462     (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, REF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2463     while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2464     {
2465         /* Wait for the measurement to complete */
2466     }
2467 
2468     oldFreq = Cy_SysClk_ClkMeasurementCountersGetFreq(false, refClkFreq);
2469     do
2470     {
2471         fTrim = _FLD2VAL(SRSS_CLK_PILO_CONFIG_PILO_FFREQ, SRSS_CLK_PILO_CONFIG);
2472         /* Update the fine trim value */
2473         CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, fTrim + 1u);
2474         /* Wait for 2 ms after setting FTRIM */
2475         Cy_SysLib_DelayUs(TRIM_DELAY);
2476         (void) Cy_SysClk_StartClkMeasurementCounters(CY_SYSCLK_MEAS_CLK_PILO, REF_COUNT, CY_SYSCLK_MEAS_CLK_ALTHF);
2477         while ( true != Cy_SysClk_ClkMeasurementCountersDone() )
2478         {
2479             /* Wait for the measurement to complete */
2480         }
2481         newFreq = Cy_SysClk_ClkMeasurementCountersGetFreq(false, refClkFreq);
2482         stepSize += (newFreq - oldFreq);
2483         oldFreq = newFreq;
2484         iteration++;
2485 
2486     } while (iteration < STEP_SIZE_ITER);
2487     stepSize = (stepSize/STEP_SIZE_ITER);
2488     /* Restore the fine trim value */
2489     CY_REG32_CLR_SET(SRSS_CLK_PILO_CONFIG, SRSS_CLK_PILO_CONFIG_PILO_FFREQ, initialFtrim);
2490     /* Wait for 2 ms after setting FTRIM */
2491     Cy_SysLib_DelayUs(TRIM_DELAY);
2492 #endif
2493 }
2494 
2495 
2496 /* ========================================================================== */
2497 /* ======================    POWER MANAGEMENT SECTION    ==================== */
2498 /* ========================================================================== */
2499 
2500 
2501 /** \cond INTERNAL */
2502 /* Timeout count for use in function Cy_SysClk_DeepSleepCallback() is sufficiently large for ~1 second */
2503 #define TIMEOUT (1000000UL)
2504 /** \endcond */
2505 
Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)2506 cy_en_syspm_status_t Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams, cy_en_syspm_callback_mode_t mode)
2507 {
2508 
2509     /* Bitmapped paths with enabled FLL/PLL sourced by ECO */
2510     static uint16_t changedSourcePaths;
2511     static uint16_t pllAutoModes;
2512 
2513     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
2514 
2515     (void)callbackParams; /* Suppress "not used" warning */
2516     (void)changedSourcePaths;
2517     (void)pllAutoModes;
2518 
2519     switch (mode)
2520     {
2521         case CY_SYSPM_CHECK_READY:
2522             /* Don't allow entry into Deep Sleep mode if currently measuring a frequency */
2523             if (!clkCounting)
2524             {
2525                 /* Indicating that we can go into Deep Sleep.
2526                  * Prevent starting a new clock measurement until
2527                  * after we've come back from Deep Sleep.
2528                  */
2529                 preventCounting = true;
2530                 retVal = CY_SYSPM_SUCCESS;
2531             }
2532             break;
2533 
2534         case CY_SYSPM_CHECK_FAIL:
2535             /* Cancellation of going into Deep Sleep, therefore allow a new clock measurement */
2536             preventCounting = false;
2537             retVal = CY_SYSPM_SUCCESS;
2538             break;
2539 
2540         case CY_SYSPM_BEFORE_TRANSITION:
2541             {
2542 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2543                 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);
2544 #else
2545                 uint32_t fllpll; /* 0 = FLL, all other values = a PLL */
2546 
2547                 /* Initialize the storage of changed paths */
2548                 changedSourcePaths = 0U;
2549                 pllAutoModes = 0U;
2550 
2551                 /* For FLL and each PLL */
2552                 for (fllpll = 0UL; fllpll <= CY_SRSS_NUM_PLL; fllpll++)
2553                 {
2554                     /* If FLL or PLL is enabled */
2555                     if ((0UL == fllpll) ? Cy_SysClk_FllIsEnabled() : Cy_SysClk_PllIsEnabled(fllpll))
2556                     {
2557                         /* And the FLL/PLL has ECO as a source */
2558                         if (Cy_SysClk_ClkPathGetSource(fllpll) == CY_SYSCLK_CLKPATH_IN_ECO)
2559                         {
2560                             /* Bypass the FLL/PLL */
2561                             if (0UL == fllpll)
2562                             {
2563                                 CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2564                             }
2565                             else
2566                             {
2567                                 if (((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO  == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllpll - 1UL])) ||
2568                                     ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_AUTO1 == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[fllpll - 1UL])))
2569                                 {
2570                                     pllAutoModes |= (uint16_t)(1UL << fllpll);
2571                                 }
2572 
2573                                 CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2574                             }
2575 
2576                             /* Change this path source to IMO */
2577                             (void)Cy_SysClk_ClkPathSetSource(fllpll, CY_SYSCLK_CLKPATH_IN_IMO);
2578 
2579                             /* Store a record that this path source was changed from ECO */
2580                             changedSourcePaths |= (uint16_t)(1UL << fllpll);
2581                         }
2582                         else if (0UL == fllpll)
2583                         {
2584                             CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
2585                         }
2586                         else
2587                         {
2588                             /* Do nothing */
2589                         }
2590                     }
2591                 }
2592 
2593                 retVal = CY_SYSPM_SUCCESS;
2594 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))  */
2595             }
2596             break;
2597 
2598         case CY_SYSPM_AFTER_TRANSITION:
2599             {
2600 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2601                 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);
2602 #else
2603                 /* After return from Deep Sleep, for each FLL/PLL, if needed, restore the source to ECO.
2604                  * And block until the FLL/PLL has regained its frequency lock.
2605                  */
2606                 uint32_t timeout = TIMEOUT;
2607                 retVal = CY_SYSPM_TIMEOUT;
2608 
2609                 if (0U != changedSourcePaths)
2610                 {
2611                     /* If any FLL/PLL was sourced by the ECO, timeout wait for the ECO to become fully stabilized again */
2612                     while ((CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeout))
2613                     {
2614                         timeout--;
2615                     }
2616 
2617                     if (0UL != timeout)
2618                     {
2619                         uint32_t fllpll; /* 0 = FLL, all other values = PLL */
2620 
2621                         for (fllpll = 0UL; fllpll <= CY_SRSS_NUM_PLL; fllpll++)
2622                         {
2623                             /* If there is a correspondent record about a changed clock source */
2624                             if (0U != (changedSourcePaths & (uint16_t)(1UL << fllpll)))
2625                             {
2626                                 /* Change this path source back to ECO */
2627                                 (void)Cy_SysClk_ClkPathSetSource(fllpll, CY_SYSCLK_CLKPATH_IN_ECO);
2628 
2629                                 /* Timeout wait for FLL/PLL to regain lock.
2630                                  * Split FLL and PLL lock polling loops into two separate threads to minimize one polling loop duration.
2631                                  */
2632                                 if (0UL == fllpll)
2633                                 {
2634                                     while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
2635                                     {
2636                                         timeout--;
2637                                     }
2638                                 }
2639                                 else
2640                                 {
2641                                     while ((!Cy_SysClk_PllLocked(fllpll)) && (0UL != timeout))
2642                                     {
2643                                         timeout--;
2644                                     }
2645                                 }
2646 
2647                                 if (0UL != timeout)
2648                                 {
2649                                     /* Undo bypass the FLL/PLL */
2650                                     if (0UL == fllpll)
2651                                     {
2652                                         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2653                                     }
2654                                     else
2655                                     {
2656                                         if (0U != (pllAutoModes & (uint16_t)(1UL << fllpll)))
2657                                         {
2658                                             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_AUTO);
2659                                         }
2660                                         else
2661                                         {
2662                                             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[fllpll - 1UL], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2663                                         }
2664                                     }
2665 
2666                                     retVal = CY_SYSPM_SUCCESS;
2667                                 }
2668                             }
2669                         }
2670                     }
2671                 }
2672                 else if (Cy_SysClk_FllIsEnabled())
2673                 {
2674                     /* Timeout wait for FLL to regain lock */
2675                     while ((!Cy_SysClk_FllLocked()) && (0UL != timeout))
2676                     {
2677                         timeout--;
2678                     }
2679 
2680                     if (0UL != timeout)
2681                     {
2682                         /* Undo bypass the FLL */
2683                         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
2684                         retVal = CY_SYSPM_SUCCESS;
2685                     }
2686                 }
2687                 else
2688                 {
2689                     retVal = CY_SYSPM_SUCCESS;
2690                 }
2691 
2692                 preventCounting = false; /* Allow clock measurement */
2693 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2694             }
2695             break;
2696 
2697         default: /* Unsupported mode, return CY_SYSPM_FAIL */
2698             break;
2699     }
2700 
2701     return (retVal);
2702 
2703 }
2704 
2705 
2706 /* ========================================================================== */
2707 /* =========================    clkHf[n] SECTION    ========================= */
2708 /* ========================================================================== */
2709 
2710 
Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)2711 uint32_t Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)
2712 {
2713     /* variables holding intermediate clock frequencies, dividers and FLL/PLL settings */
2714     uint32_t pDiv = 1UL << (uint32_t)Cy_SysClk_ClkHfGetDivider(clkHf); /* root prescaler (1/2/4/8) */
2715     uint32_t path = (uint32_t) Cy_SysClk_ClkHfGetSource(clkHf); /* path input for root 0 (clkHf[0]) */
2716     uint32_t freq = Cy_SysClk_ClkPathGetFrequency(path);
2717 
2718     /* Divide the path input frequency down and return the result */
2719     return (CY_SYSLIB_DIV_ROUND(freq, pDiv));
2720 }
2721 
2722 
2723 /* ========================================================================== */
2724 /* =====================    clk_peripherals SECTION    ====================== */
2725 /* ========================================================================== */
2726 
2727 
Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType,uint32_t dividerNum)2728 uint32_t Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType, uint32_t dividerNum)
2729 {
2730     uint32_t integer = 0UL;        /* Integer part of peripheral divider */
2731     uint32_t freq = Cy_SysClk_ClkPeriGetFrequency(); /* Get Peri frequency */
2732 
2733     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_DIV_8_NR))    || \
2734                  ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_DIV_16_NR))   || \
2735                  ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_DIV_16_5_NR)) || \
2736                  ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_DIV_24_5_NR)));
2737 
2738     /* get the divider value for clk_peri to the selected peripheral clock */
2739     switch(dividerType)
2740     {
2741         case CY_SYSCLK_DIV_8_BIT:
2742         case CY_SYSCLK_DIV_16_BIT:
2743             integer = 1UL + Cy_SysClk_PeriphGetDivider(dividerType, dividerNum);
2744             freq = CY_SYSLIB_DIV_ROUND(freq, integer);
2745             break;
2746 
2747         case CY_SYSCLK_DIV_16_5_BIT:
2748         case CY_SYSCLK_DIV_24_5_BIT:
2749             {
2750                 uint32_t locFrac;
2751                 uint32_t locDiv;
2752                 uint64_t locFreq = freq * 32ULL;
2753                 Cy_SysClk_PeriphGetFracDivider(dividerType, dividerNum, &integer, &locFrac);
2754                 /* For fractional dividers, the divider is (int + 1) + frac/32 */
2755                 locDiv = ((1UL + integer) * 32UL) + locFrac;
2756                 freq = (uint32_t) CY_SYSLIB_DIV_ROUND(locFreq, (uint64_t)locDiv);
2757             }
2758             break;
2759 
2760         default:
2761             /* Unknown divider */
2762             break;
2763     }
2764 
2765     return (freq);
2766 }
2767 
2768 
Cy_SysClk_ClkTimerGetFrequency(void)2769 uint32_t Cy_SysClk_ClkTimerGetFrequency(void)
2770 {
2771     uint32_t freq = 0UL;
2772 
2773     if (Cy_SysClk_ClkTimerIsEnabled())
2774     {
2775         freq = Cy_SysClk_ClkHfGetFrequency(0UL);
2776 
2777         switch (Cy_SysClk_ClkTimerGetSource())
2778         {
2779             case CY_SYSCLK_CLKTIMER_IN_IMO:
2780                 freq = CY_SYSCLK_IMO_FREQ;
2781                 break;
2782 
2783             case CY_SYSCLK_CLKTIMER_IN_HF0_NODIV:
2784                 break;
2785 
2786             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV2:
2787                 freq /= 2UL;
2788                 break;
2789 
2790             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV4:
2791                 freq /= 4UL;
2792                 break;
2793 
2794             case CY_SYSCLK_CLKTIMER_IN_HF0_DIV8:
2795                 freq /= 8UL;
2796                 break;
2797 
2798             default:
2799                 freq = 0UL;
2800                 break;
2801         }
2802     }
2803 
2804     /* Divide the input frequency down and return the result */
2805     return (CY_SYSLIB_DIV_ROUND(freq, 1UL + (uint32_t)Cy_SysClk_ClkTimerGetDivider()));
2806 }
2807 
2808 
Cy_SysClk_FllGetFrequency(void)2809 uint32_t Cy_SysClk_FllGetFrequency(void)
2810 {
2811     uint32_t fDiv ;    /* FLL multiplier/feedback divider */
2812     uint32_t rDiv;    /* FLL reference divider */
2813     uint32_t oDiv;    /* FLL output divider */
2814     bool  enabled;    /* FLL enable status; n/a for direct */
2815     uint32_t freq = 0UL;    /* FLL Frequency */
2816 
2817     cy_stc_fll_manual_config_t fllCfg;
2818     Cy_SysClk_FllGetConfiguration(&fllCfg);
2819     enabled = (Cy_SysClk_FllIsEnabled()) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != fllCfg.outputMode);
2820     fDiv = fllCfg.fllMult;
2821     rDiv = fllCfg.refDiv;
2822     oDiv = (fllCfg.enableOutputDiv) ? 2UL : 1UL;
2823 
2824     if (enabled && /* If FLL is enabled and not bypassed */
2825         (0UL != rDiv)) /* to avoid division by zero */
2826     {
2827         freq = Cy_SysClk_ClkPathMuxGetFrequency(0UL); /* FLL mapped always to path 0 */
2828         freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
2829                                              ((uint64_t)rDiv * (uint64_t)oDiv));
2830     }
2831 
2832     return (freq);
2833 }
2834 
Cy_SysClk_PllGetFrequency(uint32_t clkPath)2835 uint32_t Cy_SysClk_PllGetFrequency(uint32_t clkPath)
2836 {
2837     uint32_t fDiv = 0UL;    /* PLL multiplier/feedback divider */
2838     uint32_t rDiv = 0UL;    /* PLL reference divider */
2839     uint32_t oDiv = 0UL;    /* PLL output divider */
2840     bool  enabled = false;    /* PLL enable status; n/a for direct */
2841     uint32_t freq=0UL;    /* PLL Frequency */
2842 
2843     if((CY_SRSS_NUM_PLL > 0UL) && (clkPath > 0UL))
2844     {
2845         CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
2846 
2847         if (clkPath <= CY_SRSS_NUM_PLL)
2848         {
2849             cy_stc_pll_manual_config_t pllcfg;
2850             if (CY_SYSCLK_SUCCESS == Cy_SysClk_PllGetConfiguration(clkPath, &pllcfg))
2851             {
2852                 enabled = (Cy_SysClk_PllIsEnabled(clkPath)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.outputMode);
2853                 fDiv = pllcfg.feedbackDiv;
2854                 rDiv = pllcfg.referenceDiv;
2855                 oDiv = pllcfg.outputDiv;
2856             }
2857 
2858             if (enabled && /* If PLL is enabled and not bypassed */
2859             (0UL != rDiv) && (0UL != oDiv)) /* to avoid division by zero */
2860             {
2861                 freq = Cy_SysClk_ClkPathMuxGetFrequency(clkPath);
2862                 freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
2863                                                      ((uint64_t)rDiv * (uint64_t)oDiv));
2864             }
2865         }
2866     }
2867 
2868     return (freq);
2869 }
2870 
2871 #if defined (CY_DEVICE_SECURE)
2872 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 17.2')
2873 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.6')
2874 #endif
2875 
2876 #endif
2877 
2878 /* [] END OF FILE */
2879