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