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