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