1 /***************************************************************************//**
2 * \file cy_sysclk_v2.c
3 * \version 3.110
4 *
5 * Provides an API implementation of the sysclk driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright (c) (2016-2022), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation.
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined (CY_IP_MXS22SRSS)
29 
30 #include "cy_sysclk.h"
31 #include "cy_syslib.h"
32 #include "cy_syspm_btss.h"
33 #include <stdlib.h>
34 
35 /* Static variable declarations */
36 /* Cy_SysClk_StartClkMeasurementCounters() input parameter saved for use later in other functions */
37 static uint32_t clk1Count1;
38 
39 /* These variables act as locks to prevent collisions between clock measurement and entry into
40    Deep Sleep mode. See Cy_SysClk_DeepSleep(). */
41 static bool clkCounting = false;
42 static bool preventCounting = false;
43 
44 /* End static variable section */
45 
46 #if defined (CY_IP_MXS22SRSS)
47 #define SLOW_SEL_OUTPUT_INDEX       11UL
48 #else
49 #define SLOW_SEL_OUTPUT_INDEX       7UL
50 #endif
51 
52 #if defined (CY_IP_MXS22SRSS) || (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
53 #define CSV_MIN_TARGET_VAL          200UL /* Minimum Target value to get 1 percent accuracy for CSV (Clock Supervision). */
54 #endif
55 
56 /* ECO Prescaler timeout value in micro seconds */
57 #define CY_SYSCLK_ECO_PRESCALER_TIMEOUT_US 1000U
58 
59 
60 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkSetDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerValue)61                 Cy_SysClk_PeriPclkSetDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType,
62                                            uint32_t dividerNum, uint32_t dividerValue)
63 {
64     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
65     uint8_t grpNum = 0;
66     uint8_t instNum = 0;
67 
68 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
69     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
70     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
71 
72     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
73     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
74 #else
75     CY_UNUSED_PARAMETER(grpNum);
76     CY_UNUSED_PARAMETER(instNum);
77     CY_UNUSED_PARAMETER(ipBlock);
78 #endif
79 
80     if (dividerType == CY_SYSCLK_DIV_8_BIT)
81     {
82         if ((dividerNum < (PERI_PCLK_GR_DIV_8_NR(instNum, grpNum))) &&
83             (dividerValue <= (PERI_DIV_8_CTL_INT8_DIV_Msk >> PERI_DIV_8_CTL_INT8_DIV_Pos)))
84         {
85             CY_REG32_CLR_SET(PERI_DIV_8_CTL(instNum, grpNum, dividerNum), PERI_DIV_8_CTL_INT8_DIV, dividerValue);
86             retVal = CY_SYSCLK_SUCCESS;
87         }
88     }
89     else if (dividerType == CY_SYSCLK_DIV_16_BIT)
90     {
91         if ((dividerNum < (PERI_PCLK_GR_DIV_16_NR(instNum, grpNum))) &&
92             (dividerValue <= (PERI_DIV_16_CTL_INT16_DIV_Msk >> PERI_DIV_16_CTL_INT16_DIV_Pos)))
93         {
94             CY_REG32_CLR_SET(PERI_DIV_16_CTL(instNum, grpNum, dividerNum), PERI_DIV_16_CTL_INT16_DIV, dividerValue);
95             retVal = CY_SYSCLK_SUCCESS;
96         }
97     }
98     else
99     { /* return bad parameter */
100     }
101     return (retVal);
102 }
103 
104 
Cy_SysClk_PeriPclkGetDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)105 uint32_t Cy_SysClk_PeriPclkGetDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum)
106 {
107     uint32_t retVal;
108     uint8_t grpNum = 0;
109     uint8_t instNum = 0;
110 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
111     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
112     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
113 
114     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
115     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
116 #else
117     CY_UNUSED_PARAMETER(grpNum);
118     CY_UNUSED_PARAMETER(instNum);
119     CY_UNUSED_PARAMETER(ipBlock);
120 #endif
121     CY_ASSERT_L1(dividerType <= CY_SYSCLK_DIV_16_BIT);
122     if (dividerType == CY_SYSCLK_DIV_8_BIT)
123     {
124         CY_ASSERT_L1(dividerNum < PERI_PCLK_GR_DIV_8_NR(instNum, grpNum));
125         retVal = _FLD2VAL(PERI_DIV_8_CTL_INT8_DIV, PERI_DIV_8_CTL(instNum, grpNum, dividerNum));
126     }
127     else
128     { /* 16-bit divider */
129         CY_ASSERT_L1(dividerNum < PERI_PCLK_GR_DIV_16_NR(instNum, grpNum));
130         retVal = _FLD2VAL(PERI_DIV_16_CTL_INT16_DIV, PERI_DIV_16_CTL(instNum, grpNum, dividerNum));
131     }
132     return (retVal);
133 }
134 
135 
136 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkSetFracDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerIntValue,uint32_t dividerFracValue)137                 Cy_SysClk_PeriPclkSetFracDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum,
138                                                uint32_t dividerIntValue, uint32_t dividerFracValue)
139 {
140     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
141     uint8_t grpNum = 0;
142     uint8_t instNum = 0;
143 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
144     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
145     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
146 
147     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
148     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
149 #else
150     CY_UNUSED_PARAMETER(grpNum);
151     CY_UNUSED_PARAMETER(instNum);
152     CY_UNUSED_PARAMETER(ipBlock);
153 #endif
154 
155 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
156     if (dividerType == CY_SYSCLK_DIV_16_5_BIT)
157     {
158         if (((uint32_t)dividerNum < (PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum))) &&
159             (dividerIntValue <= (PERI_DIV_16_5_CTL_INT16_DIV_Msk >> PERI_DIV_16_5_CTL_INT16_DIV_Pos)) &&
160             (dividerFracValue <= (PERI_DIV_16_5_CTL_FRAC5_DIV_Msk >> PERI_DIV_16_5_CTL_FRAC5_DIV_Pos)))
161         {
162             CY_REG32_CLR_SET(PERI_DIV_16_5_CTL(instNum, grpNum, dividerNum), PERI_DIV_16_5_CTL_INT16_DIV, dividerIntValue);
163             CY_REG32_CLR_SET(PERI_DIV_16_5_CTL(instNum, grpNum, dividerNum), PERI_DIV_16_5_CTL_FRAC5_DIV, dividerFracValue);
164             retVal = CY_SYSCLK_SUCCESS;
165         }
166     }
167 #endif
168 
169     if (dividerType == CY_SYSCLK_DIV_24_5_BIT)
170     {
171         if (((uint32_t)dividerNum < (PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))) &&
172             (dividerIntValue <= (PERI_DIV_24_5_CTL_INT24_DIV_Msk >> PERI_DIV_24_5_CTL_INT24_DIV_Pos)) &&
173             (dividerFracValue <= (PERI_DIV_24_5_CTL_FRAC5_DIV_Msk >> PERI_DIV_24_5_CTL_FRAC5_DIV_Pos)))
174         {
175             CY_REG32_CLR_SET(PERI_DIV_24_5_CTL(instNum, grpNum, dividerNum), PERI_DIV_24_5_CTL_INT24_DIV, dividerIntValue);
176             CY_REG32_CLR_SET(PERI_DIV_24_5_CTL(instNum, grpNum, dividerNum), PERI_DIV_24_5_CTL_FRAC5_DIV, dividerFracValue);
177             retVal = CY_SYSCLK_SUCCESS;
178         }
179     }
180 
181     /* if none of the above conditions are true, the function will return bad parameter */
182 
183     return (retVal);
184 }
185 
186 
Cy_SysClk_PeriPclkGetFracDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t * dividerIntValue,uint32_t * dividerFracValue)187 void Cy_SysClk_PeriPclkGetFracDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum,
188                                                     uint32_t *dividerIntValue, uint32_t *dividerFracValue)
189 {
190     uint8_t grpNum = 0;
191     uint8_t instNum = 0;
192 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
193     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
194     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
195 
196     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
197     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
198 #else
199     CY_UNUSED_PARAMETER(grpNum);
200     CY_UNUSED_PARAMETER(instNum);
201     CY_UNUSED_PARAMETER(ipBlock);
202 #endif
203     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_16_5_BIT) || (dividerType == CY_SYSCLK_DIV_24_5_BIT)) && \
204                  (dividerIntValue != NULL) && (dividerFracValue != NULL));
205 
206 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
207     if (dividerType == CY_SYSCLK_DIV_16_5_BIT)
208     {
209         CY_ASSERT_L1(dividerNum < PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum));
210         *dividerIntValue  = _FLD2VAL(PERI_DIV_16_5_CTL_INT16_DIV, PERI_DIV_16_5_CTL(instNum, grpNum, dividerNum));
211         *dividerFracValue = _FLD2VAL(PERI_DIV_16_5_CTL_FRAC5_DIV, PERI_DIV_16_5_CTL(instNum, grpNum, dividerNum));
212     }
213 #endif
214 
215     if (dividerType == CY_SYSCLK_DIV_24_5_BIT)
216     { /* 24.5-bit divider */
217         CY_ASSERT_L1(dividerNum < PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum));
218         *dividerIntValue  = _FLD2VAL(PERI_DIV_24_5_CTL_INT24_DIV, PERI_DIV_24_5_CTL(instNum, grpNum, dividerNum));
219         *dividerFracValue = _FLD2VAL(PERI_DIV_24_5_CTL_FRAC5_DIV, PERI_DIV_24_5_CTL(instNum, grpNum, dividerNum));
220     }
221 }
222 
223 
224 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkAssignDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)225                 Cy_SysClk_PeriPclkAssignDivider(en_clk_dst_t ipBlock,
226                                               cy_en_divider_types_t dividerType, uint32_t dividerNum)
227 {
228     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
229     uint8_t grpNum = 0;
230     uint8_t instNum = 0;
231     uint8_t periNum = 0;
232 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
233     grpNum    = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
234     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
235     periNum  = (uint8_t)((uint32_t)ipBlock & PERI_PCLK_PERI_NUM_Msk);
236 
237     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
238     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
239 #endif
240     if (CY_SYSCLK_DIV_24_5_BIT >= dividerType)
241     {
242         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < (PERI_PCLK_GR_DIV_8_NR(instNum, grpNum))))    ||
243             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < (PERI_PCLK_GR_DIV_16_NR(instNum, grpNum))))   ||
244 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
245             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum)))) ||
246 #endif
247             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum)))))
248         {
249 #if defined (CY_IP_MXS40SRSS) && (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3))
250             CY_UNUSED_PARAMETER(grpNum);
251             CY_UNUSED_PARAMETER(instNum);
252             CY_UNUSED_PARAMETER(periNum);
253             if (CY_PERI_CLOCK_NR > (uint32_t)ipBlock)
254             {
255                 PERI_CLOCK_CTL[ipBlock] = _VAL2FLD(CY_PERI_CLOCK_CTL_TYPE_SEL, dividerType) |
256                                         _VAL2FLD(CY_PERI_CLOCK_CTL_DIV_SEL, dividerNum);
257 
258                 retVal = CY_SYSCLK_SUCCESS;
259             }
260 #else
261             PERI_CLOCK_CTL(instNum, grpNum, periNum) = _VAL2FLD(CY_PERI_CLOCK_CTL_TYPE_SEL, dividerType) |
262                                       _VAL2FLD(CY_PERI_CLOCK_CTL_DIV_SEL, dividerNum);
263 
264             retVal = CY_SYSCLK_SUCCESS;
265 #endif
266         }
267     }
268     return (retVal);
269 }
270 
271 
Cy_SysClk_PeriPclkGetAssignedDivider(en_clk_dst_t ipBlock)272 uint32_t Cy_SysClk_PeriPclkGetAssignedDivider(en_clk_dst_t ipBlock)
273 {
274 #if defined (CY_IP_MXS40SRSS) && (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3))
275     CY_ASSERT_L1(CY_PERI_CLOCK_NR > (uint32_t)ipBlock);
276     return (PERI_CLOCK_CTL[ipBlock] & (CY_PERI_CLOCK_CTL_DIV_SEL_Msk | CY_PERI_CLOCK_CTL_TYPE_SEL_Msk));
277 #else
278     uint8_t grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
279     uint8_t instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
280     uint8_t periNum  = (uint8_t)((uint32_t)ipBlock & PERI_PCLK_PERI_NUM_Msk );
281 
282     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
283     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
284     return (PERI_CLOCK_CTL(instNum, grpNum, periNum) & (CY_PERI_CLOCK_CTL_DIV_SEL_Msk | CY_PERI_CLOCK_CTL_TYPE_SEL_Msk));
285 #endif
286 }
287 
288 
289 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkEnableDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)290                 Cy_SysClk_PeriPclkEnableDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum)
291 {
292     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
293     uint8_t grpNum = 0;
294     uint8_t instNum = 0;
295 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
296     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
297     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
298 
299     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
300     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
301 #else
302     CY_UNUSED_PARAMETER(grpNum);
303     CY_UNUSED_PARAMETER(instNum);
304     CY_UNUSED_PARAMETER(ipBlock);
305 #endif
306     if (dividerType <= CY_SYSCLK_DIV_24_5_BIT)
307     {
308         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < (PERI_PCLK_GR_DIV_8_NR(instNum, grpNum))))    ||
309             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < (PERI_PCLK_GR_DIV_16_NR(instNum, grpNum))))   ||
310 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
311             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum)))) ||
312 #endif
313             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum)))))
314         {
315             /* specify the divider, make the reference = clk_peri, and enable the divider */
316             PERI_DIV_CMD(instNum, grpNum) = PERI_DIV_CMD_ENABLE_Msk                         |
317                            CY_PERI_DIV_CMD_PA_TYPE_SEL_Msk                 |
318                            CY_PERI_DIV_CMD_PA_DIV_SEL_Msk                  |
319                            _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType) |
320                            _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
321             (void)PERI_DIV_CMD(instNum, grpNum); /* dummy read to handle buffered writes */
322             retVal = CY_SYSCLK_SUCCESS;
323         }
324     }
325     return (retVal);
326 }
327 
328 
329 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkDisableDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)330                 Cy_SysClk_PeriPclkDisableDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum)
331 {
332     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
333     uint8_t grpNum = 0;
334     uint8_t instNum = 0;
335 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
336     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
337     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
338 
339     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
340     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
341 #else
342     CY_UNUSED_PARAMETER(grpNum);
343     CY_UNUSED_PARAMETER(instNum);
344     CY_UNUSED_PARAMETER(ipBlock);
345 #endif
346     if (dividerType <= CY_SYSCLK_DIV_24_5_BIT)
347     {
348         if (((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < (PERI_PCLK_GR_DIV_8_NR(instNum, grpNum))))    ||
349             ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < (PERI_PCLK_GR_DIV_16_NR(instNum, grpNum))))   ||
350 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
351             ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum)))) ||
352 #endif
353             ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < (PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum)))))
354         {
355             /* specify the divider and disable it */
356             PERI_DIV_CMD(instNum, grpNum) = PERI_DIV_CMD_DISABLE_Msk          |
357              _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType) |
358              _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
359             retVal = CY_SYSCLK_SUCCESS;
360         }
361     }
362     return (retVal);
363 }
364 
365 
366 cy_en_sysclk_status_t
Cy_SysClk_PeriPclkEnablePhaseAlignDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum,cy_en_divider_types_t dividerTypePA,uint32_t dividerNumPA)367                 Cy_SysClk_PeriPclkEnablePhaseAlignDivider(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum,
368                                                         cy_en_divider_types_t dividerTypePA, uint32_t dividerNumPA)
369 {
370     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
371     uint8_t grpNum = 0;
372     uint8_t instNum = 0;
373 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
374     grpNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
375     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
376 
377     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
378     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
379 #else
380     CY_UNUSED_PARAMETER(grpNum);
381     CY_UNUSED_PARAMETER(instNum);
382     CY_UNUSED_PARAMETER(ipBlock);
383 #endif
384     if (dividerTypePA <= CY_SYSCLK_DIV_24_5_BIT)
385     {
386         if (((dividerTypePA == CY_SYSCLK_DIV_8_BIT)    && (dividerNumPA < (PERI_PCLK_GR_DIV_8_NR(instNum, grpNum))))    ||
387             ((dividerTypePA == CY_SYSCLK_DIV_16_BIT)   && (dividerNumPA < (PERI_PCLK_GR_DIV_16_NR(instNum, grpNum))))   ||
388 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
389             ((dividerTypePA == CY_SYSCLK_DIV_16_5_BIT) && (dividerNumPA < (PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum)))) ||
390 #endif
391             ((dividerTypePA == CY_SYSCLK_DIV_24_5_BIT) && ((dividerNumPA < (PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))) || (dividerNumPA == 63u))))
392         {
393             /* First, disable the divider that is to be phase-aligned.
394                The other two parameters are checked in that function;
395                if they're not valid, the divider is not disabled. */
396             retVal = Cy_SysClk_PeriphDisableDivider(dividerType, dividerNum);
397             if (retVal == CY_SYSCLK_SUCCESS)
398             {
399                 /* Then, specify the reference divider, and the divider, and enable the divider */
400                 PERI_DIV_CMD(instNum, grpNum) = PERI_DIV_CMD_ENABLE_Msk             |
401                  _VAL2FLD(CY_PERI_DIV_CMD_PA_TYPE_SEL, dividerTypePA) |
402                  _VAL2FLD(CY_PERI_DIV_CMD_PA_DIV_SEL,  dividerNumPA)  |
403                  _VAL2FLD(CY_PERI_DIV_CMD_TYPE_SEL, dividerType)   |
404                  _VAL2FLD(CY_PERI_DIV_CMD_DIV_SEL,  dividerNum);
405             }
406         }
407     }
408     return (retVal);
409 }
410 
411 
Cy_SysClk_PeriPclkGetDividerEnabled(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)412 bool Cy_SysClk_PeriPclkGetDividerEnabled(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum)
413 {
414     bool retVal = false;
415     uint8_t grpNum = 0;
416     uint8_t instNum = 0;
417 #if defined (CY_IP_MXSPERI) || (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3))
418     grpNum = (uint8_t)((((uint32_t)ipBlock) & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos);
419     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
420 
421     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
422     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
423 #else
424     CY_UNUSED_PARAMETER(grpNum);
425     CY_UNUSED_PARAMETER(instNum);
426     CY_UNUSED_PARAMETER(ipBlock);
427 #endif
428 
429 #if (defined (CY_IP_MXS40SRSS) && (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3U)))
430     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_PCLK_GR_DIV_8_NR(instNum, grpNum)))    || \
431                  ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_PCLK_GR_DIV_16_NR(instNum, grpNum)))   || \
432                  ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))));
433 #else
434     CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_PCLK_GR_DIV_8_NR(instNum, grpNum)))    || \
435                  ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_PCLK_GR_DIV_16_NR(instNum, grpNum)))   || \
436                  ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum))) || \
437                  ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))));
438 #endif
439 
440     switch(dividerType)
441     {
442         case CY_SYSCLK_DIV_8_BIT:
443             retVal = _FLD2BOOL(PERI_DIV_8_CTL_EN, PERI_DIV_8_CTL(instNum, grpNum, dividerNum));
444             break;
445         case CY_SYSCLK_DIV_16_BIT:
446             retVal = _FLD2BOOL(PERI_DIV_16_CTL_EN, PERI_DIV_16_CTL(instNum, grpNum, dividerNum));
447             break;
448         case CY_SYSCLK_DIV_16_5_BIT:
449             retVal = _FLD2BOOL(PERI_DIV_16_5_CTL_EN, PERI_DIV_16_5_CTL(instNum, grpNum, dividerNum));
450             break;
451         case CY_SYSCLK_DIV_24_5_BIT:
452             retVal = _FLD2BOOL(PERI_DIV_24_5_CTL_EN, PERI_DIV_24_5_CTL(instNum, grpNum, dividerNum));
453             break;
454         default:
455             /* Unknown Divider */
456             break;
457     }
458     return (retVal);
459 }
460 
461 
462 /* ========================================================================== */
463 /* =====================    clk_peripherals SECTION    ====================== */
464 /* ========================================================================== */
465 
466 
Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType,uint32_t dividerNum)467 uint32_t Cy_SysClk_PeriphGetFrequency(cy_en_divider_types_t dividerType, uint32_t dividerNum)
468 {
469     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
470 
471     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
472     return Cy_SysClk_PeriPclkGetFrequency((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum);
473 }
474 
475 
476 cy_en_sysclk_status_t
Cy_SysClk_PeriphSetDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerValue)477                 Cy_SysClk_PeriphSetDivider(cy_en_divider_types_t dividerType,
478                                            uint32_t dividerNum, uint32_t dividerValue)
479 {
480     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
481     return Cy_SysClk_PeriPclkSetDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum, dividerValue);
482 }
483 
484 
Cy_SysClk_PeriphGetDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)485 uint32_t Cy_SysClk_PeriphGetDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
486 {
487     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
488     return Cy_SysClk_PeriPclkGetDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum);
489 }
490 
491 
492 cy_en_sysclk_status_t
Cy_SysClk_PeriphSetFracDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t dividerIntValue,uint32_t dividerFracValue)493                 Cy_SysClk_PeriphSetFracDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
494                                                uint32_t dividerIntValue, uint32_t dividerFracValue)
495 {
496     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
497     return Cy_SysClk_PeriPclkSetFracDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum, dividerIntValue, dividerFracValue);
498 }
499 
500 
Cy_SysClk_PeriphGetFracDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum,uint32_t * dividerIntValue,uint32_t * dividerFracValue)501 void Cy_SysClk_PeriphGetFracDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
502                                                     uint32_t *dividerIntValue, uint32_t *dividerFracValue)
503 {
504     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
505     Cy_SysClk_PeriPclkGetFracDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum, dividerIntValue, dividerFracValue);
506 }
507 
508 
509 cy_en_sysclk_status_t
Cy_SysClk_PeriphAssignDivider(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)510                 Cy_SysClk_PeriphAssignDivider(en_clk_dst_t ipBlock,
511                                               cy_en_divider_types_t dividerType, uint32_t dividerNum)
512 {
513     return Cy_SysClk_PeriPclkAssignDivider(ipBlock, dividerType, dividerNum);
514 }
515 
516 
Cy_SysClk_PeriphGetAssignedDivider(en_clk_dst_t ipBlock)517 uint32_t Cy_SysClk_PeriphGetAssignedDivider(en_clk_dst_t ipBlock)
518 {
519     return Cy_SysClk_PeriPclkGetAssignedDivider(ipBlock);
520 }
521 
522 
523 cy_en_sysclk_status_t
Cy_SysClk_PeriphEnableDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)524                 Cy_SysClk_PeriphEnableDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
525 {
526     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
527     return Cy_SysClk_PeriPclkEnableDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum);
528 }
529 
530 
531 cy_en_sysclk_status_t
Cy_SysClk_PeriphDisableDivider(cy_en_divider_types_t dividerType,uint32_t dividerNum)532                 Cy_SysClk_PeriphDisableDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum)
533 {
534     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
535     return Cy_SysClk_PeriPclkDisableDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum);
536 }
537 
538 
539 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)540                 Cy_SysClk_PeriphEnablePhaseAlignDivider(cy_en_divider_types_t dividerType, uint32_t dividerNum,
541                                                         cy_en_divider_types_t dividerTypePA, uint32_t dividerNumPA)
542 {
543     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
544     return Cy_SysClk_PeriPclkEnablePhaseAlignDivider((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum, dividerTypePA,  dividerNumPA);
545 }
546 
547 
Cy_SysClk_PeriphGetDividerEnabled(cy_en_divider_types_t dividerType,uint32_t dividerNum)548 bool Cy_SysClk_PeriphGetDividerEnabled(cy_en_divider_types_t dividerType, uint32_t dividerNum)
549 {
550     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to en_clk_dst_t enum.');
551     return Cy_SysClk_PeriPclkGetDividerEnabled((en_clk_dst_t)PERI_PCLK_PERIPHERAL_GROUP_NUM, dividerType, dividerNum);
552 }
553 
554 
555 /* ========================================================================== */
556 /* =========================    clk_slow SECTION    ========================= */
557 /* ========================================================================== */
558 
559 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)
560 
Cy_SysClk_ClkSlowGetFrequency(void)561 uint32_t Cy_SysClk_ClkSlowGetFrequency(void)
562 {
563 #if defined (CY_IP_M7CPUSS)
564     uint32_t locFreq = Cy_SysClk_ClkMemGetFrequency(); /* Get Mem frequency */
565 #elif defined (CY_IP_M4CPUSS)
566     uint32_t locFreq = Cy_SysClk_ClkPeriGetFrequency(); /* Get Peri frequency */
567 #else
568     #error "Unsupported Core Type"
569 #endif
570     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkSlowGetDivider(); /* Range (1-256) */
571 
572     /* Divide the path input frequency down and return the result */
573     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
574 }
575 
576 
Cy_SysClk_ClkSlowSetDivider(uint8_t divider)577 void Cy_SysClk_ClkSlowSetDivider(uint8_t divider)
578 {
579 #if defined (CY_IP_M7CPUSS)
580     CY_REG32_CLR_SET(CPUSS_SLOW_CLOCK_CTL, CPUSS_SLOW_CLOCK_CTL_INT_DIV, divider);
581 #elif defined (CY_IP_M4CPUSS)
582     CY_REG32_CLR_SET(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, divider);
583 #else
584     #error "Unsupported Core Type"
585 #endif
586 }
587 
588 
Cy_SysClk_ClkSlowGetDivider(void)589 uint8_t Cy_SysClk_ClkSlowGetDivider(void)
590 {
591 #if defined (CY_IP_M7CPUSS)
592     return ((uint8_t)_FLD2VAL(CPUSS_SLOW_CLOCK_CTL_INT_DIV, CPUSS_SLOW_CLOCK_CTL));
593 #elif defined (CY_IP_M4CPUSS)
594     return ((uint8_t)_FLD2VAL(CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, CPUSS_CM0_CLOCK_CTL));
595 #else
596     #error "Unsupported Core Type"
597 #endif
598 }
599 
600 #endif /* defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) */
601 
602 /* ========================================================================== */
603 /* =========================    clk_mem SECTION    ========================= */
604 /* ========================================================================== */
605 
606 #if defined (CY_IP_MXS40SRSS) && defined (CY_IP_M7CPUSS)
607 
Cy_SysClk_ClkMemGetFrequency(void)608 uint32_t Cy_SysClk_ClkMemGetFrequency(void)
609 {
610     uint32_t locFreq = Cy_SysClk_ClkHfGetFrequency(CY_SYSCLK_CLK_MEM_HF_PATH_NUM); /* Get HF frequency */
611     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkMemGetDivider(); /* Range (1-256) */
612 
613     /* Divide the path input frequency down and return the result */
614     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
615 }
616 
617 
Cy_SysClk_ClkMemSetDivider(uint8_t divider)618 void Cy_SysClk_ClkMemSetDivider(uint8_t divider)
619 {
620     CY_REG32_CLR_SET(CPUSS_MEM_CLOCK_CTL, CPUSS_MEM_CLOCK_CTL_INT_DIV, divider);
621 }
622 
623 
Cy_SysClk_ClkMemGetDivider(void)624 uint8_t Cy_SysClk_ClkMemGetDivider(void)
625 {
626     return ((uint8_t)_FLD2VAL(CPUSS_MEM_CLOCK_CTL_INT_DIV, CPUSS_MEM_CLOCK_CTL));
627 }
628 
629 #endif /* defined (CY_IP_MXS40SRSS) && defined (CY_IP_M7CPUSS) */
630 
631 /* ========================================================================== */
632 /* =========================    clk_pump SECTION    ========================= */
633 /* ========================================================================== */
634 
635 #if defined (CY_IP_MXS40SSRSS)
Cy_SysClk_ClkPumpSetSource(cy_en_clkpump_in_sources_t source)636 void Cy_SysClk_ClkPumpSetSource(cy_en_clkpump_in_sources_t source)
637 {
638     CY_ASSERT_L3(source <= CY_SYSCLK_PUMP_IN_CLKPATH15);
639     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_PUMP_SEL, source);
640 }
641 
Cy_SysClk_ClkPumpGetSource(void)642 cy_en_clkpump_in_sources_t Cy_SysClk_ClkPumpGetSource(void)
643 {
644     return ((cy_en_clkpump_in_sources_t)((uint32_t)_FLD2VAL(SRSS_CLK_SELECT_PUMP_SEL, SRSS_CLK_SELECT)));
645 }
646 
Cy_SysClk_ClkPumpSetDivider(cy_en_clkpump_divide_t divider)647 void Cy_SysClk_ClkPumpSetDivider(cy_en_clkpump_divide_t divider)
648 {
649     CY_ASSERT_L3(CY_SYSCLK_FLL_IS_DIVIDER_VALID(divider));
650     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_PUMP_DIV, divider);
651 }
652 
Cy_SysClk_ClkPumpGetDivider(void)653 cy_en_clkpump_divide_t Cy_SysClk_ClkPumpGetDivider(void)
654 {
655     return ((cy_en_clkpump_divide_t)((uint32_t)_FLD2VAL(SRSS_CLK_SELECT_PUMP_DIV, SRSS_CLK_SELECT)));
656 }
657 
Cy_SysClk_ClkPumpIsEnabled(void)658 bool Cy_SysClk_ClkPumpIsEnabled(void)
659 {
660     return (_FLD2BOOL(SRSS_CLK_SELECT_PUMP_ENABLE, SRSS_CLK_SELECT));
661 }
662 
Cy_SysClk_ClkPumpEnable(void)663 void Cy_SysClk_ClkPumpEnable(void)
664 {
665     SRSS_CLK_SELECT |= SRSS_CLK_SELECT_PUMP_ENABLE_Msk;
666 }
667 
668 
Cy_SysClk_ClkPumpDisable(void)669 void Cy_SysClk_ClkPumpDisable(void)
670 {
671     SRSS_CLK_SELECT &= ~SRSS_CLK_SELECT_PUMP_ENABLE_Msk;
672 }
673 
Cy_SysClk_ClkPumpGetFrequency(void)674 uint32_t Cy_SysClk_ClkPumpGetFrequency(void)
675 {
676     /* Divide the input frequency down and return the result */
677     return (Cy_SysClk_ClkPumpIsEnabled() ?
678             (Cy_SysClk_ClkPathGetFrequency((uint32_t)Cy_SysClk_ClkPumpGetSource()) /
679              (1UL << (uint32_t)Cy_SysClk_ClkPumpGetDivider())) : 0UL);
680 }
681 #endif /* defined (CY_IP_MXS40SSRSS) */
682 /* ========================================================================== */
683 /* ==========================    clk_bak SECTION    ========================= */
684 /* ========================================================================== */
685 
Cy_SysClk_ClkBakSetSource(cy_en_clkbak_in_sources_t source)686 void Cy_SysClk_ClkBakSetSource(cy_en_clkbak_in_sources_t source)
687 {
688     CY_ASSERT_L3(source <= CY_SYSCLK_BAK_IN_PILO);
689 
690 #if defined (CY_IP_MXS22SRSS)
691     BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, SRSS_CLK_WCO_CONFIG_CLK_RTC_SEL, (uint32_t) source));
692 #else
693     BACKUP_CTL = (_CLR_SET_FLD32U(BACKUP_CTL, BACKUP_CTL_CLK_SEL, (uint32_t) source));
694 #endif
695 }
696 
697 
Cy_SysClk_ClkBakGetSource(void)698 cy_en_clkbak_in_sources_t Cy_SysClk_ClkBakGetSource(void)
699 {
700     CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.8', 1, 'Intentional typecast to cy_en_clkbak_in_sources_t enum.')
701 #if defined (CY_IP_MXS22SRSS)
702     return ((cy_en_clkbak_in_sources_t)_FLD2VAL(SRSS_CLK_WCO_CONFIG_CLK_RTC_SEL, BACKUP_CTL));
703 #else
704     return ((cy_en_clkbak_in_sources_t)_FLD2VAL(BACKUP_CTL_CLK_SEL, BACKUP_CTL));
705 #endif
706     CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.8')
707 }
708 
709 /* ========================================================================== */
710 /* ===========================    clkLf SECTION    ========================== */
711 /* ========================================================================== */
712 
Cy_SysClk_ClkLfSetSource(cy_en_clklf_in_sources_t source)713 void Cy_SysClk_ClkLfSetSource(cy_en_clklf_in_sources_t source)
714 {
715     CY_ASSERT_L3(source <= CY_SYSCLK_CLKLF_IN_MAX);
716     CY_REG32_CLR_SET(SRSS_CLK_SELECT, SRSS_CLK_SELECT_LFCLK_SEL, source);
717 }
718 
719 
Cy_SysClk_ClkLfGetSource(void)720 cy_en_clklf_in_sources_t Cy_SysClk_ClkLfGetSource(void)
721 {
722     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_clklf_in_sources_t enum.');
723     return ((cy_en_clklf_in_sources_t)(_FLD2VAL(SRSS_CLK_SELECT_LFCLK_SEL, SRSS_CLK_SELECT)));
724 }
725 
726 
727 #if defined (CY_IP_MXS22SRSS) || (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
Cy_SysClk_ClkLfGetFrequency(void)728 uint32_t Cy_SysClk_ClkLfGetFrequency(void)
729 {
730     uint32_t freq = 0UL;
731 
732     cy_en_clklf_in_sources_t source = Cy_SysClk_ClkLfGetSource();
733 
734     /* Get the frequency of the source  */
735     switch(source)
736      {
737         case CY_SYSCLK_CLKLF_IN_PILO:
738             freq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
739             break;
740 
741         case CY_SYSCLK_CLKLF_IN_WCO:
742             freq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
743             break;
744 
745         case CY_SYSCLK_CLKLF_IN_ILO:
746             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
747             break;
748 
749         case CY_SYSCLK_CLKLF_IN_ECO_PRESCALER:
750             freq = Cy_SysClk_EcoPrescaleGetFrequency();
751             break;
752 
753         default:
754             /* Don't know the frequency of dsi_out, leave freq = 0UL */
755             break;
756      }
757     return (freq);
758  }
759 
760 
Cy_SysClk_ClkLfCsvGetRefFrequency(cy_en_clklf_csv_ref_clk_t refClk)761 uint32_t Cy_SysClk_ClkLfCsvGetRefFrequency(cy_en_clklf_csv_ref_clk_t refClk)
762  {
763     uint32_t freq = 0UL;
764 
765     /* Get the frequency of the source  */
766     switch(refClk)
767      {
768  #if defined (CY_IP_MXS22SRSS)
769         case CY_SYSCLK_CLKLF_CSV_REF_PILO:
770             freq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
771             break;
772 
773         case CY_SYSCLK_CLKLF_CSV_REF_ILO:
774             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
775             break;
776 
777         case CY_SYSCLK_CLKLF_CSV_REF_WCO:
778             freq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
779             break;
780 
781 #else
782         case CY_SYSCLK_CLKLF_CSV_REF_IMO: /* The IMO frequency is fixed at 8 MHz */
783             freq = CY_SYSCLK_IMO_FREQ;
784             break;
785 
786         case CY_SYSCLK_CLKLF_CSV_REF_EXT:
787             freq = Cy_SysClk_ExtClkGetFrequency();
788             break;
789 
790         case CY_SYSCLK_CLKLF_CSV_REF_ECO:
791             freq = Cy_SysClk_EcoGetFrequency();
792             break;
793 
794         case CY_SYSCLK_CLKLF_CSV_REF_IHO:
795             freq = (Cy_SysClk_IhoIsEnabled()) ? CY_SYSCLK_IHO_FREQ : 0UL;
796             break;
797 #endif
798         default:
799             /* Don't know the frequency of dsi_out, leave freq = 0UL */
800             break;
801      }
802     return (freq);
803  }
804 
805 
Cy_SysClk_ClkLfCsvManualConfigure(cy_en_clklf_csv_ref_clk_t refClk,const cy_stc_clklf_csv_manual_config_t * csvConfig)806 cy_en_sysclk_status_t Cy_SysClk_ClkLfCsvManualConfigure(cy_en_clklf_csv_ref_clk_t refClk, const cy_stc_clklf_csv_manual_config_t * csvConfig)
807 {
808     /* Check for errors */
809     CY_ASSERT_L1(csvConfig != NULL);
810 
811     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
812     uint32_t monitorFreq = Cy_SysClk_ClkLfGetFrequency();
813     uint32_t refFreq = Cy_SysClk_ClkLfCsvGetRefFrequency(refClk);
814 
815     CY_ASSERT_L1(csvConfig->upperLimit > CSV_MIN_TARGET_VAL);
816     CY_ASSERT_L1(csvConfig->lowerLimit < csvConfig->upperLimit -1UL);
817     CY_ASSERT_L1(monitorFreq > 0UL);
818     CY_ASSERT_L1(csvConfig->period <= ((csvConfig->upperLimit + 1UL) / (refFreq / monitorFreq)) - 1UL);
819     CY_ASSERT_L1(csvConfig->startTime >= ((csvConfig->period +3UL) * (refFreq / monitorFreq)) - csvConfig->upperLimit);
820 
821     (void) monitorFreq; /* Used only in Assert comparison. */
822     (void) refFreq;  /* Used only in Assert comparison.  */
823 
824     CY_REG32_CLR_SET(SRSS_CSV_REF_SEL, SRSS_CSV_REF_SEL_REF_MUX, refClk);
825     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_REF_CTL, CSV_LF_CSV_REF_CTL_CSV_STARTUP, csvConfig->startTime - 1UL);
826     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_REF_LIMIT, CSV_LF_CSV_REF_LIMIT_CSV_LOWER, csvConfig->lowerLimit - 1UL);
827     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_REF_LIMIT, CSV_LF_CSV_REF_LIMIT_CSV_UPPER, csvConfig->upperLimit - 1UL);
828     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_MON_CTL, CSV_LF_CSV_MON_CTL_CSV_PERIOD, csvConfig->period - 1UL);
829     retVal = CY_SYSCLK_SUCCESS;
830 
831     return retVal;
832 }
833 
834 
Cy_SysClk_ClkLfCsvConfigure(cy_en_clklf_csv_ref_clk_t refClk,uint32_t accuracy)835 cy_en_sysclk_status_t Cy_SysClk_ClkLfCsvConfigure(cy_en_clklf_csv_ref_clk_t refClk, uint32_t accuracy)
836 {
837     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
838     cy_stc_clklf_csv_manual_config_t csvConfig= {0, 0, 0, 0};
839 
840     uint32_t target = CSV_MIN_TARGET_VAL;
841     uint32_t monitorFreq = Cy_SysClk_ClkLfGetFrequency();
842     uint32_t refFreq = Cy_SysClk_ClkLfCsvGetRefFrequency(refClk);
843 
844     CY_ASSERT_L1(monitorFreq > 0UL);
845 
846     if(monitorFreq > 0UL && refFreq > 0UL)
847     {
848         csvConfig.lowerLimit = target - (accuracy / 2UL);
849         csvConfig.upperLimit = target + (accuracy / 2UL);
850         csvConfig.period =  target / (refFreq / monitorFreq);
851         csvConfig.startTime = (csvConfig.period + 3UL) * (refFreq / monitorFreq) - csvConfig.upperLimit;
852         retVal= Cy_SysClk_ClkLfCsvManualConfigure(refClk, &csvConfig);
853     }
854 
855     return retVal;
856 }
857 
858 
Cy_SysClk_ClkLfCsvEnable(void)859 void Cy_SysClk_ClkLfCsvEnable(void)
860 {
861     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_REF_CTL, CSV_LF_CSV_REF_CTL_CSV_EN, 1U);
862 }
863 
864 
Cy_SysClk_ClkLfCsvDisable(void)865 void Cy_SysClk_ClkLfCsvDisable(void)
866 {
867     CY_REG32_CLR_SET(SRSS_CSV_LF_CSV_REF_CTL, CSV_LF_CSV_REF_CTL_CSV_EN, 0U);
868 }
869 
870 
Cy_SysClk_IsClkLfCsvEnabled(void)871 bool Cy_SysClk_IsClkLfCsvEnabled(void)
872 {
873     return (0UL != (SRSS_CSV_LF_CSV_REF_CTL & CSV_LF_CSV_REF_CTL_CSV_EN_Msk));
874 }
875 #endif
876 
877 
878 /* ========================================================================== */
879 /* ========================    clk_peri SECTION    ========================== */
880 /* ========================================================================== */
881 
882 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)
883 
Cy_SysClk_ClkPeriGetFrequency(void)884 uint32_t Cy_SysClk_ClkPeriGetFrequency(void)
885 {
886     uint32_t locFreq = Cy_SysClk_ClkHfGetFrequency(0UL); /* Get root frequency */
887     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider(); /* peri prescaler (1-256) */
888 
889     /* Divide the path input frequency down and return the result */
890     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
891 }
892 
Cy_SysClk_ClkPeriSetDivider(uint8_t divider)893 void Cy_SysClk_ClkPeriSetDivider(uint8_t divider)
894 {
895 #if defined (CY_IP_M7CPUSS)
896     CY_REG32_CLR_SET(CPUSS_PERI_CLOCK_CTL, CPUSS_PERI_CLOCK_CTL_INT_DIV, divider);
897 #elif defined (CY_IP_M4CPUSS)
898     CY_REG32_CLR_SET(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, divider);
899 #else
900     #error "Unsupported Core Type"
901 #endif
902 }
903 
Cy_SysClk_ClkPeriGetDivider(void)904 uint8_t Cy_SysClk_ClkPeriGetDivider(void)
905 {
906 #if defined (CY_IP_M7CPUSS)
907     return ((uint8_t)_FLD2VAL(CPUSS_PERI_CLOCK_CTL_INT_DIV, CPUSS_PERI_CLOCK_CTL));
908 #elif defined (CY_IP_M4CPUSS)
909     return ((uint8_t)_FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS_CM0_CLOCK_CTL));
910 #else
911     #error "Unsupported Core Type"
912 #endif
913 }
914 
915 #endif /* defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) */
916 
917 /* ========================================================================== */
918 /* ========================    PERI SECTION    ========================== */
919 /* ========================================================================== */
920 
921 /* TVII B-E Parts are part of CAT1A where this API is not defined */
922 #if !(defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3))
923 
924 /** \cond INTERNAL */
925 /* Mask to evaluate group number value */
926 #define CY_SYSCLK_PERI_GR_NUM_Msk (0x000000FFUL)
927 /** \endcond */
928 
Cy_SysClk_PeriGroupSetDivider(uint32_t groupNum,uint32_t divider)929 cy_en_sysclk_status_t Cy_SysClk_PeriGroupSetDivider(uint32_t groupNum, uint32_t divider)
930 {
931     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
932     uint8_t instNum = (uint8_t)(((uint32_t)groupNum & PERI_GR_INST_NUM_Msk )>>PERI_GR_INST_NUM_Pos);
933 
934     groupNum = (uint8_t)(groupNum & CY_SYSCLK_PERI_GR_NUM_Msk);
935 
936     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
937     CY_ASSERT_L1(groupNum < CY_PERI_GROUP_NR);
938 
939     if (divider <= (PERI_GR_CLOCK_CTL_INT8_DIV_Msk >> PERI_GR_CLOCK_CTL_INT8_DIV_Pos))
940     {
941         CY_REG32_CLR_SET(PERI_GR_CLOCK_CTL(instNum, groupNum), PERI_GR_CLOCK_CTL_INT8_DIV, divider);
942         retVal = CY_SYSCLK_SUCCESS;
943     }
944 
945     return retVal;
946 }
947 
948 
Cy_SysClk_PeriGroupGetDivider(uint32_t groupNum)949 uint32_t Cy_SysClk_PeriGroupGetDivider(uint32_t groupNum)
950 {
951     uint8_t instNum = (uint8_t)(((uint32_t)groupNum & PERI_GR_INST_NUM_Msk )>>PERI_GR_INST_NUM_Pos);
952 
953     groupNum = (uint8_t)(groupNum & CY_SYSCLK_PERI_GR_NUM_Msk);
954 
955     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
956     CY_ASSERT_L1(groupNum < CY_PERI_GROUP_NR);
957 
958     return(_FLD2VAL(PERI_GR_CLOCK_CTL_INT8_DIV, PERI_GR_CLOCK_CTL(instNum, groupNum)));
959 }
960 
Cy_SysClk_PeriGroupSetSlaveCtl(uint32_t groupNum,cy_en_peri_grp_sl_ctl_num_t slaveCtl,uint32_t value)961 cy_en_sysclk_status_t Cy_SysClk_PeriGroupSetSlaveCtl(uint32_t groupNum, cy_en_peri_grp_sl_ctl_num_t slaveCtl, uint32_t value)
962 {
963     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
964     uint8_t instNum = (uint8_t)(((uint32_t)groupNum & PERI_GR_INST_NUM_Msk )>>PERI_GR_INST_NUM_Pos);
965 
966     groupNum = (uint8_t)(groupNum & CY_SYSCLK_PERI_GR_NUM_Msk);
967 
968     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
969     CY_ASSERT_L1(groupNum  < CY_PERI_GROUP_NR);
970     CY_ASSERT_L1(CY_SYSCLK_IS_SL_CTL_NUM_VALID(slaveCtl));
971 
972     switch(slaveCtl)
973     {
974         case CY_SYSCLK_PERI_GROUP_SL_CTL:
975             PERI_GR_SL_CTL(instNum, groupNum) = value;
976             retVal = CY_SYSCLK_SUCCESS;
977             break;
978 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
979         case CY_SYSCLK_PERI_GROUP_SL_CTL2:
980             PERI_GR_SL_CTL2(instNum, groupNum) = value;
981             retVal = CY_SYSCLK_SUCCESS;
982             break;
983         case CY_SYSCLK_PERI_GROUP_SL_CTL3:
984             /* Writes not allowed on SL_CTL3 */
985             retVal = CY_SYSCLK_BAD_PARAM;
986             break;
987 #endif
988         default:
989             retVal = CY_SYSCLK_BAD_PARAM;
990             break;
991     }
992 
993     return retVal;
994 }
995 
996 
Cy_SysClk_PeriGroupGetSlaveCtl(uint32_t groupNum,cy_en_peri_grp_sl_ctl_num_t slaveCtl)997 uint32_t Cy_SysClk_PeriGroupGetSlaveCtl(uint32_t groupNum, cy_en_peri_grp_sl_ctl_num_t slaveCtl)
998 {
999     uint32_t retVal = 0;
1000     uint8_t instNum = (uint8_t)(((uint32_t)groupNum & PERI_GR_INST_NUM_Msk )>>PERI_GR_INST_NUM_Pos);
1001 
1002     groupNum = (uint8_t)(groupNum & CY_SYSCLK_PERI_GR_NUM_Msk);
1003 
1004     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
1005     CY_ASSERT_L1(groupNum < CY_PERI_GROUP_NR);
1006     CY_ASSERT_L1(CY_SYSCLK_IS_SL_CTL_NUM_VALID(slaveCtl));
1007 
1008     switch(slaveCtl)
1009     {
1010         case CY_SYSCLK_PERI_GROUP_SL_CTL:
1011             retVal = PERI_GR_SL_CTL(instNum, groupNum);
1012             break;
1013 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
1014         case CY_SYSCLK_PERI_GROUP_SL_CTL2:
1015             retVal = PERI_GR_SL_CTL2(instNum, groupNum);
1016             break;
1017         case CY_SYSCLK_PERI_GROUP_SL_CTL3:
1018             retVal = PERI_GR_SL_CTL3(instNum, groupNum);
1019             break;
1020 #endif
1021         default:
1022             retVal = (uint32_t)CY_SYSCLK_BAD_PARAM;
1023             break;
1024     }
1025 
1026     return retVal;
1027 }
1028 
Cy_SysClk_IsPeriGroupSlaveCtlSet(uint32_t groupNum,cy_en_peri_grp_sl_ctl_num_t slaveCtl,uint32_t slaveMsk)1029 bool Cy_SysClk_IsPeriGroupSlaveCtlSet(uint32_t groupNum,cy_en_peri_grp_sl_ctl_num_t slaveCtl, uint32_t slaveMsk)
1030 {
1031     bool retVal = false;
1032     uint8_t instNum = (uint8_t)(((uint32_t)groupNum & PERI_GR_INST_NUM_Msk )>>PERI_GR_INST_NUM_Pos);
1033 
1034     groupNum = (uint8_t)(groupNum & CY_SYSCLK_PERI_GR_NUM_Msk);
1035 
1036 
1037     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
1038     CY_ASSERT_L1(groupNum < CY_PERI_GROUP_NR);
1039     CY_ASSERT_L1(CY_SYSCLK_IS_SL_CTL_NUM_VALID(slaveCtl));
1040 
1041     switch(slaveCtl)
1042     {
1043         case CY_SYSCLK_PERI_GROUP_SL_CTL:
1044             if ((PERI_GR_SL_CTL(instNum, groupNum) & slaveMsk) != 0UL)
1045             {
1046                 retVal = true;
1047             }
1048             break;
1049 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
1050         case CY_SYSCLK_PERI_GROUP_SL_CTL2:
1051             if ((PERI_GR_SL_CTL2(instNum, groupNum) & slaveMsk) != 0UL)
1052             {
1053                 retVal = true;
1054             }
1055             break;
1056         case CY_SYSCLK_PERI_GROUP_SL_CTL3:
1057             if ((PERI_GR_SL_CTL3(instNum, groupNum) & slaveMsk) != 0UL)
1058             {
1059                 retVal = true;
1060             }
1061             break;
1062 #endif
1063         default:
1064             CY_ASSERT_L2(false);
1065             break;
1066     }
1067 
1068     return retVal;
1069 }
1070 
1071 #if  defined (CY_IP_MXS22SRSS)
Cy_SysClk_PeriGroupSlaveInit(uint32_t periNum,uint32_t groupNum,uint32_t slaveNum,uint32_t clkHfNum)1072 void Cy_SysClk_PeriGroupSlaveInit(uint32_t periNum, uint32_t groupNum, uint32_t slaveNum, uint32_t clkHfNum)
1073 {
1074     CY_ASSERT_L1(periNum < PERI_INSTANCE_COUNT);
1075     CY_ASSERT_L1(groupNum  < CY_PERI_GROUP_NR);
1076     CY_ASSERT_L1(clkHfNum < CY_SRSS_NUM_HFROOT);
1077     CY_ASSERT_L1(slaveNum < 32U);
1078 
1079     if(false == Cy_SysClk_ClkHfIsEnabled(clkHfNum))
1080     {
1081         (void)Cy_SysClk_ClkHfEnable(clkHfNum);         /* Suppress a compiler warning about unused return value */
1082     }
1083 
1084     /* Release reset for the IP */
1085     PERI_GR_SL_CTL2(periNum, groupNum) &= ~(0x1UL << slaveNum);
1086 
1087     /* Enable IP */
1088     PERI_GR_SL_CTL(periNum, groupNum) |= (0x1UL << slaveNum);
1089 }
1090 
Cy_SysClk_PeriGroupSlaveDeinit(uint32_t periNum,uint32_t groupNum,uint32_t slaveNum)1091 void Cy_SysClk_PeriGroupSlaveDeinit(uint32_t periNum, uint32_t groupNum, uint32_t slaveNum)
1092 {
1093     CY_ASSERT_L1(periNum < PERI_INSTANCE_COUNT);
1094     CY_ASSERT_L1(groupNum  < CY_PERI_GROUP_NR);
1095     CY_ASSERT_L1(slaveNum < 32U);
1096 
1097     /* Release reset for the IP */
1098     PERI_GR_SL_CTL(periNum, groupNum) &= ~(0x1UL << slaveNum);
1099 }
1100 #endif
1101 
1102 #endif /* !defined (CY_DEVICE_TVIIBE) */
1103 
1104 /* ========================================================================== */
1105 /* =========================    clk_fast SECTION    ========================= */
1106 /* ========================================================================== */
1107 
1108 #if defined (CY_IP_MXS40SRSS) && defined (CY_IP_M7CPUSS)
1109 
Cy_SysClk_ClkFastSrcGetFrequency(uint32_t clkFastNum)1110 uint32_t Cy_SysClk_ClkFastSrcGetFrequency(uint32_t clkFastNum)
1111 {
1112     uint32_t freq = Cy_SysClk_ClkHfGetFrequency(CY_SYSCLK_CLK_FAST_HF_NUM); /* Get root frequency */
1113     uint32_t integer = 0UL;        /* Integer part of peripheral divider */
1114     uint32_t locFrac;
1115     uint32_t locDiv;
1116     uint64_t locFreq = freq * 32ULL;
1117 
1118     Cy_SysClk_ClkFastSrcGetDivider(clkFastNum, &integer, &locFrac);
1119     /* For fractional dividers, the divider is (int + 1) + frac/32 */
1120     locDiv = ((1UL + integer) * 32UL) + locFrac;
1121 
1122     return (uint32_t) CY_SYSLIB_DIV_ROUND(locFreq, (uint64_t)locDiv);
1123 }
1124 
Cy_SysClk_ClkFastSrcSetDivider(uint32_t clkFastNum,uint8_t intDiv,uint8_t fracDiv)1125 void Cy_SysClk_ClkFastSrcSetDivider(uint32_t clkFastNum, uint8_t intDiv, uint8_t fracDiv)
1126 {
1127     if(0UL == clkFastNum)
1128     {
1129         CY_REG32_CLR_SET(CPUSS_FAST_0_CLOCK_CTL, CPUSS_FAST_0_CLOCK_CTL_INT_DIV, intDiv);
1130         CY_REG32_CLR_SET(CPUSS_FAST_0_CLOCK_CTL, CPUSS_FAST_0_CLOCK_CTL_FRAC_DIV, fracDiv);
1131     }
1132     else
1133     {
1134         CY_REG32_CLR_SET(CPUSS_FAST_1_CLOCK_CTL, CPUSS_FAST_1_CLOCK_CTL_INT_DIV, intDiv);
1135         CY_REG32_CLR_SET(CPUSS_FAST_1_CLOCK_CTL, CPUSS_FAST_1_CLOCK_CTL_FRAC_DIV, fracDiv);
1136     }
1137 }
1138 
Cy_SysClk_ClkFastSrcGetDivider(uint32_t clkFastNum,uint32_t * dividerIntValue,uint32_t * dividerFracValue)1139 void Cy_SysClk_ClkFastSrcGetDivider(uint32_t clkFastNum, uint32_t *dividerIntValue, uint32_t *dividerFracValue)
1140 {
1141     if(0UL == clkFastNum)
1142     {
1143         *dividerIntValue = ((uint8_t)_FLD2VAL(CPUSS_FAST_0_CLOCK_CTL_INT_DIV, CPUSS_FAST_0_CLOCK_CTL));
1144         *dividerFracValue = ((uint8_t)_FLD2VAL(CPUSS_FAST_0_CLOCK_CTL_FRAC_DIV, CPUSS_FAST_0_CLOCK_CTL));
1145     }
1146     else
1147     {
1148         *dividerIntValue = ((uint8_t)_FLD2VAL(CPUSS_FAST_1_CLOCK_CTL_INT_DIV, CPUSS_FAST_1_CLOCK_CTL));
1149         *dividerFracValue = ((uint8_t)_FLD2VAL(CPUSS_FAST_1_CLOCK_CTL_FRAC_DIV, CPUSS_FAST_1_CLOCK_CTL));
1150     }
1151 }
1152 
1153 #endif /* defined (CY_IP_MXS40SRSS) && defined (CY_IP_M7CPUSS) */
1154 
1155 #if defined (CY_IP_MXS40SRSS) && defined (CY_IP_M4CPUSS)
1156 
Cy_SysClk_ClkFastGetFrequency(void)1157 uint32_t Cy_SysClk_ClkFastGetFrequency(void)
1158 {
1159     uint32_t locFreq = Cy_SysClk_ClkHfGetFrequency(0UL); /* Get root frequency */
1160     uint32_t locDiv = 1UL + (uint32_t)Cy_SysClk_ClkFastGetDivider(); /* fast prescaler (1-256) */
1161 
1162     /* Divide the path input frequency down and return the result */
1163     return (CY_SYSLIB_DIV_ROUND(locFreq, locDiv));
1164 }
1165 
1166 
Cy_SysClk_ClkFastSetDivider(uint8_t divider)1167 void Cy_SysClk_ClkFastSetDivider(uint8_t divider)
1168 {
1169 #if defined (CY_DEVICE_SECURE)
1170     cy_en_pra_status_t retStatus;
1171     retStatus = CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY, CY_PRA_CLK_FUNC_FAST_SET_DIVIDER, divider);
1172 
1173     if (retStatus != CY_PRA_STATUS_SUCCESS)
1174     {
1175         CY_ASSERT_L1(false);
1176     }
1177 #endif /* defined (CY_DEVICE_SECURE) */
1178 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1179     CY_REG32_CLR_SET(CPUSS_CM4_CLOCK_CTL, CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, divider);
1180 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1181 }
1182 
1183 
Cy_SysClk_ClkFastGetDivider(void)1184 uint8_t Cy_SysClk_ClkFastGetDivider(void)
1185 {
1186     return ((uint8_t)_FLD2VAL(CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, CPUSS_CM4_CLOCK_CTL));
1187 }
1188 
1189 #endif /* defined (CY_IP_MXS40SRSS) && defined (CY_IP_M4CPUSS) */
1190 
1191 /* ========================================================================== */
1192 /* =========================    clkHf[n] SECTION    ========================= */
1193 /* ========================================================================== */
1194 
Cy_SysClk_ClkHfEnable(uint32_t clkHf)1195 cy_en_sysclk_status_t Cy_SysClk_ClkHfEnable(uint32_t clkHf)
1196 {
1197     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1198     uint32_t hfFreq = Cy_SysClk_ClkHfGetFrequency(clkHf);
1199 
1200     if(clkHf < CY_SRSS_NUM_HFROOT)
1201     {
1202         if (hfFreq <= CY_SYSCLK_HF_MAX_FREQ(clkHf))
1203         {
1204             SRSS_CLK_ROOT_SELECT[clkHf] |= SRSS_CLK_ROOT_SELECT_ENABLE_Msk;
1205             retVal = CY_SYSCLK_SUCCESS;
1206         }
1207         else
1208         {
1209             retVal = CY_SYSCLK_INVALID_STATE;
1210         }
1211     }
1212 
1213     return (retVal);
1214 }
1215 
1216 
Cy_SysClk_ClkHfIsEnabled(uint32_t clkHf)1217 bool Cy_SysClk_ClkHfIsEnabled(uint32_t clkHf)
1218 {
1219     bool retVal = false;
1220     if (clkHf < CY_SRSS_NUM_HFROOT)
1221     {
1222         retVal = _FLD2BOOL(SRSS_CLK_ROOT_SELECT_ENABLE, SRSS_CLK_ROOT_SELECT[clkHf]);
1223     }
1224     return (retVal);
1225 }
1226 
Cy_SysClk_ClkHfDisable(uint32_t clkHf)1227 cy_en_sysclk_status_t Cy_SysClk_ClkHfDisable(uint32_t clkHf)
1228 {
1229     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1230     if ((0UL < clkHf) /* prevent CLK_HF0 disabling */
1231            && (clkHf < CY_SRSS_NUM_HFROOT))
1232     {
1233         SRSS_CLK_ROOT_SELECT[clkHf] &= ~SRSS_CLK_ROOT_SELECT_ENABLE_Msk;
1234         retVal = CY_SYSCLK_SUCCESS;
1235     }
1236     return (retVal);
1237 }
1238 
1239 
Cy_SysClk_ClkHfSetSource(uint32_t clkHf,cy_en_clkhf_in_sources_t source)1240 cy_en_sysclk_status_t Cy_SysClk_ClkHfSetSource(uint32_t clkHf, cy_en_clkhf_in_sources_t source)
1241 {
1242     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1243     if ((clkHf < CY_SRSS_NUM_HFROOT) && (source <= CY_SYSCLK_CLKHF_IN_CLKPATH15))
1244     {
1245         CY_REG32_CLR_SET(SRSS_CLK_ROOT_SELECT[clkHf], SRSS_CLK_ROOT_SELECT_ROOT_MUX, source);
1246         retVal = CY_SYSCLK_SUCCESS;
1247     }
1248     return (retVal);
1249 }
1250 
1251 
Cy_SysClk_ClkHfGetSource(uint32_t clkHf)1252 cy_en_clkhf_in_sources_t Cy_SysClk_ClkHfGetSource(uint32_t clkHf)
1253 {
1254     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1255     return ((cy_en_clkhf_in_sources_t)((uint32_t)(_FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_MUX, SRSS_CLK_ROOT_SELECT[clkHf]))));
1256 }
1257 
1258 
Cy_SysClk_ClkHfSetDivider(uint32_t clkHf,cy_en_clkhf_dividers_t divider)1259 cy_en_sysclk_status_t Cy_SysClk_ClkHfSetDivider(uint32_t clkHf, cy_en_clkhf_dividers_t divider)
1260 {
1261     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1262     if ((clkHf < CY_SRSS_NUM_HFROOT) && (divider < CY_SYSCLK_CLKHF_MAX_DIVIDER))
1263     {
1264         CY_REG32_CLR_SET(SRSS_CLK_ROOT_SELECT[clkHf], SRSS_CLK_ROOT_SELECT_ROOT_DIV, divider);
1265         retVal = CY_SYSCLK_SUCCESS;
1266     }
1267     return (retVal);
1268 }
1269 
1270 
Cy_SysClk_ClkHfGetDivider(uint32_t clkHf)1271 cy_en_clkhf_dividers_t Cy_SysClk_ClkHfGetDivider(uint32_t clkHf)
1272 {
1273     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1274 #if (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
1275     return ((cy_en_clkhf_dividers_t)(((uint32_t)_FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV_INT, SRSS_CLK_ROOT_SELECT[clkHf]))));
1276 #else
1277     return ((cy_en_clkhf_dividers_t)(((uint32_t)_FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV, SRSS_CLK_ROOT_SELECT[clkHf]))));
1278 #endif
1279 }
1280 
Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)1281 uint32_t Cy_SysClk_ClkHfGetFrequency(uint32_t clkHf)
1282 {
1283     /* variables holding intermediate clock frequencies, dividers and FLL/PLL settings */
1284 #if defined (CY_IP_MXS22SRSS) || (defined (CY_MXS40SSRSS_VER_1_2) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
1285     uint32_t pDiv = (uint32_t)Cy_SysClk_ClkHfGetDivider(clkHf) + 1U; /* root prescaler */
1286 #else
1287     uint32_t pDiv = 1UL << (uint32_t)Cy_SysClk_ClkHfGetDivider(clkHf); /* root prescaler */
1288 #endif
1289     uint32_t path = (uint32_t) Cy_SysClk_ClkHfGetSource(clkHf); /* path input for root 0 (clkHf[0]) */
1290     uint32_t freq = Cy_SysClk_ClkPathGetFrequency(path);
1291 
1292     /* Divide the path input frequency down and return the result */
1293 #if defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3))
1294     if(Cy_SysClk_IsClkHfDirectSelEnabled(clkHf))
1295     {
1296         return (CY_SYSCLK_IMO_FREQ);
1297     }
1298     else
1299     {
1300         return (CY_SYSLIB_DIV_ROUND(freq, pDiv));
1301     }
1302 #else
1303         return (CY_SYSLIB_DIV_ROUND(freq, pDiv));
1304 #endif
1305 }
1306 
1307 #if defined (CY_IP_MXS22SRSS)
Cy_SysClk_ClkHfGetMaskOnPath(cy_en_clkhf_in_sources_t clkPath)1308 uint32_t Cy_SysClk_ClkHfGetMaskOnPath(cy_en_clkhf_in_sources_t clkPath)
1309 {
1310   uint32_t clkHfMask = 0;
1311   if (clkPath <= CY_SYSCLK_CLKHF_IN_CLKPATH15)
1312   {
1313     for (uint32_t i = 0; i < CY_SRSS_NUM_HFROOT; i++)
1314     {
1315       bool enabled;
1316       cy_en_clkhf_in_sources_t src;
1317       enabled = Cy_SysClk_ClkHfIsEnabled(i);
1318       if (enabled)
1319       {
1320         src = Cy_SysClk_ClkHfGetSource(i);
1321         if (src == clkPath)
1322         {
1323           clkHfMask |= (1UL  << i);
1324         }
1325       }
1326     }
1327   }
1328   return clkHfMask;
1329 }
1330 
Cy_SysClk_ClkHfAllGetMask(void)1331 uint32_t Cy_SysClk_ClkHfAllGetMask(void)
1332 {
1333     uint32_t clkHfMask = 0;
1334     for (uint32_t i = 0; i < CY_SRSS_NUM_HFROOT; i++)
1335     {
1336         bool enabled;
1337         enabled = Cy_SysClk_ClkHfIsEnabled(i);
1338         if (enabled)
1339         {
1340             clkHfMask |= (1UL  << i);
1341         }
1342       }
1343   return clkHfMask;
1344 }
1345 
Cy_SysClk_ClkHfEnableDividerWithMask(uint32_t clkHfMask,cy_en_clkhf_dividers_t divider)1346 void Cy_SysClk_ClkHfEnableDividerWithMask(uint32_t clkHfMask, cy_en_clkhf_dividers_t divider)
1347 {
1348     uint32_t clkHf = 0UL;
1349 
1350     if (clkHfMask != 0UL)
1351     {
1352         while (clkHfMask != 0UL)
1353         {
1354             if ((clkHfMask & 1UL) != 0UL)
1355             {
1356                 /* disable/disable root selection and enable clock path */
1357                 (void)Cy_SysClk_ClkHfSetDivider(clkHf, divider);
1358             }
1359             clkHfMask = clkHfMask >> 1;
1360             clkHf++;
1361         }
1362     }
1363 }
1364 
Cy_SysClk_ClkHfEnableDirectMuxWithMask(uint32_t clkHfMask,bool enable)1365 void Cy_SysClk_ClkHfEnableDirectMuxWithMask(uint32_t clkHfMask, bool enable)
1366 {
1367   uint32_t clkHf = 0UL;
1368 
1369   if (clkHfMask != 0UL)
1370   {
1371     while (clkHfMask != 0UL)
1372     {
1373       if ((clkHfMask & 1UL) != 0UL)
1374       {
1375         /* disable/disable root selection and enable clock path */
1376         (void)Cy_SysClk_ClkHfDirectSel(clkHf, enable);
1377       }
1378       clkHfMask = clkHfMask >> 1;
1379       clkHf++;
1380     }
1381   }
1382 }
1383 #endif /*  defined (CY_IP_MXS22SRSS) */
1384 
1385 #if defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
1386 
Cy_SysClk_ClkHfDirectSel(uint32_t clkHf,bool enable)1387 cy_en_sysclk_status_t Cy_SysClk_ClkHfDirectSel(uint32_t clkHf, bool enable)
1388 {
1389     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1390     if (clkHf < CY_SRSS_NUM_HFROOT)
1391     {
1392         CY_REG32_CLR_SET(SRSS_CLK_DIRECT_SELECT[clkHf], SRSS_CLK_DIRECT_SELECT_DIRECT_MUX, !(enable));
1393         retVal = CY_SYSCLK_SUCCESS;
1394     }
1395     return (retVal);
1396 }
1397 
Cy_SysClk_IsClkHfDirectSelEnabled(uint32_t clkHf)1398 bool Cy_SysClk_IsClkHfDirectSelEnabled(uint32_t clkHf)
1399 {
1400     bool retVal = false;
1401     if (clkHf < CY_SRSS_NUM_HFROOT)
1402     {
1403         return !(_FLD2BOOL(SRSS_CLK_DIRECT_SELECT_DIRECT_MUX, SRSS_CLK_DIRECT_SELECT[clkHf]));
1404     }
1405     return (retVal);
1406 }
1407 
1408 #elif (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3))
Cy_SysClk_ClkHfDirectSel(uint32_t clkHf,bool enable)1409 cy_en_sysclk_status_t Cy_SysClk_ClkHfDirectSel(uint32_t clkHf, bool enable)
1410 {
1411     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1412     if (clkHf < CY_SRSS_NUM_HFROOT)
1413     {
1414         CY_REG32_CLR_SET(SRSS_CLK_ROOT_SELECT[clkHf], SRSS_CLK_ROOT_SELECT_DIRECT_MUX, !(enable));
1415         retVal = CY_SYSCLK_SUCCESS;
1416     }
1417     return (retVal);
1418 }
1419 
Cy_SysClk_IsClkHfDirectSelEnabled(uint32_t clkHf)1420 bool Cy_SysClk_IsClkHfDirectSelEnabled(uint32_t clkHf)
1421 {
1422     bool retVal = false;
1423     if (clkHf < CY_SRSS_NUM_HFROOT)
1424     {
1425         return !(_FLD2BOOL(SRSS_CLK_ROOT_SELECT_DIRECT_MUX, SRSS_CLK_ROOT_SELECT[clkHf]));
1426     }
1427     return (retVal);
1428 }
1429 
1430 #endif /* defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS) */
1431 
1432 #if defined (CY_IP_MXS22SRSS) || (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
Cy_SysClk_ClkHfCsvGetRefFrequency(cy_en_clkhf_csv_ref_clk_t refClk)1433 uint32_t Cy_SysClk_ClkHfCsvGetRefFrequency(cy_en_clkhf_csv_ref_clk_t refClk)
1434  {
1435     uint32_t freq = 0UL;
1436 
1437     /* Get the frequency of the source  */
1438     switch(refClk)
1439      {
1440         case CY_SYSCLK_CLKHF_CSV_REF_IMO: /* The IMO frequency is fixed at 8 MHz */
1441             freq = CY_SYSCLK_IMO_FREQ;
1442             break;
1443 
1444         case CY_SYSCLK_CLKHF_CSV_REF_EXT:
1445             freq = Cy_SysClk_ExtClkGetFrequency();
1446             break;
1447 
1448         case CY_SYSCLK_CLKHF_CSV_REF_ECO:
1449             freq = Cy_SysClk_EcoGetFrequency();
1450             break;
1451 
1452         case CY_SYSCLK_CLKHF_CSV_REF_IHO:
1453             freq = (Cy_SysClk_IhoIsEnabled()) ? CY_SYSCLK_IHO_FREQ : 0UL;
1454             break;
1455 
1456         default:
1457             /* Don't know the frequency of dsi_out, leave freq = 0UL */
1458             break;
1459      }
1460     return (freq);
1461  }
1462 
1463 
Cy_SysClk_ClkHfCsvManualConfigure(const cy_stc_clkhf_csv_hf_config_t * hfConfig,const cy_stc_clkhf_csv_manual_config_t * csvConfig)1464 cy_en_sysclk_status_t Cy_SysClk_ClkHfCsvManualConfigure(const cy_stc_clkhf_csv_hf_config_t * hfConfig, const cy_stc_clkhf_csv_manual_config_t * csvConfig)
1465 {
1466     /* Check for errors */
1467     CY_ASSERT_L1(hfConfig != NULL);
1468     CY_ASSERT_L1(csvConfig != NULL);
1469     CY_ASSERT_L1(hfConfig->clkHf < CY_SRSS_NUM_HFROOT);
1470 
1471     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1472     uint32_t monitorFreq = Cy_SysClk_ClkHfGetFrequency(hfConfig->clkHf);
1473     uint32_t refFreq = Cy_SysClk_ClkHfCsvGetRefFrequency(hfConfig->refClk);
1474 
1475     CY_ASSERT_L1(csvConfig->upperLimit > CSV_MIN_TARGET_VAL);
1476     CY_ASSERT_L1(csvConfig->lowerLimit < csvConfig->upperLimit -1U);
1477     CY_ASSERT_L1(csvConfig->startTime >= ((csvConfig->period +3UL) * (refFreq / monitorFreq)) - csvConfig->upperLimit);
1478 
1479     (void) monitorFreq; /* Used only in Assert comparison. */
1480     (void) refFreq;  /* Used only in Assert comparison.  */
1481 
1482     if(hfConfig->clkHf < CY_SRSS_NUM_HFROOT)
1483     {
1484         CY_REG32_CLR_SET(SRSS_CSV_REF_SEL, SRSS_CSV_REF_SEL_REF_MUX, hfConfig->refClk);
1485         CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_CTL(hfConfig->clkHf), CSV_HF_CSV_REF_CTL_CSV_STARTUP, csvConfig->startTime - 1UL);
1486         CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_LIMIT(hfConfig->clkHf), CSV_HF_CSV_REF_LIMIT_CSV_LOWER, csvConfig->lowerLimit - 1UL);
1487         CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_LIMIT(hfConfig->clkHf), CSV_HF_CSV_REF_LIMIT_CSV_UPPER, csvConfig->upperLimit - 1UL);
1488         CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_MON_CTL(hfConfig->clkHf), CSV_HF_CSV_MON_CTL_CSV_PERIOD, csvConfig->period - 1UL);
1489         retVal = CY_SYSCLK_SUCCESS;
1490     }
1491 
1492     return retVal;
1493 }
1494 
1495 
Cy_SysClk_ClkHfCsvConfigure(const cy_stc_clkhf_csv_hf_config_t * hfConfig,uint32_t accuracy)1496 cy_en_sysclk_status_t Cy_SysClk_ClkHfCsvConfigure(const cy_stc_clkhf_csv_hf_config_t * hfConfig, uint32_t accuracy)
1497 {
1498     CY_ASSERT_L1(hfConfig != NULL);
1499     CY_ASSERT_L1(hfConfig->clkHf < CY_SRSS_NUM_HFROOT);
1500 
1501     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
1502     cy_stc_clkhf_csv_manual_config_t csvConfig= {0, 0, 0, 0};
1503 
1504     if(hfConfig->clkHf < CY_SRSS_NUM_HFROOT)
1505     {
1506         uint32_t target = CSV_MIN_TARGET_VAL;
1507         uint32_t monitorFreq = Cy_SysClk_ClkHfGetFrequency(hfConfig->clkHf);
1508         uint32_t refFreq = Cy_SysClk_ClkHfCsvGetRefFrequency(hfConfig->refClk);
1509         csvConfig.lowerLimit = target - (accuracy / 2UL);
1510         csvConfig.upperLimit = target + (accuracy / 2UL);
1511         csvConfig.period =  target / (refFreq / monitorFreq);
1512         csvConfig.startTime = (csvConfig.period + 3UL) * (refFreq / monitorFreq) - csvConfig.upperLimit;
1513 
1514         retVal= Cy_SysClk_ClkHfCsvManualConfigure(hfConfig, &csvConfig);
1515     }
1516     return retVal;
1517 }
1518 
1519 
Cy_SysClk_ClkHfCsvAction(uint32_t clkHf,cy_en_clkhf_csv_action_t action)1520 void Cy_SysClk_ClkHfCsvAction(uint32_t clkHf, cy_en_clkhf_csv_action_t action)
1521 {
1522     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1523     CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_CTL(clkHf), CSV_HF_CSV_REF_CTL_CSV_ACTION, action);
1524 }
1525 
1526 
Cy_SysClk_ClkHfCsvEnable(uint32_t clkHf)1527 void Cy_SysClk_ClkHfCsvEnable(uint32_t clkHf)
1528 {
1529     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1530     CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_CTL(clkHf), CSV_HF_CSV_REF_CTL_CSV_EN, 1U);
1531 }
1532 
1533 
Cy_SysClk_ClkHfCsvDisable(uint32_t clkHf)1534 void Cy_SysClk_ClkHfCsvDisable(uint32_t clkHf)
1535 {
1536     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1537     CY_REG32_CLR_SET(SRSS_CSV_HF_CSV_REF_CTL(clkHf), CSV_HF_CSV_REF_CTL_CSV_EN, 0U);
1538 }
1539 
1540 
Cy_SysClk_IsClkHfCsvEnabled(uint32_t clkHf)1541 bool Cy_SysClk_IsClkHfCsvEnabled(uint32_t clkHf)
1542 {
1543     CY_ASSERT_L1(clkHf < CY_SRSS_NUM_HFROOT);
1544     return (0UL != (SRSS_CSV_HF_CSV_REF_CTL(clkHf) & CSV_HF_CSV_REF_CTL_CSV_EN_Msk));
1545 }
1546 #endif
1547 
1548 /* ========================================================================== */
1549 /* ============================    MFO SECTION    ============================ */
1550 /* ========================================================================== */
1551 
1552 #if defined (CY_IP_MXS40SSRSS)
1553 
Cy_SysClk_MfoEnable(bool deepSleepEnable)1554 void Cy_SysClk_MfoEnable(bool deepSleepEnable)
1555 {
1556 #if (defined(CY_SRSS_MFO_PRESENT) && (CY_SRSS_MFO_PRESENT))
1557 #if defined (CY_IP_MXS28SRSS)
1558     SRSS_CLK_MFO_CONFIG = SRSS_CLK_MFO_CONFIG_ENABLE_Msk;
1559 #else
1560     SRSS_CLK_MFO_CONFIG = SRSS_CLK_MFO_CONFIG_ENABLE_Msk | (deepSleepEnable ? SRSS_CLK_MFO_CONFIG_DPSLP_ENABLE_Msk : 0UL);
1561 #endif
1562 #endif
1563     (void) deepSleepEnable;
1564 }
1565 
Cy_SysClk_MfoIsEnabled(void)1566 bool Cy_SysClk_MfoIsEnabled(void)
1567 {
1568 #if (defined(CY_SRSS_MFO_PRESENT) && (CY_SRSS_MFO_PRESENT))
1569     return (0UL != (SRSS_CLK_MFO_CONFIG & SRSS_CLK_MFO_CONFIG_ENABLE_Msk));
1570 #else
1571     return false;
1572 #endif
1573 
1574 }
1575 
Cy_SysClk_MfoDisable(void)1576 void Cy_SysClk_MfoDisable(void)
1577 {
1578 #if (defined(CY_SRSS_MFO_PRESENT) && (CY_SRSS_MFO_PRESENT))
1579     SRSS_CLK_MFO_CONFIG = 0UL;
1580 #endif
1581 }
1582 #endif
1583 
1584 /* ========================================================================== */
1585 /* ============================    CLK_MF SECTION    ============================ */
1586 /* ========================================================================== */
1587 
1588 #if defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS28SRSS)
1589 
Cy_SysClk_ClkMfEnable(void)1590 void Cy_SysClk_ClkMfEnable(void)
1591 {
1592     SRSS_CLK_MF_SELECT |= SRSS_CLK_MF_SELECT_ENABLE_Msk;
1593 }
1594 
1595 
Cy_SysClk_ClkMfIsEnabled(void)1596 bool Cy_SysClk_ClkMfIsEnabled(void)
1597 {
1598     return ((0UL != (SRSS_CLK_MF_SELECT & SRSS_CLK_MF_SELECT_ENABLE_Msk)));
1599 }
1600 
1601 
Cy_SysClk_ClkMfDisable(void)1602 void Cy_SysClk_ClkMfDisable(void)
1603 {
1604     SRSS_CLK_MF_SELECT &= ~SRSS_CLK_MF_SELECT_ENABLE_Msk;
1605 }
1606 
1607 
Cy_SysClk_ClkMfSetDivider(uint32_t divider)1608 void Cy_SysClk_ClkMfSetDivider(uint32_t divider)
1609 {
1610     if (CY_SYSCLK_IS_MF_DIVIDER_VALID(divider))
1611     {
1612         if (!Cy_SysClk_ClkMfIsEnabled())
1613         {
1614             CY_REG32_CLR_SET(SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_MFCLK_DIV, divider - 1UL);
1615         }
1616     }
1617 }
1618 
1619 
Cy_SysClk_ClkMfGetDivider(void)1620 uint32_t Cy_SysClk_ClkMfGetDivider(void)
1621 {
1622     return ((1UL + _FLD2VAL(SRSS_CLK_MF_SELECT_MFCLK_DIV, SRSS_CLK_MF_SELECT)));
1623 }
1624 
1625 
Cy_SysClk_ClkMfGetFrequency(void)1626 uint32_t Cy_SysClk_ClkMfGetFrequency(void)
1627 {
1628     uint32_t mfFreq = 0UL, mfDiv;
1629 
1630       /* Get the frequency of the source, i.e., the path mux input */
1631         switch(Cy_SysClk_ClkMfGetSource())
1632         {
1633 #if defined(CY_IP_MXS22SRSS)
1634             case CY_SYSCLK_CLKMF_IN_IMO: /* The IMO frequency is fixed at 8 MHz */
1635                 mfFreq = CY_SYSCLK_IMO_FREQ;
1636                 break;
1637 #else
1638             case CY_SYSCLK_CLKMF_IN_MFO: /* The IMO frequency is fixed at 8 MHz */
1639                 mfFreq =(Cy_SysClk_MfoIsEnabled()) ? CY_SYSCLK_MFO_FREQ : 0UL;
1640                 break;
1641 #endif
1642             case CY_SYSCLK_CLKMF_IN_ILO:
1643                 mfFreq = CY_SYSCLK_ILO_FREQ;
1644                 break;
1645 
1646             case CY_SYSCLK_CLKMF_IN_WCO:
1647                 mfFreq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
1648                 break;
1649 
1650 #if (defined (CY_SRSS_ALTHF_PRESENT) && (CY_SRSS_ALTHF_PRESENT == 1U))
1651             case CY_SYSCLK_CLKMF_IN_ALTLF:
1652                 mfFreq = (Cy_SysClk_IsAltHfEnabled()) ? Cy_SysClk_AltHfGetFrequency() : 0UL;
1653                 break;
1654 #endif
1655 
1656             case CY_SYSCLK_CLKMF_IN_PILO:
1657                 mfFreq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
1658                 break;
1659 
1660 #if defined(CY_IP_MXS22SRSS)
1661             case CY_SYSCLK_CLKMF_IN_IHO:
1662                 mfFreq = CY_SYSCLK_IHO_FREQ;
1663                 break;
1664 #endif
1665 
1666             default:
1667                 /* Don't know the frequency of dsi_out, leave freq = 0UL */
1668                 break;
1669         }
1670 
1671     mfDiv = Cy_SysClk_ClkMfGetDivider(); /* clkMf prescaler (1-256) */
1672 
1673     /* Divide the path input frequency down and return the result */
1674     return (CY_SYSLIB_DIV_ROUND(mfFreq, mfDiv));
1675 }
1676 
Cy_SysClk_ClkMfSetSource(cy_en_clkmf_in_sources_t source)1677 void Cy_SysClk_ClkMfSetSource(cy_en_clkmf_in_sources_t source)
1678 {
1679     CY_ASSERT_L3(CY_SYSCLK_IF_MF_SOURCE_VALID(source));
1680     CY_REG32_CLR_SET(SRSS_CLK_MF_SELECT, SRSS_CLK_MF_SELECT_MFCLK_SEL, source);
1681 }
1682 
1683 
Cy_SysClk_ClkMfGetSource(void)1684 cy_en_clkmf_in_sources_t Cy_SysClk_ClkMfGetSource(void)
1685 {
1686     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_clkmf_in_sources_t enum.');
1687     return ((cy_en_clkmf_in_sources_t)(_FLD2VAL(SRSS_CLK_MF_SELECT_MFCLK_SEL, SRSS_CLK_MF_SELECT)));
1688 }
1689 
1690 #endif /* defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS28SRSS) */
1691 
1692 /* ========================================================================== */
1693 /* ===========================    WCO SECTION    =========================== */
1694 /* ========================================================================== */
1695 
Cy_SysClk_WcoEnable(uint32_t timeoutus)1696 cy_en_sysclk_status_t Cy_SysClk_WcoEnable(uint32_t timeoutus)
1697 {
1698     cy_en_sysclk_status_t retVal = CY_SYSCLK_TIMEOUT;
1699 
1700     /* Enable WCO */
1701 #if defined (CY_IP_MXS28SRSS)
1702     BACKUP_WCO_CTL |= BACKUP_WCO_CTL_WCO_EN_Msk;
1703 #elif defined (CY_IP_MXS22SRSS)
1704     BACKUP_CTL |= SRSS_CLK_WCO_CONFIG_WCO_EN_Msk;
1705 #else
1706     BACKUP_CTL |= BACKUP_CTL_WCO_EN_Msk;
1707 #endif
1708 
1709     /* now do the timeout wait for STATUS, bit WCO_OK */
1710     for (; (Cy_SysClk_WcoOkay() == false) && (0UL != timeoutus); timeoutus--)
1711     {
1712         Cy_SysLib_DelayUs(1U);
1713     }
1714 
1715     if (0UL != timeoutus)
1716     {
1717         retVal = CY_SYSCLK_SUCCESS;
1718     }
1719 
1720     return (retVal);
1721 }
1722 
Cy_SysClk_WcoOkay(void)1723 bool Cy_SysClk_WcoOkay(void)
1724 {
1725 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
1726     return (_FLD2BOOL(BACKUP_STATUS_WCO_OK, BACKUP_STATUS));
1727 #elif defined (CY_IP_MXS22SRSS)
1728     return (_FLD2BOOL(SRSS_CLK_WCO_STATUS_WCO_OK, BACKUP_WCO_STATUS));
1729 #else
1730     return (_FLD2BOOL(BACKUP_WCO_STATUS_WCO_OK, BACKUP_STATUS));
1731 #endif
1732 }
1733 
Cy_SysClk_WcoDisable(void)1734 void Cy_SysClk_WcoDisable(void)
1735 {
1736 #if defined (CY_IP_MXS28SRSS)
1737     BACKUP_WCO_CTL &= (uint32_t)~BACKUP_WCO_CTL_WCO_EN_Msk;
1738 #elif defined (CY_IP_MXS22SRSS)
1739     BACKUP_CTL &= (uint32_t)~SRSS_CLK_WCO_CONFIG_WCO_EN_Msk;
1740 #else
1741     BACKUP_CTL &= (uint32_t)~BACKUP_CTL_WCO_EN_Msk;
1742 #endif
1743 }
1744 
1745 #if defined (CY_IP_MXS28SRSS)
Cy_SysClk_WcoGainControl(cy_en_wco_gain_ctrl_modes_t gmMode)1746 void Cy_SysClk_WcoGainControl(cy_en_wco_gain_ctrl_modes_t gmMode)
1747 {
1748     CY_REG32_CLR_SET(BACKUP_WCO_CTL, BACKUP_WCO_CTL_GM, gmMode);
1749 }
1750 #endif /* defined (CY_IP_MXS28SRSS) */
1751 
Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)1752 void Cy_SysClk_WcoBypass(cy_en_wco_bypass_modes_t bypass)
1753 {
1754 #if defined (CY_IP_MXS28SRSS)
1755     CY_REG32_CLR_SET(BACKUP_WCO_CTL, BACKUP_WCO_CTL_WCO_BYP_EN, bypass);
1756 #elif defined (CY_IP_MXS22SRSS)
1757     CY_REG32_CLR_SET(BACKUP_CTL, SRSS_CLK_WCO_CONFIG_WCO_BYPASS, bypass);
1758 #else
1759     CY_REG32_CLR_SET(BACKUP_CTL, BACKUP_CTL_WCO_BYPASS, bypass);
1760 #endif
1761 }
1762 
1763 /* ========================================================================== */
1764 /* ===========================    PILO SECTION    =========================== */
1765 /* ========================================================================== */
1766 
1767 #define CY_SYSCLK_PILO_STARTUP_DELAY 250U
1768 #define CY_SYSCLK_PILO_TEST_COUNT 10U
1769 #define CY_SYSCLK_PILO_TEST_DELAY 100U
1770 
Cy_SysClk_PiloEnable(void)1771 void Cy_SysClk_PiloEnable(void)
1772 {
1773 #if (defined (CY_SRSS_PILO_PRESENT) && (0U != CY_SRSS_PILO_PRESENT))
1774     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_EN_Msk; /* 1 = enable */
1775 #endif
1776 
1777     /* Max 150us is needed for PILO Startup */
1778     Cy_SysLib_DelayUs(CY_SYSCLK_PILO_STARTUP_DELAY);
1779 }
1780 #if defined (CY_IP_MXS40SSRSS)
Cy_SysClk_PiloBackupEnable(void)1781 void Cy_SysClk_PiloBackupEnable(void)
1782 {
1783 #if defined (CY_SRSS_PILO_PRESENT) && (0U != CY_SRSS_PILO_PRESENT)
1784     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_BACKUP_Msk; /* 1 = enable */
1785 #endif
1786 }
1787 
Cy_SysClk_PiloBackupDisable(void)1788 void Cy_SysClk_PiloBackupDisable(void)
1789 {
1790 #if defined (CY_SRSS_PILO_PRESENT) && (0U != CY_SRSS_PILO_PRESENT)
1791     /* Clear PILO_BACKUP bitfields. */
1792     SRSS_CLK_PILO_CONFIG &= (uint32_t)~(SRSS_CLK_PILO_CONFIG_PILO_BACKUP_Msk);
1793 #endif
1794 }
1795 #endif
1796 
1797 #if defined (CY_IP_MXS40SSRSS)
Cy_SysClk_PiloTcscEnable(void)1798 void Cy_SysClk_PiloTcscEnable(void)
1799 {
1800 #if (CY_SRSS_PILO_PRESENT)
1801     SRSS_CLK_PILO_CONFIG |= SRSS_CLK_PILO_CONFIG_PILO_TCSC_EN_Msk; /* 1 = enable */
1802 #endif
1803 }
1804 
Cy_SysClk_PiloTcscDisable(void)1805 void Cy_SysClk_PiloTcscDisable(void)
1806 {
1807 #if (CY_SRSS_PILO_PRESENT)
1808     /* Clear PILO_TCSC_EN( Second order temperature curvature correction.) bitfields. */
1809     SRSS_CLK_PILO_CONFIG &= (uint32_t)~(SRSS_CLK_PILO_CONFIG_PILO_TCSC_EN_Msk);
1810 #endif
1811 }
1812 
Cy_SysClk_PiloOkay(void)1813 bool Cy_SysClk_PiloOkay(void)
1814 {
1815 #if (CY_SRSS_PILO_PRESENT)
1816     SRSS_CLK_OUTPUT_FAST = SLOW_SEL_OUTPUT_INDEX;
1817     SRSS_CLK_OUTPUT_SLOW = (uint32_t)CY_SYSCLK_MEAS_CLK_PILO;
1818     SRSS_CLK_CAL_CNT1 = CY_SYSCLK_PILO_TEST_COUNT;
1819 
1820     /* Wait atleast two PILO clock cycles before reading CAL_CLK1_PRESENT bit */
1821     Cy_SysLib_DelayUs(CY_SYSCLK_PILO_TEST_DELAY);
1822 
1823     return (_FLD2BOOL(SRSS_CLK_CAL_CNT1_CAL_CLK1_PRESENT, SRSS_CLK_CAL_CNT1));
1824 #else
1825     return false;
1826 #endif
1827 }
1828 #endif /* defined (CY_IP_MXS40SSRSS) */
1829 
Cy_SysClk_PiloIsEnabled(void)1830 bool Cy_SysClk_PiloIsEnabled(void)
1831 {
1832 #if (defined (CY_SRSS_PILO_PRESENT) && (0U != CY_SRSS_PILO_PRESENT))
1833     return (_FLD2BOOL(SRSS_CLK_PILO_CONFIG_PILO_EN, SRSS_CLK_PILO_CONFIG));
1834 #else
1835     return false;
1836 #endif
1837 }
1838 
Cy_SysClk_PiloDisable(void)1839 void Cy_SysClk_PiloDisable(void)
1840 {
1841 #if (defined (CY_SRSS_PILO_PRESENT) && (0U != CY_SRSS_PILO_PRESENT))
1842     /* Clear PILO_EN */
1843     SRSS_CLK_PILO_CONFIG &= (uint32_t)~(SRSS_CLK_PILO_CONFIG_PILO_EN_Msk);
1844 #endif
1845 }
1846 
1847 /* ========================================================================== */
1848 /* ==========================    ALTHF SECTION    =========================== */
1849 /* ========================================================================== */
1850 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS)
Cy_SysClk_AltHfGetFrequency(void)1851 uint32_t Cy_SysClk_AltHfGetFrequency(void)
1852 {
1853     #if defined (CY_IP_MXS40BLE52SS)
1854         return Cy_BTSS_GetXtalOscFreq();
1855     #else
1856         return (0UL);
1857     #endif /* CY_IP_MXS40BLE52SS */
1858 }
1859 
Cy_SysClk_AltHfEnable(uint32_t timeoutus)1860 cy_en_sysclk_status_t Cy_SysClk_AltHfEnable(uint32_t timeoutus)
1861 {
1862     cy_en_sysclk_status_t retVal = CY_SYSCLK_TIMEOUT;
1863 
1864     CY_UNUSED_PARAMETER(timeoutus);
1865 #if (defined (CY_SRSS_ALTHF_PRESENT) && (CY_SRSS_ALTHF_PRESENT == 1U))
1866     /* Enable ALTHF */
1867     SRSS_CLK_ALTHF_CTL |= SRSS_CLK_ALTHF_CTL_ALTHF_ENABLE_Msk;
1868 
1869     /* now do the timeout for ALTHF to be enabled  */
1870     for (; (Cy_SysClk_IsAltHfEnabled() == false) && (0UL != timeoutus); timeoutus--)
1871     {
1872         Cy_SysLib_DelayUs(1U);
1873     }
1874 
1875     if (0UL != timeoutus)
1876     {
1877         retVal = CY_SYSCLK_SUCCESS;
1878     }
1879 #endif
1880 
1881     return (retVal);
1882 }
1883 
Cy_SysClk_IsAltHfEnabled(void)1884 bool Cy_SysClk_IsAltHfEnabled(void)
1885 {
1886 #if (defined (CY_SRSS_ALTHF_PRESENT) && (CY_SRSS_ALTHF_PRESENT == 1U))
1887     return (_FLD2BOOL(SRSS_CLK_ALTHF_CTL_ALTHF_ENABLED, SRSS_CLK_ALTHF_CTL));
1888 #else
1889     return false;
1890 #endif
1891 }
1892 
1893 #endif /* defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) */
1894 /* ========================================================================== */
1895 /* ==========================    ALTLF SECTION    =========================== */
1896 /* ========================================================================== */
1897 
1898 
Cy_SysClk_AltLfGetFrequency(void)1899 uint32_t Cy_SysClk_AltLfGetFrequency(void)
1900 {
1901     return (0UL);
1902 }
1903 
1904 
Cy_SysClk_AltLfIsEnabled(void)1905 bool Cy_SysClk_AltLfIsEnabled(void)
1906 {
1907     return (false);
1908 }
1909 
1910 
1911 /* ========================================================================== */
1912 /* ===========================    ILO SECTION    ============================ */
1913 /* ========================================================================== */
1914 
1915 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
1916 
1917 
1918 /* Below ILO API's are valid for both ILO0 and ILO1 */
Cy_SysClk_IloSrcEnable(uint32_t iloNum)1919 void Cy_SysClk_IloSrcEnable(uint32_t iloNum)
1920 {
1921     CY_ASSERT_L1(iloNum < CY_SRSS_ILO_COUNT);
1922 
1923     if (0UL == iloNum)
1924     {
1925         SRSS_CLK_ILO0_CONFIG |= SRSS_CLK_ILO0_CONFIG_ENABLE_Msk;
1926     }
1927     else
1928     {
1929         SRSS_CLK_ILO1_CONFIG |= SRSS_CLK_ILO1_CONFIG_ENABLE_Msk;
1930     }
1931 }
1932 
Cy_SysClk_IloSrcDisable(uint32_t iloNum)1933 cy_en_sysclk_status_t Cy_SysClk_IloSrcDisable(uint32_t iloNum)
1934 {
1935     CY_ASSERT_L1(iloNum < CY_SRSS_ILO_COUNT);
1936     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
1937 
1938     if (0UL == iloNum)
1939     {
1940         if (!_FLD2BOOL(WDT_CTL_ENABLED, SRSS_WDT_CTL)) /* if disabled */
1941         {
1942             SRSS_CLK_ILO0_CONFIG &= ~SRSS_CLK_ILO0_CONFIG_ENABLE_Msk;
1943             retVal = CY_SYSCLK_SUCCESS;
1944         }
1945     }
1946     else
1947     {
1948         SRSS_CLK_ILO1_CONFIG &= ~SRSS_CLK_ILO1_CONFIG_ENABLE_Msk;
1949         retVal = CY_SYSCLK_SUCCESS;
1950     }
1951     return (retVal);
1952 }
1953 
Cy_SysClk_IloSrcIsEnabled(uint32_t iloNum)1954 bool Cy_SysClk_IloSrcIsEnabled(uint32_t iloNum)
1955 {
1956     CY_ASSERT_L1(iloNum < CY_SRSS_ILO_COUNT);
1957 
1958     if (0UL == iloNum)
1959     {
1960         return (_FLD2BOOL(SRSS_CLK_ILO0_CONFIG_ENABLE, SRSS_CLK_ILO0_CONFIG));
1961     }
1962     else
1963     {
1964         return (_FLD2BOOL(SRSS_CLK_ILO1_CONFIG_ENABLE, SRSS_CLK_ILO1_CONFIG));
1965     }
1966 }
1967 
Cy_SysClk_IloSrcHibernateOn(uint32_t iloNum,bool on)1968 void Cy_SysClk_IloSrcHibernateOn(uint32_t iloNum, bool on)
1969 {
1970     if (0UL == iloNum)
1971     {
1972         CY_REG32_CLR_SET(SRSS_CLK_ILO0_CONFIG, SRSS_CLK_ILO0_CONFIG_ILO0_BACKUP, ((on) ? 1UL : 0UL));
1973     }
1974 }
1975 
1976 #elif (defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS))
Cy_SysClk_IloEnable(void)1977 void Cy_SysClk_IloEnable(void)
1978 {
1979 #if (CY_SRSS_ILO_PRESENT)
1980     SRSS_CLK_ILO_CONFIG |= SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1981 #endif
1982 }
1983 
1984 
Cy_SysClk_IloDisable(void)1985 cy_en_sysclk_status_t Cy_SysClk_IloDisable(void)
1986 {
1987 #if (CY_SRSS_ILO_PRESENT)
1988     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
1989     if (!_FLD2BOOL(SRSS_WDT_CTL_WDT_EN, SRSS_WDT_CTL)) /* if disabled */
1990     {
1991         SRSS_CLK_ILO_CONFIG &= ~SRSS_CLK_ILO_CONFIG_ENABLE_Msk;
1992         retVal = CY_SYSCLK_SUCCESS;
1993     }
1994     return (retVal);
1995 #else
1996     return CY_SYSCLK_UNSUPPORTED_STATE;
1997 #endif
1998 }
1999 
Cy_SysClk_IloIsEnabled(void)2000 bool Cy_SysClk_IloIsEnabled(void)
2001 {
2002 #if (CY_SRSS_ILO_PRESENT)
2003     return (_FLD2BOOL(SRSS_CLK_ILO_CONFIG_ENABLE, SRSS_CLK_ILO_CONFIG));
2004 #else
2005     return false;
2006 #endif
2007 }
2008 
Cy_SysClk_IloHibernateOn(bool on)2009 void Cy_SysClk_IloHibernateOn(bool on)
2010 {
2011     CY_UNUSED_PARAMETER(on);
2012 #if (CY_SRSS_ILO_PRESENT)
2013     CY_REG32_CLR_SET(SRSS_CLK_ILO_CONFIG, SRSS_CLK_ILO_CONFIG_ILO_BACKUP, ((on) ? 1UL : 0UL));
2014 #endif
2015 }
2016 
2017 #endif /* (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) */
2018 
2019 
2020 /* ========================================================================== */
2021 /* =========================    EXTCLK SECTION    =========================== */
2022 /* ========================================================================== */
2023 
2024 
2025     static uint32_t cySysClkExtFreq = 0UL;
2026 
2027 #if defined (SRSS_HT_VARIANT)
2028 #define CY_SYSCLK_EXTCLK_MAX_FREQ (80000000UL) /* 80 MHz */
2029 #else
2030 #define CY_SYSCLK_EXTCLK_MAX_FREQ (100000000UL) /* 100 MHz */
2031 #endif
2032 
2033 
Cy_SysClk_ExtClkSetFrequency(uint32_t freq)2034 void Cy_SysClk_ExtClkSetFrequency(uint32_t freq)
2035 {
2036     if (freq <= CY_SYSCLK_EXTCLK_MAX_FREQ)
2037     {
2038         cySysClkExtFreq = freq;
2039     }
2040 }
2041 
2042 /*******************************************************************************
2043 * Function Name: Cy_SysClk_ExtClkGetFrequency
2044 ****************************************************************************//**
2045 *
2046 * Returns the frequency of the External Clock Source (EXTCLK) from the
2047 * internal storage.
2048 *
2049 * \return The frequency of the External Clock Source.
2050 *
2051 * \funcusage
2052 * \snippet sysclk/snippet/main.c snippet_Cy_SysClk_ExtClkSetFrequency
2053 *
2054 *******************************************************************************/
Cy_SysClk_ExtClkGetFrequency(void)2055 uint32_t Cy_SysClk_ExtClkGetFrequency(void)
2056 {
2057     return (cySysClkExtFreq);
2058 }
2059 
2060 /* ========================================================================== */
2061 /* ===========================    ECO SECTION    ============================ */
2062 /* ========================================================================== */
2063 
2064 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined (CY_IP_MXS22SRSS) || \
2065     (defined (CY_IP_MXS40SSRSS) && (SRSS_ECO_PRESENT == 1UL))
2066 #if (CY_SRSS_ECO_PRESENT)
2067 static uint32_t ecoFrequency = 0UL; /* Internal storage for ECO frequency user setting */
2068 #endif
2069 
2070 #define CY_SYSCLK_INVALID_TRIM_VALUE (0xFFFFFFFFUL)
2071 
2072 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || (defined (CY_IP_MXS40SSRSS) && (SRSS_ECO_PRESENT == 1UL))
2073 
2074 #define M_PI (3.1415927f)
2075 
2076 /** \cond *********************************************************************
2077 * Function Name: cy_sqrt
2078 * Calculates square root.
2079 * The input is 32-bit wide.
2080 * The result is 16-bit wide.
2081 *******************************************************************************/
2082 static uint32_t cy_sqrt(uint32_t x);
cy_sqrt(uint32_t x)2083 static uint32_t cy_sqrt(uint32_t x)
2084 {
2085     uint32_t i;
2086     uint32_t res = 0UL;
2087     uint32_t add = 0x8000UL;
2088 
2089     for(i = 0UL; i < 16UL; i++)
2090     {
2091         uint32_t tmp = res | add;
2092 
2093         if (x >= (tmp * tmp))
2094         {
2095             res = tmp;
2096         }
2097 
2098         add >>= 1U;
2099     }
2100 
2101     return (res);
2102 }
2103 
2104 /*******************************************************************************
2105 * Function Name: Cy_SysClk_SelectEcoAtrim
2106 ****************************************************************************//**
2107 *
2108 *   In accordance with the table below, this function Outputs proper
2109 *   value for ATRIM bits in register CLK_ECO_CONFIG2.
2110 *   max amplitude (Vp) |   ATRIM value
2111 *   Below configuration is for CAT1C devices
2112 *      0.50[V] <= Vp < 0.55[V]    |      0x04
2113 *      0.55[V] <= Vp < 0.55[V]    |      0x05
2114 *      0.60[V] <= Vp < 0.65[V]    |      0x06
2115 *      0.65[V] <= Vp < 0.65[V]    |      0x07
2116 *      0.70[V] <= Vp < 0.75[V]    |      0x08
2117 *      0.75[V] <= Vp < 0.75[V]    |      0x09
2118 *      0.80[V] <= Vp < 0.85[V]    |      0x0A
2119 *      0.85[V] <= Vp < 0.75[V]    |      0x0B
2120 *      0.90[V] <= Vp < 0.95[V]    |      0x0C
2121 *      0.95[V] <= Vp < 1.00[V]    |      0x0D
2122 *      1.00[V] <= Vp < 1.05[V]    |      0x0E
2123 *      1.05[V] <= Vp < 1.10[V]    |      0x0F
2124 *      1.10[V] <= Vp              |      0x00
2125 *
2126 * Below configuration is for CAT1B(B2) devices
2127 *      150[mV] = Vp               |      0x0
2128 *      175[mV] = Vp               |      0x1
2129 *      200[mV] = Vp               |      0x2
2130 *      225[mV] = Vp               |      0x3
2131 *      250[mV] = Vp               |      0x4
2132 *      275[mV] = Vp               |      0x5
2133 *      300[mV] = Vp               |      0x6
2134 *      325[mV] = Vp               |      0x7
2135 *      350[mV] = Vp               |      0x8
2136 *      375[mV] = Vp               |      0x9
2137 *      400[mV] = Vp               |      0xA
2138 *      425[mV] = Vp               |      0xB
2139 *      450[mV] = Vp               |      0xC
2140 *      475[mV] = Vp               |      0xD
2141 *      500[mV] = Vp               |      0xE
2142 *      525[mV] = Vp               |      0xF
2143 *
2144 *   \param maxAmplitude: Max amplitude (Vp) calculated by below formula.
2145 *         Vpp = 1,000 * sqrt(drivelevel / 2 / esr) / 3.14 / freqMHz / cLoad
2146 *
2147 *   \return : value to be set to ATRIM.
2148 *             It returns 0xFFFFFFFF, when there are no proper value.
2149 *
2150 *******************************************************************************/
2151 
Cy_SysClk_SelectEcoAtrim(float32_t maxAmplitude)2152 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoAtrim(float32_t maxAmplitude)
2153 {
2154 
2155 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
2156 
2157     if(maxAmplitude < 0.50f)
2158     {
2159         return (CY_SYSCLK_INVALID_TRIM_VALUE);
2160     }
2161 
2162     if((0.50f <= maxAmplitude) && (maxAmplitude < 0.55f))
2163     {
2164         return(0x04UL);
2165     }
2166     else if(maxAmplitude < 0.60f)
2167     {
2168         return(0x05UL);
2169     }
2170     else if(maxAmplitude < 0.65f)
2171     {
2172         return(0x06UL);
2173     }
2174     else if(maxAmplitude < 0.70f)
2175     {
2176         return(0x07UL);
2177     }
2178     else if(maxAmplitude < 0.75f)
2179     {
2180         return(0x08UL);
2181     }
2182     else if(maxAmplitude < 0.80f)
2183     {
2184         return(0x09UL);
2185     }
2186     else if(maxAmplitude < 0.85f)
2187     {
2188         return(0x0AUL);
2189     }
2190     else if(maxAmplitude < 0.90f)
2191     {
2192         return(0x0BUL);
2193     }
2194     else if(maxAmplitude < 0.95f)
2195     {
2196         return(0x0CUL);
2197     }
2198     else if(maxAmplitude < 1.00f)
2199     {
2200         return(0x0DUL);
2201     }
2202     else if(maxAmplitude < 1.05f)
2203     {
2204         return(0x0EUL);
2205     }
2206     else if(maxAmplitude < 1.10f)
2207     {
2208         return(0x0FUL);
2209     }
2210     else if(1.1f <= maxAmplitude)
2211     {
2212         return(0x00UL);
2213     }
2214     else
2215     {
2216         // invalid input
2217         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2218     }
2219 
2220 #else
2221 
2222     if(maxAmplitude < 0.150f)
2223     {
2224         return (CY_SYSCLK_INVALID_TRIM_VALUE);
2225     }
2226 
2227     if(maxAmplitude <= 0.150f)
2228     {
2229         return(0x00L);
2230     }
2231     else if(maxAmplitude <= 0.175f)
2232     {
2233         return(0x01UL);
2234     }
2235     else if(maxAmplitude <= 0.20f)
2236     {
2237         return(0x02UL);
2238     }
2239     else if(maxAmplitude <= 0.225f)
2240     {
2241         return(0x03UL);
2242     }
2243     else if(maxAmplitude <= 0.250f)
2244     {
2245         return(0x04UL);
2246     }
2247     else if(maxAmplitude <= 0.275f)
2248     {
2249         return(0x05UL);
2250     }
2251     else if(maxAmplitude <= 0.3f)
2252     {
2253         return(0x06UL);
2254     }
2255     else if(maxAmplitude <= 0.325f)
2256     {
2257         return(0x07UL);
2258     }
2259     else if(maxAmplitude <= 0.350f)
2260     {
2261         return(0x08UL);
2262     }
2263     else if(maxAmplitude <= 0.375f)
2264     {
2265         return(0x09UL);
2266     }
2267     else if(maxAmplitude <= 0.4f)
2268     {
2269         return(0xAUL);
2270     }
2271     else if(maxAmplitude <= 0.425f)
2272     {
2273         return(0xBUL);
2274     }
2275     else if(maxAmplitude <= 0.450f)
2276     {
2277         return(0xCUL);
2278     }
2279     else if(maxAmplitude <= 0.475f)
2280     {
2281         return(0xDUL);
2282     }
2283     else if(maxAmplitude <= 0.5f)
2284     {
2285         return(0xEUL);
2286     }
2287     else if(maxAmplitude <= 0.525f)
2288     {
2289         return(0xFUL);
2290     }
2291     else
2292     {
2293         // invalid input
2294         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2295     }
2296 #endif
2297 }
2298 
2299 /*******************************************************************************
2300 * Function Name: Cy_SysClk_SelectEcoAGCEN
2301 ****************************************************************************//**
2302 *
2303 *   In accordance with the table below, this function Outputs proper
2304 *   value for AGC_EN bits in register CLK_ECO_CONFIG.
2305 *   max amplitude (Vp) |   ATRIM value
2306 *      0.50[V] <= Vp < 1.10[V]    |      0x00
2307 *      1.10[V] <= Vp              |      0x01
2308 *
2309 *   \param maxAmplitude: Max amplitude (Vp) calculated by below formula.
2310 *         Vpp = 1,000 * sqrt(drivelevel / 2 / esr) / 3.14 / freqMHz / cLoad
2311 *
2312 *   \return : value to be set to AGC_EN.
2313 *             It returns 0xFFFFFFFF, when there are no proper value.
2314 *
2315 *******************************************************************************/
Cy_SysClk_SelectEcoAGCEN(float32_t maxAmplitude)2316 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoAGCEN(float32_t maxAmplitude)
2317 {
2318     if((0.50f <= maxAmplitude) && (maxAmplitude < 1.10f))
2319     {
2320         return(0x01UL);
2321     }
2322     else if(1.10f <= maxAmplitude)
2323     {
2324         return(0x00UL);
2325     }
2326     else
2327     {
2328         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2329     }
2330 }
2331 
2332 /*******************************************************************************
2333 * Function Name: Cy_SysClk_SelectEcoWDtrim
2334 ****************************************************************************//**
2335 *
2336 *   In accordance with the table below, this function Outputs proper
2337 *   value for WDTRIM bits in register CLK_ECO_CONFIG2.
2338 *   max amplitude (Vp) |   WDTRIM value
2339 * Below configuration is for CAT1C devices
2340 *      0.5[V] <= Vp <  0.6[V]    |      0x02
2341 *      0.6[V] <= Vp <  0.7[V]    |      0x03
2342 *      0.7[V] <= Vp <  0.8[V]    |      0x04
2343 *      0.8[V] <= Vp <  0.9[V]    |      0x05
2344 *      0.9[V] <= Vp <  1.0[V]    |      0x06
2345 *      1.0[V] <= Vp <  1.1[V]    |      0x07
2346 *      1.1[V] <= Vp              |      0x07
2347 * Below configuration is for CAT1B(B2) devices
2348 *      50[mV] = Vp               |      0x0
2349 *      75[mV] = Vp               |      0x1
2350 *      100[mV] = Vp              |      0x2
2351 *      125[mV] = Vp              |      0x3
2352 *      150[mV] = Vp              |      0x4
2353 *      175[mV] = Vp              |      0x5
2354 *      200[mV] = Vp              |      0x6
2355 *      225[mV] = Vp              |      0x7
2356 *   \param amplitude: Max amplitude (Vp) calculated by below formula.
2357 *         Vp = 1,000 * sqrt(drivelevel / 2 / esr) / 3.14 / freqMHz / cLoad
2358 *
2359 *   \return : value to be set to WDTRIM.
2360 *             It returns CY_SYSCLK_INVALID_TRIM_VALUE, when there are no proper value.
2361 *
2362 *******************************************************************************/
Cy_SysClk_SelectEcoWDtrim(float32_t amplitude)2363 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoWDtrim(float32_t amplitude)
2364 {
2365 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
2366 
2367     if(amplitude < 0.50f)
2368     {
2369         return (CY_SYSCLK_INVALID_TRIM_VALUE);
2370     }
2371 
2372     if( (0.50f <= amplitude) && (amplitude < 0.60f))
2373     {
2374         return(0x02UL);
2375     }
2376     else if(amplitude < 0.7f)
2377     {
2378         return(0x03UL);
2379     }
2380     else if(amplitude < 0.8f)
2381     {
2382         return(0x04UL);
2383     }
2384     else if(amplitude < 0.9f)
2385     {
2386         return(0x05UL);
2387     }
2388     else if(amplitude < 1.0f)
2389     {
2390         return(0x06UL);
2391     }
2392     else if(amplitude < 1.1f)
2393     {
2394         return(0x07UL);
2395     }
2396     else if(1.1f <= amplitude)
2397     {
2398         return(0x07UL);
2399     }
2400     else
2401     {
2402         // invalid input
2403         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2404     }
2405 
2406 #else
2407 
2408     if(amplitude < 0.05f)
2409     {
2410         return (CY_SYSCLK_INVALID_TRIM_VALUE);
2411     }
2412 
2413     if(amplitude <= 0.05f)
2414     {
2415         return(0x0UL);
2416     }
2417     else if(amplitude <= 0.075f)
2418     {
2419         return(0x01UL);
2420     }
2421     else if(amplitude <= 0.1f)
2422     {
2423         return(0x02UL);
2424     }
2425     else if(amplitude <= 0.125f)
2426     {
2427         return(0x03UL);
2428     }
2429     else if(amplitude <= 0.150f)
2430     {
2431         return(0x04UL);
2432     }
2433     else if(amplitude <= 0.175f)
2434     {
2435         return(0x05UL);
2436     }
2437     else if(amplitude <= 0.2f)
2438     {
2439         return(0x06UL);
2440     }
2441     else if(amplitude <= 0.225f)
2442     {
2443         return(0x07UL);
2444     }
2445     else
2446     {
2447         // invalid input
2448         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2449     }
2450 
2451 #endif
2452 }
2453 
2454 /*******************************************************************************
2455 * Function Name: Cy_SysClk_SelectEcoGtrim
2456 ****************************************************************************//**
2457 *
2458 *   The range of gm value will be defined by GTRIM value as shown in below table.
2459 *   We set the GTRIM value so that it is guaranteed for gm value to be more than gm_min
2460 *
2461 *    GTRIM value |  gm
2462 *       0x00     |  0.0[mA/V] <= gm < 2.2[mA/V]
2463 *       0x01     |  2.2[mA/V] <= gm < 4.4[mA/V]
2464 *       0x02     |  4.4[mA/V] <= gm < 6.6[mA/V]
2465 *       0x03     |  6.6[mA/V] <= gm < 8.8[mA/V]
2466 *       0x04     |  8.8[mA/V] <= gm <11.0[mA/V]
2467 *       0x05     | 11.0[mA/V] <= gm <13.2[mA/V]
2468 *       0x06     | 13.2[mA/V] <= gm <15.4[mA/V]
2469 *       0x07     | 15.4[mA/V] <= gm <17.6[mA/V]
2470 *
2471 *   \param gm_min: Minimum of gm (gm_min) calculated by below formula.
2472 *   gm_min mA/V = 5 * 4 * 3.14 * 3.14 * freqMhz^2 * cLoad^2 * 4 * esr / 1,000,000,000
2473 *
2474 *   \return : value to be set to GTRIM.
2475 *             It returns CY_SYSCLK_INVALID_TRIM_VALUE, when there are no proper value.
2476 *
2477 *******************************************************************************/
Cy_SysClk_SelectEcoGtrim(float32_t gm_min)2478 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoGtrim(float32_t gm_min)
2479 {
2480     if( (0.0f <= gm_min) && (gm_min < 2.2f))
2481     {
2482         return(0x00UL+1UL);
2483     }
2484     else if(gm_min < 4.4f)
2485     {
2486         return(0x01UL+1UL);
2487     }
2488     else if(gm_min < 6.6f)
2489     {
2490         return(0x02UL+1UL);
2491     }
2492     else if(gm_min < 8.8f)
2493     {
2494         return(0x03UL+1UL);
2495     }
2496     else if(gm_min < 11.0f)
2497     {
2498         return(0x04UL+1UL);
2499     }
2500     else if(gm_min < 13.2f)
2501     {
2502         return(0x05UL+1UL);
2503     }
2504     else if(gm_min < 15.4f)
2505     {
2506         return(0x06UL+1UL);
2507     }
2508     else if(gm_min < 17.6f)
2509     {
2510         // invalid input
2511         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2512     }
2513     else
2514     {
2515         // invalid input
2516         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2517     }
2518 }
2519 
2520 /*******************************************************************************
2521 * Function Name: Cy_SysClk_SelectEcoRtrim
2522 ****************************************************************************//**
2523 *
2524 *   In accordance with the table below, this function Outputs proper
2525 *   value for RTRIM bits in register CLK_ECO_CONFIG2.
2526 *         Eco freq  (F)            |   RTRIM value
2527 *                  F > 28.60[MHz]  |      0x00
2528 *    28.60[MHz] >= F > 23.33[MHz]  |      0x01
2529 *    23.33[MHz] >= F > 16.50[MHz]  |      0x02
2530 *    16.50[MHz] >= F               |      0x03
2531 *
2532 *   \param freqMHz: Operating frequency of the crystal in MHz.
2533 *
2534 *   \return : value to be set to RTRIM.
2535 *             It returns CY_SYSCLK_INVALID_TRIM_VALUE, when there are no proper value.
2536 *
2537 *******************************************************************************/
Cy_SysClk_SelectEcoRtrim(float32_t freqMHz)2538 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoRtrim(float32_t freqMHz)
2539 {
2540     if(freqMHz > 28.6f)
2541     {
2542         return(0x00UL);
2543     }
2544     else if(freqMHz > 23.33f)
2545     {
2546         return(0x01UL);
2547     }
2548     else if(freqMHz > 16.5f)
2549     {
2550         return(0x02UL);
2551     }
2552     else if(freqMHz > 0.0f)
2553     {
2554         return(0x03UL);
2555     }
2556     else
2557     {
2558         // invalid input
2559         return(CY_SYSCLK_INVALID_TRIM_VALUE);
2560     }
2561 }
2562 
2563 /*******************************************************************************
2564 * Function Name: Cy_SysClk_SelectEcoFtrim
2565 ****************************************************************************//**
2566 *
2567 *   In accordance with the table below, this function Outputs proper
2568 *   value for FTRIM bits in register CLK_ECO_CONFIG2.
2569 *
2570 *   \return : value to be set to FTRIM.
2571 *
2572 *   \note: This function does not check the invalid input value.
2573 *          It should be cared by caller program.
2574 *******************************************************************************/
Cy_SysClk_SelectEcoFtrim(void)2575 __STATIC_INLINE uint32_t Cy_SysClk_SelectEcoFtrim(void)
2576 {
2577     return(0x03UL);
2578 }
2579 
Cy_SysClk_EcoConfigure(uint32_t freq,uint32_t cSum,uint32_t esr,uint32_t driveLevel)2580 cy_en_sysclk_status_t Cy_SysClk_EcoConfigure(uint32_t freq, uint32_t cSum, uint32_t esr, uint32_t driveLevel)
2581 {
2582     uint32_t minRneg = (5UL * esr);
2583 
2584     /* Invalid state error if ECO is already enabled */
2585     if (0UL != (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
2586     {
2587         return(CY_SYSCLK_INVALID_STATE);
2588     }
2589 
2590     /* calculate intermediate values */
2591     float32_t freqMHz = (float32_t)freq / 1000000.0f;
2592 
2593     uint32_t maxAmpl = CY_SYSLIB_DIV_ROUND((159155UL * /* 5 * 100000 / PI */
2594            cy_sqrt(CY_SYSLIB_DIV_ROUND(2000000UL * driveLevel, esr))), /* Scaled by 2 */
2595                                        (CY_SYSLIB_DIV_ROUND(freq, 1000UL)/* KHz */ * cSum)); /* The result is scaled by 10^3 */
2596 
2597     float32_t maxAmplitude = (float32_t)maxAmpl/1000.0f;
2598 
2599     float32_t gm_min = (157.91367042f /*4 * M_PI * M_PI * 4*/ * (float32_t)minRneg * freqMHz * freqMHz * (float32_t)cSum * (float32_t)cSum) /
2600                              1000000000.0f;
2601 
2602     /* Get trim values according to calculated values */
2603     uint32_t atrim, agcen, wdtrim, gtrim, rtrim, ftrim;
2604 
2605     atrim  = Cy_SysClk_SelectEcoAtrim(maxAmplitude);
2606     if(atrim == CY_SYSCLK_INVALID_TRIM_VALUE)
2607     {
2608         return(CY_SYSCLK_BAD_PARAM);
2609     }
2610 
2611     agcen = Cy_SysClk_SelectEcoAGCEN(maxAmplitude);
2612     if(agcen == CY_SYSCLK_INVALID_TRIM_VALUE)
2613     {
2614         return(CY_SYSCLK_BAD_PARAM);
2615     }
2616 
2617     wdtrim = Cy_SysClk_SelectEcoWDtrim(maxAmplitude);
2618     if(wdtrim == CY_SYSCLK_INVALID_TRIM_VALUE)
2619     {
2620         return(CY_SYSCLK_BAD_PARAM);
2621     }
2622 
2623     gtrim  = Cy_SysClk_SelectEcoGtrim(gm_min);
2624     if(gtrim == CY_SYSCLK_INVALID_TRIM_VALUE)
2625     {
2626         return(CY_SYSCLK_BAD_PARAM);
2627     }
2628 
2629     rtrim  = Cy_SysClk_SelectEcoRtrim(freqMHz);
2630     if(rtrim == CY_SYSCLK_INVALID_TRIM_VALUE)
2631     {
2632         return(CY_SYSCLK_BAD_PARAM);
2633     }
2634 
2635     ftrim  = Cy_SysClk_SelectEcoFtrim();
2636 
2637     /* Update all fields of trim control register with one write, without changing the ITRIM field */
2638     SRSS_CLK_ECO_CONFIG2 =
2639         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_WDTRIM, wdtrim)  |
2640         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_ATRIM, atrim) |
2641         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_FTRIM, ftrim)    |
2642         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_RTRIM, rtrim)    |
2643         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_GTRIM, gtrim);
2644 
2645     SRSS_CLK_ECO_CONFIG = _VAL2FLD(SRSS_CLK_ECO_CONFIG_AGC_EN, agcen);
2646 
2647     ecoFrequency = freq;
2648 
2649     return(CY_SYSCLK_SUCCESS);
2650 }
2651 
2652 #endif /* (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) */
2653 
2654 #if defined (CY_IP_MXS22SRSS)
2655 
Cy_SysClk_EcoManualConfigure(const cy_stc_clk_eco_config_t * ecoConfig)2656 cy_en_sysclk_status_t Cy_SysClk_EcoManualConfigure(const cy_stc_clk_eco_config_t *ecoConfig)
2657 {
2658     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
2659 
2660     CY_ASSERT_L3(CY_SYSCLK_IS_CLK_ECO_CTRIM_VALID(ecoConfig->ecoCtrim));
2661     CY_ASSERT_L3(CY_SYSCLK_IS_CLK_ECO_GTRIM_VALID(ecoConfig->ecoGtrim));
2662 
2663     /* Invalid state error if ECO is already enabled */
2664     if (0UL != (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
2665     {
2666         retVal = CY_SYSCLK_INVALID_STATE;
2667     }
2668 
2669     if( CY_SYSCLK_SUCCESS == retVal)
2670     {
2671         SRSS_CLK_ECO_CONFIG2 =
2672         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_ECO_TRIM_CL, ecoConfig->ecoCtrim) |
2673         _VAL2FLD(SRSS_CLK_ECO_CONFIG2_ECO_TRIM_GAIN, ecoConfig->ecoGtrim);
2674 
2675         SRSS_CLK_TRIM_ECO_CTL |=
2676         _VAL2FLD(SRSS_CLK_TRIM_ECO_CTL_ECO_CTRL_IBOOSTEN, ecoConfig->ecoIboost);
2677 
2678         ecoFrequency = ecoConfig->ecoClkfreq;
2679     }
2680 
2681     return retVal;
2682 
2683 }
2684 
2685 
2686 #endif /* defined (CY_IP_MXS22SRSS) */
2687 
2688 
Cy_SysClk_EcoDisable(void)2689 void Cy_SysClk_EcoDisable(void)
2690 {
2691 #if (CY_SRSS_ECO_PRESENT)
2692     SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
2693 #endif
2694 }
2695 
2696 
Cy_SysClk_EcoGetStatus(void)2697 uint32_t Cy_SysClk_EcoGetStatus(void)
2698 {
2699 #if (CY_SRSS_ECO_PRESENT)
2700     uint32_t eco_status        = SRSS_CLK_ECO_STATUS;
2701     uint32_t eco_status_mask   = SRSS_CLK_ECO_STATUS_Msk;
2702 
2703     /* if ECO is not ready, just report the ECO_OK bit. Otherwise report 2 = ECO ready */
2704     return ((eco_status_mask == (eco_status_mask & eco_status)) ?
2705         CY_SYSCLK_ECOSTAT_STABLE : (SRSS_CLK_ECO_STATUS_Msk & eco_status));
2706 #else
2707     return 0;
2708 #endif
2709 }
2710 
2711 
Cy_SysClk_EcoEnable(uint32_t timeoutus)2712 cy_en_sysclk_status_t Cy_SysClk_EcoEnable(uint32_t timeoutus)
2713 {
2714 #if (CY_SRSS_ECO_PRESENT)
2715     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
2716     bool zeroTimeout = (0UL == timeoutus);
2717 
2718     /* Invalid state error if ECO is already enabled */
2719     if (0UL == (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
2720     {
2721         /* Set ECO enable */
2722         SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
2723 
2724         /* Wait for CY_SYSCLK_ECOSTAT_STABLE */
2725         for (; (CY_SYSCLK_ECOSTAT_STABLE != Cy_SysClk_EcoGetStatus()) && (0UL != timeoutus); timeoutus--)
2726         {
2727             Cy_SysLib_DelayUs(1U);
2728         }
2729 
2730         if (zeroTimeout || (0UL != timeoutus))
2731         {
2732             retVal = CY_SYSCLK_SUCCESS;
2733         }
2734         else
2735         {
2736             /* If ECO doesn't start, then disable it */
2737             SRSS_CLK_ECO_CONFIG &= ~SRSS_CLK_ECO_CONFIG_ECO_EN_Msk;
2738             retVal = CY_SYSCLK_TIMEOUT;
2739         }
2740     }
2741 
2742     return (retVal);
2743 
2744 #else
2745     (void) timeoutus;
2746     return CY_SYSCLK_UNSUPPORTED_STATE;
2747 #endif
2748 }
2749 
Cy_SysClk_EcoGetFrequency(void)2750 uint32_t Cy_SysClk_EcoGetFrequency(void)
2751 {
2752 #if (CY_SRSS_ECO_PRESENT)
2753     return ((CY_SYSCLK_ECOSTAT_STABLE == Cy_SysClk_EcoGetStatus()) ? ecoFrequency : 0UL);
2754 #else
2755     return 0;
2756 #endif
2757 }
2758 
Cy_SysClk_EcoSetFrequency(uint32_t freq)2759 void Cy_SysClk_EcoSetFrequency(uint32_t freq)
2760 {
2761 #if (CY_SRSS_ECO_PRESENT)
2762     ecoFrequency = freq;
2763 #else
2764     ecoFrequency = 0;
2765 #endif
2766 }
2767 
Cy_SysClk_EcoPrescaleConfigure(uint32_t enable,uint32_t int_div,uint32_t frac_div)2768 cy_en_sysclk_status_t Cy_SysClk_EcoPrescaleConfigure(uint32_t enable, uint32_t int_div, uint32_t frac_div)
2769 {
2770     uint32_t timeoutus = CY_SYSCLK_ECO_PRESCALER_TIMEOUT_US;
2771     (void) enable;
2772 #if (CY_SRSS_ECO_PRESENT)
2773     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
2774 
2775     if(0UL != enable) {
2776         /* Invalid state error if CO_DIV_ENABLED is already enabled */
2777         if (0UL == (SRSS_CLK_ECO_PRESCALE_ECO_DIV_ENABLED_Msk & SRSS_CLK_ECO_PRESCALE))
2778         {
2779             SRSS_CLK_ECO_PRESCALE = (_VAL2FLD(SRSS_CLK_ECO_PRESCALE_ECO_INT_DIV, int_div) | \
2780                                       _VAL2FLD(SRSS_CLK_ECO_PRESCALE_ECO_FRAC_DIV, frac_div));
2781 
2782             SRSS_CLK_ECO_CONFIG |= SRSS_CLK_ECO_CONFIG_ECO_DIV_ENABLE_Msk;
2783 
2784             retVal = CY_SYSCLK_SUCCESS;
2785         }
2786     }
2787     else {
2788         /* Invalid state error if CO_DIV_ENABLED is already disabled */
2789         if (1UL == (SRSS_CLK_ECO_PRESCALE_ECO_DIV_ENABLED_Msk & SRSS_CLK_ECO_PRESCALE))
2790         {
2791             SRSS_CLK_ECO_CONFIG |= (SRSS_CLK_ECO_CONFIG_ECO_DIV_DISABLE_Msk);
2792             retVal = CY_SYSCLK_SUCCESS;
2793         }
2794     }
2795 
2796     if(retVal == CY_SYSCLK_SUCCESS)
2797     {
2798         /* Wait until ENABLED bit is set or cleared */
2799         for (; (_FLD2BOOL(SRSS_CLK_ECO_PRESCALE_ECO_DIV_ENABLED, SRSS_CLK_ECO_PRESCALE) != (bool)enable) &&
2800                (0UL != timeoutus);
2801              timeoutus--)
2802         {
2803             Cy_SysLib_DelayUs(1U);
2804         }
2805 
2806         if ((0UL != timeoutus))
2807         {
2808             retVal = CY_SYSCLK_SUCCESS;
2809         }
2810         else
2811         {
2812             retVal = CY_SYSCLK_TIMEOUT;
2813         }
2814     }
2815     return retVal;
2816 #else
2817     (void) frac_div;
2818     (void) int_div;
2819 
2820     return CY_SYSCLK_UNSUPPORTED_STATE;
2821 #endif
2822 }
2823 
2824 
Cy_SysClk_EcoPrescaleIsEnabled(void)2825 bool Cy_SysClk_EcoPrescaleIsEnabled(void)
2826 {
2827 #if (CY_SRSS_ECO_PRESENT)
2828     return (_FLD2BOOL(SRSS_CLK_ECO_PRESCALE_ECO_DIV_ENABLED, SRSS_CLK_ECO_PRESCALE));
2829 #else
2830     return false;
2831 #endif
2832 }
2833 
Cy_SysClk_EcoPrescaleGetFrequency(void)2834 uint32_t Cy_SysClk_EcoPrescaleGetFrequency(void)
2835 {
2836     uint32_t freq = Cy_SysClk_EcoGetFrequency();
2837     uint32_t div =  (_FLD2VAL(SRSS_CLK_ECO_PRESCALE_ECO_INT_DIV, SRSS_CLK_ECO_PRESCALE) + \
2838                     (_FLD2VAL(SRSS_CLK_ECO_PRESCALE_ECO_FRAC_DIV, SRSS_CLK_ECO_PRESCALE) / 256UL));
2839 
2840     /* Divide the path input frequency down and return the result */
2841     return (CY_SYSLIB_DIV_ROUND(freq, div));
2842 }
2843 
2844 #endif /* (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined (CY_IP_MXS22SRSS) */
2845 
2846 
2847 #if defined (CY_IP_MXS28SRSS)
Cy_SysClk_EcoBleControl(cy_en_eco_for_ble_t control,uint32_t timeoutus)2848 cy_en_sysclk_status_t Cy_SysClk_EcoBleControl(cy_en_eco_for_ble_t control, uint32_t timeoutus)
2849 {
2850 #if (CY_SRSS_ECO_PRESENT)
2851     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
2852     bool zeroTimeout = (0UL == timeoutus);
2853 
2854     CY_ASSERT_L1(control < sizeof(cy_en_eco_for_ble_t));
2855 
2856     /* Set ECO for BLE with control value */
2857     SRSS_CLK_ECO_CONFIG |= (control << SRSS_CLK_ECO_CONFIG_ECO_BLE_EN_Pos);
2858 
2859     /* Wait for CY_SYSCLK_ECOSTAT_STABLE */
2860     for (; (CY_SYSCLK_ECOSTAT_BLE_ENABLED != Cy_SysClk_EcoBleGetStatus()) && (0UL != timeoutus); timeoutus--)
2861     {
2862         Cy_SysLib_DelayUs(1U);
2863     }
2864 
2865     retVal = (zeroTimeout || (0UL != timeoutus)) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_TIMEOUT;
2866 
2867     return (retVal);
2868 #else
2869     return CY_SYSCLK_UNSUPPORTED_STATE;
2870 #endif
2871 }
2872 
2873 #endif /* defined (CY_IP_MXS28SRSS) */
2874 
2875 #if defined (CY_IP_MXS28SRSS)
2876 
Cy_SysClk_EcoBleGetStatus(void)2877 uint32_t Cy_SysClk_EcoBleGetStatus(void)
2878 {
2879 #if defined (CY_IP_MXS28SRSS)
2880 #if (CY_SRSS_ECO_PRESENT)
2881     /* if ECO for BLE is Enabled, report 1. Otherwise report 0 */
2882     return ((SRSS_CLK_ECO_STATUS_ECO_BLE_ENABLED_Msk == (SRSS_CLK_ECO_STATUS_ECO_BLE_ENABLED_Msk & SRSS_CLK_ECO_STATUS)) ?
2883       CY_SYSCLK_ECOSTAT_BLE_ENABLED : CY_SYSCLK_ECOSTAT_BLE_DISABLED);
2884 #else
2885     return 0;
2886 #endif
2887 #else
2888     return 0;
2889 #endif
2890 
2891 }
2892 
2893 #endif /* defined (CY_IP_MXS28SRSS) */
2894 
2895 /* ========================================================================== */
2896 /* ==========================    LPECO SECTION    =========================== */
2897 /* ========================================================================== */
2898 
2899 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3)) && (defined (SRSS_BACKUP_S40E_LPECO_PRESENT) && (SRSS_BACKUP_S40E_LPECO_PRESENT == 1u))
2900 
2901 #define Cy_SysClk_LpEco_PRESCALER_MAX_INT_DIV (1023u) /* 10 bit value */
2902 #define Cy_SysClk_LpEco_PRESCALER_MAX_FRAC_DIV (255u) /* 8 bit value */
2903 
2904 static uint32_t lpecoFrequency = 0UL; /* Internal storage for LPECO frequency user setting */
2905 
Cy_SysClk_LpEcoConfigure(cy_en_clkbak_lpeco_loadcap_range_t capValue,cy_en_clkbak_lpeco_frequency_range_t freqValue,cy_en_clkbak_lpeco_max_amplitude_t ampValue,bool ampDetEn)2906 void Cy_SysClk_LpEcoConfigure(cy_en_clkbak_lpeco_loadcap_range_t capValue,
2907                               cy_en_clkbak_lpeco_frequency_range_t freqValue,
2908                               cy_en_clkbak_lpeco_max_amplitude_t ampValue,
2909                               bool ampDetEn)
2910 {
2911     BACKUP_LPECO_CTL |= (_VAL2FLD(BACKUP_LPECO_CTL_LPECO_CRANGE, capValue) |
2912                          _VAL2FLD(BACKUP_LPECO_CTL_LPECO_FRANGE, freqValue) |
2913                          _VAL2FLD(BACKUP_LPECO_CTL_LPECO_AMP_SEL, ampValue) |
2914                          _VAL2FLD(BACKUP_LPECO_CTL_LPECO_AMPDET_EN, (ampDetEn ? 1u : 0u)));
2915 }
2916 
Cy_SysClk_LpEcoEnable(uint32_t timeoutus)2917 cy_en_sysclk_status_t Cy_SysClk_LpEcoEnable(uint32_t timeoutus)
2918 {
2919     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
2920     bool zeroTimeout = (0U == timeoutus);
2921 
2922     /* Invalid state error if ECO is already enabled */
2923     if (0UL == (SRSS_CLK_ECO_CONFIG_ECO_EN_Msk & SRSS_CLK_ECO_CONFIG))
2924     {
2925         /* Enable the LPECO */
2926         BACKUP_LPECO_CTL |= BACKUP_LPECO_CTL_LPECO_EN_Msk;
2927 
2928         if (zeroTimeout)
2929         {
2930             /* Do not wait for the LPECO to stabilize, just exit and report success */
2931             retVal = CY_SYSCLK_SUCCESS;
2932         }
2933         else
2934         {
2935             bool ampDetEn = _FLD2BOOL(BACKUP_LPECO_CTL_LPECO_AMPDET_EN, BACKUP_LPECO_CTL);
2936 
2937             /* Wait for the LPECO to stabilize OR the timeout to expire */
2938             do {
2939                 bool lpecoStable = Cy_SysClk_LpEcoIsReady();
2940                 if (ampDetEn)
2941                 {
2942                     /* Only check the LPECO amplitude if checking is enabled */
2943                     lpecoStable = lpecoStable && Cy_SysClk_LpEcoAmplitudeOkay();
2944                 }
2945 
2946                 if (lpecoStable)
2947                 {
2948                     retVal = CY_SYSCLK_SUCCESS;
2949                     break;
2950                 }
2951 
2952                 timeoutus--;
2953                 Cy_SysLib_DelayUs(1U);
2954 
2955             } while (timeoutus > 0U);
2956 
2957             if (retVal != CY_SYSCLK_SUCCESS)
2958             {
2959                 /* If LPECO doesn't start, then disable it */
2960                 Cy_SysClk_LpEcoDisable();
2961                 retVal = CY_SYSCLK_TIMEOUT;
2962             }
2963         }
2964     }
2965 
2966     return retVal;
2967 }
2968 
Cy_SysClk_LpEcoDisable(void)2969 void Cy_SysClk_LpEcoDisable(void)
2970 {
2971     BACKUP_LPECO_CTL &= ~BACKUP_LPECO_CTL_LPECO_EN_Msk;
2972 }
2973 
Cy_SysClk_LpEcoSetFrequency(uint32_t freq)2974 void Cy_SysClk_LpEcoSetFrequency(uint32_t freq)
2975 {
2976     lpecoFrequency = freq;
2977 }
2978 
Cy_SysClk_LpEcoGetFrequency(void)2979 uint32_t Cy_SysClk_LpEcoGetFrequency(void)
2980 {
2981     bool lpecoStable = Cy_SysClk_LpEcoIsReady();
2982     if (_FLD2BOOL(BACKUP_LPECO_CTL_LPECO_AMPDET_EN, BACKUP_LPECO_CTL))
2983     {
2984         /* Only check the LPECO amplitude if checking is enabled */
2985         lpecoStable = lpecoStable && Cy_SysClk_LpEcoAmplitudeOkay();
2986     }
2987     return (lpecoStable ? lpecoFrequency : 0UL);
2988 }
2989 
Cy_SysClk_LpEcoPrescaleConfigure(bool enable,uint32_t int_div,uint32_t frac_div)2990 cy_en_sysclk_status_t Cy_SysClk_LpEcoPrescaleConfigure(bool enable, uint32_t int_div, uint32_t frac_div)
2991 {
2992     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
2993 
2994     if (enable)
2995     {
2996         /* Do not attempt to enable the LPECO if the inputs are invalid OR the LPECO is already enabled */
2997         if ((int_div > Cy_SysClk_LpEco_PRESCALER_MAX_INT_DIV) || (frac_div > Cy_SysClk_LpEco_PRESCALER_MAX_FRAC_DIV))
2998         {
2999             retVal = CY_SYSCLK_BAD_PARAM;
3000         }
3001         else if (!Cy_SysClk_LpEcoPrescaleIsEnabled())
3002         {
3003             BACKUP_LPECO_PRESCALE |= (_VAL2FLD(BACKUP_LPECO_PRESCALE_LPECO_INT_DIV, int_div) |
3004                                     _VAL2FLD(BACKUP_LPECO_PRESCALE_LPECO_FRAC_DIV, frac_div));
3005 
3006             BACKUP_LPECO_CTL |= BACKUP_LPECO_CTL_LPECO_DIV_ENABLE_Msk;
3007             retVal = CY_SYSCLK_SUCCESS;
3008         }
3009         else
3010         {
3011             /* Do nothing */
3012         }
3013     }
3014     else
3015     {
3016         /* Disable the prescaler */
3017         BACKUP_LPECO_CTL &= ~BACKUP_LPECO_CTL_LPECO_DIV_ENABLE_Msk;
3018         retVal = CY_SYSCLK_SUCCESS;
3019     }
3020 
3021     return retVal;
3022 }
3023 
Cy_SysClk_LpEcoPrescaleIsEnabled(void)3024 bool Cy_SysClk_LpEcoPrescaleIsEnabled(void)
3025 {
3026     return (_FLD2BOOL(BACKUP_LPECO_PRESCALE_LPECO_DIV_ENABLED, BACKUP_LPECO_PRESCALE));
3027 }
3028 
Cy_SysClk_LpEcoAmplitudeOkay(void)3029 bool Cy_SysClk_LpEcoAmplitudeOkay(void)
3030 {
3031     return (_FLD2BOOL(BACKUP_LPECO_STATUS_LPECO_AMPDET_OK, BACKUP_LPECO_STATUS));
3032 }
3033 
Cy_SysClk_LpEcoIsReady(void)3034 bool Cy_SysClk_LpEcoIsReady(void)
3035 {
3036     return (_FLD2BOOL(BACKUP_LPECO_STATUS_LPECO_READY, BACKUP_LPECO_STATUS));
3037 }
3038 
3039 #endif /* (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3)) && (defined (SRSS_BACKUP_S40E_LPECO_PRESENT) && (SRSS_BACKUP_S40E_LPECO_PRESENT == 1u)) */
3040 
3041 /* ========================================================================== */
3042 /* ===========================    IHO SECTION    ============================ */
3043 /* ========================================================================== */
3044 
3045 #if defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
Cy_SysClk_IhoIsEnabled(void)3046 bool Cy_SysClk_IhoIsEnabled(void)
3047 {
3048 #if (CY_SRSS_IHO_PRESENT)
3049     return (_FLD2BOOL(SRSS_CLK_IHO_CONFIG_ENABLE, SRSS_CLK_IHO_CONFIG));
3050 #else
3051     return false;
3052 #endif
3053 }
3054 
Cy_SysClk_IhoDisable(void)3055 void Cy_SysClk_IhoDisable(void)
3056 {
3057 #if (CY_SRSS_IHO_PRESENT)
3058     SRSS_CLK_IHO_CONFIG &= ~SRSS_CLK_IHO_CONFIG_ENABLE_Msk;
3059 #endif
3060 }
3061 
Cy_SysClk_IhoEnable(void)3062 void Cy_SysClk_IhoEnable(void)
3063 {
3064 #if (CY_SRSS_IHO_PRESENT)
3065     SRSS_CLK_IHO_CONFIG |= SRSS_CLK_IHO_CONFIG_ENABLE_Msk;
3066 #endif
3067 }
3068 
3069 #endif /* defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS) */
3070 
3071 #if defined (CY_IP_MXS22SRSS)
Cy_SysClk_IhoDeepsleepEnable(void)3072 void Cy_SysClk_IhoDeepsleepEnable(void)
3073 {
3074 #if (CY_SRSS_IHO_PRESENT)
3075     SRSS_CLK_IHO_CONFIG |= SRSS_CLK_IHO_CONFIG_DPSLP_ENABLE_Msk;
3076 #endif
3077 }
3078 
Cy_SysClk_IhoIsDeepsleepEnabled(void)3079 bool Cy_SysClk_IhoIsDeepsleepEnabled(void)
3080 {
3081 #if (CY_SRSS_IHO_PRESENT)
3082     return (_FLD2BOOL(SRSS_CLK_IHO_CONFIG_DPSLP_ENABLE, SRSS_CLK_IHO_CONFIG));
3083 #else
3084     return false;
3085 #endif
3086 }
3087 
Cy_SysClk_IhoDeepsleepDisable(void)3088 void Cy_SysClk_IhoDeepsleepDisable(void)
3089 {
3090 #if (CY_SRSS_IHO_PRESENT)
3091     SRSS_CLK_IHO_CONFIG &= ~SRSS_CLK_IHO_CONFIG_DPSLP_ENABLE_Msk;
3092 #endif
3093 }
3094 
Cy_SysClk_IhoSetTrim(uint32_t trimVal)3095 void Cy_SysClk_IhoSetTrim(uint32_t trimVal)
3096 {
3097 #if (CY_SRSS_IHO_PRESENT)
3098     CY_REG32_CLR_SET(SRSS_CLK_IHO_CONFIG, SRSS_CLK_IHO_CONFIG_IHO_TRIM_FREQ, trimVal);
3099 #endif
3100 }
3101 
Cy_SysClk_IhoGetTrim(void)3102 uint32_t Cy_SysClk_IhoGetTrim(void)
3103 {
3104 #if (CY_SRSS_IHO_PRESENT)
3105     return (_FLD2VAL(SRSS_CLK_IHO_CONFIG_IHO_TRIM_FREQ, SRSS_CLK_IHO_CONFIG));
3106 #else
3107     return 0U;
3108 #endif
3109 }
3110 
3111 
3112 #endif /* defined (CY_IP_MXS22SRSS) */
3113 
3114 
3115 /* ========================================================================== */
3116 /* ===========================    IMO SECTION    ============================ */
3117 /* ========================================================================== */
3118 #if defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
3119 
Cy_SysClk_ImoEnable(void)3120 void Cy_SysClk_ImoEnable(void)
3121 {
3122 #if defined (CY_SRSS_IMO_PRESENT) && (CY_SRSS_IMO_PRESENT == 1)
3123     SRSS_CLK_IMO_CONFIG |= SRSS_CLK_IMO_CONFIG_ENABLE_Msk;
3124 #endif
3125 }
3126 
Cy_SysClk_ImoDisable(void)3127 void Cy_SysClk_ImoDisable(void)
3128 {
3129 #if defined (CY_SRSS_IMO_PRESENT) && (CY_SRSS_IMO_PRESENT == 1)
3130     SRSS_CLK_IMO_CONFIG &= ~SRSS_CLK_IMO_CONFIG_ENABLE_Msk;
3131 #endif
3132 }
3133 
Cy_SysClk_ImoIsEnabled(void)3134 bool Cy_SysClk_ImoIsEnabled(void)
3135 {
3136 #if defined (CY_SRSS_IMO_PRESENT) && (CY_SRSS_IMO_PRESENT == 1)
3137     return (_FLD2BOOL(SRSS_CLK_IMO_CONFIG_ENABLE, SRSS_CLK_IMO_CONFIG));
3138 #else
3139     return false;
3140 #endif
3141 }
3142 #endif /* defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) */
3143 
3144 #if defined (CY_IP_MXS40SSRSS)
3145 
Cy_SysClk_ImoDeepsleepEnable(void)3146 void Cy_SysClk_ImoDeepsleepEnable(void)
3147 {
3148 #if (CY_SRSS_IMO_PRESENT)
3149     SRSS_CLK_IMO_CONFIG |= SRSS_CLK_IMO_CONFIG_DPSLP_ENABLE_Msk;
3150 #endif
3151 }
3152 
Cy_SysClk_ImoIsDeepsleepEnabled(void)3153 bool Cy_SysClk_ImoIsDeepsleepEnabled(void)
3154 {
3155 #if (CY_SRSS_IMO_PRESENT)
3156     return (_FLD2BOOL(SRSS_CLK_IMO_CONFIG_DPSLP_ENABLE, SRSS_CLK_IMO_CONFIG));
3157 #else
3158     return false;
3159 #endif
3160 }
3161 
Cy_SysClk_ImoDeepsleepDisable(void)3162 void Cy_SysClk_ImoDeepsleepDisable(void)
3163 {
3164 #if (CY_SRSS_IMO_PRESENT)
3165     SRSS_CLK_IMO_CONFIG &= ~SRSS_CLK_IMO_CONFIG_DPSLP_ENABLE_Msk;
3166 #endif
3167 }
3168 #endif /* defined (CY_IP_MXS40SSRSS) */
3169 
3170 /* ========================================================================== */
3171 /* ====================    INPUT MULTIPLEXER SECTION    ===================== */
3172 /* ========================================================================== */
3173 
3174 
Cy_SysClk_ClkPathSetSource(uint32_t clkPath,cy_en_clkpath_in_sources_t source)3175 cy_en_sysclk_status_t Cy_SysClk_ClkPathSetSource(uint32_t clkPath, cy_en_clkpath_in_sources_t source)
3176 {
3177     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
3178 
3179     CY_ASSERT_L3(CY_SYSCLK_IS_CLKPATH_SOURCE_VALID(source));
3180 
3181     if (clkPath < CY_SRSS_NUM_CLKPATH)
3182     {
3183         if (source >= CY_SYSCLK_CLKPATH_IN_DSI)
3184         {
3185             SRSS_CLK_DSI_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_DSI_SELECT_DSI_MUX, (uint32_t)source);
3186             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)CY_SYSCLK_CLKPATH_IN_DSIMUX);
3187         }
3188         else
3189         {
3190             SRSS_CLK_PATH_SELECT[clkPath] = _VAL2FLD(SRSS_CLK_PATH_SELECT_PATH_MUX, (uint32_t)source);
3191         }
3192         retVal = CY_SYSCLK_SUCCESS;
3193     }
3194     return (retVal);
3195 }
3196 
Cy_SysClk_ClkPathGetSource(uint32_t clkPath)3197 cy_en_clkpath_in_sources_t Cy_SysClk_ClkPathGetSource(uint32_t clkPath)
3198 {
3199     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
3200     cy_en_clkpath_in_sources_t retVal =
3201         (cy_en_clkpath_in_sources_t )((uint32_t)_FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS_CLK_PATH_SELECT[clkPath]));
3202     if (retVal == CY_SYSCLK_CLKPATH_IN_DSIMUX)
3203     {
3204         retVal = (cy_en_clkpath_in_sources_t)((uint32_t)(((uint32_t)CY_SYSCLK_CLKPATH_IN_DSI) |
3205                     ((uint32_t)(_FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS_CLK_DSI_SELECT[clkPath])))));
3206     }
3207     return (retVal);
3208 }
3209 
Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)3210 uint32_t Cy_SysClk_ClkPathMuxGetFrequency(uint32_t clkPath)
3211 {
3212     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
3213 
3214     uint32_t freq = 0UL;    /* The path mux output frequency in Hz, 0 = an unknown frequency */
3215 
3216     /* Get the frequency of the source, i.e., the path mux input */
3217     switch(Cy_SysClk_ClkPathGetSource(clkPath))
3218     {
3219         case CY_SYSCLK_CLKPATH_IN_IMO: /* The IMO frequency is fixed at 8 MHz */
3220             freq = CY_SYSCLK_IMO_FREQ;
3221             break;
3222 
3223         case CY_SYSCLK_CLKPATH_IN_EXT:
3224             freq = Cy_SysClk_ExtClkGetFrequency();
3225             break;
3226 
3227         case CY_SYSCLK_CLKPATH_IN_ECO:
3228 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined (CY_IP_MXS22SRSS) || \
3229             (defined (CY_IP_MXS40SSRSS) && (SRSS_ECO_PRESENT == 1UL))
3230             freq = Cy_SysClk_EcoGetFrequency();
3231 #endif
3232             break;
3233 
3234 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 3)) && (defined (SRSS_BACKUP_S40E_LPECO_PRESENT) && (SRSS_BACKUP_S40E_LPECO_PRESENT == 1u))
3235         case CY_SYSCLK_CLKPATH_IN_LPECO:
3236             freq = Cy_SysClk_LpEcoGetFrequency();
3237             break;
3238 #endif
3239 
3240 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS)
3241         case CY_SYSCLK_CLKPATH_IN_ALTHF:
3242             freq = Cy_SysClk_AltHfGetFrequency();
3243             break;
3244 #endif
3245 #if defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
3246         case CY_SYSCLK_CLKPATH_IN_PILO:
3247             freq = (0UL != (SRSS_CLK_PILO_CONFIG & SRSS_CLK_PILO_CONFIG_PILO_EN_Msk)) ? CY_SYSCLK_PILO_FREQ : 0UL;
3248             break;
3249 #endif
3250 
3251 #if defined (CY_IP_MXS40SSRSS)
3252         case CY_SYSCLK_CLKPATH_IN_ALTLF:
3253             freq = Cy_SysClk_AltLfGetFrequency();
3254             break;
3255 #endif
3256 
3257 #if defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
3258         case CY_SYSCLK_CLKPATH_IN_IHO:
3259             freq = (Cy_SysClk_IhoIsEnabled()) ? CY_SYSCLK_IHO_FREQ : 0UL;
3260             break;
3261 #endif
3262 
3263 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
3264         case CY_SYSCLK_CLKPATH_IN_ILO0:
3265 #else
3266         case CY_SYSCLK_CLKPATH_IN_ILO:
3267 #endif
3268             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
3269             break;
3270 
3271         case CY_SYSCLK_CLKPATH_IN_WCO:
3272             freq = (Cy_SysClk_WcoOkay()) ? CY_SYSCLK_WCO_FREQ : 0UL;
3273             break;
3274 
3275 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
3276         case CY_SYSCLK_CLKPATH_IN_ILO1:
3277             freq = (0UL != (SRSS_CLK_ILO_CONFIG & SRSS_CLK_ILO_CONFIG_ENABLE_Msk)) ? CY_SYSCLK_ILO_FREQ : 0UL;
3278             break;
3279 #endif
3280 
3281         default:
3282             /* Don't know the frequency of dsi_out, leave freq = 0UL */
3283             break;
3284     }
3285 
3286     return (freq);
3287 }
3288 
3289 /*******************************************************************************
3290 * Function Name: Cy_SysClk_ClkPathGetFrequency
3291 ****************************************************************************//**
3292 *
3293 * Returns the output frequency of the clock path mux.
3294 *
3295 * \return The output frequency of the path mux.
3296 *
3297 * \note If the return value equals zero, that means either:
3298 * - the selected path mux source signal frequency is unknown (e.g. dsi_out, etc.) or
3299 * - the selected path mux source is not configured/enabled/stable (e.g. ECO, EXTCLK, etc.).
3300 *
3301 * \funcusage
3302 * \snippet sysclk/snippet/main.c snippet_Cy_SysClk_FllEnable
3303 *
3304 *******************************************************************************/
Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)3305 uint32_t Cy_SysClk_ClkPathGetFrequency(uint32_t clkPath)
3306 {
3307     CY_ASSERT_L1(clkPath < CY_SRSS_NUM_CLKPATH);
3308 
3309     uint32_t freq = Cy_SysClk_ClkPathMuxGetFrequency(clkPath);
3310 
3311 #if defined (CY_IP_MXS22SRSS)
3312 #if (CY_SRSS_PLL_PRESENT > 0U)
3313     if (clkPath < (CY_SRSS_NUM_PLL) && Cy_SysClk_PllIsEnabled(clkPath)) /* PLL? (always path 1...N)*/
3314     {
3315         freq = Cy_SysClk_PllGetFrequency(clkPath);
3316     }
3317 #endif /* CY_SRSS_PLL_PRESENT */
3318     else
3319     {
3320         /* Do nothing with the path mux frequency */
3321     }
3322 #elif (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
3323     if (clkPath == (uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0 && Cy_SysClk_FllIsEnabled()) /* FLL? (always path 0) */
3324     {
3325         freq = Cy_SysClk_FllGetFrequency();
3326     }
3327     else if ((clkPath != 0UL) && (clkPath <= (CY_SRSS_NUM_PLL)) && Cy_SysClk_PllIsEnabled(clkPath))
3328     {
3329         freq = Cy_SysClk_PllGetFrequency(clkPath);
3330     }
3331     else
3332     {
3333         /* Do nothing with the path mux frequency */
3334     }
3335 #else
3336     if (clkPath == (uint32_t)CY_SYSCLK_CLKHF_IN_CLKPATH0 && Cy_SysClk_FllIsEnabled()) /* FLL? (always path 0) */
3337     {
3338         freq = Cy_SysClk_FllGetFrequency();
3339     }
3340 #if ((CY_SRSS_PLL_PRESENT > 0U) && (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)))
3341     else if ((clkPath > 0UL) && (clkPath <= CY_SRSS_NUM_PLL) && Cy_SysClk_PllIsEnabled(clkPath)) /* PLL? (always path 1...N)*/
3342     {
3343         freq = Cy_SysClk_PllGetFrequency(clkPath);
3344     }
3345 #endif /* CY_SRSS_PLL_PRESENT */
3346     else
3347     {
3348         /* Do nothing with the path mux frequency */
3349     }
3350 #endif /* defined (CY_IP_MXS22SRSS) */
3351 
3352     return (freq);
3353 }
3354 
3355 /* ========================================================================== */
3356 /* ===========================    FLL SECTION    ============================ */
3357 /* ========================================================================== */
3358 #if defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION < 2))
3359 
3360 /* min and max FLL output frequencies, in Hz */
3361 #define  CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ (48000000UL)
3362 #define  CY_SYSCLK_FLL_MIN_OUTPUT_FREQ     (CY_SYSCLK_FLL_MIN_CCO_OUTPUT_FREQ / 2U)
3363 
3364 #define  CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(range) (((range) == CY_SYSCLK_FLL_CCO_RANGE0) || \
3365                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE1) || \
3366                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE2) || \
3367                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE3) || \
3368                                                   ((range) == CY_SYSCLK_FLL_CCO_RANGE4))
3369 /** \cond INTERNAL */
3370 #define  CY_SYSCLK_FLL_INT_COEF (327680000UL)
3371 #define  CY_SYSCLK_FLL_GAIN_IDX (11U)
3372 #define  CY_SYSCLK_FLL_GAIN_VAL (8UL * CY_SYSCLK_FLL_INT_COEF)
3373 
3374 #define TRIM_STEPS_SCALE        (100000000ULL) /* 10 ^ 8 */
3375 #define MARGIN_SCALE            (100000ULL) /* 10 ^ 5 */
3376 /** \endcond */
3377 
Cy_SysClk_FllIsEnabled(void)3378 bool Cy_SysClk_FllIsEnabled(void)
3379 {
3380 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3381     return (_FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_ENABLE, SRSS_CLK_FLL_CONFIG));
3382 #else
3383     return false;
3384 #endif
3385 }
3386 
3387 
Cy_SysClk_FllLocked(void)3388 bool Cy_SysClk_FllLocked(void)
3389 {
3390 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3391     return (_FLD2BOOL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS_CLK_FLL_STATUS));
3392 #else
3393     return false;
3394 #endif
3395 }
3396 
Cy_SysClk_FllDisable(void)3397 cy_en_sysclk_status_t Cy_SysClk_FllDisable(void)
3398 {
3399 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3400     uint32_t timeoutus = CY_SYSCLK_FLL_DISABLE_TIMEOUT;
3401     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
3402 
3403 
3404     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
3405 
3406     /* Wait until BYPASS bits are changed with a timeout */
3407     for (; (((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT) != _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS_CLK_FLL_CONFIG3)) &&
3408            (0UL != timeoutus);
3409          timeoutus--)
3410     {
3411         Cy_SysLib_DelayUs(1U);
3412     }
3413 
3414     retVal = (0UL != timeoutus) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_TIMEOUT;
3415 
3416     if(retVal == CY_SYSCLK_SUCCESS)
3417     {
3418         Cy_SysLib_DelayUs((uint16_t)CY_SYSCLK_BYPASS_CONFIGURE_DELAY);
3419 
3420         SRSS_CLK_FLL_CONFIG  &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
3421         SRSS_CLK_FLL_CONFIG4 &= ~SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
3422 
3423     }
3424 
3425     return retVal;
3426 #else
3427     return (CY_SYSCLK_UNSUPPORTED_STATE);
3428 #endif
3429 }
3430 
Cy_SysClk_FllOutputDividerEnable(bool enable)3431 void Cy_SysClk_FllOutputDividerEnable(bool enable)
3432 {
3433 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3434     SRSS_CLK_FLL_CONFIG = _BOOL2FLD(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, enable);
3435 #else
3436     CY_UNUSED_PARAMETER(enable); /* Suppress a compiler warning about unused variables */
3437 #endif
3438 }
3439 
3440 
Cy_SysClk_FllConfigure(uint32_t inputFreq,uint32_t outputFreq,cy_en_fll_pll_output_mode_t outputMode)3441 cy_en_sysclk_status_t Cy_SysClk_FllConfigure(uint32_t inputFreq, uint32_t outputFreq, cy_en_fll_pll_output_mode_t outputMode)
3442 {
3443 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3444     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
3445 
3446     /* check for errors */
3447     if ((outputFreq < CY_SYSCLK_FLL_MIN_OUTPUT_FREQ) || (CY_SYSCLK_FLL_MAX_OUTPUT_FREQ < outputFreq) || /* invalid output frequency */
3448       (outputFreq  < ((inputFreq * 11UL) / 10UL ))) /* check output/input frequency ratio */
3449     {
3450         retVal = CY_SYSCLK_BAD_PARAM;
3451     }
3452     else /* no errors */
3453     {
3454         /* If output mode is bypass (input routed directly to output), then done.
3455            The output frequency equals the input frequency regardless of the
3456            frequency parameters. */
3457         if (outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
3458         {
3459             cy_stc_fll_manual_config_t config;
3460             uint32_t ccoFreq;
3461             bool wcoSource = (CY_SYSCLK_CLKPATH_IN_WCO == Cy_SysClk_ClkPathGetSource(0UL/*FLL*/)) ? true : false;
3462 
3463             config.outputMode = outputMode;
3464             /* 1. Output division by 2 is always required */
3465             config.enableOutputDiv = true;
3466             /* 2. Compute the target CCO frequency from the target output frequency and output division */
3467             ccoFreq = outputFreq * 2UL;
3468             /* 3. Compute the CCO range value from the CCO frequency */
3469             config.ccoRange = ((ccoFreq >= 150339200UL) ? CY_SYSCLK_FLL_CCO_RANGE4 :
3470                                ((ccoFreq >= 113009380UL) ? CY_SYSCLK_FLL_CCO_RANGE3 :
3471                                 ((ccoFreq >=  84948700UL) ? CY_SYSCLK_FLL_CCO_RANGE2 :
3472                                  ((ccoFreq >=  63855600UL) ? CY_SYSCLK_FLL_CCO_RANGE1 : CY_SYSCLK_FLL_CCO_RANGE0))));
3473 
3474         /* 4. Compute the FLL reference divider value.
3475               refDiv is a constant if the WCO is the FLL source, otherwise the formula is
3476               refDiv = ROUNDUP((inputFreq / outputFreq) * 250) */
3477             config.refDiv = wcoSource ? 19U : (uint16_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)inputFreq * 250ULL, (uint64_t)outputFreq);
3478 
3479         /* 5. Compute the FLL multiplier value.
3480               Formula is fllMult = ccoFreq / (inputFreq / refDiv) */
3481             config.fllMult = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)ccoFreq * (uint64_t)config.refDiv, (uint64_t)inputFreq);
3482         /* 6. Compute the lock tolerance.
3483               Formula is lock tolerance = 1.5 * fllMult * (((1 + CCO accuracy) / (1 - source clock accuracy)) - 1)
3484               We assume CCO accuracy is 0.25%.
3485               We assume the source clock accuracy = 1%. This is the accuracy of the IMO.
3486               Therefore the formula is lock tolerance = 1.5 * fllMult * 0.012626 = 0.018939 * fllMult */
3487             config.lockTolerance = (uint16_t)CY_SYSLIB_DIV_ROUNDUP(config.fllMult * 18939UL, 1000000UL);
3488 
3489             {
3490                 /* constants indexed by ccoRange */
3491                 const uint32_t trimSteps[] = {110340UL, 110200UL, 110000UL, 110000UL, 117062UL}; /* Scaled by 10^8 */
3492                 const uint32_t margin[] = {436UL, 581UL, 772UL, 1030UL, 1320UL}; /* Scaled by 10^5 */
3493         /* 7. Compute the CCO igain and pgain */
3494                 {
3495                     /* intermediate parameters */
3496                     uint32_t kcco = (trimSteps[config.ccoRange] * margin[config.ccoRange]);
3497                     uint32_t ki_p = (uint32_t)CY_SYSLIB_DIV_ROUND(850ULL * CY_SYSCLK_FLL_INT_COEF * inputFreq, (uint64_t)kcco * (uint64_t)config.refDiv);
3498 
3499                     /* find the largest IGAIN value that is less than or equal to ki_p */
3500                     uint32_t locigain = CY_SYSCLK_FLL_GAIN_VAL;
3501                     uint32_t locpgain = CY_SYSCLK_FLL_GAIN_VAL;
3502 
3503                     /* find the largest IGAIN value that is less than or equal to ki_p */
3504                     for(config.igain = CY_SYSCLK_FLL_GAIN_IDX; config.igain != 0UL; config.igain--)
3505                     {
3506                        if(locigain <= ki_p)
3507                        {
3508                           break;
3509                        }
3510                        locigain >>= 1U;
3511                     }
3512                     /* decrement igain if the WCO is the FLL source */
3513                     if (wcoSource && (config.igain > 0U))
3514                     {
3515                         config.igain--;
3516                         locigain >>= 1U;
3517                     }
3518 
3519                     /* then find the largest PGAIN value that is less than or equal to ki_p - igain */
3520                     for(config.pgain = CY_SYSCLK_FLL_GAIN_IDX; config.pgain != 0UL; config.pgain--)
3521                     {
3522                       if(locpgain <= (ki_p - locigain))
3523                       {
3524                           break;
3525                       }
3526                       locpgain >>= 1U;
3527                     }
3528 
3529                     /* decrement pgain if the WCO is the FLL source */
3530                     if (wcoSource && (config.pgain > 0U))
3531                     {
3532                         config.pgain--;
3533                     }
3534                 }
3535 
3536         /* 8. Compute the CCO_FREQ bits in CLK_FLL_CONFIG4 register */
3537                 {
3538                     uint64_t cmp = CY_SYSLIB_DIV_ROUND(((TRIM_STEPS_SCALE / MARGIN_SCALE) * (uint64_t)ccoFreq), (uint64_t)margin[config.ccoRange]);
3539                     uint64_t mlt = TRIM_STEPS_SCALE + (uint64_t)trimSteps[config.ccoRange];
3540                     uint64_t res = mlt;
3541 
3542                     config.cco_Freq = 0U;
3543 
3544                     while(res < cmp)
3545                     {
3546                         res *= mlt;
3547                         res /= TRIM_STEPS_SCALE;
3548                         config.cco_Freq++;
3549                     }
3550                 }
3551             }
3552 
3553         /* 9. Compute the settling count, using a 1 usec settling time. Use a constant if the WCO is the FLL source */
3554             {
3555                 uint64_t fref = CY_SYSLIB_DIV_ROUND(6000ULL * (uint64_t)inputFreq, (uint64_t)config.refDiv);
3556                 uint32_t divval = CY_SYSLIB_DIV_ROUNDUP(inputFreq, 1000000UL);
3557                 uint32_t altval = (uint32_t)CY_SYSLIB_DIV_ROUNDUP((uint64_t)divval * fref, 6000000ULL) + 1UL;
3558 
3559                 config.settlingCount = wcoSource ? 200U : (uint16_t)
3560                           ((outputFreq < fref) ? divval :
3561                             ((divval > altval) ? divval : altval));
3562             }
3563         /* Configure FLL based on calculated values */
3564             retVal = Cy_SysClk_FllManualConfigure(&config);
3565         }
3566         else /* if not, bypass output mode */
3567         {
3568             CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
3569         }
3570     }
3571 
3572     return (retVal);
3573 #else
3574     CY_UNUSED_PARAMETER(inputFreq); /* Suppress a compiler warning about unused variables */
3575     CY_UNUSED_PARAMETER(outputFreq); /* Suppress a compiler warning about unused variables */
3576     CY_UNUSED_PARAMETER(outputMode); /* Suppress a compiler warning about unused variables */
3577     return CY_SYSCLK_UNSUPPORTED_STATE;
3578 #endif
3579 }
3580 
3581 
Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t * config)3582 cy_en_sysclk_status_t Cy_SysClk_FllManualConfigure(const cy_stc_fll_manual_config_t *config)
3583 {
3584 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3585     cy_en_sysclk_status_t retVal = CY_SYSCLK_INVALID_STATE;
3586 
3587     /* Check for errors */
3588     CY_ASSERT_L1(config != NULL);
3589 
3590     if (!Cy_SysClk_FllIsEnabled()) /* If disabled */
3591     {
3592         /* update CLK_FLL_CONFIG register with 2 parameters; FLL_ENABLE is already 0 */
3593         /* asserts just check for bitfield overflow */
3594         CY_ASSERT_L1(config->fllMult <= (SRSS_CLK_FLL_CONFIG_FLL_MULT_Msk >> SRSS_CLK_FLL_CONFIG_FLL_MULT_Pos));
3595 
3596         SRSS_CLK_FLL_CONFIG = _VAL2FLD(SRSS_CLK_FLL_CONFIG_FLL_MULT, config->fllMult) |
3597                              _BOOL2FLD(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, config->enableOutputDiv);
3598 
3599         /* update CLK_FLL_CONFIG2 register with 2 parameters */
3600         /* asserts just check for bitfield overflow */
3601         CY_ASSERT_L1(config->refDiv <= (SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Msk >> SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV_Pos));
3602         CY_ASSERT_L1(config->lockTolerance <= (SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Msk >> SRSS_CLK_FLL_CONFIG2_LOCK_TOL_Pos));
3603 
3604         SRSS_CLK_FLL_CONFIG2 = _VAL2FLD(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, config->refDiv) |
3605                                _VAL2FLD(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, config->lockTolerance);
3606 
3607         /* update CLK_FLL_CONFIG3 register with 4 parameters */
3608         /* asserts just check for bitfield overflow */
3609         CY_ASSERT_L1(config->igain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN_Pos));
3610         CY_ASSERT_L1(config->pgain <= (SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Msk >> SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN_Pos));
3611         CY_ASSERT_L1(config->settlingCount <= (SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Msk >> SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT_Pos));
3612 
3613         SRSS_CLK_FLL_CONFIG3 = _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, config->igain) |
3614                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, config->pgain) |
3615                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, config->settlingCount) |
3616                                _VAL2FLD(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, config->outputMode);
3617 
3618         /* update CLK_FLL_CONFIG4 register with 1 parameter; preserve other bits */
3619         /* asserts just check for bitfield overflow */
3620         CY_ASSERT_L1(CY_SYSCLK_FLL_IS_CCO_RANGE_VALID(config->ccoRange));
3621         CY_ASSERT_L1(config->cco_Freq <= (SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Msk >> SRSS_CLK_FLL_CONFIG4_CCO_FREQ_Pos));
3622 
3623         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_RANGE, (uint32_t)(config->ccoRange));
3624         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG4, SRSS_CLK_FLL_CONFIG4_CCO_FREQ, (uint32_t)(config->cco_Freq));
3625 
3626         retVal = CY_SYSCLK_SUCCESS;
3627     }
3628 
3629     return (retVal);
3630 #else
3631     CY_UNUSED_PARAMETER(config); /* Suppress a compiler warning about unused variables */
3632     return CY_SYSCLK_UNSUPPORTED_STATE;
3633 #endif
3634 }
3635 
3636 
Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t * config)3637 void Cy_SysClk_FllGetConfiguration(cy_stc_fll_manual_config_t *config)
3638 {
3639 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3640     CY_ASSERT_L1(config != NULL);
3641     /* read 2 parameters from CLK_FLL_CONFIG register */
3642     uint32_t tempReg = SRSS_CLK_FLL_CONFIG;
3643     config->fllMult         = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, tempReg);
3644     config->enableOutputDiv = _FLD2BOOL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, tempReg);
3645     /* read 2 parameters from CLK_FLL_CONFIG2 register */
3646     tempReg = SRSS_CLK_FLL_CONFIG2;
3647     config->refDiv          = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, tempReg);
3648     config->lockTolerance   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG2_LOCK_TOL, tempReg);
3649     /* read 4 parameters from CLK_FLL_CONFIG3 register */
3650     tempReg = SRSS_CLK_FLL_CONFIG3;
3651     config->igain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_IGAIN, tempReg);
3652     config->pgain           = (uint8_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_FLL_LF_PGAIN, tempReg);
3653     config->settlingCount   = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_SETTLING_COUNT, tempReg);
3654     config->outputMode      = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, tempReg));
3655     /* read 2 parameters from CLK_FLL_CONFIG4 register */
3656     tempReg = SRSS_CLK_FLL_CONFIG4;
3657     config->ccoRange        = (cy_en_fll_cco_ranges_t)((uint32_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_RANGE, tempReg));
3658     config->cco_Freq        = (uint16_t)_FLD2VAL(SRSS_CLK_FLL_CONFIG4_CCO_FREQ, tempReg);
3659 #else
3660     CY_UNUSED_PARAMETER(config); /* Suppress a compiler warning about unused variables */
3661 #endif
3662 }
3663 
3664 #if defined (__ARMCC_VERSION)
Cy_SysClk_FllEnable(uint32_t timeoutus)3665 cy_en_sysclk_status_t __attribute__((optnone)) Cy_SysClk_FllEnable(uint32_t timeoutus)
3666 #elif defined(__GNUC__)
3667 cy_en_sysclk_status_t __attribute__((optimize("Og"))) Cy_SysClk_FllEnable(uint32_t timeoutus)
3668 #else
3669 cy_en_sysclk_status_t Cy_SysClk_FllEnable(uint32_t timeoutus)
3670 #endif /* defined (__ARMCC_VERSION) */
3671 {
3672 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3673     bool zeroTimeout = (0UL == timeoutus);
3674 
3675     /* first set the CCO enable bit */
3676     SRSS_CLK_FLL_CONFIG4 |= SRSS_CLK_FLL_CONFIG4_CCO_ENABLE_Msk;
3677 
3678     /* Wait until CCO is ready */
3679     for (; (!_FLD2BOOL(SRSS_CLK_FLL_STATUS_CCO_READY, SRSS_CLK_FLL_STATUS)) && /* if cco_ready == 0 */
3680            (0UL != timeoutus);
3681          timeoutus--)
3682     {
3683         Cy_SysLib_DelayUs(1U);
3684     }
3685 
3686     /* Set the FLL bypass mode to FLL_REF */
3687     CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
3688 
3689     /* Set the FLL enable bit, if CCO is ready */
3690     if (zeroTimeout || (0UL != timeoutus))
3691     {
3692         SRSS_CLK_FLL_CONFIG |= SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
3693     }
3694 
3695     /* now do the timeout wait for FLL_STATUS, bit LOCKED */
3696     for (; (!Cy_SysClk_FllLocked()) && /* if locked == 0 */
3697            (0UL != timeoutus);
3698          timeoutus--)
3699     {
3700         Cy_SysLib_DelayUs(1U);
3701     }
3702 
3703     if (zeroTimeout || (0UL != timeoutus))
3704     {
3705         /* Set the FLL bypass mode to FLL_OUT (ignoring lock indicator) */
3706         CY_REG32_CLR_SET(SRSS_CLK_FLL_CONFIG3, SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
3707     }
3708     else
3709     {
3710         /* If lock doesn't occur, FLL is stopped */
3711         (void)Cy_SysClk_FllDisable();
3712     }
3713 
3714     return ((zeroTimeout || (0UL != timeoutus)) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_TIMEOUT);
3715 #else
3716     CY_UNUSED_PARAMETER(timeoutus); /* Suppress a compiler warning about unused variables */
3717     return CY_SYSCLK_UNSUPPORTED_STATE;
3718 #endif
3719 }
3720 
Cy_SysClk_FllGetFrequency(void)3721 uint32_t Cy_SysClk_FllGetFrequency(void)
3722 {
3723 #if ((defined CY_SRSS_FLL_PRESENT) && (CY_SRSS_FLL_PRESENT == 1U))
3724 
3725     uint32_t fDiv ;    /* FLL multiplier/feedback divider */
3726     uint32_t rDiv;    /* FLL reference divider */
3727     uint32_t oDiv;    /* FLL output divider */
3728     bool  enabled;    /* FLL enable status; n/a for direct */
3729     uint32_t freq = 0UL;    /* FLL Frequency */
3730 
3731     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};
3732     Cy_SysClk_FllGetConfiguration(&fllCfg);
3733     enabled = (Cy_SysClk_FllIsEnabled()) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != fllCfg.outputMode);
3734     fDiv = fllCfg.fllMult;
3735     rDiv = fllCfg.refDiv;
3736     oDiv = (fllCfg.enableOutputDiv) ? 2UL : 1UL;
3737 
3738     if (enabled && /* If FLL is enabled and not bypassed */
3739         (0UL != rDiv)) /* to avoid division by zero */
3740     {
3741         freq = Cy_SysClk_ClkPathMuxGetFrequency(0UL); /* FLL mapped always to path 0 */
3742         freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
3743                                              ((uint64_t)rDiv * (uint64_t)oDiv));
3744     }
3745 
3746     return (freq);
3747 #else
3748     return 0U;
3749 #endif
3750 }
3751 #endif /* defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION < 2)) */
3752 /* ========================================================================== */
3753 /* ===========================    PLL SECTION    ============================ */
3754 /* ========================================================================== */
3755 
3756 /* PLL200M */
3757 /* PLL OUTPUT_DIV bitfield allowable range */
3758 #define CY_SYSCLK_PLL_MIN_OUTPUT_DIV   (2UL)
3759 #define CY_SYSCLK_PLL_MAX_OUTPUT_DIV   (16UL)
3760 
3761 /* PLL REFERENCE_DIV bitfield allowable range */
3762 #define CY_SYSCLK_PLL_MIN_REF_DIV      (1UL)
3763 #define CY_SYSCLK_PLL_MAX_REF_DIV      (18UL)
3764 
3765 /* PLL FEEDBACK_DIV bitfield allowable ranges, LF and normal modes */
3766 #define CY_SYSCLK_PLL_MIN_FB_DIV_LF    (19UL)
3767 #define CY_SYSCLK_PLL_MAX_FB_DIV_LF    (56UL)
3768 #define CY_SYSCLK_PLL_MIN_FB_DIV_NORM  (22UL)
3769 #define CY_SYSCLK_PLL_MAX_FB_DIV_NORM  (112UL)
3770 
3771 /* PLL FEEDBACK_DIV bitfield allowable range selection */
3772 #define CY_SYSCLK_PLL_MIN_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FB_DIV_LF : CY_SYSCLK_PLL_MIN_FB_DIV_NORM)
3773 #define CY_SYSCLK_PLL_MAX_FB_DIV       ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FB_DIV_LF : CY_SYSCLK_PLL_MAX_FB_DIV_NORM)
3774 
3775 /* PLL Fvco range allowable ranges, LF and normal modes */
3776 #define CY_SYSCLK_PLL_MIN_FVCO_LF      (170000000UL)
3777 #define CY_SYSCLK_PLL_MAX_FVCO_LF      (200000000UL)
3778 #define CY_SYSCLK_PLL_MIN_FVCO_NORM    (200000000UL)
3779 #define CY_SYSCLK_PLL_MAX_FVCO_NORM    (400000000UL)
3780 /* PLL Fvco range selection */
3781 #define CY_SYSCLK_PLL_MIN_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MIN_FVCO_LF : CY_SYSCLK_PLL_MIN_FVCO_NORM)
3782 #define CY_SYSCLK_PLL_MAX_FVCO         ((config->lfMode) ? CY_SYSCLK_PLL_MAX_FVCO_LF : CY_SYSCLK_PLL_MAX_FVCO_NORM)
3783 
3784 /* PLL input and output frequency limits */
3785 #define CY_SYSCLK_PLL_MIN_IN_FREQ  (4000000UL)
3786 #define CY_SYSCLK_PLL_MAX_IN_FREQ  (64000000UL)
3787 #define CY_SYSCLK_PLL_MIN_OUT_FREQ (CY_SYSCLK_PLL_MIN_FVCO / CY_SYSCLK_PLL_MAX_OUTPUT_DIV)
3788 #if defined (CY_DEVICE_SERIES_CYT2B6)
3789 #define CY_SYSCLK_PLL_MAX_OUT_FREQ (80000000UL)
3790 #elif defined (CY_DEVICE_TVIIBE)
3791 #define CY_SYSCLK_PLL_MAX_OUT_FREQ (160000000UL)
3792 #else
3793 #define CY_SYSCLK_PLL_MAX_OUT_FREQ (200000000UL)
3794 #endif
3795 
3796 /* PLL400M */
3797 
3798 /* Only include PLL400M macros for devices that contain PLL400M IP. */
3799 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3800 /* PLL OUTPUT_DIV bitfield allowable range */
3801 #define CY_SYSCLK_PLL400M_MIN_OUTPUT_DIV   (2UL)
3802 #define CY_SYSCLK_PLL400M_MAX_OUTPUT_DIV   (16UL)
3803 
3804 /* PLL REFERENCE_DIV bitfield allowable range */
3805 #define CY_SYSCLK_PLL400M_MIN_REF_DIV      (1UL)
3806 #define CY_SYSCLK_PLL400M_MAX_REF_DIV      (16UL)
3807 
3808 /* PLL FEEDBACK_DIV bitfield allowable range selection */
3809 #define CY_SYSCLK_PLL400M_MIN_FB_DIV       (16UL)
3810 #define CY_SYSCLK_PLL400M_MAX_FB_DIV       (200UL)
3811 
3812 /* PLL Fvco range selection */
3813 #define CY_SYSCLK_PLL400M_MIN_FVCO         (400000000UL)
3814 #define CY_SYSCLK_PLL400M_MAX_FVCO         (800000000UL)
3815 
3816 /* PLL input and output frequency limits */
3817 #define CY_SYSCLK_PLL400M_MIN_IN_FREQ  (4000000UL)
3818 #define CY_SYSCLK_PLL400M_MAX_IN_FREQ  (64000000UL)
3819 #define CY_SYSCLK_PLL400M_MIN_OUT_FREQ (25000000UL)
3820 #define CY_SYSCLK_PLL400M_MAX_OUT_FREQ (400000000UL)
3821 #endif
3822 
3823 
3824 
3825 /* DPLL-LP */
3826 
3827 /* DPLL-LP OUTPUT_DIV bitfield allowable range */
3828 #define CY_SYSCLK_DPLL_LP_MIN_OUTPUT_DIV   (1UL)
3829 #define CY_SYSCLK_DPLL_LP_MAX_OUTPUT_DIV   (16UL)
3830 
3831 /* DPLL-LP REFERENCE_DIV bitfield allowable range */
3832 #define CY_SYSCLK_DPLL_LP_MIN_REF_DIV      (1UL)
3833 #define CY_SYSCLK_DPLL_LP_MAX_REF_DIV      (16UL)
3834 
3835 /* DPLL-LP FEEDBACK_DIV bitfield allowable range selection */
3836 #define CY_SYSCLK_DPLL_LP_MIN_FB_DIV       (16UL)
3837 #define CY_SYSCLK_DPLL_LP_MAX_FB_DIV       (200UL)
3838 
3839 /* DPLL-LP Fdco range selection */
3840 #define CY_SYSCLK_DPLL_LP_MIN_FDCO         (160000000UL)
3841 #define CY_SYSCLK_DPLL_LP_MAX_FDCO         (480000000UL)
3842 #define CY_SYSCLK_DPLL_LP_DCO_MODE_LIMIT   (310000000UL)
3843 
3844 /* DPLL-LP pdf range selection */
3845 #define CY_SYSCLK_DPLL_LP_MIN_PDF         (4000000UL)
3846 #define CY_SYSCLK_DPLL_LP_MAX_PDF         (8000000UL)
3847 
3848 /* DPLL-LP input and output frequency limits */
3849 #define CY_SYSCLK_DPLL_LP_MIN_IN_FREQ  (4000000UL)
3850 #define CY_SYSCLK_DPLL_LP_MAX_IN_FREQ  (64000000UL)
3851 #define CY_SYSCLK_DPLL_LP_MIN_OUT_FREQ (10000000UL)
3852 #define CY_SYSCLK_DPLL_LP_MAX_OUT_FREQ (400000000UL)
3853 
3854 /* DPLL-LP default config values */
3855 #define CY_SYSCLK_DPLL_LP_CONFIG4_DCO_CODE  (0xFUL)
3856 #define CY_SYSCLK_DPLL_LP_CONFIG5_KI_INT    (0xAUL)
3857 #define CY_SYSCLK_DPLL_LP_CONFIG5_KI_FRACT  (0xBUL)
3858 #define CY_SYSCLK_DPLL_LP_CONFIG5_KI_SSCG   (0x7UL)
3859 #define CY_SYSCLK_DPLL_LP_CONFIG5_KP_INT    (0x8UL)
3860 #define CY_SYSCLK_DPLL_LP_CONFIG5_KP_FRACT  (0x9UL)
3861 #define CY_SYSCLK_DPLL_LP_CONFIG5_KP_SSCG   (0x7UL)
3862 
3863 /* DPLL-HP */
3864 
3865 /* DPLL-HP NDIV bitfield allowable range */
3866 #define CY_SYSCLK_DPLL_HP_MIN_NDIV   (8UL)
3867 #define CY_SYSCLK_DPLL_HP_MAX_NDIV   (250UL)
3868 
3869 /* DPLL-HP PDIV bitfield allowable range */
3870 #define CY_SYSCLK_DPLL_HP_MIN_PDIV   (1UL)
3871 #define CY_SYSCLK_DPLL_HP_MAX_PDIV   (8UL)
3872 
3873 /* DPLL-HP KDIV bitfield allowable range */
3874 #define CY_SYSCLK_DPLL_HP_MIN_KDIV   (2UL)
3875 #define CY_SYSCLK_DPLL_HP_MAX_KDIV   (8UL)
3876 /* DPLL-HP Fdco range selection */
3877 #define CY_SYSCLK_DPLL_HP_MIN_FDCO         (400000UL)
3878 #define CY_SYSCLK_DPLL_HP_MAX_FDCO         (1000000UL)
3879 
3880 /* DPLL-HP pdf range selection */
3881 #define CY_SYSCLK_DPLL_HP_MIN_PDF         (17000UL)
3882 #define CY_SYSCLK_DPLL_HP_MAX_PDF         (50000UL)
3883 
3884 /* DPLL-HP input and output frequency limits */
3885 #define CY_SYSCLK_DPLL_HP_MIN_IN_FREQ  (4000000UL)
3886 #define CY_SYSCLK_DPLL_HP_MAX_IN_FREQ  (50000000UL)
3887 #define CY_SYSCLK_DPLL_HP_MIN_OUT_FREQ (50000000UL)
3888 #define CY_SYSCLK_DPLL_HP_MAX_OUT_FREQ (400000000UL)
3889 
3890 /* DPLL-HP default config values */
3891 #define CY_SYSCLK_DPLL_HP_CONFIG2_FREQ_MODE_SEL_CODE  (CY_SYSCLK_DPLL_HP_CLK50MHZ_1US_CNT_VAL)
3892 #define CY_SYSCLK_DPLL_HP_CONFIG2_IVR_TRIM            (0x8U)
3893 #define CY_SYSCLK_DPLL_HP_CONFIG3_CLKR_SEL            (true)
3894 
3895 #define CY_SYSCLK_DPLL_HP_CONFIG4_LF_LC_ALPHA         (0xCU)
3896 #define CY_SYSCLK_DPLL_HP_CONFIG4_LF_LC_BETA          (0x5U)
3897 
3898 #define CY_SYSCLK_DPLL_HP_CONFIG4_FLOCK_EN_TH3        (0x3U)
3899 #define CY_SYSCLK_DPLL_HP_CONFIG4_FLOCK_EN_TH7        (0x7U)
3900 
3901 #define CY_SYSCLK_DPLL_HP_CONFIG4_FLOCK_WAITPER       (0x6U)
3902 #define CY_SYSCLK_DPLL_HP_CONFIG4_LK_TH               (0x7U)
3903 #define CY_SYSCLK_DPLL_HP_CONFIG4_LK_WAITPER          (0x8U)
3904 
3905 #define CY_SYSCLK_DPLL_HP_CONFIG5_LF_ALPHA            (0x14U)
3906 #define CY_SYSCLK_DPLL_HP_CONFIG5_LF_BETA             (0x14U)
3907 #define CY_SYSCLK_DPLL_HP_CONFIG5_LF_SET_PARAMS       (true)
3908 
3909 #define CY_SYSCLK_DPLL_HP_DUTY_CAL_CTL_DC_EN          (true)
3910 
3911 
3912 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined(CY_IP_MXS22SRSS) || (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
3913 
3914 #if (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2))
3915 
3916 /* Only include PLL400M functions for devices that contain PLL400M IP. */
3917 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
Cy_SysClk_Pll400MIsEnabled(uint32_t pllNum)3918 bool Cy_SysClk_Pll400MIsEnabled(uint32_t pllNum)
3919 {
3920     CY_UNUSED_PARAMETER(pllNum);
3921 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3922     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
3923     return (_FLD2BOOL(CLK_PLL400M_CONFIG_ENABLE, SRSS_CLK_PLL_400M_CONFIG(pllNum)));
3924 #else
3925     return false;
3926 #endif
3927 }
3928 
3929 
Cy_SysClk_Pll400MLocked(uint32_t pllNum)3930 bool Cy_SysClk_Pll400MLocked(uint32_t pllNum)
3931 {
3932     CY_UNUSED_PARAMETER(pllNum);
3933 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3934     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
3935     return (_FLD2BOOL(CLK_PLL400M_STATUS_LOCKED, SRSS_CLK_PLL_400M_STATUS(pllNum)));
3936 #else
3937      return false;
3938 #endif
3939 }
3940 
3941 
Cy_SysClk_Pll400MLostLock(uint32_t pllNum)3942 bool Cy_SysClk_Pll400MLostLock(uint32_t pllNum)
3943 {
3944     CY_UNUSED_PARAMETER(pllNum);
3945 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3946     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
3947 
3948     bool retVal = _FLD2BOOL(CLK_PLL400M_STATUS_UNLOCK_OCCURRED, SRSS_CLK_PLL_400M_STATUS(pllNum));
3949     /* write a 1 to clear the unlock occurred bit */
3950     SRSS_CLK_PLL_400M_STATUS(pllNum) = CLK_PLL400M_STATUS_UNLOCK_OCCURRED_Msk;
3951     return (retVal);
3952 #else
3953     return false;
3954 #endif
3955 }
3956 
3957 
Cy_SysClk_Pll400MDisable(uint32_t pllNum)3958 cy_en_sysclk_status_t Cy_SysClk_Pll400MDisable(uint32_t pllNum)
3959 {
3960     CY_UNUSED_PARAMETER(pllNum);
3961 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3962 
3963     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
3964 
3965     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
3966 
3967     /* First bypass PLL */
3968     CY_REG32_CLR_SET(SRSS_CLK_PLL_400M_CONFIG(pllNum), CLK_PLL400M_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
3969     /* Wait at least 6 PLL clock cycles */
3970     Cy_SysLib_DelayUs(1U);
3971     /* And now disable the PLL itself */
3972     SRSS_CLK_PLL_400M_CONFIG(pllNum) &= ~CLK_PLL400M_CONFIG_ENABLE_Msk;
3973     retVal = CY_SYSCLK_SUCCESS;
3974 
3975     return (retVal);
3976 #else
3977     return CY_SYSCLK_UNSUPPORTED_STATE;
3978 #endif
3979 }
3980 
3981 
Cy_SysClk_Pll400MConfigure(uint32_t pllNum,const cy_stc_pll_config_t * config)3982 cy_en_sysclk_status_t Cy_SysClk_Pll400MConfigure(uint32_t pllNum, const cy_stc_pll_config_t *config)
3983 {
3984     CY_UNUSED_PARAMETER(pllNum);
3985     CY_UNUSED_PARAMETER(config);
3986 
3987 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
3988 
3989     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
3990 
3991     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
3992 
3993     if (((config->inputFreq)  < CY_SYSCLK_PLL400M_MIN_IN_FREQ)  || (CY_SYSCLK_PLL400M_MAX_IN_FREQ  < (config->inputFreq)) ||
3994         ((config->outputFreq) < CY_SYSCLK_PLL400M_MIN_OUT_FREQ) || (CY_SYSCLK_PLL400M_MAX_OUT_FREQ < (config->outputFreq)))
3995     {
3996         retVal = CY_SYSCLK_BAD_PARAM;
3997     }
3998     else
3999     {
4000         cy_stc_pll_manual_config_t manualConfig = {0U,0U,0U,false,CY_SYSCLK_FLLPLL_OUTPUT_AUTO, 0, false, false, 0 , 0 , false};
4001 
4002         /* If output mode is not bypass (input routed directly to output), then
4003            calculate new parameters. */
4004         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4005         {
4006             /* for each possible value of OUTPUT_DIV and REFERENCE_DIV (Q), try
4007                to find a value for FEEDBACK_DIV (P) that gives an output frequency
4008                as close as possible to the desired output frequency. */
4009             uint32_t p, q, out;
4010             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
4011 
4012             /* REFERENCE_DIV (Q) selection */
4013             for (q = CY_SYSCLK_PLL400M_MIN_REF_DIV; q <= CY_SYSCLK_PLL400M_MAX_REF_DIV; q++)
4014             {
4015                 /* FEEDBACK_DIV (P) selection */
4016                 for (p = CY_SYSCLK_PLL400M_MIN_FB_DIV; p <= CY_SYSCLK_PLL400M_MAX_FB_DIV; p++)
4017                 {
4018                     /* Calculate the intermediate Fvco, and make sure that it's in range */
4019                     uint32_t fvco = (uint32_t)(((uint64_t)(config->inputFreq) * (uint64_t)p) / (uint64_t)q);
4020                     if ((CY_SYSCLK_PLL400M_MIN_FVCO <= fvco) && (fvco <= CY_SYSCLK_PLL400M_MAX_FVCO))
4021                     {
4022                         /* OUTPUT_DIV selection */
4023                         for (out = CY_SYSCLK_PLL400M_MIN_OUTPUT_DIV; out <= CY_SYSCLK_PLL400M_MAX_OUTPUT_DIV; out++)
4024                         {
4025                             uint64_t tempVco = ((uint64_t)config->outputFreq) * ((uint64_t)out);
4026                             uint64_t tempFeedBackDivLeftShifted = ((tempVco << (uint64_t)SRSS_PLL400M_FRAC_BIT_COUNT) * (uint64_t)q) / (uint64_t)config->inputFreq;
4027                             volatile uint32_t feedBackFracDiv  = (uint32_t)(tempFeedBackDivLeftShifted & ((1ULL << (uint64_t)SRSS_PLL400M_FRAC_BIT_COUNT) - 1ULL));
4028                             /* Calculate what output frequency will actually be produced.
4029                                If it's closer to the target than what we have so far, then save it. */
4030                             uint32_t fout = (uint32_t)((((uint64_t)config->inputFreq * (((uint64_t)p << SRSS_PLL400M_FRAC_BIT_COUNT) + (uint64_t)feedBackFracDiv)) / ((uint64_t)q * (uint64_t)out)) >> SRSS_PLL400M_FRAC_BIT_COUNT);
4031 
4032                             if ((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
4033                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq)))
4034                             {
4035                                 if (foutBest == (config->outputFreq))
4036                                 {
4037                                    break;
4038                                 }
4039 
4040                                 foutBest = fout;
4041                                 manualConfig.feedbackDiv  = (uint8_t)p;
4042                                 manualConfig.referenceDiv = (uint8_t)q;
4043                                 manualConfig.outputDiv    = (uint8_t)out;
4044                                 manualConfig.fracEn       = true;
4045                                 manualConfig.fracDiv      = feedBackFracDiv;
4046                             }
4047                         }
4048                     }
4049                 }
4050             }
4051             /* exit loops if foutBest equals outputFreq */
4052 
4053         } /* if not, bypass output mode */
4054 
4055         /* If output mode is bypass (input routed directly to output), then
4056            use old parameters. */
4057         else
4058         {
4059             (void)Cy_SysClk_Pll400MGetConfiguration(pllNum, &manualConfig);
4060         }
4061         /* configure PLL based on calculated values */
4062 
4063         manualConfig.outputMode = config->outputMode;
4064         retVal = Cy_SysClk_Pll400MManualConfigure(pllNum, &manualConfig);
4065 
4066     } /* if no error */
4067 
4068     return (retVal);
4069 #else
4070     return CY_SYSCLK_UNSUPPORTED_STATE;
4071 #endif
4072 }
4073 
4074 
Cy_SysClk_Pll400MManualConfigure(uint32_t pllNum,const cy_stc_pll_manual_config_t * config)4075 cy_en_sysclk_status_t Cy_SysClk_Pll400MManualConfigure(uint32_t pllNum, const cy_stc_pll_manual_config_t *config)
4076 {
4077     CY_UNUSED_PARAMETER(pllNum);
4078     CY_UNUSED_PARAMETER(config);
4079 
4080 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
4081 
4082     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
4083 
4084     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
4085 
4086     if (Cy_SysClk_Pll400MIsEnabled(pllNum))
4087     {
4088         retVal = CY_SYSCLK_INVALID_STATE;
4089     }
4090     /* valid divider bitfield values */
4091     else if ((config->outputDiv    < CY_SYSCLK_PLL400M_MIN_OUTPUT_DIV) || (CY_SYSCLK_PLL400M_MAX_OUTPUT_DIV < config->outputDiv)    ||
4092              (config->referenceDiv < CY_SYSCLK_PLL400M_MIN_REF_DIV)    || (CY_SYSCLK_PLL400M_MAX_REF_DIV    < config->referenceDiv) ||
4093              (config->feedbackDiv  < CY_SYSCLK_PLL400M_MIN_FB_DIV)     || (CY_SYSCLK_PLL400M_MAX_FB_DIV     < config->feedbackDiv))
4094     {
4095          retVal = CY_SYSCLK_BAD_PARAM;
4096     }
4097     else /* no errors */
4098     {
4099         /* If output mode is bypass (input routed directly to output), then done.
4100            The output frequency equals the input frequency regardless of the frequency parameters. */
4101         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4102         {
4103                 SRSS_CLK_PLL_400M_CONFIG(pllNum) =
4104                 _VAL2FLD(CLK_PLL400M_CONFIG_FEEDBACK_DIV,  config->feedbackDiv)  |
4105                 _VAL2FLD(CLK_PLL400M_CONFIG_REFERENCE_DIV, config->referenceDiv) |
4106                 _VAL2FLD(CLK_PLL400M_CONFIG_OUTPUT_DIV,    config->outputDiv);
4107 
4108                 SRSS_CLK_PLL_400M_CONFIG2(pllNum) =
4109                 _VAL2FLD(CLK_PLL400M_CONFIG2_FRAC_DIV, config->fracDiv)  |
4110                 _VAL2FLD(CLK_PLL400M_CONFIG2_FRAC_DITHER_EN, config->fracDitherEn) |
4111                 _VAL2FLD(CLK_PLL400M_CONFIG2_FRAC_EN, config->fracEn);
4112 
4113                 SRSS_CLK_PLL_400M_CONFIG3(pllNum) =
4114                 _VAL2FLD(CLK_PLL400M_CONFIG3_SSCG_DEPTH, config->sscgDepth)  |
4115                 _VAL2FLD(CLK_PLL400M_CONFIG3_SSCG_RATE, config->sscgRate) |
4116                 _VAL2FLD(CLK_PLL400M_CONFIG3_SSCG_EN, config->sscgEn);
4117 
4118         }
4119 
4120         CY_REG32_CLR_SET(SRSS_CLK_PLL_400M_CONFIG(pllNum), CLK_PLL400M_CONFIG_BYPASS_SEL, (uint32_t)config->outputMode);
4121     }
4122 
4123     return (retVal);
4124 #else
4125     return CY_SYSCLK_UNSUPPORTED_STATE;
4126 #endif
4127 }
4128 
4129 
Cy_SysClk_Pll400MGetConfiguration(uint32_t pllNum,cy_stc_pll_manual_config_t * config)4130 cy_en_sysclk_status_t Cy_SysClk_Pll400MGetConfiguration(uint32_t pllNum, cy_stc_pll_manual_config_t *config)
4131 {
4132     CY_UNUSED_PARAMETER(pllNum);
4133     CY_UNUSED_PARAMETER(config);
4134 
4135 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
4136 
4137     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4138 
4139     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
4140 
4141     /* Initialize config structure to 0 */
4142     *config = (cy_stc_pll_manual_config_t){0};
4143 
4144     uint32_t tempReg = SRSS_CLK_PLL_400M_CONFIG(pllNum);
4145     config->feedbackDiv  = (uint8_t)_FLD2VAL(CLK_PLL400M_CONFIG_FEEDBACK_DIV,  tempReg);
4146     config->referenceDiv = (uint8_t)_FLD2VAL(CLK_PLL400M_CONFIG_REFERENCE_DIV, tempReg);
4147     config->outputDiv    = (uint8_t)_FLD2VAL(CLK_PLL400M_CONFIG_OUTPUT_DIV,    tempReg);
4148     config->outputMode   = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(CLK_PLL400M_CONFIG_BYPASS_SEL, tempReg));
4149 
4150     tempReg = SRSS_CLK_PLL_400M_CONFIG2(pllNum);
4151     config->fracDiv      = _FLD2VAL(CLK_PLL400M_CONFIG2_FRAC_DIV,  tempReg);
4152     config->fracDitherEn = (bool)_FLD2VAL(CLK_PLL400M_CONFIG2_FRAC_DITHER_EN, tempReg);
4153     config->fracEn       = (bool)_FLD2VAL(CLK_PLL400M_CONFIG2_FRAC_EN,    tempReg);
4154 
4155     tempReg = SRSS_CLK_PLL_400M_CONFIG3(pllNum);
4156     config->sscgDepth  = (uint8_t)_FLD2VAL(CLK_PLL400M_CONFIG3_SSCG_DEPTH,  tempReg);
4157     config->sscgRate   = (uint8_t)_FLD2VAL(CLK_PLL400M_CONFIG3_SSCG_RATE, tempReg);
4158     config->sscgEn     = (bool)_FLD2VAL(CLK_PLL400M_CONFIG3_SSCG_EN,    tempReg);
4159 
4160     retVal = CY_SYSCLK_SUCCESS;
4161 
4162     return (retVal);
4163 #else
4164     return CY_SYSCLK_UNSUPPORTED_STATE;
4165 #endif
4166 }
4167 
Cy_SysClk_Pll400MEnable(uint32_t pllNum,uint32_t timeoutus)4168 cy_en_sysclk_status_t Cy_SysClk_Pll400MEnable(uint32_t pllNum, uint32_t timeoutus)
4169 {
4170     CY_UNUSED_PARAMETER(pllNum);
4171     CY_UNUSED_PARAMETER(timeoutus);
4172 #if defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u)
4173 
4174     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4175     bool zeroTimeout = (timeoutus == 0UL);
4176 
4177     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
4178 
4179     /* first set the PLL enable bit */
4180     SRSS_CLK_PLL_400M_CONFIG(pllNum) |= CLK_PLL400M_CONFIG_ENABLE_Msk;
4181 
4182     /* now do the timeout wait for PLL_STATUS, bit LOCKED */
4183     for (; (0UL == (CLK_PLL400M_STATUS_LOCKED_Msk & SRSS_CLK_PLL_400M_STATUS(pllNum))) &&
4184            (0UL != timeoutus);
4185          timeoutus--)
4186     {
4187         Cy_SysLib_DelayUs(1U);
4188     }
4189 
4190     if (zeroTimeout || (0UL != timeoutus))
4191     {
4192         /* Unbypass PLL, if it is not in AUTO mode */
4193         if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(CLK_PLL400M_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_400M_CONFIG(pllNum)))
4194         {
4195             CY_REG32_CLR_SET(SRSS_CLK_PLL_400M_CONFIG(pllNum), CLK_PLL400M_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
4196         }
4197 
4198         retVal = CY_SYSCLK_SUCCESS;
4199     }
4200     else
4201     {
4202         /* If lock doesn't occur, then bypass PLL */
4203         CY_REG32_CLR_SET(SRSS_CLK_PLL_400M_CONFIG(pllNum), CLK_PLL400M_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4204         /* Wait at least 6 PLL clock cycles */
4205         Cy_SysLib_DelayUs(1U);
4206         /* And now disable the PLL itself */
4207         SRSS_CLK_PLL_400M_CONFIG(pllNum) &= ~CLK_PLL400M_CONFIG_ENABLE_Msk;
4208         retVal = CY_SYSCLK_TIMEOUT;
4209     }
4210 
4211     return (retVal);
4212 #else
4213     return CY_SYSCLK_UNSUPPORTED_STATE;
4214 #endif
4215 }
4216 
Cy_SysClk_Pll400MGetFrequency(uint32_t pllNum)4217 uint32_t Cy_SysClk_Pll400MGetFrequency(uint32_t pllNum)
4218 {
4219     uint32_t fDiv;    /* PLL multiplier/feedback divider */
4220     uint32_t rDiv;    /* PLL reference divider */
4221     uint32_t oDiv;    /* PLL output divider */
4222     uint32_t fracDiv; /* PLL Fractional divider */
4223     bool  enabled;    /* PLL enable status; n/a for direct */
4224     uint32_t freq=0UL;    /* PLL Frequency */
4225 
4226 
4227     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL400M);
4228 
4229     cy_stc_pll_manual_config_t pllcfg = {0U,0U,0U,false,CY_SYSCLK_FLLPLL_OUTPUT_AUTO, 0, false, false, 0 , 0 , false};
4230     (void)Cy_SysClk_Pll400MGetConfiguration(pllNum, &pllcfg);
4231     enabled = (Cy_SysClk_Pll400MIsEnabled(pllNum)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.outputMode);
4232     fDiv    = pllcfg.feedbackDiv;
4233     rDiv    = pllcfg.referenceDiv;
4234     oDiv    = pllcfg.outputDiv;
4235     fracDiv = pllcfg.fracDiv;
4236 
4237     if (enabled && /* If PLL is enabled and not bypassed */
4238     (0UL != rDiv) && (0UL != oDiv)) /* to avoid division by zero */
4239     {
4240         freq = Cy_SysClk_ClkPathMuxGetFrequency(pllNum + 1UL);
4241         freq = (uint32_t)((((uint64_t)freq * (((uint64_t)fDiv << SRSS_PLL400M_FRAC_BIT_COUNT) + (uint64_t)fracDiv)) / ((uint64_t)rDiv * (uint64_t)oDiv)) >> SRSS_PLL400M_FRAC_BIT_COUNT);
4242     }
4243 
4244     return (freq);
4245 }
4246 
4247 #endif  /* defined (CY_SRSS_PLL400M_PRESENT) && (CY_SRSS_PLL400M_PRESENT == 1u) */
4248 
4249 /* PLL200M */
4250 
Cy_SysClk_Pll200MIsEnabled(uint32_t pllNum)4251 bool Cy_SysClk_Pll200MIsEnabled(uint32_t pllNum)
4252 {
4253     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4254 
4255     return (_FLD2BOOL(SRSS_CLK_PLL_CONFIG_ENABLE, SRSS_CLK_PLL_CONFIG[pllNum]));
4256 }
4257 
Cy_SysClk_Pll200MLocked(uint32_t pllNum)4258 bool Cy_SysClk_Pll200MLocked(uint32_t pllNum)
4259 {
4260     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4261 
4262     return (_FLD2BOOL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS_CLK_PLL_STATUS[pllNum]));
4263 }
4264 
Cy_SysClk_Pll200MLostLock(uint32_t pllNum)4265 bool Cy_SysClk_Pll200MLostLock(uint32_t pllNum)
4266 {
4267     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4268 
4269     bool retVal = _FLD2BOOL(SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED, SRSS_CLK_PLL_STATUS[pllNum]);
4270     /* write a 1 to clear the unlock occurred bit */
4271     SRSS_CLK_PLL_STATUS[pllNum] = SRSS_CLK_PLL_STATUS_UNLOCK_OCCURRED_Msk;
4272     return (retVal);
4273 }
4274 
4275 
Cy_SysClk_Pll200MDisable(uint32_t pllNum)4276 cy_en_sysclk_status_t Cy_SysClk_Pll200MDisable(uint32_t pllNum)
4277 {
4278     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4279 
4280     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4281 
4282     /* First bypass PLL */
4283     CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[pllNum], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4284     /* Wait at least 6 PLL clock cycles */
4285     Cy_SysLib_DelayUs(1U);
4286     /* And now disable the PLL itself */
4287     SRSS_CLK_PLL_CONFIG[pllNum] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
4288     retVal = CY_SYSCLK_SUCCESS;
4289 
4290     return (retVal);
4291 }
4292 
4293 
Cy_SysClk_Pll200MConfigure(uint32_t pllNum,const cy_stc_pll_config_t * config)4294 cy_en_sysclk_status_t Cy_SysClk_Pll200MConfigure(uint32_t pllNum, const cy_stc_pll_config_t *config)
4295 {
4296     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
4297 
4298     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4299 
4300     if (((config->inputFreq)  < CY_SYSCLK_PLL_MIN_IN_FREQ)  || (CY_SYSCLK_PLL_MAX_IN_FREQ  < (config->inputFreq)) ||
4301         ((config->outputFreq) < CY_SYSCLK_PLL_MIN_OUT_FREQ) || (CY_SYSCLK_PLL_MAX_OUT_FREQ < (config->outputFreq)))
4302     {
4303         retVal = CY_SYSCLK_BAD_PARAM;
4304     }
4305     else
4306     {
4307         cy_stc_pll_manual_config_t manualConfig;
4308 
4309         /* If output mode is not bypass (input routed directly to output), then
4310            calculate new parameters. */
4311         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4312         {
4313             /* for each possible value of OUTPUT_DIV and REFERENCE_DIV (Q), try
4314                to find a value for FEEDBACK_DIV (P) that gives an output frequency
4315                as close as possible to the desired output frequency. */
4316             uint32_t p, q, out;
4317             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
4318 
4319             /* REFERENCE_DIV (Q) selection */
4320             for (q = CY_SYSCLK_PLL_MIN_REF_DIV; q <= CY_SYSCLK_PLL_MAX_REF_DIV; q++)
4321             {
4322                 /* FEEDBACK_DIV (P) selection */
4323                 for (p = CY_SYSCLK_PLL_MIN_FB_DIV; p <= CY_SYSCLK_PLL_MAX_FB_DIV; p++)
4324                 {
4325                     /* Calculate the intermediate Fvco, and make sure that it's in range */
4326                     uint32_t fvco = (uint32_t)(((uint64_t)(config->inputFreq) * (uint64_t)p) / (uint64_t)q);
4327                     if ((CY_SYSCLK_PLL_MIN_FVCO <= fvco) && (fvco <= CY_SYSCLK_PLL_MAX_FVCO))
4328                     {
4329                         /* OUTPUT_DIV selection */
4330                         for (out = CY_SYSCLK_PLL_MIN_OUTPUT_DIV; out <= CY_SYSCLK_PLL_MAX_OUTPUT_DIV; out++)
4331                         {
4332                             /* Calculate what output frequency will actually be produced.
4333                                If it's closer to the target than what we have so far, then save it. */
4334                             uint32_t fout = ((p * config->inputFreq) / q) / out;
4335                             if ((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
4336                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq)))
4337                             {
4338                                 if (foutBest == (config->outputFreq))
4339                                 {
4340                                    break;
4341                                 }
4342 
4343                                 foutBest = fout;
4344                                 manualConfig.feedbackDiv  = (uint8_t)p;
4345                                 manualConfig.referenceDiv = (uint8_t)q;
4346                                 manualConfig.outputDiv    = (uint8_t)out;
4347                             }
4348                         }
4349                     }
4350                 }
4351             }
4352             /* exit loops if foutBest equals outputFreq */
4353 
4354             manualConfig.lfMode = config->lfMode;
4355         } /* if not, bypass output mode */
4356 
4357         /* If output mode is bypass (input routed directly to output), then
4358            use old parameters. */
4359         else
4360         {
4361             (void)Cy_SysClk_Pll200MGetConfiguration(pllNum, &manualConfig);
4362         }
4363         /* configure PLL based on calculated values */
4364 
4365         manualConfig.outputMode = config->outputMode;
4366         retVal = Cy_SysClk_Pll200MManualConfigure(pllNum, &manualConfig);
4367 
4368     } /* if no error */
4369 
4370     return (retVal);
4371 }
4372 
4373 
Cy_SysClk_Pll200MManualConfigure(uint32_t pllNum,const cy_stc_pll_manual_config_t * config)4374 cy_en_sysclk_status_t Cy_SysClk_Pll200MManualConfigure(uint32_t pllNum, const cy_stc_pll_manual_config_t *config)
4375 {
4376     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
4377 
4378     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4379 
4380     if (Cy_SysClk_Pll200MIsEnabled(pllNum))
4381     {
4382         retVal = CY_SYSCLK_INVALID_STATE;
4383     }
4384     /* valid divider bitfield values */
4385     else if ((config->outputDiv    < CY_SYSCLK_PLL_MIN_OUTPUT_DIV) || (CY_SYSCLK_PLL_MAX_OUTPUT_DIV < config->outputDiv)    ||
4386              (config->referenceDiv < CY_SYSCLK_PLL_MIN_REF_DIV)    || (CY_SYSCLK_PLL_MAX_REF_DIV    < config->referenceDiv) ||
4387              (config->feedbackDiv  < CY_SYSCLK_PLL_MIN_FB_DIV)     || (CY_SYSCLK_PLL_MAX_FB_DIV     < config->feedbackDiv))
4388     {
4389          retVal = CY_SYSCLK_BAD_PARAM;
4390     }
4391     else /* no errors */
4392     {
4393         /* If output mode is bypass (input routed directly to output), then done.
4394            The output frequency equals the input frequency regardless of the frequency parameters. */
4395         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4396         {
4397             SRSS_CLK_PLL_CONFIG[pllNum] =
4398                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  config->feedbackDiv)  |
4399                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, config->referenceDiv) |
4400                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    config->outputDiv)    |
4401                 _VAL2FLD(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   config->lfMode);
4402         }
4403 
4404         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[pllNum], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, (uint32_t)config->outputMode);
4405     }
4406 
4407     return (retVal);
4408 }
4409 
4410 
Cy_SysClk_Pll200MGetConfiguration(uint32_t pllNum,cy_stc_pll_manual_config_t * config)4411 cy_en_sysclk_status_t Cy_SysClk_Pll200MGetConfiguration(uint32_t pllNum, cy_stc_pll_manual_config_t *config)
4412 {
4413     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4414 
4415     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4416 
4417     /* Initialize config structure to 0 */
4418     *config = (cy_stc_pll_manual_config_t){0};
4419 
4420     uint32_t tempReg = SRSS_CLK_PLL_CONFIG[pllNum];
4421     config->feedbackDiv  = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV,  tempReg);
4422     config->referenceDiv = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, tempReg);
4423     config->outputDiv    = (uint8_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV,    tempReg);
4424     config->lfMode       =         _FLD2BOOL(SRSS_CLK_PLL_CONFIG_PLL_LF_MODE,   tempReg);
4425     config->outputMode   = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, tempReg));
4426     retVal = CY_SYSCLK_SUCCESS;
4427 
4428     return (retVal);
4429 }
4430 
Cy_SysClk_Pll200MEnable(uint32_t pllNum,uint32_t timeoutus)4431 cy_en_sysclk_status_t Cy_SysClk_Pll200MEnable(uint32_t pllNum, uint32_t timeoutus)
4432 {
4433     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4434     bool zeroTimeout = (timeoutus == 0UL);
4435 
4436     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4437 
4438     /* first set the PLL enable bit */
4439     SRSS_CLK_PLL_CONFIG[pllNum] |= SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
4440 
4441     /* now do the timeout wait for PLL_STATUS, bit LOCKED */
4442     for (; (0UL == (SRSS_CLK_PLL_STATUS_LOCKED_Msk & SRSS_CLK_PLL_STATUS[pllNum])) &&
4443            (0UL != timeoutus);
4444          timeoutus--)
4445     {
4446         Cy_SysLib_DelayUs(1U);
4447     }
4448 
4449     if (zeroTimeout || (0UL != timeoutus))
4450     {
4451         /* Unbypass PLL, if it is not in AUTO mode */
4452         if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS_CLK_PLL_CONFIG[pllNum]))
4453         {
4454             CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[pllNum], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
4455         }
4456 
4457         retVal = CY_SYSCLK_SUCCESS;
4458     }
4459     else
4460     {
4461         /* If lock doesn't occur, then bypass PLL */
4462         CY_REG32_CLR_SET(SRSS_CLK_PLL_CONFIG[pllNum], SRSS_CLK_PLL_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4463         /* Wait at least 6 PLL clock cycles */
4464         Cy_SysLib_DelayUs(1U);
4465         /* And now disable the PLL itself */
4466         SRSS_CLK_PLL_CONFIG[pllNum] &= ~SRSS_CLK_PLL_CONFIG_ENABLE_Msk;
4467         retVal = CY_SYSCLK_TIMEOUT;
4468     }
4469 
4470     return (retVal);
4471 }
4472 
4473 
Cy_SysClk_Pll200MGetFrequency(uint32_t pllNum)4474 uint32_t Cy_SysClk_Pll200MGetFrequency(uint32_t pllNum)
4475 {
4476     uint32_t fDiv;    /* PLL multiplier/feedback divider */
4477     uint32_t rDiv;    /* PLL reference divider */
4478     uint32_t oDiv;    /* PLL output divider */
4479     bool  enabled;    /* PLL enable status; n/a for direct */
4480     uint32_t freq=0UL;    /* PLL Frequency */
4481 
4482 
4483     CY_ASSERT_L1(pllNum < CY_SRSS_NUM_PLL200M);
4484 
4485     cy_stc_pll_manual_config_t pllcfg = {0U,0U,0U,false,CY_SYSCLK_FLLPLL_OUTPUT_AUTO, 0, false, false, 0 , 0 , false};
4486     (void)Cy_SysClk_Pll200MGetConfiguration(pllNum, &pllcfg);
4487     enabled = (Cy_SysClk_Pll200MIsEnabled(pllNum)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.outputMode);
4488     fDiv = pllcfg.feedbackDiv;
4489     rDiv = pllcfg.referenceDiv;
4490     oDiv = pllcfg.outputDiv;
4491 
4492     if (enabled && /* If PLL is enabled and not bypassed */
4493     (0UL != rDiv) && (0UL != oDiv)) /* to avoid division by zero */
4494     {
4495         freq = Cy_SysClk_ClkPathMuxGetFrequency((pllNum + 1UL) + CY_SRSS_NUM_PLL400M);
4496 
4497         freq = (uint32_t)CY_SYSLIB_DIV_ROUND(((uint64_t)freq * (uint64_t)fDiv),
4498                                              ((uint64_t)rDiv * (uint64_t)oDiv));
4499     }
4500 
4501     return (freq);
4502 }
4503 
4504 #endif
4505 
4506 #if defined (CY_IP_MXS22SRSS) || (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
4507 /* DPLL-LP */
Cy_SysClk_DpllLpIsEnabled(uint32_t pllNum)4508 bool Cy_SysClk_DpllLpIsEnabled(uint32_t pllNum)
4509 {
4510     CY_UNUSED_PARAMETER(pllNum);
4511 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4512     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4513     return (_FLD2BOOL(CLK_DPLL_LP_CONFIG_ENABLE, SRSS_CLK_DPLL_LP_CONFIG(pllNum)));
4514 #else
4515     return false;
4516 #endif
4517 }
4518 
4519 
Cy_SysClk_DpllLpLocked(uint32_t pllNum)4520 bool Cy_SysClk_DpllLpLocked(uint32_t pllNum)
4521 {
4522     CY_UNUSED_PARAMETER(pllNum);
4523 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4524     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4525     return (_FLD2BOOL(CLK_DPLL_LP_STATUS_LOCKED, SRSS_CLK_DPLL_LP_STATUS(pllNum)));
4526 #else
4527      return false;
4528 #endif
4529 }
4530 
4531 
Cy_SysClk_DpllLpLostLock(uint32_t pllNum)4532 bool Cy_SysClk_DpllLpLostLock(uint32_t pllNum)
4533 {
4534     CY_UNUSED_PARAMETER(pllNum);
4535 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4536     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4537 
4538     bool retVal = _FLD2BOOL(CLK_DPLL_LP_STATUS_UNLOCK_OCCURRED, SRSS_CLK_DPLL_LP_STATUS(pllNum));
4539     /* write a 1 to clear the unlock occurred bit */
4540     SRSS_CLK_DPLL_LP_STATUS(pllNum) = CLK_DPLL_LP_STATUS_UNLOCK_OCCURRED_Msk;
4541     return (retVal);
4542 #else
4543     return false;
4544 #endif
4545 }
4546 
4547 
Cy_SysClk_DpllLpDisable(uint32_t pllNum)4548 cy_en_sysclk_status_t Cy_SysClk_DpllLpDisable(uint32_t pllNum)
4549 {
4550     CY_UNUSED_PARAMETER(pllNum);
4551 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4552 
4553     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4554 
4555     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4556 
4557     /* First bypass PLL */
4558     CY_REG32_CLR_SET(SRSS_CLK_DPLL_LP_CONFIG(pllNum), CLK_DPLL_LP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4559     /* Wait at least 6 PLL clock cycles */
4560     Cy_SysLib_DelayUs(1U);
4561     /* And now disable the PLL itself */
4562     SRSS_CLK_DPLL_LP_CONFIG(pllNum) &= ~CLK_DPLL_LP_CONFIG_ENABLE_Msk;
4563     retVal = CY_SYSCLK_SUCCESS;
4564 
4565     return (retVal);
4566 #else
4567     return CY_SYSCLK_UNSUPPORTED_STATE;
4568 #endif
4569 }
4570 
4571 
Cy_SysClk_DpllLpConfigure(uint32_t pllNum,const cy_stc_pll_config_t * config)4572 cy_en_sysclk_status_t Cy_SysClk_DpllLpConfigure(uint32_t pllNum, const cy_stc_pll_config_t *config)
4573 {
4574     CY_UNUSED_PARAMETER(pllNum);
4575     CY_UNUSED_PARAMETER(config);
4576 
4577 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4578 
4579     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
4580 
4581     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4582 
4583     if (((config->inputFreq)  < CY_SYSCLK_DPLL_LP_MIN_IN_FREQ)  || (CY_SYSCLK_DPLL_LP_MAX_IN_FREQ  < (config->inputFreq)) ||
4584         ((config->outputFreq) < CY_SYSCLK_DPLL_LP_MIN_OUT_FREQ) || (CY_SYSCLK_DPLL_LP_MAX_OUT_FREQ < (config->outputFreq)))
4585     {
4586         retVal = CY_SYSCLK_BAD_PARAM;
4587     }
4588     else
4589     {
4590         cy_stc_dpll_lp_config_t    manualDpllLpConfig = (cy_stc_dpll_lp_config_t){0};
4591 #if defined (CY_IP_MXS22SRSS)
4592         cy_stc_pll_manual_config_t manualConfig = {&manualDpllLpConfig, NULL};
4593 #else
4594         cy_stc_pll_manual_config_t manualConfig = {&manualDpllLpConfig};
4595 #endif
4596         /* If output mode is not bypass (input routed directly to output), then
4597            calculate new parameters. */
4598         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4599         {
4600             /* for each possible value of OUTPUT_DIV and REFERENCE_DIV (Q), try
4601                to find a value for FEEDBACK_DIV (P) that gives an output frequency
4602                as close as possible to the desired output frequency. */
4603             uint32_t p, q, out;
4604             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
4605 
4606             /* REFERENCE_DIV (Q) selection */
4607             for (q = CY_SYSCLK_DPLL_LP_MIN_REF_DIV; q <= CY_SYSCLK_DPLL_LP_MAX_REF_DIV; q++)
4608             {
4609                 /* FEEDBACK_DIV (P) selection */
4610                 for (p = CY_SYSCLK_DPLL_LP_MIN_FB_DIV; p <= CY_SYSCLK_DPLL_LP_MAX_FB_DIV; p++)
4611                 {
4612                     /* Calculate the intermediate FDCO,PDF and make sure that it's in range */
4613                     uint32_t pdf = (uint32_t)((uint64_t)(config->inputFreq) / (uint64_t)q);
4614                     uint32_t fdco = (uint32_t)((uint64_t)(pdf) * (uint64_t)p);
4615 
4616                     if (((CY_SYSCLK_DPLL_LP_MIN_FDCO <= fdco) && (fdco <= CY_SYSCLK_DPLL_LP_MAX_FDCO)) && ((CY_SYSCLK_DPLL_LP_MIN_PDF <= pdf) && (pdf <= CY_SYSCLK_DPLL_LP_MAX_PDF)))
4617                     {
4618                         /* OUTPUT_DIV selection */
4619                         for (out = CY_SYSCLK_DPLL_LP_MIN_OUTPUT_DIV; out <= CY_SYSCLK_DPLL_LP_MAX_OUTPUT_DIV; out++)
4620                         {
4621                             uint64_t tempVco = ((uint64_t)config->outputFreq) * ((uint64_t)out);
4622                             uint64_t tempFeedBackDivLeftShifted = ((tempVco << (uint64_t)SRSS_DPLL_LP_FRAC_BIT_COUNT) * (uint64_t)q) / (uint64_t)config->inputFreq;
4623                             volatile uint32_t feedBackFracDiv  = (uint32_t)(tempFeedBackDivLeftShifted & ((1ULL << (uint64_t)SRSS_DPLL_LP_FRAC_BIT_COUNT) - 1ULL));
4624                             /* Calculate what output frequency will actually be produced.
4625                                If it's closer to the target than what we have so far, then save it. */
4626                             uint32_t fout = (uint32_t)((((uint64_t)config->inputFreq * (((uint64_t)p << SRSS_DPLL_LP_FRAC_BIT_COUNT) + (uint64_t)feedBackFracDiv)) / ((uint64_t)q * (uint64_t)out)) >> SRSS_DPLL_LP_FRAC_BIT_COUNT);
4627 
4628                             if ((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
4629                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq)))
4630                             {
4631                                 if (foutBest == (config->outputFreq))
4632                                 {
4633                                    break;
4634                                 }
4635 
4636                                 foutBest = fout;
4637                                 manualConfig.lpPllCfg->feedbackDiv  = (uint8_t)p;
4638                                 manualConfig.lpPllCfg->referenceDiv = (uint8_t)q;
4639                                 manualConfig.lpPllCfg->outputDiv    = (uint8_t)out;
4640                                 manualConfig.lpPllCfg->fracEn       = true;
4641                                 manualConfig.lpPllCfg->fracDiv      = feedBackFracDiv;
4642                                 manualConfig.lpPllCfg->pllDcoMode   = (fdco >= CY_SYSCLK_DPLL_LP_DCO_MODE_LIMIT) ? true : false;
4643                             }
4644                         }
4645                     }
4646                 }
4647             }
4648             /* exit loops if foutBest equals outputFreq */
4649 
4650         } /* if not, bypass output mode */
4651 
4652         /* If output mode is bypass (input routed directly to output), then
4653            use old parameters. */
4654         else
4655         {
4656             (void)Cy_SysClk_DpllLpGetConfiguration(pllNum, &manualConfig);
4657         }
4658         /* configure PLL based on calculated values */
4659 
4660         manualConfig.lpPllCfg->outputMode = config->outputMode;
4661         /* Set the default parameters to remaining PLL configurations */
4662         manualConfig.lpPllCfg->dcoCode = CY_SYSCLK_DPLL_LP_CONFIG4_DCO_CODE;
4663         manualConfig.lpPllCfg->kiInt   = CY_SYSCLK_DPLL_LP_CONFIG5_KI_INT;
4664         manualConfig.lpPllCfg->kiFrac  = CY_SYSCLK_DPLL_LP_CONFIG5_KI_FRACT;
4665         manualConfig.lpPllCfg->kiSscg  = CY_SYSCLK_DPLL_LP_CONFIG5_KI_SSCG;
4666         manualConfig.lpPllCfg->kpInt   = CY_SYSCLK_DPLL_LP_CONFIG5_KP_INT;
4667         manualConfig.lpPllCfg->kpFrac  = CY_SYSCLK_DPLL_LP_CONFIG5_KP_FRACT;
4668         manualConfig.lpPllCfg->kpSscg  = CY_SYSCLK_DPLL_LP_CONFIG5_KP_SSCG;
4669 
4670         retVal = Cy_SysClk_DpllLpManualConfigure(pllNum, &manualConfig);
4671 
4672     } /* if no error */
4673 
4674     return (retVal);
4675 #else
4676     return CY_SYSCLK_UNSUPPORTED_STATE;
4677 #endif
4678 }
4679 
4680 
Cy_SysClk_DpllLpManualConfigure(uint32_t pllNum,const cy_stc_pll_manual_config_t * config)4681 cy_en_sysclk_status_t Cy_SysClk_DpllLpManualConfigure(uint32_t pllNum, const cy_stc_pll_manual_config_t *config)
4682 {
4683     CY_UNUSED_PARAMETER(pllNum);
4684     CY_UNUSED_PARAMETER(config);
4685 
4686 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4687 
4688     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
4689 
4690     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4691 
4692     if (Cy_SysClk_DpllLpIsEnabled(pllNum))
4693     {
4694         retVal = CY_SYSCLK_INVALID_STATE;
4695     }
4696     /* valid divider bitfield values */
4697     else if ((config->lpPllCfg->outputDiv    < CY_SYSCLK_DPLL_LP_MIN_OUTPUT_DIV) || (CY_SYSCLK_DPLL_LP_MAX_OUTPUT_DIV < config->lpPllCfg->outputDiv)    ||
4698              (config->lpPllCfg->referenceDiv < CY_SYSCLK_DPLL_LP_MIN_REF_DIV)    || (CY_SYSCLK_DPLL_LP_MAX_REF_DIV    < config->lpPllCfg->referenceDiv) ||
4699              (config->lpPllCfg->feedbackDiv  < CY_SYSCLK_DPLL_LP_MIN_FB_DIV)     || (CY_SYSCLK_DPLL_LP_MAX_FB_DIV     < config->lpPllCfg->feedbackDiv))
4700     {
4701          retVal = CY_SYSCLK_BAD_PARAM;
4702     }
4703     else /* no errors */
4704     {
4705         /* If output mode is bypass (input routed directly to output), then done.
4706            The output frequency equals the input frequency regardless of the frequency parameters. */
4707         if (config->lpPllCfg->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
4708         {
4709                 SRSS_CLK_DPLL_LP_CONFIG(pllNum) =
4710                 _VAL2FLD(CLK_DPLL_LP_CONFIG_FEEDBACK_DIV,  config->lpPllCfg->feedbackDiv)  |
4711                 _VAL2FLD(CLK_DPLL_LP_CONFIG_REFERENCE_DIV, config->lpPllCfg->referenceDiv) |
4712                 _VAL2FLD(CLK_DPLL_LP_CONFIG_OUTPUT_DIV,    config->lpPllCfg->outputDiv)    |
4713         #if defined (CY_IP_MXS22SRSS)
4714                 _VAL2FLD(CLK_DPLL_LP_CONFIG_PLL_DCO_MODE,    config->lpPllCfg->pllDcoMode);
4715         #else
4716                 _VAL2FLD(CLK_DPLL_LP_CONFIG_PLL_DCO_CODE_MULT,    config->lpPllCfg->pllDcoMode);
4717         #endif
4718 
4719                 SRSS_CLK_DPLL_LP_CONFIG2(pllNum) =
4720                 _VAL2FLD(CLK_DPLL_LP_CONFIG2_FRAC_DIV, config->lpPllCfg->fracDiv)  |
4721                 _VAL2FLD(CLK_DPLL_LP_CONFIG2_FRAC_DITHER_EN, config->lpPllCfg->fracDitherEn) |
4722                 _VAL2FLD(CLK_DPLL_LP_CONFIG2_FRAC_EN, config->lpPllCfg->fracEn);
4723 
4724                 SRSS_CLK_DPLL_LP_CONFIG3(pllNum) =
4725                 _VAL2FLD(CLK_DPLL_LP_CONFIG3_SSCG_DEPTH, config->lpPllCfg->sscgDepth)  |
4726                 _VAL2FLD(CLK_DPLL_LP_CONFIG3_SSCG_RATE, config->lpPllCfg->sscgRate) |
4727                 _VAL2FLD(CLK_DPLL_LP_CONFIG3_SSCG_DITHER_EN, config->lpPllCfg->sscgDitherEn) |
4728                 _VAL2FLD(CLK_DPLL_LP_CONFIG3_SSCG_MODE, config->lpPllCfg->sscgMode) |
4729                 _VAL2FLD(CLK_DPLL_LP_CONFIG3_SSCG_EN, config->lpPllCfg->sscgEn);
4730          #if defined (CY_IP_MXS22SRSS)
4731                 SRSS_CLK_DPLL_LP_CONFIG4(pllNum) =
4732                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_DCO_CODE, config->lpPllCfg->dcoCode)  |
4733                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_PLL_CS_PB2_DIS, config->lpPllCfg->disableBias) |
4734                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_DCO_SD_EN, config->lpPllCfg->enableDcoSd);
4735 
4736                 SRSS_CLK_DPLL_LP_CONFIG5(pllNum) =
4737                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KI_INT, config->lpPllCfg->kiInt)  |
4738                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KI_FRACT, config->lpPllCfg->kiFrac) |
4739                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KI_SSCG, config->lpPllCfg->kiSscg)  |
4740                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KP_INT, config->lpPllCfg->kpInt)  |
4741                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KP_FRACT, config->lpPllCfg->kpFrac) |
4742                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KP_SSCG, config->lpPllCfg->kpSscg);
4743         #else
4744                  SRSS_CLK_DPLL_LP_CONFIG4(pllNum) =
4745                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_DCO_CODE, config->lpPllCfg->dcoCode) |
4746                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_ACC_MODE, config->lpPllCfg->accMode) |
4747                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_TDC_MODE, config->lpPllCfg->tdcMode) |
4748                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_PLL_TG, config->lpPllCfg->pllTg) |
4749                 _VAL2FLD(CLK_DPLL_LP_CONFIG4_ACC_CNT_LOCK, config->lpPllCfg->accCntLock);
4750 
4751                  SRSS_CLK_DPLL_LP_CONFIG5(pllNum) =
4752                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KI_INT, config->lpPllCfg->kiInt) |
4753                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KP_INT, config->lpPllCfg->kpInt) |
4754                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KI_ACC_INT, config->lpPllCfg->kiAccInt) |
4755                 _VAL2FLD(CLK_DPLL_LP_CONFIG5_KP_ACC_INT, config->lpPllCfg->kpAccInt);
4756 
4757                  SRSS_CLK_DPLL_LP_CONFIG6(pllNum) =
4758                 _VAL2FLD(CLK_DPLL_LP_CONFIG6_KI_FRACT, config->lpPllCfg->kiFrac) |
4759                 _VAL2FLD(CLK_DPLL_LP_CONFIG6_KP_FRACT, config->lpPllCfg->kpFrac) |
4760                 _VAL2FLD(CLK_DPLL_LP_CONFIG6_KI_ACC_FRACT, config->lpPllCfg->kiAccFrac) |
4761                 _VAL2FLD(CLK_DPLL_LP_CONFIG6_KP_ACC_FRACT, config->lpPllCfg->kpAccFrac);
4762 
4763                  SRSS_CLK_DPLL_LP_CONFIG7(pllNum) =
4764                 _VAL2FLD(CLK_DPLL_LP_CONFIG7_KI_SSCG, config->lpPllCfg->kiSscg) |
4765                 _VAL2FLD(CLK_DPLL_LP_CONFIG7_KP_SSCG, config->lpPllCfg->kpSscg) |
4766                 _VAL2FLD(CLK_DPLL_LP_CONFIG7_KI_ACC_SSCG, config->lpPllCfg->kiAccSscg) |
4767                 _VAL2FLD(CLK_DPLL_LP_CONFIG7_KP_ACC_SSCG, config->lpPllCfg->kpAccSscg);
4768         #endif
4769         }
4770 
4771         CY_REG32_CLR_SET(SRSS_CLK_DPLL_LP_CONFIG(pllNum), CLK_DPLL_LP_CONFIG_BYPASS_SEL, (uint32_t)config->lpPllCfg->outputMode);
4772     }
4773 
4774     return (retVal);
4775 #else
4776     return CY_SYSCLK_UNSUPPORTED_STATE;
4777 #endif
4778 }
4779 
4780 
Cy_SysClk_DpllLpGetConfiguration(uint32_t pllNum,cy_stc_pll_manual_config_t * config)4781 cy_en_sysclk_status_t Cy_SysClk_DpllLpGetConfiguration(uint32_t pllNum, cy_stc_pll_manual_config_t *config)
4782 {
4783     CY_UNUSED_PARAMETER(pllNum);
4784     CY_UNUSED_PARAMETER(config);
4785 
4786 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4787 
4788     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4789 
4790     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4791 
4792     /* Initialize config structure to 0 */
4793     *(config->lpPllCfg) = (cy_stc_dpll_lp_config_t){0};
4794 
4795     uint32_t tempReg = SRSS_CLK_DPLL_LP_CONFIG(pllNum);
4796     config->lpPllCfg->feedbackDiv  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG_FEEDBACK_DIV,  tempReg);
4797     config->lpPllCfg->referenceDiv = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG_REFERENCE_DIV, tempReg);
4798     config->lpPllCfg->outputDiv    = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG_OUTPUT_DIV,    tempReg);
4799 #if defined (CY_IP_MXS22SRSS)
4800     config->lpPllCfg->pllDcoMode   = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG_PLL_DCO_MODE,tempReg);
4801 #else
4802     config->lpPllCfg->pllDcoMode   = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG_PLL_DCO_CODE_MULT,tempReg);
4803 #endif
4804     config->lpPllCfg->outputMode   = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(CLK_DPLL_LP_CONFIG_BYPASS_SEL, tempReg));
4805 
4806     tempReg = SRSS_CLK_DPLL_LP_CONFIG2(pllNum);
4807     config->lpPllCfg->fracDiv      = _FLD2VAL(CLK_DPLL_LP_CONFIG2_FRAC_DIV,  tempReg);
4808     config->lpPllCfg->fracDitherEn = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG2_FRAC_DITHER_EN, tempReg);
4809     config->lpPllCfg->fracEn       = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG2_FRAC_EN,    tempReg);
4810 
4811     tempReg = SRSS_CLK_DPLL_LP_CONFIG3(pllNum);
4812     config->lpPllCfg->sscgDepth  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG3_SSCG_DEPTH,  tempReg);
4813     config->lpPllCfg->sscgRate   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG3_SSCG_RATE, tempReg);
4814     config->lpPllCfg->sscgDitherEn   = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG3_SSCG_DITHER_EN, tempReg);
4815     config->lpPllCfg->sscgMode   = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG3_SSCG_MODE, tempReg);
4816     config->lpPllCfg->sscgEn     = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG3_SSCG_EN,    tempReg);
4817 
4818 #if (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
4819 
4820     tempReg = SRSS_CLK_DPLL_LP_CONFIG4(pllNum);
4821     config->lpPllCfg->dcoCode  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG4_DCO_CODE,  tempReg);
4822     config->lpPllCfg->accMode   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG4_ACC_MODE, tempReg);
4823     config->lpPllCfg->tdcMode   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG4_TDC_MODE, tempReg);
4824     config->lpPllCfg->pllTg   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG4_PLL_TG, tempReg);
4825     config->lpPllCfg->accCntLock     = (bool)_FLD2VAL(CLK_DPLL_LP_CONFIG4_ACC_CNT_LOCK, tempReg);
4826 
4827     tempReg = SRSS_CLK_DPLL_LP_CONFIG5(pllNum);
4828     config->lpPllCfg->kiInt  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG5_KI_INT,  tempReg);
4829     config->lpPllCfg->kpInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG5_KP_INT, tempReg);
4830     config->lpPllCfg->kiAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG5_KI_ACC_INT, tempReg);
4831     config->lpPllCfg->kpAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG5_KP_ACC_INT, tempReg);
4832 
4833     tempReg = SRSS_CLK_DPLL_LP_CONFIG6(pllNum);
4834     config->lpPllCfg->kiInt  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG6_KI_FRACT,  tempReg);
4835     config->lpPllCfg->kpInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG6_KP_FRACT, tempReg);
4836     config->lpPllCfg->kiAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG6_KI_ACC_FRACT, tempReg);
4837     config->lpPllCfg->kpAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG6_KP_ACC_FRACT, tempReg);
4838 
4839     tempReg = SRSS_CLK_DPLL_LP_CONFIG7(pllNum);
4840     config->lpPllCfg->kiInt  = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG7_KI_SSCG,  tempReg);
4841     config->lpPllCfg->kpInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG7_KP_SSCG, tempReg);
4842     config->lpPllCfg->kiAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG7_KI_ACC_SSCG, tempReg);
4843     config->lpPllCfg->kpAccInt   = (uint8_t)_FLD2VAL(CLK_DPLL_LP_CONFIG7_KP_ACC_SSCG, tempReg);
4844 #endif
4845     retVal = CY_SYSCLK_SUCCESS;
4846 
4847     return (retVal);
4848 #else
4849     return CY_SYSCLK_UNSUPPORTED_STATE;
4850 #endif
4851 }
4852 
Cy_SysClk_DpllLpEnable(uint32_t pllNum,uint32_t timeoutus)4853 cy_en_sysclk_status_t Cy_SysClk_DpllLpEnable(uint32_t pllNum, uint32_t timeoutus)
4854 {
4855     CY_UNUSED_PARAMETER(pllNum);
4856     CY_UNUSED_PARAMETER(timeoutus);
4857 #if (CY_SRSS_DPLL_LP_PRESENT != 0U )
4858 
4859     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4860     bool zeroTimeout = (timeoutus == 0UL);
4861 
4862     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4863 
4864     /* first set the PLL enable bit */
4865     SRSS_CLK_DPLL_LP_CONFIG(pllNum) |= CLK_DPLL_LP_CONFIG_ENABLE_Msk;
4866 
4867     /* now do the timeout wait for PLL_STATUS, bit LOCKED */
4868     for (; (0UL == (CLK_DPLL_LP_STATUS_LOCKED_Msk & SRSS_CLK_DPLL_LP_STATUS(pllNum))) &&
4869            (0UL != timeoutus);
4870          timeoutus--)
4871     {
4872         Cy_SysLib_DelayUs(1U);
4873     }
4874 
4875     if (zeroTimeout || (0UL != timeoutus))
4876     {
4877         /* Unbypass PLL, if it is not in AUTO mode */
4878         if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(CLK_DPLL_LP_CONFIG_BYPASS_SEL, SRSS_CLK_DPLL_LP_CONFIG(pllNum)))
4879         {
4880             CY_REG32_CLR_SET(SRSS_CLK_DPLL_LP_CONFIG(pllNum), CLK_DPLL_LP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
4881         }
4882 
4883         retVal = CY_SYSCLK_SUCCESS;
4884     }
4885     else
4886     {
4887         /* If lock doesn't occur, then bypass PLL */
4888         CY_REG32_CLR_SET(SRSS_CLK_DPLL_LP_CONFIG(pllNum), CLK_DPLL_LP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4889         /* Wait at least 6 PLL clock cycles */
4890         Cy_SysLib_DelayUs(1U);
4891         /* And now disable the PLL itself */
4892         SRSS_CLK_DPLL_LP_CONFIG(pllNum) &= ~CLK_DPLL_LP_CONFIG_ENABLE_Msk;
4893         retVal = CY_SYSCLK_TIMEOUT;
4894     }
4895 
4896     return (retVal);
4897 #else
4898     return CY_SYSCLK_UNSUPPORTED_STATE;
4899 #endif
4900 }
4901 
Cy_SysClk_DpllLpGetFrequency(uint32_t pllNum)4902 uint32_t Cy_SysClk_DpllLpGetFrequency(uint32_t pllNum)
4903 {
4904     uint32_t fDiv;    /* PLL multiplier/feedback divider */
4905     uint32_t rDiv;    /* PLL reference divider */
4906     uint32_t oDiv;    /* PLL output divider */
4907     uint32_t fracDiv; /* PLL Fractional divider */
4908     bool  enabled;    /* PLL enable status; n/a for direct */
4909     uint32_t freq=0UL;    /* PLL Frequency */
4910 
4911 
4912     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
4913 
4914     cy_stc_dpll_lp_config_t    DpllLpConfig = (cy_stc_dpll_lp_config_t){0};
4915 #if defined (CY_IP_MXS22SRSS)
4916     cy_stc_pll_manual_config_t pllcfg = {&DpllLpConfig, NULL};
4917 #else
4918     cy_stc_pll_manual_config_t pllcfg = {&DpllLpConfig};
4919 #endif
4920     (void)Cy_SysClk_DpllLpGetConfiguration(pllNum, &pllcfg);
4921     enabled = (Cy_SysClk_DpllLpIsEnabled(pllNum)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.lpPllCfg->outputMode);
4922     fDiv    = pllcfg.lpPllCfg->feedbackDiv;
4923     rDiv    = pllcfg.lpPllCfg->referenceDiv;
4924     oDiv    = pllcfg.lpPllCfg->outputDiv;
4925     fracDiv = pllcfg.lpPllCfg->fracDiv;
4926 
4927     if (enabled && /* If PLL is enabled and not bypassed */
4928     (0UL != rDiv) && (0UL != oDiv)) /* to avoid division by zero */
4929     {
4930         freq = Cy_SysClk_ClkPathMuxGetFrequency(pllNum);
4931         freq = (uint32_t)((((uint64_t)freq * (((uint64_t)fDiv << SRSS_DPLL_LP_FRAC_BIT_COUNT) + (uint64_t)fracDiv)) / ((uint64_t)rDiv * (uint64_t)oDiv)) >> SRSS_DPLL_LP_FRAC_BIT_COUNT);
4932     }
4933 
4934     return (freq);
4935 }
4936 
4937 
4938 /* DPLL-HP */
4939 #if defined(CY_IP_MXS22SRSS) || defined(CY_DOXYGEN)
Cy_SysClk_DpllHpIsEnabled(uint32_t pllNum)4940 bool Cy_SysClk_DpllHpIsEnabled(uint32_t pllNum)
4941 {
4942     CY_UNUSED_PARAMETER(pllNum);
4943 #if (CY_SRSS_DPLL_HP_PRESENT)
4944     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
4945     return (_FLD2BOOL(CLK_DPLL_HP_CONFIG_ENABLE, SRSS_CLK_DPLL_HP_CONFIG(pllNum)));
4946 #else
4947     return false;
4948 #endif
4949 }
4950 
4951 
Cy_SysClk_DpllHpLocked(uint32_t pllNum)4952 bool Cy_SysClk_DpllHpLocked(uint32_t pllNum)
4953 {
4954     CY_UNUSED_PARAMETER(pllNum);
4955 #if (CY_SRSS_DPLL_HP_PRESENT)
4956     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
4957     return (_FLD2BOOL(CLK_DPLL_HP_STATUS_LOCKED, SRSS_CLK_DPLL_HP_STATUS(pllNum)));
4958 #else
4959      return false;
4960 #endif
4961 }
4962 
4963 
Cy_SysClk_DpllHpLostLock(uint32_t pllNum)4964 bool Cy_SysClk_DpllHpLostLock(uint32_t pllNum)
4965 {
4966     CY_UNUSED_PARAMETER(pllNum);
4967 #if (CY_SRSS_DPLL_HP_PRESENT)
4968     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
4969 
4970     bool retVal = _FLD2BOOL(CLK_DPLL_HP_STATUS_UNLOCK_OCCURRED, SRSS_CLK_DPLL_HP_STATUS(pllNum));
4971     /* write a 1 to clear the unlock occurred bit */
4972     SRSS_CLK_DPLL_HP_STATUS(pllNum) = CLK_DPLL_HP_STATUS_UNLOCK_OCCURRED_Msk;
4973     return (retVal);
4974 #else
4975     return false;
4976 #endif
4977 }
4978 
4979 
Cy_SysClk_DpllHpDisable(uint32_t pllNum)4980 cy_en_sysclk_status_t Cy_SysClk_DpllHpDisable(uint32_t pllNum)
4981 {
4982     CY_UNUSED_PARAMETER(pllNum);
4983 #if (CY_SRSS_DPLL_HP_PRESENT)
4984 
4985     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
4986 
4987     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
4988 
4989     /* First bypass PLL */
4990     CY_REG32_CLR_SET(SRSS_CLK_DPLL_HP_CONFIG(pllNum), CLK_DPLL_HP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
4991     /* Wait at least 6 PLL clock cycles */
4992     Cy_SysLib_DelayUs(1U);
4993     /* And now disable the PLL itself */
4994     SRSS_CLK_DPLL_HP_CONFIG(pllNum) &= ~CLK_DPLL_HP_CONFIG_ENABLE_Msk;
4995     retVal = CY_SYSCLK_SUCCESS;
4996 
4997     return (retVal);
4998 #else
4999     return CY_SYSCLK_UNSUPPORTED_STATE;
5000 #endif
5001 }
5002 
Cy_SysClk_DpllHpGetFreqMode(uint32_t inputFreq)5003 __STATIC_INLINE cy_en_wait_mode_select_t Cy_SysClk_DpllHpGetFreqMode(uint32_t inputFreq)
5004 {
5005     cy_en_wait_mode_select_t freqMode = CY_SYSCLK_DPLL_HP_CLK50MHZ_1US_CNT_VAL;
5006 
5007     if((inputFreq > 45000000U) && (inputFreq <= 50000000U))
5008     {
5009         freqMode = CY_SYSCLK_DPLL_HP_CLK50MHZ_1US_CNT_VAL;
5010     }
5011     else if((inputFreq > 40000000U) && (inputFreq <= 45000000U))
5012     {
5013         freqMode = CY_SYSCLK_DPLL_HP_CLK45MHZ_1US_CNT_VAL;
5014     }
5015     else if((inputFreq > 32000000U) && (inputFreq <= 40000000U))
5016     {
5017         freqMode = CY_SYSCLK_DPLL_HP_CLK40MHZ_1US_CNT_VAL;
5018     }
5019     else if((inputFreq > 25000000U) && (inputFreq <= 32000000U))
5020     {
5021         freqMode = CY_SYSCLK_DPLL_HP_CLK30MHZ_1US_CNT_VAL;
5022     }
5023     else if((inputFreq > 16000000U) && (inputFreq <= 25000000U))
5024     {
5025         freqMode = CY_SYSCLK_DPLL_HP_CLK20MHZ_1US_CNT_VAL;
5026     }
5027     else if((inputFreq > 10000000U) && (inputFreq <= 16000000U))
5028     {
5029         freqMode = CY_SYSCLK_DPLL_HP_CLK15MHZ_1US_CNT_VAL;
5030     }
5031     else if((inputFreq > 6000000U) && (inputFreq <= 10000000U))
5032     {
5033         freqMode = CY_SYSCLK_DPLL_HP_CLK10MHZ_1US_CNT_VAL;
5034     }
5035     else if((inputFreq > 4000000U) && (inputFreq <= 6000000U))
5036     {
5037         freqMode = CY_SYSCLK_DPLL_HP_CLK4MHZ_1US_CNT_VAL;
5038     }
5039     else
5040     {
5041         freqMode = CY_SYSCLK_DPLL_HP_CLK50MHZ_1US_CNT_VAL;
5042     }
5043 
5044     return freqMode;
5045 }
5046 
Cy_SysClk_DpllHpGetFlockTh(uint32_t nDiv)5047 __STATIC_INLINE uint8_t Cy_SysClk_DpllHpGetFlockTh(uint32_t nDiv)
5048 {
5049     uint8_t flockEnTh;
5050 
5051     if(nDiv < 20U)
5052     {
5053         flockEnTh = 0x3U;
5054     }
5055     else
5056     {
5057         flockEnTh = 0x7U;
5058     }
5059 
5060     return flockEnTh;
5061 }
5062 
Cy_SysClk_DpllHpGetLfBeta(uint32_t inputFreq,uint32_t pDiv)5063 __STATIC_INLINE uint8_t Cy_SysClk_DpllHpGetLfBeta(uint32_t inputFreq, uint32_t pDiv)
5064 {
5065     uint8_t lfBeta;
5066     uint32_t pfd = inputFreq/(pDiv + 1U);
5067 
5068     if(pfd < 25000000U)
5069     {
5070         lfBeta = 0x10U;
5071     }
5072     else
5073     {
5074         lfBeta = 0x14U;
5075     }
5076 
5077     return lfBeta;
5078 }
5079 
Cy_SysClk_DpllHpConfigure(uint32_t pllNum,const cy_stc_pll_config_t * config)5080 cy_en_sysclk_status_t Cy_SysClk_DpllHpConfigure(uint32_t pllNum, const cy_stc_pll_config_t *config)
5081 {
5082     CY_UNUSED_PARAMETER(pllNum);
5083     CY_UNUSED_PARAMETER(config);
5084 
5085 #if (CY_SRSS_DPLL_HP_PRESENT)
5086 
5087     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
5088 
5089     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
5090 
5091     if (((config->inputFreq)  < CY_SYSCLK_DPLL_HP_MIN_IN_FREQ)  || (CY_SYSCLK_DPLL_HP_MAX_IN_FREQ  < (config->inputFreq)) ||
5092         ((config->outputFreq) < CY_SYSCLK_DPLL_HP_MIN_OUT_FREQ) || (CY_SYSCLK_DPLL_HP_MAX_OUT_FREQ < (config->outputFreq)))
5093     {
5094         retVal = CY_SYSCLK_BAD_PARAM;
5095     }
5096     else
5097     {
5098         cy_stc_dpll_hp_config_t    DpllHpConfig = (cy_stc_dpll_hp_config_t){0};
5099         cy_stc_pll_manual_config_t manualConfig = {NULL, &DpllHpConfig};
5100 
5101         /* If output mode is not bypass (input routed directly to output), then
5102            calculate new parameters. */
5103         if (config->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
5104         {
5105             /* for each possible value of NDIV(nDiv) and PDIV(pDiv), try
5106                to find a value for KDIV (kDiv) that gives an output frequency
5107                as close as possible to the desired output frequency. */
5108             uint32_t pDiv, kDiv, nDiv;
5109             uint32_t foutBest = 0UL; /* to ensure at least one pass through the for loops below */
5110 
5111             /* PDIV (pDiv) selection */
5112             for (pDiv = CY_SYSCLK_DPLL_HP_MIN_PDIV; pDiv <= CY_SYSCLK_DPLL_HP_MAX_PDIV; pDiv++)
5113             {
5114                 /* NDIV (nDiv) selection */
5115                 for (nDiv = CY_SYSCLK_DPLL_HP_MIN_NDIV; nDiv <= CY_SYSCLK_DPLL_HP_MAX_NDIV; nDiv++)
5116                 {
5117                     uint32_t pdf = (uint32_t)((uint32_t)(config->inputFreq/1000U) / (uint32_t)(pDiv));
5118                     uint32_t fdco = (uint32_t)((uint32_t)(pdf) * (uint32_t)(nDiv));
5119                     if (((CY_SYSCLK_DPLL_HP_MIN_FDCO <= fdco) && (fdco <= CY_SYSCLK_DPLL_HP_MAX_FDCO))  && ((CY_SYSCLK_DPLL_HP_MIN_PDF <= pdf) && (pdf <= CY_SYSCLK_DPLL_HP_MAX_PDF)))
5120                     {
5121                         /* KDIV (kDiv) selection */
5122                         for (kDiv = CY_SYSCLK_DPLL_HP_MIN_KDIV; kDiv <= CY_SYSCLK_DPLL_HP_MAX_KDIV; kDiv++)
5123                         {
5124                             uint64_t tempVco = ((uint64_t)config->outputFreq) * ((uint64_t)kDiv);
5125                             uint64_t tempFeedBackDivLeftShifted = ((tempVco << (uint64_t)SRSS_DPLL_HP_FRAC_BIT_COUNT) * (uint64_t)pDiv) / (uint64_t)config->inputFreq;
5126                             volatile uint32_t feedBackFracDiv  = (uint32_t)(tempFeedBackDivLeftShifted & ((1ULL << (uint64_t)SRSS_DPLL_HP_FRAC_BIT_COUNT) - 1ULL));
5127                             /* Calculate what output frequency will actually be produced.
5128                                If it's closer to the target than what we have so far, then save it. */
5129                             uint32_t fout = (uint32_t)((((uint64_t)config->inputFreq * (((uint64_t)nDiv << SRSS_DPLL_HP_FRAC_BIT_COUNT) + (uint64_t)feedBackFracDiv)) / ((uint64_t)pDiv * (uint64_t)kDiv)) >> SRSS_DPLL_HP_FRAC_BIT_COUNT);
5130 
5131                             if (((uint32_t)abs((int32_t)fout - (int32_t)(config->outputFreq)) <
5132                                 (uint32_t)abs((int32_t)foutBest - (int32_t)(config->outputFreq))))
5133                             {
5134                                 if (foutBest == (config->outputFreq))
5135                                 {
5136                                    break;
5137                                 }
5138 
5139                                 foutBest = fout;
5140                                 manualConfig.hpPllCfg->nDiv  = (uint8_t)(nDiv - 1U);
5141                                 manualConfig.hpPllCfg->pDiv  = (uint8_t)(pDiv - 1U);
5142                                 manualConfig.hpPllCfg->kDiv  = (uint8_t)(kDiv - 1U);
5143                                 manualConfig.hpPllCfg->nDivFract  = feedBackFracDiv;
5144                             }
5145                         }
5146                     }
5147                 }
5148             }
5149             /* exit loops if foutBest equals outputFreq */
5150 
5151         } /* if not, bypass output mode */
5152 
5153         /* If output mode is bypass (input routed directly to output), then
5154            use old parameters. */
5155         else
5156         {
5157             (void)Cy_SysClk_DpllHpGetConfiguration(pllNum, &manualConfig);
5158         }
5159         /* configure PLL based on calculated values */
5160         manualConfig.hpPllCfg->outputMode = config->outputMode;
5161 
5162         manualConfig.hpPllCfg->freqModeSel = Cy_SysClk_DpllHpGetFreqMode(config->inputFreq);
5163         manualConfig.hpPllCfg->flockThresh = (uint8_t)Cy_SysClk_DpllHpGetFlockTh(manualConfig.hpPllCfg->nDiv);
5164         manualConfig.hpPllCfg->betaExt     = (uint8_t)Cy_SysClk_DpllHpGetLfBeta(config->inputFreq, manualConfig.hpPllCfg->pDiv);
5165 
5166         /* Set the default parameters to remaining PLL configurations */
5167         manualConfig.hpPllCfg->ivrTrim     = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG2_IVR_TRIM;
5168         manualConfig.hpPllCfg->clkrSel     = CY_SYSCLK_DPLL_HP_CONFIG3_CLKR_SEL;
5169         manualConfig.hpPllCfg->alphaCoarse = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG4_LF_LC_ALPHA;
5170         manualConfig.hpPllCfg->betaCoarse  = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG4_LF_LC_BETA;
5171         manualConfig.hpPllCfg->flockWait   = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG4_FLOCK_WAITPER;
5172         manualConfig.hpPllCfg->flockLkThres= (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG4_LK_TH;
5173         manualConfig.hpPllCfg->flockLkWait = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG4_LK_WAITPER;
5174         manualConfig.hpPllCfg->alphaExt    = (uint8_t)CY_SYSCLK_DPLL_HP_CONFIG5_LF_ALPHA;
5175         manualConfig.hpPllCfg->lfEn        = CY_SYSCLK_DPLL_HP_CONFIG5_LF_SET_PARAMS;
5176         manualConfig.hpPllCfg->dcEn        = CY_SYSCLK_DPLL_HP_DUTY_CAL_CTL_DC_EN;
5177 
5178         retVal = Cy_SysClk_DpllHpManualConfigure(pllNum, &manualConfig);
5179 
5180     } /* if no error */
5181 
5182     return (retVal);
5183 #else
5184     return CY_SYSCLK_UNSUPPORTED_STATE;
5185 #endif
5186 }
5187 
5188 
Cy_SysClk_DpllHpManualConfigure(uint32_t pllNum,const cy_stc_pll_manual_config_t * config)5189 cy_en_sysclk_status_t Cy_SysClk_DpllHpManualConfigure(uint32_t pllNum, const cy_stc_pll_manual_config_t *config)
5190 {
5191     CY_UNUSED_PARAMETER(pllNum);
5192     CY_UNUSED_PARAMETER(config);
5193 
5194 #if (CY_SRSS_DPLL_HP_PRESENT)
5195 
5196     cy_en_sysclk_status_t retVal = CY_SYSCLK_SUCCESS;
5197 
5198     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_LP);
5199 
5200     if (Cy_SysClk_DpllHpIsEnabled(pllNum))
5201     {
5202         retVal = CY_SYSCLK_INVALID_STATE;
5203     }
5204     /* valid divider bitfield values */
5205     else if ((config->hpPllCfg->nDiv    < (CY_SYSCLK_DPLL_HP_MIN_NDIV - 1U)) || ((CY_SYSCLK_DPLL_HP_MAX_NDIV - 1U) < config->hpPllCfg->nDiv)    ||
5206              ((CY_SYSCLK_DPLL_HP_MAX_PDIV - 1U)    < config->hpPllCfg->pDiv) || ((CY_SYSCLK_DPLL_HP_MAX_KDIV - 1U)     < config->hpPllCfg->kDiv))
5207     {
5208          retVal = CY_SYSCLK_BAD_PARAM;
5209     }
5210     else /* no errors */
5211     {
5212         /* If output mode is bypass (input routed directly to output), then done.
5213            The output frequency equals the input frequency regardless of the frequency parameters. */
5214         if (config->hpPllCfg->outputMode != CY_SYSCLK_FLLPLL_OUTPUT_INPUT)
5215         {
5216                 SRSS_CLK_DPLL_HP_CONFIG(pllNum) =
5217                 _VAL2FLD(CLK_DPLL_HP_CONFIG_PLL_FREQ_NDIV_INT_SEL, config->hpPllCfg->nDiv)  |
5218                 _VAL2FLD(CLK_DPLL_HP_CONFIG_PLL_FREQ_PDIV_SEL, config->hpPllCfg->pDiv) |
5219                 _VAL2FLD(CLK_DPLL_HP_CONFIG_PLL_FREQ_KDIV_SEL, config->hpPllCfg->kDiv) |
5220                 _VAL2FLD(CLK_DPLL_HP_CONFIG_ENABLE, config->hpPllCfg->pllEn);
5221 
5222                 SRSS_CLK_DPLL_HP_CONFIG2(pllNum) =
5223                 _VAL2FLD(CLK_DPLL_HP_CONFIG2_PLL_FREQ_NDIV_FRACT_SEL, config->hpPllCfg->nDivFract)  |
5224                 _VAL2FLD(CLK_DPLL_HP_CONFIG2_PLL_FREQ_MODE_SEL, config->hpPllCfg->freqModeSel) |
5225                 _VAL2FLD(CLK_DPLL_HP_CONFIG2_PLL_IVR_TRIM, config->hpPllCfg->ivrTrim);
5226 
5227                 SRSS_CLK_DPLL_HP_CONFIG3(pllNum) =
5228                 _VAL2FLD(CLK_DPLL_HP_CONFIG3_PLL_CLKR_SEL, config->hpPllCfg->clkrSel)  |
5229                 _VAL2FLD(CLK_DPLL_HP_CONFIG3_PLL_FDSM_SEL, config->hpPllCfg->fdsmSel);
5230 
5231                 SRSS_CLK_DPLL_HP_CONFIG4(pllNum) =
5232                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_LF_LC_ALPHA, config->hpPllCfg->alphaCoarse)  |
5233                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_LF_LC_BETA, config->hpPllCfg->betaCoarse)  |
5234                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_EN_THRESH, config->hpPllCfg->flockThresh)  |
5235                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_WAITPER, config->hpPllCfg->flockWait)  |
5236                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_LK_THRESH, config->hpPllCfg->flockLkThres)  |
5237                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_LK_WAITPER, config->hpPllCfg->flockLkWait)  |
5238                 _VAL2FLD(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_OBSWIN, config->hpPllCfg->flockObs);
5239 
5240                 SRSS_CLK_DPLL_HP_CONFIG5(pllNum) =
5241                 _VAL2FLD(CLK_DPLL_HP_CONFIG5_PLL_LF_ALPHA, config->hpPllCfg->alphaExt)  |
5242                 _VAL2FLD(CLK_DPLL_HP_CONFIG5_PLL_LF_BETA, config->hpPllCfg->betaExt) |
5243                 _VAL2FLD(CLK_DPLL_HP_CONFIG5_PLL_LF_SET_PARAMS, config->hpPllCfg->lfEn);
5244 
5245                 SRSS_CLK_DPLL_HP_TRIGMOD(pllNum) =
5246                 _VAL2FLD(CLK_DPLL_HP_TRIGMOD_PLL_TRIMOD_FREQ, config->hpPllCfg->tmodFreq)  |
5247                 _VAL2FLD(CLK_DPLL_HP_TRIGMOD_PLL_TRIMOD_GRD, config->hpPllCfg->tmodGrad);
5248 
5249                 SRSS_CLK_DPLL_HP_TRIGMOD2(pllNum) =
5250                 _VAL2FLD(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_RATE, config->hpPllCfg->tmodRate)  |
5251                 _VAL2FLD(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_EN, config->hpPllCfg->tmodEn)  |
5252                 _VAL2FLD(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_STP, config->hpPllCfg->tmodStop);
5253 
5254                 SRSS_CLK_DPLL_HP_STATUS(pllNum) =
5255                 _VAL2FLD(CLK_DPLL_HP_STATUS_LOCKED, config->hpPllCfg->pllLocked)  |
5256                 _VAL2FLD(CLK_DPLL_HP_STATUS_UNLOCK_OCCURRED, config->hpPllCfg->pllUnlock) |
5257                 _VAL2FLD(CLK_DPLL_HP_STATUS_PLL_LOCKDET_RES, config->hpPllCfg->lockDetReset) |
5258                 _VAL2FLD(CLK_DPLL_HP_STATUS_PLL_LOCKDET_RES_ACK, config->hpPllCfg->lockDetRstAck);
5259 
5260                 SRSS_CLK_DPLL_HP_DUTYCAL_CTRL(pllNum) =
5261                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_DELTA, config->hpPllCfg->dcCalDelta)  |
5262                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTY_CAL_RATIO_OK, config->hpPllCfg->dcRatioStatus)  |
5263                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTY_CAL_OK, config->hpPllCfg->dcStatus)  |
5264                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_TARGET, config->hpPllCfg->dcTarget)  |
5265                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_CTRL_RG_EN, config->hpPllCfg->dcEnRingOsc)  |
5266                 _VAL2FLD(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_EN, config->hpPllCfg->dcEn);
5267         }
5268 
5269         CY_REG32_CLR_SET(SRSS_CLK_DPLL_HP_CONFIG(pllNum), CLK_DPLL_HP_CONFIG_BYPASS_SEL, (uint32_t)config->hpPllCfg->outputMode);
5270     }
5271 
5272     return (retVal);
5273 #else
5274     return CY_SYSCLK_UNSUPPORTED_STATE;
5275 #endif
5276 }
5277 
5278 
Cy_SysClk_DpllHpGetConfiguration(uint32_t pllNum,cy_stc_pll_manual_config_t * config)5279 cy_en_sysclk_status_t Cy_SysClk_DpllHpGetConfiguration(uint32_t pllNum, cy_stc_pll_manual_config_t *config)
5280 {
5281     CY_UNUSED_PARAMETER(pllNum);
5282     CY_UNUSED_PARAMETER(config);
5283 
5284 #if (CY_SRSS_DPLL_HP_PRESENT)
5285 
5286     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
5287 
5288     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
5289 
5290     /* Initialize config structure to 0 */
5291     *(config->hpPllCfg) = (cy_stc_dpll_hp_config_t){0};
5292 
5293     uint32_t tempReg = SRSS_CLK_DPLL_HP_CONFIG(pllNum);
5294     config->hpPllCfg->nDiv          = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG_PLL_FREQ_NDIV_INT_SEL, tempReg);
5295     config->hpPllCfg->pDiv          = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG_PLL_FREQ_PDIV_SEL, tempReg);
5296     config->hpPllCfg->kDiv          = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG_PLL_FREQ_KDIV_SEL, tempReg);
5297     config->hpPllCfg->outputMode    = (cy_en_fll_pll_output_mode_t)((uint32_t)_FLD2VAL(CLK_DPLL_HP_CONFIG_BYPASS_SEL, tempReg));
5298     config->hpPllCfg->pllEn         = (bool)_FLD2VAL(CLK_DPLL_HP_CONFIG_ENABLE, tempReg);
5299 
5300     tempReg = SRSS_CLK_DPLL_HP_CONFIG2(pllNum);
5301     config->hpPllCfg->nDivFract     = (uint32_t)_FLD2VAL(CLK_DPLL_HP_CONFIG2_PLL_FREQ_NDIV_FRACT_SEL, tempReg);
5302     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Cast of composite expression of essential type unsigned to essential type enum');
5303     config->hpPllCfg->freqModeSel   = (cy_en_wait_mode_select_t)_FLD2VAL(CLK_DPLL_HP_CONFIG2_PLL_FREQ_MODE_SEL, tempReg);
5304     config->hpPllCfg->ivrTrim       = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG2_PLL_IVR_TRIM, tempReg);
5305 
5306     tempReg = SRSS_CLK_DPLL_HP_CONFIG3(pllNum);
5307     config->hpPllCfg->clkrSel       = (bool)_FLD2VAL(CLK_DPLL_HP_CONFIG3_PLL_CLKR_SEL, tempReg);
5308     config->hpPllCfg->fdsmSel       = (bool)_FLD2VAL(CLK_DPLL_HP_CONFIG3_PLL_FDSM_SEL, tempReg);
5309 
5310     tempReg = SRSS_CLK_DPLL_HP_CONFIG4(pllNum);
5311     config->hpPllCfg->alphaCoarse   = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_LF_LC_ALPHA, tempReg);
5312     config->hpPllCfg->betaCoarse    = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_LF_LC_BETA, tempReg);
5313     config->hpPllCfg->flockThresh   = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_EN_THRESH, tempReg);
5314     config->hpPllCfg->flockWait     = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_WAITPER, tempReg);
5315     config->hpPllCfg->flockLkThres  = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_LK_THRESH, tempReg);
5316     config->hpPllCfg->flockLkWait   = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_LK_WAITPER, tempReg);
5317     config->hpPllCfg->flockObs      = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG4_PLL_FLOCK_OBSWIN, tempReg);
5318 
5319     tempReg = SRSS_CLK_DPLL_HP_CONFIG5(pllNum);
5320     config->hpPllCfg->alphaExt      = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG5_PLL_LF_ALPHA, tempReg);
5321     config->hpPllCfg->betaExt       = (uint8_t)_FLD2VAL(CLK_DPLL_HP_CONFIG5_PLL_LF_BETA, tempReg);
5322     config->hpPllCfg->lfEn          = (bool)_FLD2VAL(CLK_DPLL_HP_CONFIG5_PLL_LF_SET_PARAMS, tempReg);
5323 
5324     tempReg = SRSS_CLK_DPLL_HP_TRIGMOD(pllNum);
5325     config->hpPllCfg->tmodFreq     = (uint16_t)_FLD2VAL(CLK_DPLL_HP_TRIGMOD_PLL_TRIMOD_FREQ, tempReg);
5326     config->hpPllCfg->tmodGrad     = (uint16_t)_FLD2VAL(CLK_DPLL_HP_TRIGMOD_PLL_TRIMOD_GRD, tempReg);
5327 
5328     tempReg = SRSS_CLK_DPLL_HP_TRIGMOD2(pllNum);
5329     config->hpPllCfg->tmodRate      = (uint32_t)_FLD2VAL(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_RATE, tempReg);
5330     config->hpPllCfg->tmodEn        = (bool)_FLD2VAL(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_EN, tempReg);
5331     config->hpPllCfg->tmodStop      = (bool)_FLD2VAL(CLK_DPLL_HP_TRIGMOD2_PLL_TRIMOD_STP, tempReg);
5332 
5333     tempReg = SRSS_CLK_DPLL_HP_STATUS(pllNum);
5334     config->hpPllCfg->pllLocked      = (bool)_FLD2VAL(CLK_DPLL_HP_STATUS_LOCKED, tempReg);
5335     config->hpPllCfg->pllUnlock      = (bool)_FLD2VAL(CLK_DPLL_HP_STATUS_UNLOCK_OCCURRED, tempReg);
5336     config->hpPllCfg->lockDetReset   = (bool)_FLD2VAL(CLK_DPLL_HP_STATUS_PLL_LOCKDET_RES, tempReg);
5337     config->hpPllCfg->lockDetRstAck  = (bool)_FLD2VAL(CLK_DPLL_HP_STATUS_PLL_LOCKDET_RES_ACK, tempReg);
5338 
5339     tempReg = SRSS_CLK_DPLL_HP_DUTYCAL_CTRL(pllNum);
5340     config->hpPllCfg->dcCalDelta    = (uint8_t)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_DELTA, tempReg);
5341     config->hpPllCfg->dcRatioStatus = (bool)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTY_CAL_RATIO_OK, tempReg);
5342     config->hpPllCfg->dcStatus      = (bool)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTY_CAL_OK, tempReg);
5343     config->hpPllCfg->dcTarget      = (uint16_t)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_TARGET, tempReg);
5344     config->hpPllCfg->dcEnRingOsc   = (bool)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_CTRL_RG_EN, tempReg);
5345     config->hpPllCfg->dcEn          = (bool)_FLD2VAL(CLK_DPLL_HP_DUTYCAL_CTRL_PLL_DUTYCAL_EN, tempReg);
5346 
5347     retVal = CY_SYSCLK_SUCCESS;
5348 
5349     return (retVal);
5350 #else
5351     return CY_SYSCLK_UNSUPPORTED_STATE;
5352 #endif
5353 }
5354 
Cy_SysClk_DpllHpEnable(uint32_t pllNum,uint32_t timeoutus)5355 cy_en_sysclk_status_t Cy_SysClk_DpllHpEnable(uint32_t pllNum, uint32_t timeoutus)
5356 {
5357     CY_UNUSED_PARAMETER(pllNum);
5358     CY_UNUSED_PARAMETER(timeoutus);
5359 
5360 #if (CY_SRSS_DPLL_HP_PRESENT)
5361 
5362     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
5363     bool zeroTimeout = (timeoutus == 0UL);
5364 
5365     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
5366 
5367     /* first set the PLL enable bit */
5368     SRSS_CLK_DPLL_HP_CONFIG(pllNum) |= CLK_DPLL_HP_CONFIG_ENABLE_Msk;
5369 
5370     /* now do the timeout wait for PLL_STATUS, bit LOCKED */
5371     for (; (0UL == (CLK_DPLL_HP_STATUS_LOCKED_Msk & SRSS_CLK_DPLL_HP_STATUS(pllNum))) &&
5372            (0UL != timeoutus);
5373          timeoutus--)
5374     {
5375         Cy_SysLib_DelayUs(1U);
5376     }
5377 
5378     if (zeroTimeout || (0UL != timeoutus))
5379     {
5380         /* Unbypass PLL, if it is not in AUTO mode */
5381         if ((uint32_t)CY_SYSCLK_FLLPLL_OUTPUT_INPUT == (uint32_t)_FLD2VAL(CLK_DPLL_HP_CONFIG_BYPASS_SEL, SRSS_CLK_DPLL_HP_CONFIG(pllNum)))
5382         {
5383             CY_REG32_CLR_SET(SRSS_CLK_DPLL_HP_CONFIG(pllNum), CLK_DPLL_HP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_OUTPUT);
5384         }
5385 
5386         retVal = CY_SYSCLK_SUCCESS;
5387     }
5388     else
5389     {
5390         /* If lock doesn't occur, then bypass PLL */
5391         CY_REG32_CLR_SET(SRSS_CLK_DPLL_HP_CONFIG(pllNum), CLK_DPLL_HP_CONFIG_BYPASS_SEL, CY_SYSCLK_FLLPLL_OUTPUT_INPUT);
5392         /* Wait at least 6 PLL clock cycles */
5393         Cy_SysLib_DelayUs(1U);
5394         /* And now disable the PLL itself */
5395         SRSS_CLK_DPLL_HP_CONFIG(pllNum) &= ~CLK_DPLL_HP_CONFIG_ENABLE_Msk;
5396         retVal = CY_SYSCLK_TIMEOUT;
5397     }
5398 
5399     return (retVal);
5400 #else
5401     return CY_SYSCLK_UNSUPPORTED_STATE;
5402 #endif
5403 }
5404 
Cy_SysClk_DpllHpGetFrequency(uint32_t pllNum)5405 uint32_t Cy_SysClk_DpllHpGetFrequency(uint32_t pllNum)
5406 {
5407     CY_UNUSED_PARAMETER(pllNum);
5408 
5409 #if (CY_SRSS_DPLL_HP_PRESENT)
5410     uint32_t nDiv;
5411     uint32_t pDiv;
5412     uint32_t kDiv;
5413     uint32_t nDivFract;
5414     bool  enabled;
5415     uint32_t freq=0UL;
5416 
5417     CY_ASSERT_L1(pllNum < SRSS_NUM_DPLL_HP);
5418 
5419     cy_stc_dpll_hp_config_t    DpllHpConfig = (cy_stc_dpll_hp_config_t){0};
5420     cy_stc_pll_manual_config_t pllcfg = {NULL, &DpllHpConfig};
5421 
5422     (void)Cy_SysClk_DpllHpGetConfiguration(pllNum, &pllcfg);
5423     enabled  = (Cy_SysClk_DpllHpIsEnabled(pllNum)) && (CY_SYSCLK_FLLPLL_OUTPUT_INPUT != pllcfg.hpPllCfg->outputMode);
5424     nDiv     = (uint32_t)pllcfg.hpPllCfg->nDiv + 1U;
5425     pDiv     = (uint32_t)pllcfg.hpPllCfg->pDiv + 1U;
5426     kDiv     = (uint32_t)pllcfg.hpPllCfg->kDiv + 1U;
5427     nDivFract = pllcfg.hpPllCfg->nDivFract;
5428 
5429     if (enabled )/* If PLL is enabled and not bypassed */
5430     {
5431         freq = Cy_SysClk_ClkPathMuxGetFrequency(pllNum + SRSS_DPLL_HP_0_PATH_NUM);
5432         if(0U == nDivFract)
5433         {
5434             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.3','unsigned 64-bit int" to different or narrower essential type "unsigned 32-bit int');
5435             freq = (uint32_t)((uint64_t)freq * ((uint64_t)nDiv)) / (((uint64_t)pDiv) * ((uint64_t)kDiv));
5436         }
5437         else
5438         {
5439             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.3','unsigned 64-bit int" to different or narrower essential type "unsigned 32-bit int');
5440             freq = (uint32_t)((((uint64_t)freq * (((uint64_t)nDiv << SRSS_DPLL_HP_FRAC_BIT_COUNT) + (uint64_t)nDivFract)) / ((uint64_t)pDiv * (uint64_t)kDiv)) >> SRSS_DPLL_HP_FRAC_BIT_COUNT);
5441         }
5442     }
5443 
5444     return (freq);
5445 #else
5446     return 0U;
5447 #endif
5448 }
5449 
5450 
5451 #endif /* DPLL-HP */
5452 #endif /* DPLL-LP, DPLL-HP */
5453 
5454 
Cy_SysClk_PllIsEnabled(uint32_t clkPath)5455 bool Cy_SysClk_PllIsEnabled(uint32_t clkPath)
5456 {
5457 #if defined(CY_IP_MXS22SRSS)
5458     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5459 
5460     if(clkPath < SRSS_NUM_DPLL_LP)
5461     {
5462         return Cy_SysClk_DpllLpIsEnabled(clkPath);
5463     }
5464     else
5465     {
5466         return Cy_SysClk_DpllHpIsEnabled(clkPath - SRSS_NUM_DPLL_LP);
5467     }
5468 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5469     clkPath--; /* to correctly access PLL config and status registers structures */
5470     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5471     if(clkPath< SRSS_NUM_DPLL_LP)
5472     {
5473         return Cy_SysClk_DpllLpIsEnabled(clkPath);
5474     }
5475     else
5476     {
5477         return false;
5478     }
5479 #else
5480     clkPath--; /* to correctly access PLL config and status registers structures */
5481     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5482 
5483 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5484     if(clkPath < CY_SRSS_NUM_PLL400M)
5485     {
5486         return Cy_SysClk_Pll400MIsEnabled(clkPath);
5487     }
5488     else
5489 #endif
5490     {
5491         return Cy_SysClk_Pll200MIsEnabled(clkPath - CY_SRSS_NUM_PLL400M);
5492     }
5493 #endif
5494 }
5495 
Cy_SysClk_PllLocked(uint32_t clkPath)5496 bool Cy_SysClk_PllLocked(uint32_t clkPath)
5497 {
5498 #if defined(CY_IP_MXS22SRSS)
5499     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5500 
5501     if(clkPath < SRSS_NUM_DPLL_LP)
5502     {
5503         return Cy_SysClk_DpllLpLocked(clkPath);
5504     }
5505     else
5506     {
5507         return Cy_SysClk_DpllHpLocked(clkPath - SRSS_NUM_DPLL_LP);
5508     }
5509 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5510     clkPath--; /* to correctly access PLL config and status registers structures */
5511     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5512 
5513     if(clkPath < SRSS_NUM_DPLL_LP)
5514     {
5515         return Cy_SysClk_DpllLpLocked(clkPath);
5516     }
5517     else
5518     {
5519         return false;
5520     }
5521 #else
5522     clkPath--; /* to correctly access PLL config and status registers structures */
5523     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5524 
5525 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5526     if(clkPath < CY_SRSS_NUM_PLL400M)
5527     {
5528         return Cy_SysClk_Pll400MLocked(clkPath);
5529     }
5530     else
5531     {
5532         return Cy_SysClk_Pll200MLocked(clkPath - CY_SRSS_NUM_PLL400M);
5533     }
5534 #else
5535     return Cy_SysClk_Pll200MLocked(clkPath);
5536 #endif
5537 #endif
5538 }
5539 
Cy_SysClk_PllLostLock(uint32_t clkPath)5540 bool Cy_SysClk_PllLostLock(uint32_t clkPath)
5541 {
5542 #if defined(CY_IP_MXS22SRSS)
5543     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5544 
5545     if(clkPath < SRSS_NUM_DPLL_LP)
5546     {
5547         return Cy_SysClk_DpllLpLostLock(clkPath);
5548     }
5549     else
5550     {
5551         return Cy_SysClk_DpllHpLostLock(clkPath - SRSS_NUM_DPLL_LP);
5552     }
5553 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5554     clkPath--; /* to correctly access PLL config and status registers structures */
5555     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5556 
5557     if(clkPath < SRSS_NUM_DPLL_LP)
5558     {
5559         return Cy_SysClk_DpllLpLostLock(clkPath);
5560     }
5561     else
5562     {
5563         return false;
5564     }
5565 #else
5566     clkPath--; /* to correctly access PLL config and status registers structures */
5567     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5568 
5569 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5570     if(clkPath < CY_SRSS_NUM_PLL400M)
5571     {
5572         return Cy_SysClk_Pll400MLostLock(clkPath);
5573     }
5574     else
5575     {
5576         return Cy_SysClk_Pll200MLostLock(clkPath - CY_SRSS_NUM_PLL400M);
5577     }
5578 #else
5579     return Cy_SysClk_Pll200MLostLock(clkPath);
5580 #endif
5581 #endif
5582 }
5583 
Cy_SysClk_PllDisable(uint32_t clkPath)5584 cy_en_sysclk_status_t Cy_SysClk_PllDisable(uint32_t clkPath)
5585 {
5586 #if defined(CY_IP_MXS22SRSS)
5587     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5588 
5589     if(clkPath < SRSS_NUM_DPLL_LP)
5590     {
5591         return Cy_SysClk_DpllLpDisable(clkPath);
5592     }
5593     else
5594     {
5595         return Cy_SysClk_DpllHpDisable(clkPath - SRSS_NUM_DPLL_LP);
5596     }
5597 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5598     clkPath--; /* to correctly access PLL config and status registers structures */
5599     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5600 
5601     if(clkPath < SRSS_NUM_DPLL_LP)
5602     {
5603         return Cy_SysClk_DpllLpDisable(clkPath);
5604     }
5605     else
5606     {
5607         return CY_SYSCLK_BAD_PARAM;
5608     }
5609 #else
5610     clkPath--; /* to correctly access PLL config and status registers structures */
5611     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5612 
5613 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5614     if(clkPath < CY_SRSS_NUM_PLL400M)
5615     {
5616         return Cy_SysClk_Pll400MDisable(clkPath);
5617     }
5618     else
5619     {
5620         return Cy_SysClk_Pll200MDisable(clkPath - CY_SRSS_NUM_PLL400M);
5621     }
5622 #else
5623     return Cy_SysClk_Pll200MDisable(clkPath);
5624 #endif
5625 #endif
5626 }
5627 
5628 
Cy_SysClk_PllConfigure(uint32_t clkPath,const cy_stc_pll_config_t * config)5629 cy_en_sysclk_status_t Cy_SysClk_PllConfigure(uint32_t clkPath, const cy_stc_pll_config_t *config)
5630 {
5631 #if defined(CY_IP_MXS22SRSS)
5632     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5633 
5634     if(clkPath < SRSS_NUM_DPLL_LP)
5635     {
5636         return Cy_SysClk_DpllLpConfigure(clkPath, config);
5637     }
5638     else
5639     {
5640         return Cy_SysClk_DpllHpConfigure(clkPath - SRSS_NUM_DPLL_LP, config);
5641     }
5642 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5643     clkPath--; /* to correctly access PLL config and status registers structures */
5644     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5645 
5646     if(clkPath < SRSS_NUM_DPLL_LP)
5647     {
5648         return Cy_SysClk_DpllLpConfigure(clkPath, config);
5649     }
5650     else
5651     {
5652         return CY_SYSCLK_BAD_PARAM;
5653     }
5654 #else
5655     clkPath--; /* to correctly access PLL config and status registers structures */
5656     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5657 
5658 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5659     if(clkPath < CY_SRSS_NUM_PLL400M)
5660     {
5661         return Cy_SysClk_Pll400MConfigure(clkPath, config);
5662     }
5663     else
5664     {
5665         return Cy_SysClk_Pll200MConfigure((clkPath - CY_SRSS_NUM_PLL400M), config);
5666     }
5667 #else
5668     return Cy_SysClk_Pll200MConfigure(clkPath, config);
5669 #endif
5670 #endif
5671 }
5672 
Cy_SysClk_PllManualConfigure(uint32_t clkPath,const cy_stc_pll_manual_config_t * config)5673 cy_en_sysclk_status_t Cy_SysClk_PllManualConfigure(uint32_t clkPath, const cy_stc_pll_manual_config_t *config)
5674 {
5675 #if defined(CY_IP_MXS22SRSS)
5676     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5677 
5678     if(clkPath < SRSS_NUM_DPLL_LP)
5679     {
5680         return Cy_SysClk_DpllLpManualConfigure(clkPath, config);
5681     }
5682     else
5683     {
5684         return Cy_SysClk_DpllHpManualConfigure(clkPath - SRSS_NUM_DPLL_LP, config);
5685     }
5686 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5687     clkPath--; /* to correctly access PLL config and status registers structures */
5688     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5689 
5690     if(clkPath < SRSS_NUM_DPLL_LP)
5691     {
5692         return Cy_SysClk_DpllLpManualConfigure(clkPath, config);
5693     }
5694     else
5695     {
5696         return CY_SYSCLK_BAD_PARAM;
5697     }
5698 #else
5699     clkPath--; /* to correctly access PLL config and status registers structures */
5700     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5701 
5702 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5703     if(clkPath < CY_SRSS_NUM_PLL400M)
5704     {
5705         return Cy_SysClk_Pll400MManualConfigure(clkPath, config);
5706     }
5707     else
5708     {
5709         return Cy_SysClk_Pll200MManualConfigure((clkPath - CY_SRSS_NUM_PLL400M), config);
5710     }
5711 #else
5712     return Cy_SysClk_Pll200MManualConfigure(clkPath, config);
5713 #endif
5714 #endif
5715 }
5716 
Cy_SysClk_PllGetConfiguration(uint32_t clkPath,cy_stc_pll_manual_config_t * config)5717 cy_en_sysclk_status_t Cy_SysClk_PllGetConfiguration(uint32_t clkPath, cy_stc_pll_manual_config_t *config)
5718 {
5719 #if defined(CY_IP_MXS22SRSS)
5720     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5721 
5722     if(clkPath < SRSS_NUM_DPLL_LP)
5723     {
5724         return Cy_SysClk_DpllLpGetConfiguration(clkPath, config);
5725     }
5726     else
5727     {
5728         return Cy_SysClk_DpllHpGetConfiguration(clkPath - SRSS_NUM_DPLL_LP, config);
5729     }
5730 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5731     clkPath--; /* to correctly access PLL config and status registers structures */
5732     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5733 
5734     if(clkPath < SRSS_NUM_DPLL_LP)
5735     {
5736         return Cy_SysClk_DpllLpGetConfiguration(clkPath, config);
5737     }
5738     else
5739     {
5740         return CY_SYSCLK_BAD_PARAM;
5741     }
5742 #else
5743     clkPath--; /* to correctly access PLL config and status registers structures */
5744     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5745 
5746 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5747     if(clkPath < CY_SRSS_NUM_PLL400M)
5748     {
5749         return Cy_SysClk_Pll400MGetConfiguration(clkPath, config);
5750     }
5751     else
5752     {
5753         return Cy_SysClk_Pll200MGetConfiguration((clkPath - CY_SRSS_NUM_PLL400M), config);
5754     }
5755 #else
5756     return Cy_SysClk_Pll200MGetConfiguration(clkPath, config);
5757 #endif
5758 #endif
5759 }
5760 
Cy_SysClk_PllEnable(uint32_t clkPath,uint32_t timeoutus)5761 cy_en_sysclk_status_t Cy_SysClk_PllEnable(uint32_t clkPath, uint32_t timeoutus)
5762 {
5763 #if defined(CY_IP_MXS22SRSS)
5764     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5765 
5766     if(clkPath < SRSS_NUM_DPLL_LP)
5767     {
5768         return Cy_SysClk_DpllLpEnable(clkPath, timeoutus);
5769     }
5770     else
5771     {
5772         return Cy_SysClk_DpllHpEnable(clkPath - SRSS_NUM_DPLL_LP, timeoutus);
5773     }
5774 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5775     clkPath--; /* to correctly access PLL config and status registers structures */
5776     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5777 
5778     if(clkPath < SRSS_NUM_DPLL_LP)
5779     {
5780         return Cy_SysClk_DpllLpEnable(clkPath, timeoutus);
5781     }
5782     else
5783     {
5784         return CY_SYSCLK_BAD_PARAM;
5785     }
5786 #else
5787     clkPath--; /* to correctly access PLL config and status registers structures */
5788     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5789 
5790 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5791     if(clkPath < CY_SRSS_NUM_PLL400M)
5792     {
5793         return Cy_SysClk_Pll400MEnable(clkPath, timeoutus);
5794     }
5795     else
5796     {
5797         return Cy_SysClk_Pll200MEnable((clkPath - CY_SRSS_NUM_PLL400M), timeoutus);
5798     }
5799 #else
5800     return Cy_SysClk_Pll200MEnable(clkPath, timeoutus);
5801 #endif  /* defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0) */
5802 #endif
5803 }
5804 
Cy_SysClk_PllGetFrequency(uint32_t clkPath)5805 uint32_t Cy_SysClk_PllGetFrequency(uint32_t clkPath)
5806 {
5807 #if defined(CY_IP_MXS22SRSS)
5808     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5809 
5810     if(clkPath < SRSS_NUM_DPLL_LP)
5811     {
5812         return Cy_SysClk_DpllLpGetFrequency(clkPath);
5813     }
5814     else
5815     {
5816         return Cy_SysClk_DpllHpGetFrequency(clkPath - SRSS_NUM_DPLL_LP);
5817     }
5818 #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
5819     CY_ASSERT_L1(clkPath > 0U);
5820     clkPath--; /* to correctly access PLL config and status registers structures */
5821     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5822 
5823     if(clkPath < SRSS_NUM_DPLL_LP)
5824     {
5825         return Cy_SysClk_DpllLpGetFrequency(clkPath);
5826     }
5827     else
5828     {
5829         return 0UL;
5830     }
5831 #else
5832     CY_ASSERT_L1(clkPath > 0U);
5833     clkPath--; /* to correctly access PLL config and status registers structures */
5834     CY_ASSERT_L1(clkPath < (CY_SRSS_NUM_PLL));
5835 
5836 #if defined (CY_SRSS_NUM_PLL400M) && (CY_SRSS_NUM_PLL400M > 0)
5837     if(clkPath < CY_SRSS_NUM_PLL400M)
5838     {
5839         return Cy_SysClk_Pll400MGetFrequency(clkPath);
5840     }
5841     else
5842     {
5843         return Cy_SysClk_Pll200MGetFrequency(clkPath - CY_SRSS_NUM_PLL400M);
5844     }
5845 #else
5846     return Cy_SysClk_Pll200MGetFrequency(clkPath);
5847 #endif
5848 #endif
5849 }
5850 
5851 
5852 #endif /* (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) */
5853 
5854 /* ========================================================================== */
5855 /* ====================    Clock Measurement section    ===================== */
5856 /* ========================================================================== */
5857 /* Slow control register default value */
5858 #define TST_DDFT_SLOW_CTL_DEFAULT_VAL      (0x00001F1FUL)
5859 
5860 /* Fast control register */
5861 #define TST_DDFT_FAST_CTL_REG              (*(volatile uint32_t *) 0x40260104U)
5862 
5863 /* Slow control register default value */
5864 #define TST_DDFT_FAST_CTL_DEFAULT_VAL      (0x00003D3DUL)
5865 
5866 /* Define for select signal outputs in slow clock */
5867 #define SRSS_CLK_OUTPUT_SLOW_MASK  ((uint32_t) SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk | \
5868                                                SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk)
5869 
5870 /* Define for select signal outputs in fast clock */
5871 #define SRSS_CLK_OUTPUT_FAST_MASK  ((uint32_t) SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk  | \
5872                                                SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk  | \
5873                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk  | \
5874                                                SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk  | \
5875                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk | \
5876                                                SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk)
5877 
5878 
Cy_SysClk_ClkMeasurementCountersDone(void)5879 bool Cy_SysClk_ClkMeasurementCountersDone(void)
5880 {
5881     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
5882 
5883     return (_FLD2BOOL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1));
5884 }
5885 
Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1,uint32_t count1,cy_en_meas_clks_t clock2)5886 cy_en_sysclk_status_t Cy_SysClk_StartClkMeasurementCounters(cy_en_meas_clks_t clock1, uint32_t count1, cy_en_meas_clks_t clock2)
5887 {
5888     cy_en_sysclk_status_t retVal = CY_SYSCLK_BAD_PARAM;
5889 
5890     uint32_t clkOutputSlowVal = 0UL;
5891     uint32_t clkOutputFastVal = 0UL;
5892 
5893     uint32_t clkOutputSlowMask = 0UL;
5894     uint32_t clkOutputFastMask = 0UL;
5895 
5896     /* Prepare values for measurement control registers */
5897 
5898     /* Connect the indicated clocks to the respective counters:
5899 
5900        if clock1 is a slow clock,
5901          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL0, and SRSS_CLK_OUTPUT_FAST.FAST_SEL0 = SLOW_SEL0
5902        else if clock1 is a fast clock,
5903          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL0,
5904        else error, do nothing and return.
5905 
5906        if clock2 is a slow clock,
5907          select it in SRSS_CLK_OUTPUT_SLOW.SLOW_SEL1, and SRSS_CLK_OUTPUT_FAST.FAST_SEL1 = SLOW_SEL1
5908        else if clock2 is a fast clock,
5909          select it in SRSS_CLK_OUTPUT_FAST.FAST_SEL1,
5910        else error, do nothing and return.
5911     */
5912     if ((clock1 < CY_SYSCLK_MEAS_CLK_LAST_CLK) && (clock2 < CY_SYSCLK_MEAS_CLK_LAST_CLK) &&
5913         (count1 <= (SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Msk >> SRSS_CLK_CAL_CNT1_CAL_COUNTER1_Pos)))
5914     {
5915         /* Disallow entry into Deep Sleep mode while counting */
5916         clkCounting = true;
5917 
5918         if (clock1 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
5919         { /* slow clock */
5920             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0, (uint32_t)clock1);
5921             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, SLOW_SEL_OUTPUT_INDEX /*slow_sel0 output*/);
5922 
5923             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL0_Msk;
5924             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
5925         }
5926         else
5927         { /* fast clock */
5928             if (clock1 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
5929             { /* ECO, EXT, ALTHF */
5930                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (uint32_t)clock1);
5931                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
5932             }
5933             else
5934             { /* PATH or CLKHF */
5935                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL0, (((uint32_t)clock1 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
5936                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL0_Msk;
5937 
5938                 if (clock1 < CY_SYSCLK_MEAS_CLK_CLKHFS)
5939                 { /* PATH select */
5940                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
5941                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL0_Msk;
5942                 }
5943                 else
5944                 { /* CLKHF select */
5945                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0, ((uint32_t)clock1 & 0xFUL) /*use enum bits [3:0]*/);
5946                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL0_Msk;
5947                 }
5948             }
5949         } /* clock1 fast clock */
5950 
5951         if (clock2 < CY_SYSCLK_MEAS_CLK_FAST_CLKS)
5952         { /* slow clock */
5953             clkOutputSlowVal |= _VAL2FLD(SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1, (uint32_t)clock2);
5954             clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, SLOW_SEL_OUTPUT_INDEX /*slow_sel1 output*/);
5955 
5956             clkOutputSlowMask |= SRSS_CLK_OUTPUT_SLOW_SLOW_SEL1_Msk;
5957             clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
5958         }
5959         else
5960         { /* fast clock */
5961             if (clock2 < CY_SYSCLK_MEAS_CLK_PATH_CLKS)
5962             { /* ECO, EXT, ALTHF */
5963                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (uint32_t)clock2);
5964                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
5965             }
5966             else
5967             { /* PATH or CLKHF */
5968                 clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_FAST_SEL1, (((uint32_t)clock2 >> 8) & 0xFUL) /*use enum bits [11:8]*/);
5969                 clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_FAST_SEL1_Msk;
5970 
5971                 if (clock2 < CY_SYSCLK_MEAS_CLK_CLKHFS)
5972                 { /* PATH select */
5973                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_PATH_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
5974                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_PATH_SEL1_Msk;
5975                 }
5976                 else
5977                 { /* CLKHF select */
5978                     clkOutputFastVal |= _VAL2FLD(SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1, ((uint32_t)clock2 & 0xFUL) /*use enum bits [3:0]*/);
5979                     clkOutputFastMask |= SRSS_CLK_OUTPUT_FAST_HFCLK_SEL1_Msk;
5980                 }
5981             }
5982         } /* clock2 fast clock */
5983 
5984         if ((!preventCounting) /* don't start a measurement if about to enter Deep Sleep mode */  ||
5985             (_FLD2VAL(SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE, SRSS_CLK_CAL_CNT1) != 0UL/*1 = done */))
5986         {
5987             /* Set default values for counters measurement control registers */
5988             SRSS_TST_DDFT_SLOW_CTL_REG = TST_DDFT_SLOW_CTL_DEFAULT_VAL;
5989             SRSS_TST_DDFT_FAST_CTL_REG = TST_DDFT_FAST_CTL_DEFAULT_VAL;
5990 
5991             SRSS_CLK_OUTPUT_SLOW = ((SRSS_CLK_OUTPUT_SLOW & ((uint32_t) ~clkOutputSlowMask)) | clkOutputSlowVal);
5992             SRSS_CLK_OUTPUT_FAST = ((SRSS_CLK_OUTPUT_FAST & ((uint32_t) ~clkOutputFastMask)) | clkOutputFastVal);
5993 
5994             /* Save this input parameter for use later, in other functions.
5995                No error checking is done on this parameter */
5996             clk1Count1 = count1;
5997 
5998             /* Counting starts when counter1 is written with a nonzero value */
5999             SRSS_CLK_CAL_CNT1 = clk1Count1;
6000 
6001             retVal = CY_SYSCLK_SUCCESS;
6002         }
6003     }
6004     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6005 
6006     return (retVal);
6007 }
6008 
6009 
Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock,uint32_t refClkFreq)6010 uint32_t Cy_SysClk_ClkMeasurementCountersGetFreq(bool measuredClock, uint32_t refClkFreq)
6011 {
6012     uint32_t retVal = 0UL;
6013     bool isMeasurementValid = false;
6014 
6015     /* Done counting; allow entry into Deep Sleep mode */
6016     clkCounting = false;
6017 
6018     /* Check whether the device was in the Deep Sleep mode or the flash partially blocked while the
6019     *  operation was done
6020     */
6021     if(SRSS_TST_DDFT_SLOW_CTL_REG == TST_DDFT_SLOW_CTL_DEFAULT_VAL)
6022     {
6023        if(SRSS_TST_DDFT_FAST_CTL_REG == TST_DDFT_FAST_CTL_DEFAULT_VAL)
6024        {
6025            isMeasurementValid = true;
6026        }
6027     }
6028 
6029     retVal = _FLD2VAL(SRSS_CLK_CAL_CNT2_CAL_COUNTER2, SRSS_CLK_CAL_CNT2);
6030 
6031     if (isMeasurementValid && (0UL != retVal))
6032     {
6033         if (!measuredClock)
6034         {   /* clock1 is the measured clock */
6035             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)clk1Count1 * (uint64_t)refClkFreq, (uint64_t)retVal);
6036         }
6037         else
6038         {   /* clock2 is the measured clock */
6039             retVal = (uint32_t)CY_SYSLIB_DIV_ROUND((uint64_t)retVal * (uint64_t)refClkFreq, (uint64_t)clk1Count1);
6040         }
6041     }
6042     else
6043     {
6044         /* Return zero value to indicate invalid measurement */
6045         retVal = 0UL;
6046     }
6047     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6048 
6049     return (retVal);
6050 }
6051 
6052 
6053 /* ========================================================================== */
6054 /* ==========================    TRIM SECTION    ============================ */
6055 /* ========================================================================== */
6056 
6057 /** \cond INTERNAL */
6058 /** \cond INTERNAL */
6059 #define CY_SYSCLK_ILO_TARGET_FREQ  (32768UL)
6060 /* Nominal trim step size is 1.5% of "the frequency". Using the target frequency */
6061 #define CY_SYSCLK_ILO_TRIM_STEP    (CY_SYSLIB_DIV_ROUND(CY_SYSCLK_ILO_TARGET_FREQ * 15UL, 1000UL))
6062 /** \endcond */
6063 
6064 #if defined (CY_IP_MXS40SSRSS)
Cy_SysClk_IloTrim(uint32_t iloFreq)6065 int32_t Cy_SysClk_IloTrim(uint32_t iloFreq)
6066 {
6067     int32_t changeInTrim;
6068     uint32_t diff;
6069     bool sign = false;
6070 
6071     if(iloFreq > (CY_SYSCLK_ILO_TARGET_FREQ + CY_SYSCLK_ILO_TRIM_STEP))
6072     {
6073         diff = iloFreq - CY_SYSCLK_ILO_TARGET_FREQ;
6074     }
6075     else if (iloFreq < (CY_SYSCLK_ILO_TARGET_FREQ - CY_SYSCLK_ILO_TRIM_STEP))
6076     {
6077         diff = CY_SYSCLK_ILO_TARGET_FREQ - iloFreq;
6078         sign = true;
6079     }
6080     else
6081     {
6082         diff = 0UL;
6083     }
6084 
6085     /* Do nothing if iloFreq is already within one trim step from the target */
6086     if(0UL != diff)
6087     {
6088         /* Get current trim value */
6089         uint32_t trim = Cy_SysClk_IloGetTrim();
6090 
6091         diff = CY_SYSLIB_DIV_ROUND(diff, CY_SYSCLK_ILO_TRIM_STEP);
6092 
6093         if(sign)
6094         {
6095             trim += diff;
6096         }
6097         else
6098         {
6099             trim -= diff;
6100     }
6101 
6102     /* Update the trim value */
6103     Cy_SysClk_IloSetTrim(trim);
6104     }
6105 
6106     changeInTrim = (sign ? (int32_t)diff : (0L - (int32_t)diff));
6107     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6108 
6109     return changeInTrim;
6110 
6111 }
6112 
Cy_SysClk_IloSetTrim(uint32_t trimVal)6113 void Cy_SysClk_IloSetTrim(uint32_t trimVal)
6114 {
6115 #if defined (CY_IP_MXS40SSRSS)
6116     CY_REG32_CLR_SET(SRSS_CLK_TRIM_ILO_CTL, SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, trimVal);
6117     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6118 #else
6119     CY_UNUSED_PARAMETER(trimVal); /* Suppress a compiler warning about unused variables */
6120     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6121 #endif
6122 }
6123 
Cy_SysClk_IloGetTrim(void)6124 uint32_t Cy_SysClk_IloGetTrim(void)
6125 {
6126 #if defined (CY_IP_MXS40SSRSS)
6127     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6128 
6129     return (_FLD2VAL(SRSS_CLK_TRIM_ILO_CTL_ILO_FTRIM, SRSS_CLK_TRIM_ILO_CTL));
6130 #else
6131     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6132 
6133     return 0;
6134 #endif
6135 }
6136 #endif /* defined (CY_IP_MXS40SSRSS) */
6137 
6138 /* ========================================================================== */
6139 /* ======================    POWER MANAGEMENT SECTION    ==================== */
6140 /* ========================================================================== */
6141 
6142 
6143 /** \cond INTERNAL */
6144 /* Timeout count for use in function Cy_SysClk_DeepSleepCallback() is sufficiently large for ~1 second */
6145 #define TIMEOUT (1000000UL)
6146 /** \endcond */
6147 
Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)6148 cy_en_syspm_status_t Cy_SysClk_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams, cy_en_syspm_callback_mode_t mode)
6149 {
6150     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
6151 
6152     /* Suppress "not used" warning */
6153     CY_UNUSED_PARAMETER(callbackParams);
6154     CY_UNUSED_PARAMETER(clkCounting);
6155 
6156     switch (mode)
6157     {
6158         case CY_SYSPM_CHECK_READY:
6159             /* Don't allow entry into Deep Sleep mode if currently measuring a frequency */
6160             if (!clkCounting)
6161             {
6162                 /* Indicating that we can go into Deep Sleep.
6163                  * Prevent starting a new clock measurement until
6164                  * after we've come back from Deep Sleep.
6165                  */
6166                 preventCounting = true;
6167                 retVal = CY_SYSPM_SUCCESS;
6168             }
6169             break;
6170 
6171         case CY_SYSPM_CHECK_FAIL:
6172             /* Cancellation of going into Deep Sleep, therefore allow a new clock measurement */
6173             preventCounting = false;
6174             retVal = CY_SYSPM_SUCCESS;
6175             break;
6176 
6177         case CY_SYSPM_BEFORE_TRANSITION:
6178             retVal = CY_SYSPM_SUCCESS;
6179             break;
6180 
6181         case CY_SYSPM_AFTER_TRANSITION:
6182             preventCounting = false; /* Allow clock measurement */
6183             break;
6184 
6185         default: /* Unsupported mode, return CY_SYSPM_FAIL */
6186             break;
6187     }
6188 
6189     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6190 
6191     return (retVal);
6192 
6193 }
6194 
6195 
6196 /** \cond INTERNAL */
6197 /* Value to indicate invalid HF NUM */
6198 #define CY_SYSCLK_INVALID_HF_NUM (0xFFFFFFFFUL)
6199 /** \endcond */
6200 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 18.1', 5, \
6201 'Suppressing taking true and false branch.')
Cy_Sysclk_PeriPclkGetClkHfNum(uint32_t ipBlock)6202 uint32_t Cy_Sysclk_PeriPclkGetClkHfNum(uint32_t ipBlock)
6203 {
6204 #if (defined (CY_IP_MXS40SRSS) && (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3U)))
6205     /* MXPERI versions 1 & 2 do not use peri groups, this function is not compatible with PERI ver2. */
6206     CY_UNUSED_PARAMETER(ipBlock);
6207     return CY_SYSCLK_INVALID_HF_NUM;
6208 #else
6209 
6210     uint32_t grpNum = (ipBlock & PERI_PCLK_GR_NUM_Msk) >> PERI_PCLK_GR_NUM_Pos;
6211     uint32_t instNum = (uint8_t)((ipBlock & PERI_PCLK_INST_NUM_Msk) >> PERI_PCLK_INST_NUM_Pos);
6212 
6213     if (grpNum >= PERI_PCLK_GR_NUM(instNum))
6214     {
6215         return CY_SYSCLK_INVALID_HF_NUM;
6216     }
6217 
6218     #if defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION >= 3)
6219         uint32_t peri0GrpToHfArray[] = { PERI0_PCLK_GR_NUM_0_CLK_HF_NUM,
6220                                     PERI0_PCLK_GR_NUM_1_CLK_HF_NUM,
6221                                   };
6222     #elif (defined (CY_IP_MXS40SSRSS) && (SRSS_NUM_TOTAL_PLL > 0UL))
6223         uint32_t peri0GrpToHfArray[] = { PERI0_PCLK_GR_NUM_0_CLK_HF_NUM,
6224                                     PERI0_PCLK_GR_NUM_1_CLK_HF_NUM,
6225                                     PERI0_PCLK_GR_NUM_2_CLK_HF_NUM,
6226                                     PERI0_PCLK_GR_NUM_3_CLK_HF_NUM,
6227                                     PERI0_PCLK_GR_NUM_4_CLK_HF_NUM,
6228                                     PERI0_PCLK_GR_NUM_5_CLK_HF_NUM,
6229                                     PERI0_PCLK_GR_NUM_6_CLK_HF_NUM
6230                                   };
6231     #elif defined (CY_IP_MXS22SRSS)
6232         uint32_t peri0GrpToHfArray[PERI0_PCLK_GROUP_NR] = { PERI0_PCLK_GR_NUM_0_CLK_HF_NUM,
6233                                     PERI0_PCLK_GR_NUM_1_CLK_HF_NUM,
6234                                     PERI0_PCLK_GR_NUM_2_CLK_HF_NUM,
6235                                     PERI0_PCLK_GR_NUM_3_CLK_HF_NUM,
6236                                     PERI0_PCLK_GR_NUM_4_CLK_HF_NUM,
6237                                     PERI0_PCLK_GR_NUM_5_CLK_HF_NUM,
6238                                     PERI0_PCLK_GR_NUM_6_CLK_HF_NUM,
6239                                     PERI0_PCLK_GR_NUM_7_CLK_HF_NUM,
6240                                     PERI0_PCLK_GR_NUM_8_CLK_HF_NUM,
6241                                     PERI0_PCLK_GR_NUM_9_CLK_HF_NUM,
6242                                   };
6243     #else
6244         uint32_t peri0GrpToHfArray[] = { PERI0_PCLK_GR_NUM_0_CLK_HF_NUM,
6245                                     PERI0_PCLK_GR_NUM_1_CLK_HF_NUM,
6246                                     PERI0_PCLK_GR_NUM_2_CLK_HF_NUM,
6247                                     PERI0_PCLK_GR_NUM_3_CLK_HF_NUM,
6248                                     PERI0_PCLK_GR_NUM_4_CLK_HF_NUM,
6249                                     PERI0_PCLK_GR_NUM_5_CLK_HF_NUM,
6250                                     PERI0_PCLK_GR_NUM_6_CLK_HF_NUM
6251                                   };
6252     #endif
6253 
6254 #if defined (CY_IP_MXS22SRSS)
6255     uint32_t peri1GrpToHfArray[PERI1_PCLK_GROUP_NR] = { PERI1_PCLK_GR_NUM_0_CLK_HF_NUM,
6256                                 PERI1_PCLK_GR_NUM_1_CLK_HF_NUM,
6257                                 PERI1_PCLK_GR_NUM_2_CLK_HF_NUM,
6258                                 PERI1_PCLK_GR_NUM_3_CLK_HF_NUM,
6259                                 PERI1_PCLK_GR_NUM_4_CLK_HF_NUM,
6260                                 PERI1_PCLK_GR_NUM_5_CLK_HF_NUM,
6261                               };
6262 #endif
6263 
6264 #if defined (CY_IP_MXS22SRSS)
6265     if(0UL == instNum)
6266     {
6267         return peri0GrpToHfArray[grpNum];
6268     }
6269     else
6270     {
6271         return peri1GrpToHfArray[grpNum];
6272     }
6273 #else
6274     return peri0GrpToHfArray[grpNum];
6275 #endif
6276 #endif
6277 }
6278 
Cy_SysClk_PeriPclkGetFrequency(en_clk_dst_t ipBlock,cy_en_divider_types_t dividerType,uint32_t dividerNum)6279 uint32_t Cy_SysClk_PeriPclkGetFrequency(en_clk_dst_t ipBlock, cy_en_divider_types_t dividerType, uint32_t dividerNum)
6280 {
6281     uint32_t integer = 0UL;        /* Integer part of peripheral divider */
6282     uint32_t freq = 0UL;
6283     uint32_t grpNum = 0UL;
6284     uint32_t instNum = 0UL;
6285     uint32_t hfNum = CY_SYSCLK_INVALID_HF_NUM;
6286 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)
6287     uint32_t peri_div = 1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider();
6288 #endif
6289 #if defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION <= 2)
6290     hfNum = 0UL;
6291 #else
6292     grpNum = (((uint32_t)ipBlock) & PERI_PCLK_GR_NUM_Msk )>>PERI_PCLK_GR_NUM_Pos;
6293     instNum = (uint8_t)(((uint32_t)ipBlock & PERI_PCLK_INST_NUM_Msk )>>PERI_PCLK_INST_NUM_Pos);
6294 
6295 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)
6296     peri_div = (grpNum == 0UL) ? (1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider()) : 1U;
6297 #endif
6298 
6299     CY_ASSERT_L1(instNum < PERI_INSTANCE_COUNT);
6300     CY_ASSERT_L1(grpNum < PERI_PCLK_GR_NUM(instNum));
6301 
6302     hfNum = Cy_Sysclk_PeriPclkGetClkHfNum((uint32_t)ipBlock);
6303 #endif
6304 
6305 #if (defined (CY_IP_MXS40SRSS) && (defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION < 3U)))
6306         CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_PCLK_GR_DIV_8_NR(instNum, grpNum)))    || \
6307                      ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_PCLK_GR_DIV_16_NR(instNum, grpNum)))   || \
6308                      ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))));
6309 #else
6310         CY_ASSERT_L1(((dividerType == CY_SYSCLK_DIV_8_BIT)    && (dividerNum < PERI_PCLK_GR_DIV_8_NR(instNum, grpNum)))    || \
6311                      ((dividerType == CY_SYSCLK_DIV_16_BIT)   && (dividerNum < PERI_PCLK_GR_DIV_16_NR(instNum, grpNum)))   || \
6312                      ((dividerType == CY_SYSCLK_DIV_16_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_16_5_NR(instNum, grpNum))) || \
6313                      ((dividerType == CY_SYSCLK_DIV_24_5_BIT) && (dividerNum < PERI_PCLK_GR_DIV_24_5_NR(instNum, grpNum))));
6314 #endif
6315 
6316 
6317 #if !(defined (CY_IP_MXPERI) && (CY_IP_MXPERI_VERSION <= 2))
6318     if(hfNum != CY_SYSCLK_INVALID_HF_NUM)
6319 #endif
6320     {
6321         freq = Cy_SysClk_ClkHfGetFrequency(hfNum); /* Get CLK_HF* frequency */
6322 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)
6323         /* get the peri clock tree frequency */
6324         freq = CY_SYSLIB_DIV_ROUND(freq, peri_div);
6325 #endif
6326         /* get the divider value for clk_peri to the selected peripheral clock */
6327         switch(dividerType)
6328         {
6329             case CY_SYSCLK_DIV_8_BIT:
6330             case CY_SYSCLK_DIV_16_BIT:
6331                 integer = 1UL + Cy_SysClk_PeriPclkGetDivider(ipBlock, dividerType, dividerNum);
6332                 freq = CY_SYSLIB_DIV_ROUND(freq, integer);
6333                 break;
6334 
6335             case CY_SYSCLK_DIV_16_5_BIT:
6336             case CY_SYSCLK_DIV_24_5_BIT:
6337                 {
6338                     uint32_t locFrac = 0;
6339                     uint32_t locDiv = 0;
6340                     uint64_t locFreq = freq * 32ULL;
6341                     Cy_SysClk_PeriPclkGetFracDivider(ipBlock, dividerType, dividerNum, &integer, &locFrac);
6342                     /* For fractional dividers, the divider is (int + 1) + frac/32 */
6343                     locDiv = ((1UL + integer) * 32UL) + locFrac;
6344                     freq = (uint32_t) CY_SYSLIB_DIV_ROUND(locFreq, (uint64_t)locDiv);
6345                 }
6346                 break;
6347 
6348             default:
6349                 /* Unknown Divider */
6350                 break;
6351         }
6352     }
6353     CY_UNUSED_PARAMETER(clkCounting); /* Suppress a compiler warning about unused variables */
6354     CY_UNUSED_PARAMETER(instNum); /* Suppress a compiler warning about unused variables */
6355     CY_UNUSED_PARAMETER(grpNum); /* Suppress a compiler warning about unused variables */
6356 
6357     return (freq);
6358 }
6359 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.1')
6360 
6361 
6362 /* ========================================================================== */
6363 /* ===========================    CLKPWR SECTION    =========================== */
6364 /* ========================================================================== */
6365 #if (defined (CY_IP_MXS40SSRSS) && (CY_MXS40SSRSS_VER_1_2 > 0UL))
6366 
Cy_SysClk_ClkPwrSetDivider(uint32_t divider)6367 void Cy_SysClk_ClkPwrSetDivider(uint32_t divider)
6368 {
6369     if (CY_SYSCLK_IS_CLKPWR_DIVIDER_VALID(divider))
6370     {
6371         CY_REG32_CLR_SET(PWRMODE_PWR_SELECT, PWRMODE_CLK_SELECT_CLK_PWR_DIV, divider - 1UL);
6372     }
6373 }
6374 
6375 
Cy_SysClk_ClkPwrGetDivider(void)6376 uint32_t Cy_SysClk_ClkPwrGetDivider(void)
6377 {
6378     return ((1UL + _FLD2VAL(PWRMODE_CLK_SELECT_CLK_PWR_DIV, PWRMODE_PWR_SELECT)));
6379 }
6380 
Cy_SysClk_ClkPwrGetFrequency(void)6381 uint32_t Cy_SysClk_ClkPwrGetFrequency(void)
6382 {
6383     uint32_t pwrFreq = 0UL, pwrDiv;
6384 
6385       /* Get the frequency of the source */
6386         switch(Cy_SysClk_ClkPwrGetSource())
6387         {
6388             case CY_SYSCLK_CLKPWR_IN_IMO: /* The IMO frequency is fixed at 8 MHz */
6389                 pwrFreq = CY_SYSCLK_IMO_FREQ;
6390                 break;
6391 
6392             case CY_SYSCLK_CLKPWR_IN_IHO:
6393                 pwrFreq = CY_SYSCLK_IHO_FREQ;
6394                 break;
6395 
6396             default:
6397                 /* Don't know the frequency of dsi_out, leave freq = 0UL */
6398                 break;
6399         }
6400 
6401     pwrDiv = Cy_SysClk_ClkPwrGetDivider(); /* clkPwr prescaler (1-256) */
6402 
6403     /* Divide the path input frequency down and return the result */
6404     return (CY_SYSLIB_DIV_ROUND(pwrFreq, pwrDiv));
6405 }
6406 
6407 
Cy_SysClk_ClkPwrSetSource(cy_en_clkpwr_in_sources_t source)6408 void Cy_SysClk_ClkPwrSetSource(cy_en_clkpwr_in_sources_t source)
6409 {
6410     CY_ASSERT_L3(CY_SYSCLK_IF_CLKPWR_SOURCE_VALID(source));
6411     CY_REG32_CLR_SET(PWRMODE_PWR_SELECT, PWRMODE_CLK_SELECT_CLK_PWR_MUX, source);
6412 }
6413 
6414 
Cy_SysClk_ClkPwrGetSource(void)6415 cy_en_clkpwr_in_sources_t Cy_SysClk_ClkPwrGetSource(void)
6416 {
6417     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_clkpwr_in_sources_t enum.');
6418     return ((cy_en_clkpwr_in_sources_t)(_FLD2VAL(PWRMODE_CLK_SELECT_CLK_PWR_MUX, PWRMODE_PWR_SELECT)));
6419 }
6420 
6421 #endif
6422 
6423 #endif /* defined (CY_IP_MXS28SRSS) || defined (CY_IP_MXS40SSRSS) || (defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2)) || defined (CY_IP_MXS22SRSS) */
6424 /* [] END OF FILE */
6425