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