1 /*******************************************************************************
2 * File Name: cyhal_clock.c
3 *
4 * Description:
5 * Provides an implementation for high level interface for interacting with the
6 * Cypress Clocks. This is a wrapper around the lower level PDL API.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include "cy_sysclk.h"
31 #include "cy_utils.h"
32 #include "cyhal_clock.h"
33 #include "cyhal_system.h"
34 #include "cyhal_utils.h"
35 #include "cyhal_hwmgr.h"
36
37 #if (CYHAL_DRIVER_AVAILABLE_CLOCK)
38
39 #if defined(__cplusplus)
40 extern "C"
41 {
42 #endif
43
44 #if defined(TARGET_PSVP_CYW20829)
45 /* The PSVP hardware doesn't fully simulate the FLL so it will never report locked, but the "FLL Output"
46 * line provides a 48 MHz nonetheless. So we need to ignore the "locked" bit so that the rest of the
47 * system will see the FLL as enabled and draw the correct conclusions about source frequencies. If
48 * a lock timeout is provided and elapses, the PDL will set the FLL to disabled */
49 #define _CYHAL_CLOCK_FLL_LOCK_TIME (0UL)
50 #else
51 #define _CYHAL_CLOCK_FLL_LOCK_TIME (200000UL)
52 #endif
53 #define _CYHAL_CLOCK_PLL_LOCK_TIME (10000UL)
54
55 #if defined(PERI_PCLK_GR_NUM_Pos)
56 #define _CYHAL_CLOCK_GET_PCLK_GR_NUM(block) ((en_clk_dst_t)(_CYHAL_PERIPHERAL_GROUP_GET_GROUP(block) << PERI_PCLK_GR_NUM_Pos))
57 #else
58 #define _CYHAL_CLOCK_GET_PCLK_GR_NUM(block) ((en_clk_dst_t)0) /* Value is not used for devices that don't have PCLK groups. */
59 #endif
60
61 /* We can't use the PDL-defined _CYHAL_SRSS_PILO_PRESENT because on CAT1A devices it performs a struct lookup
62 * which won't work in preprocessor expressions */
63 #if defined(COMPONENT_CAT1A)
64 #define _CYHAL_SRSS_PILO_PRESENT (SRSS_PILO_PRESENT)
65 #elif defined(COMPONENT_CAT1B)
66 #define _CYHAL_SRSS_PILO_PRESENT (SRSS_S40S_PILO_PRESENT)
67 #endif
68
69
70 /******************************************************************************
71 ****************************** Clock Resources *******************************
72 *****************************************************************************/
73 const cyhal_clock_tolerance_t CYHAL_CLOCK_TOLERANCE_0_P = {CYHAL_TOLERANCE_PERCENT, 0};
74 const cyhal_clock_tolerance_t CYHAL_CLOCK_TOLERANCE_1_P = {CYHAL_TOLERANCE_PERCENT, 1};
75 const cyhal_clock_tolerance_t CYHAL_CLOCK_TOLERANCE_5_P = {CYHAL_TOLERANCE_PERCENT, 5};
76
77 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_IMO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_IMO, 0 };
78 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_EXT = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_EXT, 0 };
79 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ILO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ILO, 0 };
80
81 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_LF = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_LF, 0 };
82 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PUMP = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PUMP, 0 };
83 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_BAK = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_BAK, 0 };
84 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ALT_SYS_TICK = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ALT_SYS_TICK, 0 };
85
86 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PATHMUX[SRSS_NUM_CLKPATH] =
87 {
88 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 0 },
89 #if (SRSS_NUM_CLKPATH > 1)
90 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 1 },
91 #endif
92 #if (SRSS_NUM_CLKPATH > 2)
93 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 2 },
94 #endif
95 #if (SRSS_NUM_CLKPATH > 3)
96 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 3 },
97 #endif
98 #if (SRSS_NUM_CLKPATH > 4)
99 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 4 },
100 #endif
101 #if (SRSS_NUM_CLKPATH > 5)
102 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 5 },
103 #endif
104 #if (SRSS_NUM_CLKPATH > 6)
105 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 6 },
106 #endif
107 #if (SRSS_NUM_CLKPATH > 7)
108 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 7 },
109 #endif
110 #if (SRSS_NUM_CLKPATH > 8)
111 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 8 },
112 #endif
113 #if (SRSS_NUM_CLKPATH > 9)
114 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 9 },
115 #endif
116 #if (SRSS_NUM_CLKPATH > 10)
117 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 10 },
118 #endif
119 #if (SRSS_NUM_CLKPATH > 11)
120 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 11 },
121 #endif
122 #if (SRSS_NUM_CLKPATH > 12)
123 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 12 },
124 #endif
125 #if (SRSS_NUM_CLKPATH > 13)
126 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 13 },
127 #endif
128 #if (SRSS_NUM_CLKPATH > 14)
129 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 14 },
130 #endif
131 #if (SRSS_NUM_CLKPATH > 15)
132 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PATHMUX, 15 },
133 #endif
134 };
135
136 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_HF[SRSS_NUM_HFROOT] =
137 {
138 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 0 },
139 #if (SRSS_NUM_HFROOT > 1)
140 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 1 },
141 #endif
142 #if (SRSS_NUM_HFROOT > 2)
143 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 2 },
144 #endif
145 #if (SRSS_NUM_HFROOT > 3)
146 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 3 },
147 #endif
148 #if (SRSS_NUM_HFROOT > 4)
149 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 4 },
150 #endif
151 #if (SRSS_NUM_HFROOT > 5)
152 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 5 },
153 #endif
154 #if (SRSS_NUM_HFROOT > 6)
155 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 6 },
156 #endif
157 #if (SRSS_NUM_HFROOT > 7)
158 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 7 },
159 #endif
160 #if (SRSS_NUM_HFROOT > 8)
161 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 8 },
162 #endif
163 #if (SRSS_NUM_HFROOT > 9)
164 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 9 },
165 #endif
166 #if (SRSS_NUM_HFROOT > 10)
167 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 10 },
168 #endif
169 #if (SRSS_NUM_HFROOT > 11)
170 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 11 },
171 #endif
172 #if (SRSS_NUM_HFROOT > 12)
173 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 12 },
174 #endif
175 #if (SRSS_NUM_HFROOT > 13)
176 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 13 },
177 #endif
178 #if (SRSS_NUM_HFROOT > 14)
179 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 14 },
180 #endif
181 #if (SRSS_NUM_HFROOT > 15)
182 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_HF, 15 },
183 #endif
184 };
185
186 #if SRSS_ECO_PRESENT
187 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ECO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ECO, 0 };
188 #endif
189 #if SRSS_ALTHF_PRESENT
190 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ALTHF = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ALTHF, 0 };
191 #endif
192 #if SRSS_ALTLF_PRESENT
193 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ALTLF = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ALTLF, 0 };
194 #endif
195 #if _CYHAL_SRSS_PILO_PRESENT
196 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PILO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PILO, 0 };
197 #endif
198 #if SRSS_BACKUP_PRESENT
199 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_WCO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_WCO, 0 };
200 #endif
201 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
202 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_MFO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_MFO, 0 };
203 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_MF = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_MF, 0 };
204 #endif
205
206 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
207 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_FLL = { CYHAL_RSC_CLOCK, CYHAL_CLOCK_BLOCK_FLL, 0 };
208 #endif
209
210 #if defined(COMPONENT_CAT1A)
211 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_FAST = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_FAST, 0 };
212 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PERI = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 0 };
213 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_TIMER = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_TIMER, 0 };
214 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_SLOW = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_SLOW, 0 };
215
216 #if (SRSS_NUM_PLL > 0)
217 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PLL[SRSS_NUM_PLL] =
218 {
219 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 0 },
220 #if (SRSS_NUM_PLL > 1)
221 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 1 },
222 #endif
223 #if (SRSS_NUM_PLL > 2)
224 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 2 },
225 #endif
226 #if (SRSS_NUM_PLL > 3)
227 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 3 },
228 #endif
229 #if (SRSS_NUM_PLL > 4)
230 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 4 },
231 #endif
232 #if (SRSS_NUM_PLL > 5)
233 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 5 },
234 #endif
235 #if (SRSS_NUM_PLL > 6)
236 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 6 },
237 #endif
238 #if (SRSS_NUM_PLL > 7)
239 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 7 },
240 #endif
241 #if (SRSS_NUM_PLL > 8)
242 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 8 },
243 #endif
244 #if (SRSS_NUM_PLL > 9)
245 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 9 },
246 #endif
247 #if (SRSS_NUM_PLL > 10)
248 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 10 },
249 #endif
250 #if (SRSS_NUM_PLL > 11)
251 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 11 },
252 #endif
253 #if (SRSS_NUM_PLL > 12)
254 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 12 },
255 #endif
256 #if (SRSS_NUM_PLL > 13)
257 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 13 },
258 #endif
259 #if (SRSS_NUM_PLL > 14)
260 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL, 14 },
261 #endif
262 };
263 #endif
264
265 #elif defined(COMPONENT_CAT1B)
266 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_IHO = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_IHO, 0 };
267 #if SRSS_ECO_PRESENT
268 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_ECO_PRESCALER = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_ECO_PRESCALER, 0 };
269 #endif
270 #if SRSS_BACKUP_S40E_LPECO_PRESENT
271 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_LPECO_PRESCALER = { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_LPECO_PRESCALER, 0 };
272 #endif
273
274 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PERI[CY_PERI_GROUP_NR] =
275 {
276 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 0 },
277 #if (CY_PERI_GROUP_NR > 1)
278 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 1 },
279 #endif
280 #if (CY_PERI_GROUP_NR > 2)
281 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 2 },
282 #endif
283 #if (CY_PERI_GROUP_NR > 3)
284 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 3 },
285 #endif
286 #if (CY_PERI_GROUP_NR > 4)
287 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 4 },
288 #endif
289 #if (CY_PERI_GROUP_NR > 5)
290 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 5 },
291 #endif
292 #if (CY_PERI_GROUP_NR > 6)
293 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 6 },
294 #endif
295 #if (CY_PERI_GROUP_NR > 7)
296 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 7 },
297 #endif
298 #if (CY_PERI_GROUP_NR > 8)
299 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 8 },
300 #endif
301 #if (CY_PERI_GROUP_NR > 9)
302 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 9 },
303 #endif
304 #if (CY_PERI_GROUP_NR > 10)
305 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 10 },
306 #endif
307 #if (CY_PERI_GROUP_NR > 11)
308 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 11 },
309 #endif
310 #if (CY_PERI_GROUP_NR > 12)
311 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 12 },
312 #endif
313 #if (CY_PERI_GROUP_NR > 13)
314 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 13 },
315 #endif
316 #if (CY_PERI_GROUP_NR > 14)
317 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 14 },
318 #endif
319 #if (CY_PERI_GROUP_NR > 15)
320 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PERI, 15 },
321 #endif
322 };
323
324 #if (SRSS_NUM_PLL200M > 0)
325 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PLL[SRSS_NUM_PLL200M] =
326 {
327 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 0 },
328 #if (SRSS_NUM_PLL200M > 1)
329 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 1 },
330 #endif
331 #if (SRSS_NUM_PLL200M > 2)
332 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 2 },
333 #endif
334 #if (SRSS_NUM_PLL200M > 3)
335 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 3 },
336 #endif
337 #if (SRSS_NUM_PLL200M > 4)
338 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 4 },
339 #endif
340 #if (SRSS_NUM_PLL200M > 5)
341 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 5 },
342 #endif
343 #if (SRSS_NUM_PLL200M > 6)
344 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 6 },
345 #endif
346 #if (SRSS_NUM_PLL200M > 7)
347 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 7 },
348 #endif
349 #if (SRSS_NUM_PLL200M > 8)
350 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 8 },
351 #endif
352 #if (SRSS_NUM_PLL200M > 9)
353 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 9 },
354 #endif
355 #if (SRSS_NUM_PLL200M > 10)
356 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 10 },
357 #endif
358 #if (SRSS_NUM_PLL200M > 11)
359 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 11 },
360 #endif
361 #if (SRSS_NUM_PLL200M > 12)
362 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 12 },
363 #endif
364 #if (SRSS_NUM_PLL200M > 13)
365 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 13 },
366 #endif
367 #if (SRSS_NUM_PLL200M > 14)
368 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL200, 14 },
369 #endif
370 };
371 #endif
372
373 #if (SRSS_NUM_PLL400M > 0)
374 const cyhal_resource_inst_t CYHAL_CLOCK_RSC_PLL[SRSS_NUM_PLL400M] =
375 {
376 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 0 },
377 #if (SRSS_NUM_PLL400M > 1)
378 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 1 },
379 #endif
380 #if (SRSS_NUM_PLL400M > 2)
381 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 2 },
382 #endif
383 #if (SRSS_NUM_PLL400M > 3)
384 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 3 },
385 #endif
386 #if (SRSS_NUM_PLL400M > 4)
387 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 4 },
388 #endif
389 #if (SRSS_NUM_PLL400M > 5)
390 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 5 },
391 #endif
392 #if (SRSS_NUM_PLL400M > 6)
393 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 6 },
394 #endif
395 #if (SRSS_NUM_PLL400M > 7)
396 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 7 },
397 #endif
398 #if (SRSS_NUM_PLL400M > 8)
399 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 8 },
400 #endif
401 #if (SRSS_NUM_PLL400M > 9)
402 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 9 },
403 #endif
404 #if (SRSS_NUM_PLL400M > 10)
405 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 10 },
406 #endif
407 #if (SRSS_NUM_PLL400M > 11)
408 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 11 },
409 #endif
410 #if (SRSS_NUM_PLL400M > 12)
411 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 12 },
412 #endif
413 #if (SRSS_NUM_PLL400M > 13)
414 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 13 },
415 #endif
416 #if (SRSS_NUM_PLL400M > 14)
417 { CYHAL_RSC_CLOCK, (uint8_t)CYHAL_CLOCK_BLOCK_PLL400, 14 },
418 #endif
419 };
420 #endif
421
422 #define SRSS_NUM_PLL (SRSS_NUM_PLL200M + SRSS_NUM_PLL400M)
423
424 #endif
425
426
427
428 /******************************************************************************
429 ***************************** Support Functions*******************************
430 *****************************************************************************/
431
_cyhal_clock_compute_div(uint32_t input_hz,uint32_t desired_hz,uint32_t divider_bits,const cyhal_clock_tolerance_t * tolerance,uint32_t * div)432 static cy_rslt_t _cyhal_clock_compute_div(uint32_t input_hz, uint32_t desired_hz, uint32_t divider_bits, const cyhal_clock_tolerance_t *tolerance, uint32_t *div)
433 {
434 uint32_t max_div = (1 << divider_bits);
435 *div = (input_hz + (desired_hz / 2)) / desired_hz;
436 if (*div > max_div)
437 *div = max_div;
438
439 uint32_t diff = (tolerance != NULL)
440 ? (uint32_t)abs(_cyhal_utils_calculate_tolerance(tolerance->type, desired_hz, input_hz / *div))
441 : 0;
442
443 return ((tolerance != NULL) && (diff > tolerance->value))
444 ? CYHAL_CLOCK_RSLT_ERR_FREQ
445 : CY_RSLT_SUCCESS;
446 }
447
_cyhal_clock_get_lf_frequency(void)448 static uint32_t _cyhal_clock_get_lf_frequency(void)
449 {
450 cy_en_clklf_in_sources_t source = Cy_SysClk_ClkLfGetSource();
451 switch (source)
452 {
453 case CY_SYSCLK_CLKLF_IN_ILO:
454 return CY_SYSCLK_ILO_FREQ;
455 #if _CYHAL_SRSS_PILO_PRESENT
456 case CY_SYSCLK_CLKLF_IN_PILO:
457 return CY_SYSCLK_PILO_FREQ;
458 #endif
459 #if SRSS_BACKUP_PRESENT
460 case CY_SYSCLK_CLKLF_IN_WCO:
461 return CY_SYSCLK_WCO_FREQ;
462 #endif
463 #if SRSS_ALTLF_PRESENT
464 case CY_SYSCLK_CLKLF_IN_ALTLF:
465 return Cy_SysClk_AltLfGetFrequency();
466 #endif
467 #if defined(COMPONENT_CAT1B)
468 #if SRSS_ECO_PRESENT
469 case CY_SYSCLK_CLKLF_IN_ECO_PRESCALER:
470 //return Cy_SysClk_EcoPrescalerGetFrequency();
471 return 0;
472 #endif
473 #if SRSS_BACKUP_S40E_LPECO_PRESENT
474 case CY_SYSCLK_CLKLF_IN_LPECO_PRESCALER:
475 return Cy_SysClk_LpEcoPrescalerGetFrequency();
476 #endif
477 #endif
478 default:
479 CY_ASSERT(false);
480 return 0;
481 }
482 }
483
_cyhal_clock_update_system_state(bool before_change,uint32_t old_sysclk_freq_hz,uint32_t new_sysclk_freq_hz)484 static void _cyhal_clock_update_system_state(bool before_change, uint32_t old_sysclk_freq_hz, uint32_t new_sysclk_freq_hz)
485 {
486 // If increasing the clock frequency we need to update the speeds
487 // before the change. If decreasing the frequency we need to update
488 // after the change.
489 if ((before_change == (bool)(new_sysclk_freq_hz > old_sysclk_freq_hz)) ||
490 (!before_change == (new_sysclk_freq_hz < old_sysclk_freq_hz)))
491 {
492 #if defined(COMPONENT_CAT1A)
493 bool is_ulp = Cy_SysPm_IsSystemUlp();
494 #elif defined(COMPONENT_CAT1B)
495 bool is_ulp = true;
496 #endif
497 Cy_SysLib_SetWaitStates(is_ulp, new_sysclk_freq_hz / 1000000);
498 }
499
500 // If after the change, update the clock
501 if (!before_change)
502 SystemCoreClockUpdate();
503 }
504
505
_cyhal_clock_set_enabled_unsupported(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)506 static cy_rslt_t _cyhal_clock_set_enabled_unsupported(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
507 {
508 CY_UNUSED_PARAMETER(clock);
509 CY_UNUSED_PARAMETER(enabled);
510 CY_UNUSED_PARAMETER(wait_for_lock);
511 CY_ASSERT(false); // Unhandled clock
512 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
513 }
_cyhal_clock_set_frequency_unsupported(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)514 static cy_rslt_t _cyhal_clock_set_frequency_unsupported(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
515 {
516 CY_UNUSED_PARAMETER(clock);
517 CY_UNUSED_PARAMETER(hz);
518 CY_UNUSED_PARAMETER(tolerance);
519 CY_ASSERT(false); // Unhandled clock
520 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
521 }
_cyhal_clock_set_divider_unsupported(cyhal_clock_t * clock,uint32_t divider)522 static cy_rslt_t _cyhal_clock_set_divider_unsupported(cyhal_clock_t *clock, uint32_t divider)
523 {
524 CY_UNUSED_PARAMETER(clock);
525 CY_UNUSED_PARAMETER(divider);
526 CY_ASSERT(false); // Unhandled clock
527 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
528 }
_cyhal_clock_set_source_unsupported(cyhal_clock_t * clock,const cyhal_clock_t * source)529 static cy_rslt_t _cyhal_clock_set_source_unsupported(cyhal_clock_t *clock, const cyhal_clock_t *source)
530 {
531 CY_UNUSED_PARAMETER(clock);
532 CY_UNUSED_PARAMETER(source);
533 CY_ASSERT(false); // Unhandled clock
534 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
535 }
_cyhal_clock_is_enabled_true(const cyhal_clock_t * clock)536 static bool _cyhal_clock_is_enabled_true(const cyhal_clock_t *clock)
537 {
538 CY_UNUSED_PARAMETER(clock);
539 return true;
540 }
_cyhal_clock_get_sources_none(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)541 static cy_rslt_t _cyhal_clock_get_sources_none(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
542 {
543 CY_UNUSED_PARAMETER(clock);
544 CY_UNUSED_PARAMETER(sources);
545 *count = 0;
546 return CY_RSLT_SUCCESS;
547 }
548
549
550 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_HF[] =
551 {
552 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
553 &CYHAL_CLOCK_RSC_FLL,
554 #endif
555 #if (SRSS_NUM_PLL > 0)
556 &CYHAL_CLOCK_RSC_PLL[0],
557 #endif
558 #if (SRSS_NUM_PLL > 1)
559 &CYHAL_CLOCK_RSC_PLL[1],
560 #endif
561 #if (SRSS_NUM_PLL > 2)
562 &CYHAL_CLOCK_RSC_PLL[2],
563 #endif
564 #if (SRSS_NUM_PLL > 3)
565 &CYHAL_CLOCK_RSC_PLL[3],
566 #endif
567 #if (SRSS_NUM_PLL > 4)
568 &CYHAL_CLOCK_RSC_PLL[4],
569 #endif
570 #if (SRSS_NUM_PLL > 5)
571 &CYHAL_CLOCK_RSC_PLL[5],
572 #endif
573 #if (SRSS_NUM_PLL > 6)
574 &CYHAL_CLOCK_RSC_PLL[6],
575 #endif
576 #if (SRSS_NUM_PLL > 7)
577 &CYHAL_CLOCK_RSC_PLL[7],
578 #endif
579 #if (SRSS_NUM_PLL > 8)
580 &CYHAL_CLOCK_RSC_PLL[8],
581 #endif
582 #if (SRSS_NUM_PLL > 9)
583 &CYHAL_CLOCK_RSC_PLL[9],
584 #endif
585 #if (SRSS_NUM_PLL > 10)
586 &CYHAL_CLOCK_RSC_PLL[10],
587 #endif
588 #if (SRSS_NUM_PLL > 11)
589 &CYHAL_CLOCK_RSC_PLL[11],
590 #endif
591 #if (SRSS_NUM_PLL > 12)
592 &CYHAL_CLOCK_RSC_PLL[12],
593 #endif
594 #if (SRSS_NUM_PLL > 13)
595 &CYHAL_CLOCK_RSC_PLL[13],
596 #endif
597 #if (SRSS_NUM_PLL > 14)
598 &CYHAL_CLOCK_RSC_PLL[14],
599 #endif
600 &CYHAL_CLOCK_RSC_PATHMUX[0],
601 #if (SRSS_NUM_CLKPATH > 1)
602 &CYHAL_CLOCK_RSC_PATHMUX[1],
603 #endif
604 #if (SRSS_NUM_CLKPATH > 2)
605 &CYHAL_CLOCK_RSC_PATHMUX[2],
606 #endif
607 #if (SRSS_NUM_CLKPATH > 3)
608 &CYHAL_CLOCK_RSC_PATHMUX[3],
609 #endif
610 #if (SRSS_NUM_CLKPATH > 4)
611 &CYHAL_CLOCK_RSC_PATHMUX[4],
612 #endif
613 #if (SRSS_NUM_CLKPATH > 5)
614 &CYHAL_CLOCK_RSC_PATHMUX[5],
615 #endif
616 #if (SRSS_NUM_CLKPATH > 6)
617 &CYHAL_CLOCK_RSC_PATHMUX[6],
618 #endif
619 #if (SRSS_NUM_CLKPATH > 7)
620 &CYHAL_CLOCK_RSC_PATHMUX[7],
621 #endif
622 #if (SRSS_NUM_CLKPATH > 8)
623 &CYHAL_CLOCK_RSC_PATHMUX[8],
624 #endif
625 #if (SRSS_NUM_CLKPATH > 9)
626 &CYHAL_CLOCK_RSC_PATHMUX[9],
627 #endif
628 #if (SRSS_NUM_CLKPATH > 10)
629 &CYHAL_CLOCK_RSC_PATHMUX[10],
630 #endif
631 #if (SRSS_NUM_CLKPATH > 11)
632 &CYHAL_CLOCK_RSC_PATHMUX[11],
633 #endif
634 #if (SRSS_NUM_CLKPATH > 12)
635 &CYHAL_CLOCK_RSC_PATHMUX[12],
636 #endif
637 #if (SRSS_NUM_CLKPATH > 13)
638 &CYHAL_CLOCK_RSC_PATHMUX[13],
639 #endif
640 #if (SRSS_NUM_CLKPATH > 14)
641 &CYHAL_CLOCK_RSC_PATHMUX[14],
642 #endif
643 #if (SRSS_NUM_CLKPATH > 15)
644 &CYHAL_CLOCK_RSC_PATHMUX[15],
645 #endif
646 };
647
648 #if defined (COMPONENT_CAT1B)
_cyhal_clock_get_sources_peri_peripheral(uint8_t idx,const cyhal_resource_inst_t ** sources[],uint32_t * count)649 static cy_rslt_t _cyhal_clock_get_sources_peri_peripheral(uint8_t idx, const cyhal_resource_inst_t **sources[], uint32_t *count)
650 {
651 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_PERI[SRSS_NUM_HFROOT] =
652 {
653 &CYHAL_CLOCK_RSC_HF[0],
654 #if (SRSS_NUM_HFROOT > 1)
655 &CYHAL_CLOCK_RSC_HF[1],
656 #endif
657 #if (SRSS_NUM_HFROOT > 2)
658 &CYHAL_CLOCK_RSC_HF[2],
659 #endif
660 #if (SRSS_NUM_HFROOT > 3)
661 &CYHAL_CLOCK_RSC_HF[3],
662 #endif
663 #if (SRSS_NUM_HFROOT > 4)
664 &CYHAL_CLOCK_RSC_HF[4],
665 #endif
666 #if (SRSS_NUM_HFROOT > 5)
667 &CYHAL_CLOCK_RSC_HF[5],
668 #endif
669 #if (SRSS_NUM_HFROOT > 6)
670 &CYHAL_CLOCK_RSC_HF[6],
671 #endif
672 #if (SRSS_NUM_HFROOT > 7)
673 &CYHAL_CLOCK_RSC_HF[7],
674 #endif
675 #if (SRSS_NUM_HFROOT > 8)
676 &CYHAL_CLOCK_RSC_HF[8],
677 #endif
678 #if (SRSS_NUM_HFROOT > 9)
679 &CYHAL_CLOCK_RSC_HF[9],
680 #endif
681 #if (SRSS_NUM_HFROOT > 10)
682 &CYHAL_CLOCK_RSC_HF[10],
683 #endif
684 #if (SRSS_NUM_HFROOT > 11)
685 &CYHAL_CLOCK_RSC_HF[11],
686 #endif
687 #if (SRSS_NUM_HFROOT > 12)
688 &CYHAL_CLOCK_RSC_HF[12],
689 #endif
690 #if (SRSS_NUM_HFROOT > 13)
691 &CYHAL_CLOCK_RSC_HF[13],
692 #endif
693 #if (SRSS_NUM_HFROOT > 14)
694 &CYHAL_CLOCK_RSC_HF[14],
695 #endif
696 #if (SRSS_NUM_HFROOT > 15)
697 &CYHAL_CLOCK_RSC_HF[15],
698 #endif
699 };
700
701 *sources = &(_CYHAL_CLOCK_SOURCE_PERI[idx]);
702 *count = 1;
703 return CY_RSLT_SUCCESS;
704 }
705 #endif
706
707
708 // IMO
_cyhal_clock_get_frequency_imo(const cyhal_clock_t * clock)709 static uint32_t _cyhal_clock_get_frequency_imo(const cyhal_clock_t *clock)
710 {
711 CY_UNUSED_PARAMETER(clock);
712 return CY_SYSCLK_IMO_FREQ;
713 }
714
715
716 // ECO
717 #if SRSS_ECO_PRESENT
_cyhal_clock_is_enabled_eco(const cyhal_clock_t * clock)718 static bool _cyhal_clock_is_enabled_eco(const cyhal_clock_t *clock)
719 {
720 CY_UNUSED_PARAMETER(clock);
721 return 0u != (SRSS_CLK_ECO_CONFIG & SRSS_CLK_ECO_CONFIG_ECO_EN_Msk);
722 }
_cyhal_clock_set_enabled_eco(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)723 static cy_rslt_t _cyhal_clock_set_enabled_eco(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
724 {
725 CY_UNUSED_PARAMETER(clock);
726
727 if (enabled)
728 {
729 if (0u != (SRSS_CLK_ECO_CONFIG & SRSS_CLK_ECO_CONFIG_ECO_EN_Msk))
730 {
731 // Already enabled
732 if (wait_for_lock)
733 {
734 for (int t = 0; t < 3 && Cy_SysClk_EcoGetStatus() != CY_SYSCLK_ECOSTAT_STABLE; ++t)
735 {
736 cyhal_system_delay_us(1000UL);
737 }
738 return Cy_SysClk_EcoGetStatus() == CY_SYSCLK_ECOSTAT_STABLE
739 ? CY_RSLT_SUCCESS
740 : CY_SYSCLK_TIMEOUT;
741 }
742 return CY_RSLT_SUCCESS;
743 }
744 else
745 {
746 return Cy_SysClk_EcoEnable(wait_for_lock ? 3000UL : 0UL);
747 }
748 }
749 else
750 {
751 Cy_SysClk_EcoDisable();
752 return CY_RSLT_SUCCESS;
753 }
754 }
_cyhal_clock_get_frequency_eco(const cyhal_clock_t * clock)755 static uint32_t _cyhal_clock_get_frequency_eco(const cyhal_clock_t *clock)
756 {
757 CY_UNUSED_PARAMETER(clock);
758 return Cy_SysClk_EcoGetFrequency();
759 }
760 #endif
761
762 // EXT
_cyhal_clock_is_enabled_ext(const cyhal_clock_t * clock)763 static bool _cyhal_clock_is_enabled_ext(const cyhal_clock_t *clock)
764 {
765 CY_UNUSED_PARAMETER(clock);
766 return (Cy_SysClk_ExtClkGetFrequency() > 0);
767 }
_cyhal_clock_get_frequency_ext(const cyhal_clock_t * clock)768 static uint32_t _cyhal_clock_get_frequency_ext(const cyhal_clock_t *clock)
769 {
770 CY_UNUSED_PARAMETER(clock);
771 return Cy_SysClk_ExtClkGetFrequency();
772 }
_cyhal_clock_set_frequency_ext(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)773 static cy_rslt_t _cyhal_clock_set_frequency_ext(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
774 {
775 CY_UNUSED_PARAMETER(clock);
776 CY_UNUSED_PARAMETER(tolerance);
777
778 Cy_SysClk_ExtClkSetFrequency(hz);
779 return CY_RSLT_SUCCESS;
780 }
781
782 // ALTHF
783 #if SRSS_ALTHF_PRESENT
_cyhal_clock_is_enabled_althf(const cyhal_clock_t * clock)784 static bool _cyhal_clock_is_enabled_althf(const cyhal_clock_t *clock)
785 {
786 CY_UNUSED_PARAMETER(clock);
787 return (Cy_SysClk_AltHfGetFrequency() > 0);
788 }
_cyhal_clock_get_frequency_althf(const cyhal_clock_t * clock)789 static uint32_t _cyhal_clock_get_frequency_althf(const cyhal_clock_t *clock)
790 {
791 CY_UNUSED_PARAMETER(clock);
792 return Cy_SysClk_AltHfGetFrequency();
793 }
794 #endif
795
796 // ALTLF
797 #if SRSS_ALTLF_PRESENT
_cyhal_clock_is_enabled_altlf(const cyhal_clock_t * clock)798 static bool _cyhal_clock_is_enabled_altlf(const cyhal_clock_t *clock)
799 {
800 CY_UNUSED_PARAMETER(clock);
801 return Cy_SysClk_AltLfIsEnabled();
802 }
_cyhal_clock_get_frequency_altlf(const cyhal_clock_t * clock)803 static uint32_t _cyhal_clock_get_frequency_altlf(const cyhal_clock_t *clock)
804 {
805 CY_UNUSED_PARAMETER(clock);
806 return Cy_SysClk_AltLfGetFrequency();
807 }
808 #endif
809
810 // IHO
811 #if defined(COMPONENT_CAT1B)
_cyhal_clock_is_enabled_iho(const cyhal_clock_t * clock)812 static bool _cyhal_clock_is_enabled_iho(const cyhal_clock_t *clock)
813 {
814 CY_UNUSED_PARAMETER(clock);
815 return Cy_SysClk_IhoIsEnabled();
816 }
_cyhal_clock_set_enabled_iho(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)817 static cy_rslt_t _cyhal_clock_set_enabled_iho(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
818 {
819 CY_UNUSED_PARAMETER(clock);
820 CY_UNUSED_PARAMETER(wait_for_lock);
821
822 if (enabled)
823 Cy_SysClk_IhoEnable();
824 else
825 Cy_SysClk_IhoDisable();
826 return CY_RSLT_SUCCESS;
827 }
_cyhal_clock_get_frequency_iho(const cyhal_clock_t * clock)828 static uint32_t _cyhal_clock_get_frequency_iho(const cyhal_clock_t *clock)
829 {
830 CY_UNUSED_PARAMETER(clock);
831 return CY_SYSCLK_IHO_FREQ;
832 }
833 #endif
834
835 // ILO
_cyhal_clock_is_enabled_ilo(const cyhal_clock_t * clock)836 static bool _cyhal_clock_is_enabled_ilo(const cyhal_clock_t *clock)
837 {
838 CY_UNUSED_PARAMETER(clock);
839 return Cy_SysClk_IloIsEnabled();
840 }
_cyhal_clock_set_enabled_ilo(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)841 static cy_rslt_t _cyhal_clock_set_enabled_ilo(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
842 {
843 CY_UNUSED_PARAMETER(clock);
844 CY_UNUSED_PARAMETER(wait_for_lock);
845
846 if (enabled)
847 Cy_SysClk_IloEnable();
848 else
849 Cy_SysClk_IloDisable();
850 return CY_RSLT_SUCCESS;
851 }
_cyhal_clock_get_frequency_ilo(const cyhal_clock_t * clock)852 static uint32_t _cyhal_clock_get_frequency_ilo(const cyhal_clock_t *clock)
853 {
854 CY_UNUSED_PARAMETER(clock);
855 return CY_SYSCLK_ILO_FREQ;
856 }
857
858 // PILO
859 #if _CYHAL_SRSS_PILO_PRESENT
_cyhal_clock_is_enabled_pilo(const cyhal_clock_t * clock)860 static bool _cyhal_clock_is_enabled_pilo(const cyhal_clock_t *clock)
861 {
862 CY_UNUSED_PARAMETER(clock);
863 return Cy_SysClk_PiloIsEnabled();
864 }
_cyhal_clock_set_enabled_pilo(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)865 static cy_rslt_t _cyhal_clock_set_enabled_pilo(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
866 {
867 CY_UNUSED_PARAMETER(clock);
868 CY_UNUSED_PARAMETER(wait_for_lock);
869
870 if (enabled)
871 Cy_SysClk_PiloEnable();
872 else
873 Cy_SysClk_PiloDisable();
874 return CY_RSLT_SUCCESS;
875 }
_cyhal_clock_get_frequency_pilo(const cyhal_clock_t * clock)876 static uint32_t _cyhal_clock_get_frequency_pilo(const cyhal_clock_t *clock)
877 {
878 CY_UNUSED_PARAMETER(clock);
879 return CY_SYSCLK_PILO_FREQ;
880 }
881 #endif
882
883 // WCO
884 #if SRSS_BACKUP_PRESENT
_cyhal_clock_is_enabled_wco(const cyhal_clock_t * clock)885 static bool _cyhal_clock_is_enabled_wco(const cyhal_clock_t *clock)
886 {
887 CY_UNUSED_PARAMETER(clock);
888 #if defined(CY_IP_MXS28SRSS)
889 return 0u != (BACKUP_CTL & BACKUP_WCO_CTL_WCO_EN_Msk);
890 #else
891 return 0u != (BACKUP_CTL & BACKUP_CTL_WCO_EN_Msk);
892 #endif
893 }
_cyhal_clock_set_enabled_wco(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)894 static cy_rslt_t _cyhal_clock_set_enabled_wco(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
895 {
896 CY_UNUSED_PARAMETER(clock);
897
898 if (enabled)
899 {
900 cy_rslt_t rslt = Cy_SysClk_WcoEnable(wait_for_lock ? 1000000UL : 0UL);
901 // Ignore CY_SYSCLK_TIMEOUT unless wait_for_lock is true
902 return wait_for_lock ? rslt : CY_RSLT_SUCCESS;
903 }
904 else
905 {
906 Cy_SysClk_WcoDisable();
907 return CY_RSLT_SUCCESS;
908 }
909 }
_cyhal_clock_get_frequency_wco(const cyhal_clock_t * clock)910 static uint32_t _cyhal_clock_get_frequency_wco(const cyhal_clock_t *clock)
911 {
912 CY_UNUSED_PARAMETER(clock);
913 return CY_SYSCLK_WCO_FREQ;
914 }
915 #endif
916
917 // MFO
918 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
_cyhal_clock_is_enabled_mfo(const cyhal_clock_t * clock)919 static bool _cyhal_clock_is_enabled_mfo(const cyhal_clock_t *clock)
920 {
921 CY_UNUSED_PARAMETER(clock);
922 return Cy_SysClk_MfoIsEnabled();
923 }
_cyhal_clock_set_enabled_mfo(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)924 static cy_rslt_t _cyhal_clock_set_enabled_mfo(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
925 {
926 CY_UNUSED_PARAMETER(clock);
927 CY_UNUSED_PARAMETER(wait_for_lock);
928
929 if (enabled)
930 Cy_SysClk_MfoEnable(true);
931 else
932 Cy_SysClk_MfoDisable();
933 return CY_RSLT_SUCCESS;
934 }
_cyhal_clock_get_frequency_mfo(const cyhal_clock_t * clock)935 static uint32_t _cyhal_clock_get_frequency_mfo(const cyhal_clock_t *clock)
936 {
937 CY_UNUSED_PARAMETER(clock);
938 return CY_SYSCLK_MFO_FREQ;
939 }
_cyhal_clock_get_sources_mfo(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)940 static cy_rslt_t _cyhal_clock_get_sources_mfo(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
941 {
942 CY_UNUSED_PARAMETER(clock);
943
944 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_MFO[] =
945 {
946 &CYHAL_CLOCK_RSC_IMO,
947 };
948
949 *sources = _CYHAL_CLOCK_SOURCE_MFO;
950 *count = sizeof(_CYHAL_CLOCK_SOURCE_MFO) / sizeof(_CYHAL_CLOCK_SOURCE_MFO[0]);
951 return CY_RSLT_SUCCESS;
952 }
953 #endif
954
955 // PathMux
_cyhal_clock_get_frequency_pathmux(const cyhal_clock_t * clock)956 static uint32_t _cyhal_clock_get_frequency_pathmux(const cyhal_clock_t *clock)
957 {
958 return Cy_SysClk_ClkPathMuxGetFrequency(clock->channel);
959 }
_cyhal_clock_get_sources_pathmux(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)960 static cy_rslt_t _cyhal_clock_get_sources_pathmux(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
961 {
962 CY_UNUSED_PARAMETER(clock);
963
964 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_PATHMUX[] =
965 {
966 &CYHAL_CLOCK_RSC_IMO,
967 #if defined(COMPONENT_CAT1B)
968 &CYHAL_CLOCK_RSC_IHO,
969 #endif
970 #if SRSS_ECO_PRESENT
971 &CYHAL_CLOCK_RSC_ECO,
972 #endif
973 &CYHAL_CLOCK_RSC_EXT,
974 #if SRSS_ALTHF_PRESENT
975 &CYHAL_CLOCK_RSC_ALTHF,
976 #endif
977 &CYHAL_CLOCK_RSC_ILO,
978 #if _CYHAL_SRSS_PILO_PRESENT
979 &CYHAL_CLOCK_RSC_PILO,
980 #endif
981 #if SRSS_BACKUP_PRESENT
982 &CYHAL_CLOCK_RSC_WCO,
983 #endif
984 #if SRSS_ALTLF_PRESENT
985 &CYHAL_CLOCK_RSC_ALTLF,
986 #endif
987 };
988
989 *sources = _CYHAL_CLOCK_SOURCE_PATHMUX;
990 *count = sizeof(_CYHAL_CLOCK_SOURCE_PATHMUX) / sizeof(_CYHAL_CLOCK_SOURCE_PATHMUX[0]);
991 return CY_RSLT_SUCCESS;
992 }
_cyhal_clock_set_source_pathmux(cyhal_clock_t * clock,const cyhal_clock_t * source)993 static cy_rslt_t _cyhal_clock_set_source_pathmux(cyhal_clock_t *clock, const cyhal_clock_t *source)
994 {
995 uint32_t new_freq;
996 cy_en_clkpath_in_sources_t clkpath_src;
997 switch (source->block)
998 {
999 case CYHAL_CLOCK_BLOCK_IMO:
1000 clkpath_src = CY_SYSCLK_CLKPATH_IN_IMO;
1001 new_freq = CY_SYSCLK_IMO_FREQ;
1002 break;
1003 #if defined(COMPONENT_CAT1B)
1004 case CYHAL_CLOCK_BLOCK_IHO:
1005 clkpath_src = CY_SYSCLK_CLKPATH_IN_IHO;
1006 new_freq = CY_SYSCLK_IHO_FREQ;
1007 break;
1008 #endif
1009 case CYHAL_CLOCK_BLOCK_EXT:
1010 clkpath_src = CY_SYSCLK_CLKPATH_IN_EXT;
1011 new_freq = Cy_SysClk_ExtClkGetFrequency();
1012 break;
1013 #if SRSS_ECO_PRESENT
1014 case CYHAL_CLOCK_BLOCK_ECO:
1015 clkpath_src = CY_SYSCLK_CLKPATH_IN_ECO;
1016 new_freq = Cy_SysClk_EcoGetFrequency();
1017 break;
1018 #endif
1019 #if SRSS_ALTHF_PRESENT
1020 case CYHAL_CLOCK_BLOCK_ALTHF:
1021 clkpath_src = CY_SYSCLK_CLKPATH_IN_ALTHF;
1022 new_freq = Cy_SysClk_AltHfGetFrequency();
1023 break;
1024 #endif
1025 case CYHAL_CLOCK_BLOCK_ILO:
1026 clkpath_src = CY_SYSCLK_CLKPATH_IN_ILO;
1027 new_freq = CY_SYSCLK_ILO_FREQ;
1028 break;
1029 #if SRSS_BACKUP_PRESENT
1030 case CYHAL_CLOCK_BLOCK_WCO:
1031 clkpath_src = CY_SYSCLK_CLKPATH_IN_WCO;
1032 new_freq = CY_SYSCLK_WCO_FREQ;
1033 break;
1034 #endif
1035 #if SRSS_ALTLF_PRESENT
1036 case CYHAL_CLOCK_BLOCK_ALTLF:
1037 clkpath_src = CY_SYSCLK_CLKPATH_IN_ALTLF;
1038 new_freq = Cy_SysClk_AltLfGetFrequency();
1039 break;
1040 #endif
1041 #if _CYHAL_SRSS_PILO_PRESENT
1042 case CYHAL_CLOCK_BLOCK_PILO:
1043 clkpath_src = CY_SYSCLK_CLKPATH_IN_PILO;
1044 new_freq = CY_SYSCLK_PILO_FREQ;
1045 break;
1046 #endif
1047 default:
1048 CY_ASSERT(false); //Unhandled clock
1049 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1050 }
1051
1052 uint32_t old_hf_freq = Cy_SysClk_ClkHfGetFrequency(0);
1053 uint32_t new_hf_freq = new_freq >> ((uint8_t)Cy_SysClk_ClkHfGetDivider(0));
1054 bool is_sysclk_path = (clock->channel == (uint32_t)Cy_SysClk_ClkHfGetSource(0));
1055
1056 if (is_sysclk_path)
1057 _cyhal_clock_update_system_state(true, old_hf_freq, new_hf_freq);
1058
1059 cy_rslt_t rslt = Cy_SysClk_ClkPathSetSource(clock->channel, clkpath_src);
1060
1061 if (is_sysclk_path)
1062 {
1063 if (CY_RSLT_SUCCESS == rslt)
1064 _cyhal_clock_update_system_state(false, old_hf_freq, new_hf_freq);
1065 else // revert the change if there was one
1066 _cyhal_clock_update_system_state(false, new_hf_freq, old_hf_freq);
1067 }
1068
1069 return rslt;
1070 }
1071
1072
1073 // FLL
1074 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
_cyhal_clock_is_enabled_fll(const cyhal_clock_t * clock)1075 static bool _cyhal_clock_is_enabled_fll(const cyhal_clock_t *clock)
1076 {
1077 CY_UNUSED_PARAMETER(clock);
1078 return Cy_SysClk_FllIsEnabled();
1079 }
_cyhal_clock_set_enabled_fll(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1080 static cy_rslt_t _cyhal_clock_set_enabled_fll(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1081 {
1082 CY_UNUSED_PARAMETER(clock);
1083 CY_UNUSED_PARAMETER(wait_for_lock);
1084
1085 cy_stc_fll_manual_config_t cfg;
1086 Cy_SysClk_FllGetConfiguration(&cfg);
1087 uint32_t new_freq, old_freq;
1088 uint32_t div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1089 uint32_t src_freq = Cy_SysClk_ClkPathMuxGetFrequency(0);
1090 uint32_t fll_freq = CY_SYSLIB_DIV_ROUND((uint64_t)src_freq * (uint64_t)cfg.fllMult, (uint32_t)cfg.refDiv * ((cfg.enableOutputDiv) ? 2UL : 1UL));
1091 if (enabled)
1092 {
1093 new_freq = fll_freq >> div;
1094 old_freq = src_freq >> div;
1095 }
1096 else
1097 {
1098 new_freq = src_freq >> div;
1099 old_freq = fll_freq >> div;
1100 }
1101
1102 bool fll_sources_hf0 = (0 == (uint32_t)Cy_SysClk_ClkHfGetSource(0));
1103 if (fll_sources_hf0)
1104 _cyhal_clock_update_system_state(true, old_freq, new_freq);
1105
1106 cy_rslt_t rslt = (enabled)
1107 ? Cy_SysClk_FllEnable(wait_for_lock ? _CYHAL_CLOCK_FLL_LOCK_TIME : 0UL)
1108 : Cy_SysClk_FllDisable();
1109
1110 if (fll_sources_hf0)
1111 {
1112 if (CY_RSLT_SUCCESS == rslt)
1113 _cyhal_clock_update_system_state(false, old_freq, new_freq);
1114 else // revert the change if there was one
1115 _cyhal_clock_update_system_state(false, new_freq, old_freq);
1116 }
1117
1118 return rslt;
1119 }
_cyhal_clock_get_frequency_fll(const cyhal_clock_t * clock)1120 static uint32_t _cyhal_clock_get_frequency_fll(const cyhal_clock_t *clock)
1121 {
1122 CY_UNUSED_PARAMETER(clock);
1123 return Cy_SysClk_ClkPathGetFrequency(0);
1124 }
_cyhal_clock_set_frequency_fll(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1125 static cy_rslt_t _cyhal_clock_set_frequency_fll(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1126 {
1127 CY_UNUSED_PARAMETER(clock);
1128 CY_UNUSED_PARAMETER(tolerance);
1129
1130 cy_rslt_t rslt = CY_RSLT_SUCCESS;
1131 cy_stc_fll_manual_config_t cfg;
1132 Cy_SysClk_FllGetConfiguration(&cfg);
1133 uint32_t src_freq = Cy_SysClk_ClkPathMuxGetFrequency(0);
1134
1135 if (0 == src_freq)
1136 rslt = CYHAL_CLOCK_RSLT_ERR_SOURCE;
1137 else
1138 {
1139 uint32_t old_freq = CY_SYSLIB_DIV_ROUND((uint64_t)src_freq * (uint64_t)cfg.fllMult, (uint32_t)cfg.refDiv * ((cfg.enableOutputDiv) ? 2UL : 1UL));
1140 uint32_t div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1141 uint32_t old_hf_freq = old_freq >> div;
1142 uint32_t new_hf_freq = hz /*new_freq*/ >> div;
1143
1144 bool fll_sources_hf0 = (0 == (uint32_t)Cy_SysClk_ClkHfGetSource(0));
1145 if (fll_sources_hf0)
1146 _cyhal_clock_update_system_state(true, old_hf_freq, new_hf_freq);
1147
1148 bool enabled = Cy_SysClk_FllIsEnabled();
1149 if (enabled)
1150 rslt = Cy_SysClk_FllDisable();
1151 if (CY_RSLT_SUCCESS == rslt)
1152 {
1153 rslt = Cy_SysClk_FllConfigure(src_freq, hz/*new_freq*/, CY_SYSCLK_FLLPLL_OUTPUT_AUTO);
1154
1155 if (enabled)
1156 {
1157 cy_rslt_t rslt2 = Cy_SysClk_FllEnable(_CYHAL_CLOCK_FLL_LOCK_TIME);
1158 if (CY_RSLT_SUCCESS == rslt)
1159 rslt = rslt2;
1160 }
1161 }
1162
1163 if (fll_sources_hf0)
1164 {
1165 if (CY_RSLT_SUCCESS == rslt)
1166 _cyhal_clock_update_system_state(false, old_hf_freq, new_hf_freq);
1167 else // revert the change if there was one
1168 _cyhal_clock_update_system_state(false, new_hf_freq, old_hf_freq);
1169 }
1170 }
1171
1172 return rslt;
1173 }
_cyhal_clock_get_sources_fll(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1174 static cy_rslt_t _cyhal_clock_get_sources_fll(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1175 {
1176 CY_UNUSED_PARAMETER(clock);
1177 *sources = &(_CYHAL_CLOCK_SOURCE_HF[1 + SRSS_NUM_PLL]);
1178 *count = 1;
1179 return CY_RSLT_SUCCESS;
1180 }
1181 #endif
1182
1183 // PLL
1184 #if (SRSS_NUM_PLL > 0)
_cyhal_clock_is_enabled_pll(const cyhal_clock_t * clock)1185 static bool _cyhal_clock_is_enabled_pll(const cyhal_clock_t *clock)
1186 {
1187 return Cy_SysClk_PllIsEnabled(clock->channel + 1);
1188 }
_cyhal_clock_set_enabled_pll(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1189 static cy_rslt_t _cyhal_clock_set_enabled_pll(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1190 {
1191 CY_UNUSED_PARAMETER(clock);
1192 CY_UNUSED_PARAMETER(wait_for_lock);
1193
1194 //pll_idx is the path mux index (eg PLL number + 1) as used by PDL APIs
1195 uint32_t pll_idx = clock->channel + 1;
1196 cy_stc_pll_manual_config_t cfg;
1197 cy_rslt_t rslt = Cy_SysClk_PllGetConfiguration(pll_idx, &cfg);
1198 if (CY_RSLT_SUCCESS == rslt)
1199 {
1200 uint32_t new_freq, old_freq;
1201 uint32_t div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1202 uint32_t src_freq = Cy_SysClk_ClkPathMuxGetFrequency(pll_idx);
1203 uint32_t pll_freq = CY_SYSLIB_DIV_ROUND((uint64_t)src_freq * (uint64_t)cfg.feedbackDiv, (uint32_t)cfg.referenceDiv * (uint32_t)cfg.outputDiv);
1204 if (enabled)
1205 {
1206 new_freq = pll_freq >> div;
1207 old_freq = src_freq >> div;
1208 }
1209 else
1210 {
1211 new_freq = src_freq >> div;
1212 old_freq = pll_freq >> div;
1213 }
1214
1215 bool pll_sources_hf0 = (pll_idx == (uint32_t)Cy_SysClk_ClkHfGetSource(0));
1216 if (pll_sources_hf0)
1217 _cyhal_clock_update_system_state(true, old_freq, new_freq);
1218
1219 rslt = (enabled)
1220 ? Cy_SysClk_PllEnable(pll_idx, wait_for_lock ? _CYHAL_CLOCK_PLL_LOCK_TIME : 0UL)
1221 : Cy_SysClk_PllDisable(pll_idx);
1222
1223 if (pll_sources_hf0)
1224 {
1225 if (CY_RSLT_SUCCESS == rslt)
1226 _cyhal_clock_update_system_state(false, old_freq, new_freq);
1227 else // revert the change if there was one
1228 _cyhal_clock_update_system_state(false, new_freq, old_freq);
1229 }
1230 }
1231
1232 return rslt;
1233 }
_cyhal_clock_get_frequency_pll(const cyhal_clock_t * clock)1234 static uint32_t _cyhal_clock_get_frequency_pll(const cyhal_clock_t *clock)
1235 {
1236 return Cy_SysClk_ClkPathGetFrequency(clock->channel + 1);
1237 }
_cyhal_clock_set_frequency_pll(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1238 static cy_rslt_t _cyhal_clock_set_frequency_pll(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1239 {
1240 CY_UNUSED_PARAMETER(tolerance);
1241
1242 cy_stc_pll_manual_config_t cfg;
1243 uint8_t pll_idx = clock->channel + 1;
1244 cy_rslt_t rslt = Cy_SysClk_PllGetConfiguration(pll_idx, &cfg);
1245 if (CY_RSLT_SUCCESS == rslt)
1246 {
1247 bool enabled = Cy_SysClk_PllIsEnabled(pll_idx);
1248 if (enabled)
1249 rslt = Cy_SysClk_PllDisable(pll_idx);
1250 if (CY_RSLT_SUCCESS == rslt)
1251 {
1252 uint32_t src_freq = Cy_SysClk_ClkPathMuxGetFrequency(pll_idx);
1253 uint32_t old_freq = CY_SYSLIB_DIV_ROUND((uint64_t)src_freq * (uint64_t)cfg.feedbackDiv, (uint32_t)cfg.referenceDiv * (uint32_t)cfg.outputDiv);
1254
1255 uint32_t div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1256 uint32_t old_hf_freq = old_freq >> div;
1257 uint32_t new_hf_freq = hz/*new_freq*/ >> div;
1258
1259 bool pll_sources_hf0 = (pll_idx == (uint32_t)Cy_SysClk_ClkHfGetSource(0));
1260 if (pll_sources_hf0)
1261 _cyhal_clock_update_system_state(true, old_hf_freq, new_hf_freq);
1262
1263 uint32_t input_hz = Cy_SysClk_ClkPathMuxGetFrequency(pll_idx);
1264 cy_stc_pll_config_t cfg2 =
1265 {
1266 .inputFreq = input_hz,
1267 .outputFreq = hz/*new_freq*/,
1268 .lfMode = false,
1269 .outputMode = CY_SYSCLK_FLLPLL_OUTPUT_AUTO,
1270 };
1271 rslt = Cy_SysClk_PllConfigure(pll_idx, &cfg2);
1272
1273 if (enabled)
1274 {
1275 cy_rslt_t rslt2 = Cy_SysClk_PllEnable(pll_idx, _CYHAL_CLOCK_PLL_LOCK_TIME);
1276 if (CY_RSLT_SUCCESS == rslt)
1277 rslt = rslt2;
1278 }
1279
1280 if (pll_sources_hf0)
1281 {
1282 if (CY_RSLT_SUCCESS == rslt)
1283 _cyhal_clock_update_system_state(false, old_hf_freq, new_hf_freq);
1284 else // revert the change if there was one
1285 _cyhal_clock_update_system_state(false, new_hf_freq, old_hf_freq);
1286 }
1287 }
1288 }
1289
1290 return rslt;
1291 }
_cyhal_clock_get_sources_pll(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1292 static cy_rslt_t _cyhal_clock_get_sources_pll(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1293 {
1294 // _CYHAL_CLOCK_SOURCE_HF has entries for FLL, PLL[n], PathMux[m]
1295 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
1296 *sources = &(_CYHAL_CLOCK_SOURCE_HF[2 + SRSS_NUM_PLL + clock->channel]); /* PATHMUX[n] entry is after the FLL (+1), PLLs (+num) and FLL path mux (+1) */
1297 #else
1298 *sources = &(_CYHAL_CLOCK_SOURCE_HF[SRSS_NUM_PLL + clock->channel]); /* PATHMUX[n] entry is after the PLLs (+num) */
1299 #endif
1300 *count = 1;
1301 return CY_RSLT_SUCCESS;
1302 }
1303 #endif
1304
1305 // MF
1306 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
_cyhal_clock_is_enabled_mf(const cyhal_clock_t * clock)1307 static bool _cyhal_clock_is_enabled_mf(const cyhal_clock_t *clock)
1308 {
1309 CY_UNUSED_PARAMETER(clock);
1310 return Cy_SysClk_ClkMfIsEnabled();
1311 }
_cyhal_clock_set_enabled_mf(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1312 static cy_rslt_t _cyhal_clock_set_enabled_mf(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1313 {
1314 CY_UNUSED_PARAMETER(clock);
1315 CY_UNUSED_PARAMETER(wait_for_lock);
1316
1317 if (enabled)
1318 Cy_SysClk_ClkMfEnable();
1319 else
1320 Cy_SysClk_ClkMfDisable();
1321 return CY_RSLT_SUCCESS;
1322 }
_cyhal_clock_get_frequency_mf(const cyhal_clock_t * clock)1323 static uint32_t _cyhal_clock_get_frequency_mf(const cyhal_clock_t *clock)
1324 {
1325 CY_UNUSED_PARAMETER(clock);
1326 return Cy_SysClk_ClkMfGetFrequency();
1327 }
_cyhal_clock_set_frequency_mf(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1328 static cy_rslt_t _cyhal_clock_set_frequency_mf(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1329 {
1330 CY_UNUSED_PARAMETER(clock);
1331
1332 uint32_t div;
1333 cy_rslt_t rslt = _cyhal_clock_compute_div(CY_SYSCLK_MFO_FREQ, hz, 8, tolerance, &div);
1334
1335 if(false == CY_SYSCLK_IS_MF_DIVIDER_VALID(div))
1336 rslt = CYHAL_CLOCK_RSLT_ERR_FREQ;
1337
1338 if (CY_RSLT_SUCCESS == rslt)
1339 Cy_SysClk_ClkMfSetDivider(div);
1340
1341 return rslt;
1342 }
_cyhal_clock_set_divider_mf(cyhal_clock_t * clock,uint32_t divider)1343 static cy_rslt_t _cyhal_clock_set_divider_mf(cyhal_clock_t *clock, uint32_t divider)
1344 {
1345 CY_UNUSED_PARAMETER(clock);
1346
1347 if (divider <= 256)
1348 {
1349 Cy_SysClk_ClkMfSetDivider(divider);
1350 return CY_RSLT_SUCCESS;
1351 }
1352 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1353 }
_cyhal_clock_get_sources_mf(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1354 static cy_rslt_t _cyhal_clock_get_sources_mf(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1355 {
1356 CY_UNUSED_PARAMETER(clock);
1357
1358 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_MF[] =
1359 {
1360 &CYHAL_CLOCK_RSC_MFO,
1361 #if defined(COMPONENT_CAT1B) /* CAT1A only supports driving from the MFO */
1362 &CYHAL_CLOCK_RSC_ILO,
1363 #if SRSS_BACKUP_PRESENT
1364 &CYHAL_CLOCK_RSC_WCO,
1365 #endif
1366 #if _CYHAL_SRSS_PILO_PRESENT
1367 &CYHAL_CLOCK_RSC_PILO,
1368 #endif
1369 #if SRSS_ALTLF_PRESENT
1370 &CYHAL_CLOCK_RSC_ALTLF,
1371 #endif
1372 #if SRSS_ECO_PRESENT
1373 &CYHAL_CLOCK_RSC_ECO_PRESCALER,
1374 #endif
1375 #if SRSS_BACKUP_S40E_LPECO_PRESENT
1376 &CYHAL_CLOCK_RSC_LPECO_PRESCALER,
1377 #endif
1378 #endif /* defined(COMPONENT_CAT1B) */
1379 };
1380
1381 *sources = _CYHAL_CLOCK_SOURCE_MF;
1382 *count = sizeof(_CYHAL_CLOCK_SOURCE_MF) / sizeof(_CYHAL_CLOCK_SOURCE_MF[0]);
1383 return CY_RSLT_SUCCESS;
1384 }
_cyhal_clock_set_source_mf(cyhal_clock_t * clock,const cyhal_clock_t * source)1385 static cy_rslt_t _cyhal_clock_set_source_mf(cyhal_clock_t *clock, const cyhal_clock_t *source)
1386 {
1387 CY_UNUSED_PARAMETER(clock);
1388
1389 switch(source->block)
1390 {
1391 case CYHAL_CLOCK_BLOCK_MFO:
1392 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_MFO);
1393 return CY_RSLT_SUCCESS;
1394 case CYHAL_CLOCK_BLOCK_ILO:
1395 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_ILO);
1396 return CY_RSLT_SUCCESS;
1397 #if SRSS_BACKUP_PRESENT
1398 case CYHAL_CLOCK_BLOCK_WCO:
1399 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_WCO);
1400 return CY_RSLT_SUCCESS;
1401 #endif
1402 #if _CYHAL_SRSS_PILO_PRESENT
1403 case CYHAL_CLOCK_BLOCK_PILO:
1404 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_PILO);
1405 return CY_RSLT_SUCCESS;
1406 #endif
1407 #if SRSS_ALTLF_PRESENT
1408 case CYHAL_CLOCK_BLOCK_ALTLF:
1409 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_ALTLF);
1410 return CY_RSLT_SUCCESS;
1411 #endif
1412 #if SRSS_ECO_PRESENT
1413 case CYHAL_CLOCK_BLOCK_ECO_PRESCALER:
1414 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_ECO_PRESCALER);
1415 return CY_RSLT_SUCCESS;
1416 #endif
1417 #if SRSS_BACKUP_S40E_LPECO_PRESENT
1418 case CYHAL_CLOCK_BLOCK_LPECO_PRESCALER:
1419 Cy_SysClk_ClkMfSetSource(CY_SYSCLK_CLKMF_IN_LPECO);
1420 return CY_RSLT_SUCCESS;
1421 #endif
1422 default:
1423 CY_ASSERT(false); //Unhandled clock
1424 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1425 }
1426 }
1427 #endif
1428
1429 // HF
_cyhal_clock_is_enabled_hf(const cyhal_clock_t * clock)1430 static bool _cyhal_clock_is_enabled_hf(const cyhal_clock_t *clock)
1431 {
1432 return Cy_SysClk_ClkHfIsEnabled(clock->channel);
1433 }
_cyhal_clock_set_enabled_hf(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1434 static cy_rslt_t _cyhal_clock_set_enabled_hf(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1435 {
1436 CY_UNUSED_PARAMETER(wait_for_lock);
1437
1438 return (enabled)
1439 ? Cy_SysClk_ClkHfEnable(clock->channel)
1440 : Cy_SysClk_ClkHfDisable(clock->channel);
1441 }
_cyhal_clock_get_frequency_hf(const cyhal_clock_t * clock)1442 static uint32_t _cyhal_clock_get_frequency_hf(const cyhal_clock_t *clock)
1443 {
1444 return Cy_SysClk_ClkHfGetFrequency(clock->channel);
1445 }
_cyhal_clock_set_divider_hf(cyhal_clock_t * clock,uint32_t divider)1446 static cy_rslt_t _cyhal_clock_set_divider_hf(cyhal_clock_t *clock, uint32_t divider)
1447 {
1448 cy_en_clkhf_dividers_t new_div;
1449 switch (divider)
1450 {
1451 case 1:
1452 new_div = CY_SYSCLK_CLKHF_NO_DIVIDE;
1453 break;
1454 case 2:
1455 new_div = CY_SYSCLK_CLKHF_DIVIDE_BY_2;
1456 break;
1457 case 4:
1458 new_div = CY_SYSCLK_CLKHF_DIVIDE_BY_4;
1459 break;
1460 case 8:
1461 new_div = CY_SYSCLK_CLKHF_DIVIDE_BY_8;
1462 break;
1463 default:
1464 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1465 }
1466
1467 /* Only used if updating HFClk 0 */
1468 uint32_t old_div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1469 uint32_t src = (uint32_t)Cy_SysClk_ClkHfGetSource(0);
1470 uint32_t path_freq = Cy_SysClk_ClkPathGetFrequency(src);
1471 uint32_t old_freq = path_freq >> old_div;
1472 uint32_t new_freq = path_freq >> ((uint32_t)new_div);
1473
1474 if (0 == clock->channel)
1475 _cyhal_clock_update_system_state(true, old_freq, new_freq);
1476
1477 cy_rslt_t rslt = (cy_rslt_t)Cy_SysClk_ClkHfSetDivider(clock->channel, new_div);
1478
1479 if (0 == clock->channel)
1480 {
1481 if (CY_RSLT_SUCCESS == rslt)
1482 _cyhal_clock_update_system_state(false, old_freq, new_freq);
1483 else // revert the change if there was one
1484 _cyhal_clock_update_system_state(false, new_freq, old_freq);
1485 }
1486
1487 return rslt;
1488 }
_cyhal_clock_get_sources_hf(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1489 static cy_rslt_t _cyhal_clock_get_sources_hf(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1490 {
1491 CY_UNUSED_PARAMETER(clock);
1492 *sources = _CYHAL_CLOCK_SOURCE_HF;
1493 *count = sizeof(_CYHAL_CLOCK_SOURCE_HF) / sizeof(_CYHAL_CLOCK_SOURCE_HF[0]);
1494 return CY_RSLT_SUCCESS;
1495 }
_cyhal_clock_set_source_hf(cyhal_clock_t * clock,const cyhal_clock_t * source)1496 static cy_rslt_t _cyhal_clock_set_source_hf(cyhal_clock_t *clock, const cyhal_clock_t *source)
1497 {
1498 uint32_t new_src;
1499 if (source->block == CYHAL_CLOCK_BLOCK_PATHMUX || source->block == CYHAL_CLOCK_BLOCK_FLL)
1500 new_src = source->channel;
1501 #if defined(COMPONENT_CAT1A)
1502 else if (source->block == CYHAL_CLOCK_BLOCK_PLL)
1503 #elif defined(COMPONENT_CAT1B)
1504 else if ((source->block == CYHAL_CLOCK_BLOCK_PLL200) || (source->block == CYHAL_CLOCK_BLOCK_PLL400))
1505 #endif
1506 new_src = source->channel + 1;
1507 else
1508 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1509
1510 /* Only used if updating HFClk 0 */
1511 uint32_t div = (uint32_t)Cy_SysClk_ClkHfGetDivider(0);
1512 uint32_t old_src = (uint32_t)Cy_SysClk_ClkHfGetSource(0);
1513 uint32_t old_freq = Cy_SysClk_ClkPathGetFrequency(old_src) >> div;
1514 uint32_t new_freq = Cy_SysClk_ClkPathGetFrequency(new_src) >> div;
1515
1516 if (0 == clock->channel)
1517 _cyhal_clock_update_system_state(true, old_freq, new_freq);
1518
1519 cy_rslt_t rslt = Cy_SysClk_ClkHfSetSource(clock->channel, (cy_en_clkhf_in_sources_t)new_src);
1520
1521 if (0 == clock->channel)
1522 {
1523 if (CY_RSLT_SUCCESS == rslt)
1524 _cyhal_clock_update_system_state(false, old_freq, new_freq);
1525 else // revert the change if there was one
1526 _cyhal_clock_update_system_state(false, new_freq, old_freq);
1527 }
1528
1529 return rslt;
1530 }
1531
1532 // LF
_cyhal_clock_get_frequency_lf(const cyhal_clock_t * clock)1533 static uint32_t _cyhal_clock_get_frequency_lf(const cyhal_clock_t *clock)
1534 {
1535 CY_UNUSED_PARAMETER(clock);
1536 return _cyhal_clock_get_lf_frequency();
1537 }
_cyhal_clock_get_sources_lf(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1538 static cy_rslt_t _cyhal_clock_get_sources_lf(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1539 {
1540 CY_UNUSED_PARAMETER(clock);
1541
1542 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_LF[] =
1543 {
1544 &CYHAL_CLOCK_RSC_ILO,
1545 #if _CYHAL_SRSS_PILO_PRESENT
1546 &CYHAL_CLOCK_RSC_PILO,
1547 #endif
1548 #if SRSS_BACKUP_PRESENT
1549 &CYHAL_CLOCK_RSC_WCO,
1550 #endif
1551 #if SRSS_ALTLF_PRESENT
1552 &CYHAL_CLOCK_RSC_ALTLF,
1553 #endif
1554 #if defined(COMPONENT_CAT1B)
1555 #if SRSS_ECO_PRESENT
1556 &CYHAL_CLOCK_RSC_ECO_PRESCALER,
1557 #endif
1558 #if SRSS_BACKUP_S40E_LPECO_PRESENT
1559 &CYHAL_CLOCK_RSC_LPECO_PRESCALER,
1560 #endif
1561 #endif
1562 };
1563
1564 *sources = _CYHAL_CLOCK_SOURCE_LF;
1565 *count = sizeof(_CYHAL_CLOCK_SOURCE_LF) / sizeof(_CYHAL_CLOCK_SOURCE_LF[0]);
1566 return CY_RSLT_SUCCESS;
1567 }
_cyhal_clock_set_source_lf(cyhal_clock_t * clock,const cyhal_clock_t * source)1568 static cy_rslt_t _cyhal_clock_set_source_lf(cyhal_clock_t *clock, const cyhal_clock_t *source)
1569 {
1570 CY_UNUSED_PARAMETER(clock);
1571
1572 switch (source->block)
1573 {
1574 case CYHAL_CLOCK_BLOCK_ILO:
1575 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_ILO);
1576 return CY_RSLT_SUCCESS;
1577 #if SRSS_BACKUP_PRESENT
1578 case CYHAL_CLOCK_BLOCK_WCO:
1579 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_WCO);
1580 return CY_RSLT_SUCCESS;
1581 #endif
1582 #if SRSS_ALTLF_PRESENT
1583 case CYHAL_CLOCK_BLOCK_ALTLF:
1584 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_ALTLF);
1585 return CY_RSLT_SUCCESS;
1586 #endif
1587 #if _CYHAL_SRSS_PILO_PRESENT
1588 case CYHAL_CLOCK_BLOCK_PILO:
1589 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_PILO);
1590 return CY_RSLT_SUCCESS;
1591 #endif
1592 #if defined(COMPONENT_CAT1B)
1593 #if SRSS_ECO_PRESENT
1594 case CYHAL_CLOCK_BLOCK_ECO_PRESCALER:
1595 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_ECO_PRESCALER);
1596 return CY_RSLT_SUCCESS;
1597 #endif
1598 #if SRSS_BACKUP_S40E_LPECO_PRESENT
1599 case CYHAL_CLOCK_BLOCK_LPECO_PRESCALER:
1600 Cy_SysClk_ClkLfSetSource(CY_SYSCLK_CLKLF_IN_LPECO_PRESCALER);
1601 return CY_RSLT_SUCCESS;
1602 #endif
1603 #endif
1604 default:
1605 CY_ASSERT(false); //Unhandled clock
1606 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1607 }
1608 }
1609
1610 #if defined(COMPONENT_CAT1A)
1611 // FAST
_cyhal_clock_get_frequency_fast(const cyhal_clock_t * clock)1612 static uint32_t _cyhal_clock_get_frequency_fast(const cyhal_clock_t *clock)
1613 {
1614 CY_UNUSED_PARAMETER(clock);
1615 return Cy_SysClk_ClkFastGetFrequency();
1616 }
_cyhal_clock_set_frequency_fast(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1617 static cy_rslt_t _cyhal_clock_set_frequency_fast(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1618 {
1619 CY_UNUSED_PARAMETER(clock);
1620
1621 uint32_t div;
1622 uint32_t input_hz = Cy_SysClk_ClkHfGetFrequency(0);
1623 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz, hz, 8, tolerance, &div);
1624
1625 if (CY_RSLT_SUCCESS == rslt)
1626 {
1627 Cy_SysClk_ClkFastSetDivider((uint8_t)(div - 1));
1628
1629 SystemCoreClockUpdate();
1630 }
1631 return rslt;
1632 }
_cyhal_clock_set_divider_fast(cyhal_clock_t * clock,uint32_t divider)1633 static cy_rslt_t _cyhal_clock_set_divider_fast(cyhal_clock_t *clock, uint32_t divider)
1634 {
1635 CY_UNUSED_PARAMETER(clock);
1636
1637 if (divider <= 256)
1638 {
1639 uint32_t divVal = divider - 1;
1640 Cy_SysClk_ClkFastSetDivider((uint8_t)divVal);
1641 SystemCoreClockUpdate();
1642 return CY_RSLT_SUCCESS;
1643 }
1644 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1645 }
_cyhal_clock_get_sources_fast(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1646 static cy_rslt_t _cyhal_clock_get_sources_fast(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1647 {
1648 CY_UNUSED_PARAMETER(clock);
1649
1650 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_FAST[] =
1651 {
1652 &CYHAL_CLOCK_RSC_HF[0],
1653 };
1654
1655 *sources = _CYHAL_CLOCK_SOURCE_FAST;
1656 *count = sizeof(_CYHAL_CLOCK_SOURCE_FAST) / sizeof(_CYHAL_CLOCK_SOURCE_FAST[0]);
1657 return CY_RSLT_SUCCESS;
1658 }
1659
1660 // SLOW
_cyhal_clock_get_frequency_slow(const cyhal_clock_t * clock)1661 static uint32_t _cyhal_clock_get_frequency_slow(const cyhal_clock_t *clock)
1662 {
1663 CY_UNUSED_PARAMETER(clock);
1664 return Cy_SysClk_ClkSlowGetFrequency();
1665 }
_cyhal_clock_set_frequency_slow(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1666 static cy_rslt_t _cyhal_clock_set_frequency_slow(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1667 {
1668 CY_UNUSED_PARAMETER(clock);
1669
1670 uint32_t div;
1671 uint32_t input_hz = Cy_SysClk_ClkPeriGetFrequency();
1672 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz, hz, 8, tolerance, &div);
1673
1674 if (CY_RSLT_SUCCESS == rslt)
1675 {
1676 Cy_SysClk_ClkSlowSetDivider((uint8_t)(div - 1));
1677 SystemCoreClockUpdate();
1678 }
1679
1680 return rslt;
1681 }
_cyhal_clock_set_divider_slow(cyhal_clock_t * clock,uint32_t divider)1682 static cy_rslt_t _cyhal_clock_set_divider_slow(cyhal_clock_t *clock, uint32_t divider)
1683 {
1684 CY_UNUSED_PARAMETER(clock);
1685
1686 if (divider <= 256)
1687 {
1688 uint32_t divVal = divider - 1;
1689 Cy_SysClk_ClkSlowSetDivider((uint8_t)divVal);
1690 SystemCoreClockUpdate();
1691 return CY_RSLT_SUCCESS;
1692 }
1693 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1694 }
_cyhal_clock_get_sources_slow(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1695 static cy_rslt_t _cyhal_clock_get_sources_slow(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1696 {
1697 CY_UNUSED_PARAMETER(clock);
1698 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_SLOW[] =
1699 {
1700 &CYHAL_CLOCK_RSC_PERI,
1701 };
1702
1703 *sources = _CYHAL_CLOCK_SOURCE_SLOW;
1704 *count = sizeof(_CYHAL_CLOCK_SOURCE_SLOW) / sizeof(_CYHAL_CLOCK_SOURCE_SLOW[0]);
1705 return CY_RSLT_SUCCESS;
1706 }
1707 #elif defined(COMPONENT_CAT1B)
1708 #if SRSS_ECO_PRESENT
1709 // ECO_PRESCALER - NOTE: This clock is not supported on any device yet
_cyhal_clock_get_frequency_eco_prescaler(const cyhal_clock_t * clock)1710 static uint32_t _cyhal_clock_get_frequency_eco_prescaler(const cyhal_clock_t *clock)
1711 {
1712 CY_UNUSED_PARAMETER(clock);
1713 //return Cy_SysClk_EcoPrescalerGetFrequency();
1714 return 0;
1715 }
_cyhal_clock_set_divider_eco_prescaler(cyhal_clock_t * clock,uint32_t divider)1716 static cy_rslt_t _cyhal_clock_set_divider_eco_prescaler(cyhal_clock_t *clock, uint32_t divider)
1717 {
1718 CY_UNUSED_PARAMETER(clock);
1719 CY_UNUSED_PARAMETER(divider);
1720
1721 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
1722 }
_cyhal_clock_get_sources_eco_prescaler(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1723 static cy_rslt_t _cyhal_clock_get_sources_eco_prescaler(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1724 {
1725 CY_UNUSED_PARAMETER(clock);
1726 CY_UNUSED_PARAMETER(sources);
1727 CY_UNUSED_PARAMETER(count);
1728
1729 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
1730 }
1731 #endif
1732
1733 #if SRSS_BACKUP_S40E_LPECO_PRESENT
1734 // LPECO_PRESCALER - NOTE: This clock is not supported on any device yet
_cyhal_clock_get_frequency_lpeco_prescaler(const cyhal_clock_t * clock)1735 static uint32_t _cyhal_clock_get_frequency_lpeco_prescaler(const cyhal_clock_t *clock)
1736 {
1737 CY_UNUSED_PARAMETER(clock);
1738 return Cy_SysClk_LpEcoPrescalerGetFrequency();
1739 }
_cyhal_clock_set_divider_lpeco_prescaler(cyhal_clock_t * clock,uint32_t divider)1740 static cy_rslt_t _cyhal_clock_set_divider_lpeco_prescaler(cyhal_clock_t *clock, uint32_t divider)
1741 {
1742 CY_UNUSED_PARAMETER(clock);
1743 CY_UNUSED_PARAMETER(divider);
1744
1745 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
1746 }
_cyhal_clock_get_sources_lpeco_prescaler(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1747 static cy_rslt_t _cyhal_clock_get_sources_lpeco_prescaler(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1748 {
1749 CY_UNUSED_PARAMETER(clock);
1750 CY_UNUSED_PARAMETER(sources);
1751 CY_UNUSED_PARAMETER(count);
1752
1753 return CYHAL_CLOCK_RSLT_ERR_NOT_SUPPORTED;
1754 }
1755 #endif
1756 #endif
1757
1758 // PERI
_cyhal_clock_get_frequency_peri(const cyhal_clock_t * clock)1759 static uint32_t _cyhal_clock_get_frequency_peri(const cyhal_clock_t *clock)
1760 {
1761 CY_UNUSED_PARAMETER(clock);
1762 #if defined(COMPONENT_CAT1A)
1763 return Cy_SysClk_ClkPeriGetFrequency();
1764 #elif defined(COMPONENT_CAT1B)
1765 #if !defined(CY_DEVICE_CYW20829)
1766 CY_ASSERT(false); // this has only been validated on the CYW20829 device
1767 #endif
1768 uint8_t hfclk = _cyhal_utils_get_hfclk_for_peri_group(clock->channel);
1769 return Cy_SysClk_ClkHfGetFrequency(hfclk) / (Cy_SysClk_PeriGroupGetDivider(clock->channel) + 1);
1770 #endif
1771 }
_cyhal_clock_set_frequency_peri(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)1772 static cy_rslt_t _cyhal_clock_set_frequency_peri(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
1773 {
1774 CY_UNUSED_PARAMETER(clock);
1775
1776 uint32_t div;
1777 #if defined(COMPONENT_CAT1A)
1778 uint32_t input_hz = Cy_SysClk_ClkHfGetFrequency(0);
1779 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz, hz, 8, tolerance, &div);
1780
1781 if (CY_RSLT_SUCCESS == rslt)
1782 {
1783 Cy_SysClk_ClkPeriSetDivider((uint8_t)(div - 1));
1784 SystemCoreClockUpdate();
1785 }
1786 #elif defined(COMPONENT_CAT1B)
1787 uint32_t input_hz = Cy_SysClk_ClkHfGetFrequency(clock->channel == 1 ? 1 : 0);
1788 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz, hz, 8, tolerance, &div);
1789
1790 if (CY_RSLT_SUCCESS == rslt)
1791 {
1792 Cy_SysClk_PeriGroupSetDivider(clock->channel, (uint8_t)(div - 1));
1793 }
1794 #endif
1795 return rslt;
1796 }
_cyhal_clock_set_divider_peri(cyhal_clock_t * clock,uint32_t divider)1797 static cy_rslt_t _cyhal_clock_set_divider_peri(cyhal_clock_t *clock, uint32_t divider)
1798 {
1799 CY_UNUSED_PARAMETER(clock);
1800
1801 if (divider <= 256)
1802 {
1803 uint32_t divVal = divider - 1;
1804 #if defined(COMPONENT_CAT1A)
1805 Cy_SysClk_ClkPeriSetDivider((uint8_t)divVal);
1806 #elif defined(COMPONENT_CAT1B)
1807 Cy_SysClk_PeriGroupSetDivider(clock->channel, (uint8_t)divVal);
1808 #endif
1809 SystemCoreClockUpdate();
1810 return CY_RSLT_SUCCESS;
1811 }
1812 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1813 }
_cyhal_clock_get_sources_peri(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1814 static cy_rslt_t _cyhal_clock_get_sources_peri(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1815 {
1816 #if defined(COMPONENT_CAT1A)
1817 CY_UNUSED_PARAMETER(clock);
1818 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_PERI[] =
1819 {
1820 &CYHAL_CLOCK_RSC_HF[0],
1821 };
1822
1823 *sources = _CYHAL_CLOCK_SOURCE_PERI;
1824 *count = 1;
1825 return CY_RSLT_SUCCESS;
1826 #elif defined (COMPONENT_CAT1B)
1827 uint8_t hfclk = _cyhal_utils_get_hfclk_for_peri_group(clock->channel);
1828 return _cyhal_clock_get_sources_peri_peripheral(hfclk, sources, count);
1829 #endif
1830 }
1831
1832 // PUMP
_cyhal_clock_is_enabled_pump(const cyhal_clock_t * clock)1833 static bool _cyhal_clock_is_enabled_pump(const cyhal_clock_t *clock)
1834 {
1835 CY_UNUSED_PARAMETER(clock);
1836 return Cy_SysClk_ClkPumpIsEnabled();
1837 }
_cyhal_clock_set_enabled_pump(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1838 static cy_rslt_t _cyhal_clock_set_enabled_pump(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1839 {
1840 CY_UNUSED_PARAMETER(clock);
1841 CY_UNUSED_PARAMETER(wait_for_lock);
1842
1843 if (enabled)
1844 Cy_SysClk_ClkPumpEnable();
1845 else
1846 Cy_SysClk_ClkPumpDisable();
1847 return CY_RSLT_SUCCESS;
1848 }
_cyhal_clock_get_frequency_pump(const cyhal_clock_t * clock)1849 static uint32_t _cyhal_clock_get_frequency_pump(const cyhal_clock_t *clock)
1850 {
1851 CY_UNUSED_PARAMETER(clock);
1852 return Cy_SysClk_ClkPumpGetFrequency();
1853 }
_cyhal_clock_set_divider_pump(cyhal_clock_t * clock,uint32_t divider)1854 static cy_rslt_t _cyhal_clock_set_divider_pump(cyhal_clock_t *clock, uint32_t divider)
1855 {
1856 CY_UNUSED_PARAMETER(clock);
1857
1858 cy_en_clkpump_divide_t divVal;
1859 switch (divider)
1860 {
1861 case 1:
1862 divVal = CY_SYSCLK_PUMP_NO_DIV;
1863 break;
1864 case 2:
1865 divVal = CY_SYSCLK_PUMP_DIV_2;
1866 break;
1867 case 4:
1868 divVal = CY_SYSCLK_PUMP_DIV_4;
1869 break;
1870 case 8:
1871 divVal = CY_SYSCLK_PUMP_DIV_8;
1872 break;
1873 case 16:
1874 divVal = CY_SYSCLK_PUMP_DIV_16;
1875 break;
1876 default:
1877 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1878 }
1879 Cy_SysClk_ClkPumpSetDivider(divVal);
1880 return CY_RSLT_SUCCESS;
1881 }
1882 #define _cyhal_clock_get_sources_pump _cyhal_clock_get_sources_hf
_cyhal_clock_set_source_pump(cyhal_clock_t * clock,const cyhal_clock_t * source)1883 static cy_rslt_t _cyhal_clock_set_source_pump(cyhal_clock_t *clock, const cyhal_clock_t *source)
1884 {
1885 CY_UNUSED_PARAMETER(clock);
1886
1887 if (source->block == CYHAL_CLOCK_BLOCK_PATHMUX || source->block == CYHAL_CLOCK_BLOCK_FLL)
1888 {
1889 Cy_SysClk_ClkPumpSetSource((cy_en_clkpump_in_sources_t)source->channel);
1890 return CY_RSLT_SUCCESS;
1891 }
1892 #if defined(COMPONENT_CAT1A)
1893 else if (source->block == CYHAL_CLOCK_BLOCK_PLL)
1894 #elif defined(COMPONENT_CAT1B)
1895 else if ((source->block == CYHAL_CLOCK_BLOCK_PLL200) || (source->block == CYHAL_CLOCK_BLOCK_PLL400))
1896 #endif
1897 {
1898 Cy_SysClk_ClkPumpSetSource((cy_en_clkpump_in_sources_t)(source->channel + 1));
1899 return CY_RSLT_SUCCESS;
1900 }
1901 else
1902 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1903 }
1904
1905 // TIMER
1906 #if defined(COMPONENT_CAT1A)
_cyhal_clock_is_enabled_timer(const cyhal_clock_t * clock)1907 static bool _cyhal_clock_is_enabled_timer(const cyhal_clock_t *clock)
1908 {
1909 CY_UNUSED_PARAMETER(clock);
1910 return Cy_SysClk_ClkTimerIsEnabled();
1911 }
_cyhal_clock_set_enabled_timer(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)1912 static cy_rslt_t _cyhal_clock_set_enabled_timer(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
1913 {
1914 CY_UNUSED_PARAMETER(clock);
1915 CY_UNUSED_PARAMETER(wait_for_lock);
1916
1917 if (enabled)
1918 Cy_SysClk_ClkTimerEnable();
1919 else
1920 Cy_SysClk_ClkTimerDisable();
1921 return CY_RSLT_SUCCESS;
1922 }
_cyhal_clock_get_frequency_timer(const cyhal_clock_t * clock)1923 static uint32_t _cyhal_clock_get_frequency_timer(const cyhal_clock_t *clock)
1924 {
1925 CY_UNUSED_PARAMETER(clock);
1926 return Cy_SysClk_ClkTimerGetFrequency();
1927 }
_cyhal_clock_set_divider_timer(cyhal_clock_t * clock,uint32_t divider)1928 static cy_rslt_t _cyhal_clock_set_divider_timer(cyhal_clock_t *clock, uint32_t divider)
1929 {
1930 CY_UNUSED_PARAMETER(clock);
1931
1932 if (divider <= 256)
1933 {
1934 uint32_t divVal = divider - 1;
1935 Cy_SysClk_ClkTimerSetDivider((uint8_t)divVal);
1936 return CY_RSLT_SUCCESS;
1937 }
1938 return CYHAL_CLOCK_RSLT_ERR_FREQ;
1939 }
_cyhal_clock_get_sources_timer(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1940 static cy_rslt_t _cyhal_clock_get_sources_timer(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1941 {
1942 CY_UNUSED_PARAMETER(clock);
1943 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_TIMER[] =
1944 {
1945 &CYHAL_CLOCK_RSC_IMO,
1946 &CYHAL_CLOCK_RSC_HF[0],
1947 };
1948
1949 *sources = _CYHAL_CLOCK_SOURCE_TIMER;
1950 *count = sizeof(_CYHAL_CLOCK_SOURCE_TIMER) / sizeof(_CYHAL_CLOCK_SOURCE_TIMER[0]);
1951 return CY_RSLT_SUCCESS;
1952 }
_cyhal_clock_set_source_timer(cyhal_clock_t * clock,const cyhal_clock_t * source)1953 static cy_rslt_t _cyhal_clock_set_source_timer(cyhal_clock_t *clock, const cyhal_clock_t *source)
1954 {
1955 CY_UNUSED_PARAMETER(clock);
1956
1957 if (source->block == CYHAL_CLOCK_BLOCK_IMO)
1958 {
1959 Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_IMO);
1960 return CY_RSLT_SUCCESS;
1961 }
1962 else if (source->block == CYHAL_CLOCK_BLOCK_HF && source->channel == 0)
1963 {
1964 Cy_SysClk_ClkTimerSetSource(CY_SYSCLK_CLKTIMER_IN_HF0_NODIV);
1965 return CY_RSLT_SUCCESS;
1966 }
1967 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
1968 }
1969 #endif
1970
1971 // BAK
_cyhal_clock_get_frequency_bak(const cyhal_clock_t * clock)1972 static uint32_t _cyhal_clock_get_frequency_bak(const cyhal_clock_t *clock)
1973 {
1974 CY_UNUSED_PARAMETER(clock);
1975 cy_en_clkbak_in_sources_t src = Cy_SysClk_ClkBakGetSource();
1976 #if SRSS_BACKUP_PRESENT
1977 if (src == CY_SYSCLK_BAK_IN_WCO)
1978 return CY_SYSCLK_WCO_FREQ;
1979 #endif
1980 return _cyhal_clock_get_lf_frequency();
1981 }
_cyhal_clock_get_sources_bak(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)1982 static cy_rslt_t _cyhal_clock_get_sources_bak(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
1983 {
1984 CY_UNUSED_PARAMETER(clock);
1985 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_BAK[] =
1986 {
1987 &CYHAL_CLOCK_RSC_LF,
1988 #if SRSS_BACKUP_PRESENT
1989 &CYHAL_CLOCK_RSC_WCO,
1990 #endif
1991 };
1992
1993 *sources = _CYHAL_CLOCK_SOURCE_BAK;
1994 *count = sizeof(_CYHAL_CLOCK_SOURCE_BAK) / sizeof(_CYHAL_CLOCK_SOURCE_BAK[0]);
1995 return CY_RSLT_SUCCESS;
1996 }
_cyhal_clock_set_source_bak(cyhal_clock_t * clock,const cyhal_clock_t * source)1997 static cy_rslt_t _cyhal_clock_set_source_bak(cyhal_clock_t *clock, const cyhal_clock_t *source)
1998 {
1999 CY_UNUSED_PARAMETER(clock);
2000
2001 switch (source->block)
2002 {
2003 case CYHAL_CLOCK_BLOCK_WCO:
2004 Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_WCO);
2005 return CY_RSLT_SUCCESS;
2006 case CYHAL_CLOCK_BLOCK_LF:
2007 Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_CLKLF);
2008 return CY_RSLT_SUCCESS;
2009 #if defined(COMPONENT_CAT1B)
2010 case CYHAL_CLOCK_BLOCK_ILO:
2011 Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_ILO);
2012 return CY_RSLT_SUCCESS;
2013 #if _CYHAL_SRSS_PILO_PRESENT
2014 case CYHAL_CLOCK_BLOCK_PILO:
2015 Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_PILO);
2016 return CY_RSLT_SUCCESS;
2017 #endif
2018 #if SRSS_BACKUP_S40E_LPECO_PRESENT
2019 case CYHAL_CLOCK_BLOCK_LPECO_PRESCALER:
2020 Cy_SysClk_ClkBakSetSource(CY_SYSCLK_BAK_IN_LPECO_PRESCALER);
2021 return CY_RSLT_SUCCESS;
2022 #endif
2023 #endif
2024 default:
2025 CY_ASSERT(false); //Unhandled clock
2026 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
2027 }
2028 }
2029
2030 // ALT_SYS_TICK
_cyhal_clock_get_frequency_alt_sys_tick(const cyhal_clock_t * clock)2031 static uint32_t _cyhal_clock_get_frequency_alt_sys_tick(const cyhal_clock_t *clock)
2032 {
2033 CY_UNUSED_PARAMETER(clock);
2034 CY_ASSERT(false); // This is not supported at this time
2035 return 0;
2036 }
_cyhal_clock_get_sources_alt_sys_tick(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)2037 static cy_rslt_t _cyhal_clock_get_sources_alt_sys_tick(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
2038 {
2039 CY_UNUSED_PARAMETER(clock);
2040 static const cyhal_resource_inst_t *_CYHAL_CLOCK_SOURCE_ALT_SYS_TICK[] =
2041 {
2042 &CYHAL_CLOCK_RSC_IMO,
2043 #if SRSS_ECO_PRESENT
2044 &CYHAL_CLOCK_RSC_ECO,
2045 #endif
2046 &CYHAL_CLOCK_RSC_LF,
2047 #if defined(COMPONENT_CAT1A)
2048 &CYHAL_CLOCK_RSC_TIMER, /* Technically present on CAT1B, but deprecated */
2049 &CYHAL_CLOCK_RSC_FAST,
2050 &CYHAL_CLOCK_RSC_SLOW,
2051 #elif defined(COMPONENT_CAT1B)
2052 &CYHAL_CLOCK_RSC_HF[0], /* CPU clock */
2053 #endif
2054 };
2055
2056 *sources = _CYHAL_CLOCK_SOURCE_ALT_SYS_TICK;
2057 *count = sizeof(_CYHAL_CLOCK_SOURCE_ALT_SYS_TICK) / sizeof(_CYHAL_CLOCK_SOURCE_ALT_SYS_TICK[0]);
2058 return CY_RSLT_SUCCESS;
2059 }
_cyhal_clock_set_source_alt_sys_tick(cyhal_clock_t * clock,const cyhal_clock_t * source)2060 static cy_rslt_t _cyhal_clock_set_source_alt_sys_tick(cyhal_clock_t *clock, const cyhal_clock_t *source)
2061 {
2062 CY_UNUSED_PARAMETER(clock);
2063
2064 switch (source->block)
2065 {
2066 case CYHAL_CLOCK_BLOCK_LF:
2067 Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_LF);
2068 return CY_RSLT_SUCCESS;
2069 case CYHAL_CLOCK_BLOCK_IMO:
2070 Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_IMO);
2071 return CY_RSLT_SUCCESS;
2072 #if SRSS_ECO_PRESENT
2073 case CYHAL_CLOCK_BLOCK_ECO:
2074 Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_ECO);
2075 return CY_RSLT_SUCCESS;
2076 #endif
2077 #if defined(COMPONENT_CAT1A)
2078 case CYHAL_CLOCK_BLOCK_TIMER:
2079 Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_TIMER);
2080 return CY_RSLT_SUCCESS;
2081 case CYHAL_CLOCK_BLOCK_FAST:
2082 case CYHAL_CLOCK_BLOCK_SLOW:
2083 Cy_SysTick_SetClockSource(CY_SYSTICK_CLOCK_SOURCE_CLK_CPU);
2084 return CY_RSLT_SUCCESS;
2085 #endif
2086 default:
2087 CY_ASSERT(false); //Unhandled clock
2088 return CYHAL_CLOCK_RSLT_ERR_SOURCE;
2089 }
2090 }
2091
2092 // Peripheral
_cyhal_clock_is_enabled_peripheral(const cyhal_clock_t * clock)2093 static bool _cyhal_clock_is_enabled_peripheral(const cyhal_clock_t *clock)
2094 {
2095 return _cyhal_utils_peri_pclk_is_divider_enabled(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock);
2096 }
_cyhal_clock_set_enabled_peripheral(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)2097 static cy_rslt_t _cyhal_clock_set_enabled_peripheral(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
2098 {
2099 CY_UNUSED_PARAMETER(wait_for_lock);
2100
2101 return (enabled)
2102 ? _cyhal_utils_peri_pclk_enable_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock)
2103 : _cyhal_utils_peri_pclk_disable_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock);
2104 }
_cyhal_clock_get_frequency_peripheral(const cyhal_clock_t * clock)2105 static uint32_t _cyhal_clock_get_frequency_peripheral(const cyhal_clock_t *clock)
2106 {
2107 return _cyhal_utils_peri_pclk_get_frequency(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock);
2108 }
_cyhal_clock_set_frequency_peripheral(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)2109 static cy_rslt_t _cyhal_clock_set_frequency_peripheral(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
2110 {
2111 CY_UNUSED_PARAMETER(clock);
2112 CY_UNUSED_PARAMETER(tolerance);
2113
2114 // blocks 0b00 & 0b01 are integer, 0b10 & 0b11 are fractional
2115 uint32_t div;
2116 #if defined(COMPONENT_CAT1A)
2117 uint32_t input_hz = Cy_SysClk_ClkPeriGetFrequency();
2118 #elif defined(COMPONENT_CAT1B)
2119 uint8_t group = _CYHAL_PERIPHERAL_GROUP_GET_GROUP(clock->block);
2120 uint8_t hfclk = _cyhal_utils_get_hfclk_for_peri_group(group);
2121 uint32_t input_hz = Cy_SysClk_ClkHfGetFrequency(hfclk);
2122 #endif
2123
2124 if ((clock->block & 0x02) == 0)
2125 {
2126 uint32_t bits = (clock->block == CYHAL_CLOCK_BLOCK_PERIPHERAL_8BIT) ? 8 : 16;
2127 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz, hz, bits, tolerance, &div);
2128 return (CY_RSLT_SUCCESS == rslt)
2129 ? _cyhal_utils_peri_pclk_set_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock, (div - 1))
2130 : rslt;
2131 }
2132 else
2133 {
2134 // Multiply input by 32 so we can treat the 5 fractional bits as though they are extentions of the integer divider
2135 // Leave the the desired frequency alone, so we can just strip out the integer & fractional bits at the end.
2136 uint32_t bits = (clock->block == CYHAL_CLOCK_BLOCK_PERIPHERAL_16_5BIT) ? 21 : 29; // Integer bits + 5
2137 cy_rslt_t rslt = _cyhal_clock_compute_div(input_hz << 5, hz, bits, tolerance, &div);
2138 if (CY_RSLT_SUCCESS == rslt)
2139 {
2140 uint32_t div_int = (div >> 5) - 1;
2141 uint32_t div_frac = div & 0x1F;
2142 return _cyhal_utils_peri_pclk_set_frac_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock, div_int, div_frac);
2143 }
2144 else
2145 return rslt;
2146 }
2147 }
_cyhal_clock_set_divider_peripheral(cyhal_clock_t * clock,uint32_t divider)2148 static cy_rslt_t _cyhal_clock_set_divider_peripheral(cyhal_clock_t *clock, uint32_t divider)
2149 {
2150 CY_UNUSED_PARAMETER(clock);
2151
2152 // blocks 0b00 & 0b01 are integer, 0b10 & 0b11 are fractional
2153 return ((clock->block & 0x02) == 0)
2154 ? _cyhal_utils_peri_pclk_set_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock, divider - 1)
2155 : _cyhal_utils_peri_pclk_set_frac_divider(_CYHAL_CLOCK_GET_PCLK_GR_NUM(clock->block), clock, divider - 1, 0);
2156 }
_cyhal_clock_get_sources_peripheral(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)2157 static cy_rslt_t _cyhal_clock_get_sources_peripheral(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
2158 {
2159 #if defined(COMPONENT_CAT1A)
2160 return _cyhal_clock_get_sources_slow(clock, sources, count);
2161 #elif defined(COMPONENT_CAT1B)
2162 uint8_t group = _CYHAL_PERIPHERAL_GROUP_GET_GROUP(clock->block);
2163 uint8_t hfclk = _cyhal_utils_get_hfclk_for_peri_group(group);
2164 return _cyhal_clock_get_sources_peri_peripheral(hfclk, sources, count);
2165 #endif
2166 }
2167
2168
2169
2170 /******************************************************************************
2171 ******************************* Clock Structs ********************************
2172 *****************************************************************************/
2173
2174 /* Use a structure with function pointers to allow the driver to optimize out entire clocks if they
2175 * are not used. We make two exceptions to this. HF and peripheral clocks are called directly by
2176 * the public functions. This allows those clocks to be optimized based on what the user actually
2177 * calls. This distinction is done based on what the user is most likely to do with the HAL driver.
2178 * HF & peripheral clocks are likely to be configured at runtime based on setting up different
2179 * peripherals. Other system clocks are likely to be be set once at startup and never modified.
2180 * Based on this, we design the code so the compiler can optimize out the unused items most
2181 * efficiently.
2182 */
2183
2184 typedef struct
2185 {
2186 bool (*is_enabled)(const cyhal_clock_t *clock);
2187 cy_rslt_t (*set_enabled)(cyhal_clock_t *clock, bool enabled, bool wait_for_lock);
2188 uint32_t (*get_frequency)(const cyhal_clock_t *clock);
2189 cy_rslt_t (*set_frequency)(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance);
2190 cy_rslt_t (*set_divider)(cyhal_clock_t *clock, uint32_t divider);
2191 cy_rslt_t (*get_sources)(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count);
2192 cy_rslt_t (*set_source)(cyhal_clock_t *clock, const cyhal_clock_t *source);
2193 cyhal_clock_feature_t features;
2194 } cyhal_clock_funcs_t;
2195
2196 static const cyhal_clock_funcs_t FUNCS_IMO =
2197 {
2198 .features = CYHAL_CLOCK_FEATURE_NONE,
2199 .is_enabled = _cyhal_clock_is_enabled_true,
2200 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2201 .get_frequency = _cyhal_clock_get_frequency_imo,
2202 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2203 .set_divider = _cyhal_clock_set_divider_unsupported,
2204 .get_sources = _cyhal_clock_get_sources_none,
2205 .set_source = _cyhal_clock_set_source_unsupported,
2206 };
2207
2208 #if defined(COMPONENT_CAT1B)
2209 static const cyhal_clock_funcs_t FUNCS_IHO =
2210 {
2211 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2212 .is_enabled = _cyhal_clock_is_enabled_iho,
2213 .set_enabled = _cyhal_clock_set_enabled_iho,
2214 .get_frequency = _cyhal_clock_get_frequency_iho,
2215 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2216 .set_divider = _cyhal_clock_set_divider_unsupported,
2217 .get_sources = _cyhal_clock_get_sources_none,
2218 .set_source = _cyhal_clock_set_source_unsupported,
2219 };
2220 #endif
2221
2222 #if SRSS_ECO_PRESENT
2223 static const cyhal_clock_funcs_t FUNCS_ECO =
2224 {
2225 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2226 .is_enabled = _cyhal_clock_is_enabled_eco,
2227 .set_enabled = _cyhal_clock_set_enabled_eco,
2228 .get_frequency = _cyhal_clock_get_frequency_eco,
2229 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2230 .set_divider = _cyhal_clock_set_divider_unsupported,
2231 .get_sources = _cyhal_clock_get_sources_none,
2232 .set_source = _cyhal_clock_set_source_unsupported,
2233 };
2234 #endif
2235
2236 static const cyhal_clock_funcs_t FUNCS_EXT =
2237 {
2238 .features = CYHAL_CLOCK_FEATURE_FREQUENCY,
2239 .is_enabled = _cyhal_clock_is_enabled_ext,
2240 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2241 .get_frequency = _cyhal_clock_get_frequency_ext,
2242 .set_frequency = _cyhal_clock_set_frequency_ext,
2243 .set_divider = _cyhal_clock_set_divider_unsupported,
2244 .get_sources = _cyhal_clock_get_sources_none,
2245 .set_source = _cyhal_clock_set_source_unsupported,
2246 };
2247
2248 #if SRSS_ALTHF_PRESENT
2249 static const cyhal_clock_funcs_t FUNCS_ALTHF =
2250 {
2251 .features = CYHAL_CLOCK_FEATURE_NONE,
2252 .is_enabled = _cyhal_clock_is_enabled_althf,
2253 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2254 .get_frequency = _cyhal_clock_get_frequency_althf,
2255 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2256 .set_divider = _cyhal_clock_set_divider_unsupported,
2257 .get_sources = _cyhal_clock_get_sources_none,
2258 .set_source = _cyhal_clock_set_source_unsupported,
2259 };
2260 #endif
2261
2262 #if SRSS_ALTLF_PRESENT
2263 static const cyhal_clock_funcs_t FUNCS_ALTLF =
2264 {
2265 .features = CYHAL_CLOCK_FEATURE_NONE,
2266 .is_enabled = _cyhal_clock_is_enabled_altlf,
2267 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2268 .get_frequency = _cyhal_clock_get_frequency_altlf,
2269 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2270 .set_divider = _cyhal_clock_set_divider_unsupported,
2271 .get_sources = _cyhal_clock_get_sources_none,
2272 .set_source = _cyhal_clock_set_source_unsupported,
2273 };
2274 #endif
2275
2276 static const cyhal_clock_funcs_t FUNCS_ILO =
2277 {
2278 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2279 .is_enabled = _cyhal_clock_is_enabled_ilo,
2280 .set_enabled = _cyhal_clock_set_enabled_ilo,
2281 .get_frequency = _cyhal_clock_get_frequency_ilo,
2282 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2283 .set_divider = _cyhal_clock_set_divider_unsupported,
2284 .get_sources = _cyhal_clock_get_sources_none,
2285 .set_source = _cyhal_clock_set_source_unsupported,
2286 };
2287
2288 #if _CYHAL_SRSS_PILO_PRESENT
2289 static const cyhal_clock_funcs_t FUNCS_PILO =
2290 {
2291 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2292 .is_enabled = _cyhal_clock_is_enabled_pilo,
2293 .set_enabled = _cyhal_clock_set_enabled_pilo,
2294 .get_frequency = _cyhal_clock_get_frequency_pilo,
2295 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2296 .set_divider = _cyhal_clock_set_divider_unsupported,
2297 .get_sources = _cyhal_clock_get_sources_none,
2298 .set_source = _cyhal_clock_set_source_unsupported,
2299 };
2300 #endif
2301
2302 static const cyhal_clock_funcs_t FUNCS_WCO =
2303 {
2304 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2305 .is_enabled = _cyhal_clock_is_enabled_wco,
2306 .set_enabled = _cyhal_clock_set_enabled_wco,
2307 .get_frequency = _cyhal_clock_get_frequency_wco,
2308 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2309 .set_divider = _cyhal_clock_set_divider_unsupported,
2310 .get_sources = _cyhal_clock_get_sources_none,
2311 .set_source = _cyhal_clock_set_source_unsupported,
2312 };
2313
2314 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
2315 static const cyhal_clock_funcs_t FUNCS_MFO =
2316 {
2317 .features = CYHAL_CLOCK_FEATURE_ENABLE,
2318 .is_enabled = _cyhal_clock_is_enabled_mfo,
2319 .set_enabled = _cyhal_clock_set_enabled_mfo,
2320 .get_frequency = _cyhal_clock_get_frequency_mfo,
2321 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2322 .set_divider = _cyhal_clock_set_divider_unsupported,
2323 .get_sources = _cyhal_clock_get_sources_mfo,
2324 .set_source = _cyhal_clock_set_source_unsupported,
2325 };
2326 #endif
2327
2328 static const cyhal_clock_funcs_t FUNCS_PATHMUX =
2329 {
2330 .features = CYHAL_CLOCK_FEATURE_SOURCE,
2331 .is_enabled = _cyhal_clock_is_enabled_true,
2332 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2333 .get_frequency = _cyhal_clock_get_frequency_pathmux,
2334 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2335 .set_divider = _cyhal_clock_set_divider_unsupported,
2336 .get_sources = _cyhal_clock_get_sources_pathmux,
2337 .set_source = _cyhal_clock_set_source_pathmux,
2338 };
2339
2340 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
2341 static const cyhal_clock_funcs_t FUNCS_FLL =
2342 {
2343 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_FREQUENCY),
2344 .is_enabled = _cyhal_clock_is_enabled_fll,
2345 .set_enabled = _cyhal_clock_set_enabled_fll,
2346 .get_frequency = _cyhal_clock_get_frequency_fll,
2347 .set_frequency = _cyhal_clock_set_frequency_fll,
2348 .set_divider = _cyhal_clock_set_divider_unsupported,
2349 .get_sources = _cyhal_clock_get_sources_fll,
2350 .set_source = _cyhal_clock_set_source_unsupported,
2351 };
2352 #endif
2353
2354 #if (SRSS_NUM_PLL > 0)
2355 static const cyhal_clock_funcs_t FUNCS_PLL =
2356 {
2357 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_FREQUENCY),
2358 .is_enabled = _cyhal_clock_is_enabled_pll,
2359 .set_enabled = _cyhal_clock_set_enabled_pll,
2360 .get_frequency = _cyhal_clock_get_frequency_pll,
2361 .set_frequency = _cyhal_clock_set_frequency_pll,
2362 .set_divider = _cyhal_clock_set_divider_unsupported,
2363 .get_sources = _cyhal_clock_get_sources_pll,
2364 .set_source = _cyhal_clock_set_source_unsupported,
2365 };
2366 #endif
2367
2368 static const cyhal_clock_funcs_t FUNCS_LF =
2369 {
2370 .features = CYHAL_CLOCK_FEATURE_SOURCE,
2371 .is_enabled = _cyhal_clock_is_enabled_true,
2372 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2373 .get_frequency = _cyhal_clock_get_frequency_lf,
2374 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2375 .set_divider = _cyhal_clock_set_divider_unsupported,
2376 .get_sources = _cyhal_clock_get_sources_lf,
2377 .set_source = _cyhal_clock_set_source_lf,
2378 };
2379
2380 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
2381 static const cyhal_clock_funcs_t FUNCS_MF =
2382 {
2383 #if defined(COMPONENT_CAT1A) /* CAT1A only supports driving clk_mf from the MFO */
2384 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY),
2385 #else
2386 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY | CYHAL_CLOCK_FEATURE_SOURCE),
2387 #endif
2388 .is_enabled = _cyhal_clock_is_enabled_mf,
2389 .set_enabled = _cyhal_clock_set_enabled_mf,
2390 .get_frequency = _cyhal_clock_get_frequency_mf,
2391 .set_frequency = _cyhal_clock_set_frequency_mf,
2392 .set_divider = _cyhal_clock_set_divider_mf,
2393 .get_sources = _cyhal_clock_get_sources_mf,
2394 .set_source = _cyhal_clock_set_source_mf,
2395 };
2396 #endif
2397
2398 static const cyhal_clock_funcs_t FUNCS_HF =
2399 {
2400 // NOTE: HF0 cannot be disabled, it would stop the MCUs. Ideally HF0 would not support
2401 // CYHAL_CLOCK_FEATURE_ENABLE, but this struct is never actually used in practice so it doesn't
2402 // matter.
2403 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_SOURCE | CYHAL_CLOCK_FEATURE_DIVIDER),
2404 .is_enabled = _cyhal_clock_is_enabled_hf,
2405 .set_enabled = _cyhal_clock_set_enabled_hf,
2406 .get_frequency = _cyhal_clock_get_frequency_hf,
2407 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2408 .set_divider = _cyhal_clock_set_divider_hf,
2409 .get_sources = _cyhal_clock_get_sources_hf,
2410 .set_source = _cyhal_clock_set_source_hf,
2411 };
2412
2413 static const cyhal_clock_funcs_t FUNCS_PUMP =
2414 {
2415 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_SOURCE | CYHAL_CLOCK_FEATURE_DIVIDER),
2416 .is_enabled = _cyhal_clock_is_enabled_pump,
2417 .set_enabled = _cyhal_clock_set_enabled_pump,
2418 .get_frequency = _cyhal_clock_get_frequency_pump,
2419 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2420 .set_divider = _cyhal_clock_set_divider_pump,
2421 .get_sources = _cyhal_clock_get_sources_pump,
2422 .set_source = _cyhal_clock_set_source_pump,
2423 };
2424
2425 #if defined(COMPONENT_CAT1A)
2426 static const cyhal_clock_funcs_t FUNCS_TIMER =
2427 {
2428 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_SOURCE | CYHAL_CLOCK_FEATURE_DIVIDER),
2429 .is_enabled = _cyhal_clock_is_enabled_timer,
2430 .set_enabled = _cyhal_clock_set_enabled_timer,
2431 .get_frequency = _cyhal_clock_get_frequency_timer,
2432 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2433 .set_divider = _cyhal_clock_set_divider_timer,
2434 .get_sources = _cyhal_clock_get_sources_timer,
2435 .set_source = _cyhal_clock_set_source_timer,
2436 };
2437 #endif
2438
2439 static const cyhal_clock_funcs_t FUNCS_BAK =
2440 {
2441 .features = CYHAL_CLOCK_FEATURE_SOURCE,
2442 .is_enabled = _cyhal_clock_is_enabled_true,
2443 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2444 .get_frequency = _cyhal_clock_get_frequency_bak,
2445 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2446 .set_divider = _cyhal_clock_set_divider_unsupported,
2447 .get_sources = _cyhal_clock_get_sources_bak,
2448 .set_source = _cyhal_clock_set_source_bak,
2449 };
2450
2451 static const cyhal_clock_funcs_t FUNCS_ALT_SYS_TICK =
2452 {
2453 .features = CYHAL_CLOCK_FEATURE_SOURCE,
2454 .is_enabled = _cyhal_clock_is_enabled_true,
2455 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2456 .get_frequency = _cyhal_clock_get_frequency_alt_sys_tick,
2457 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2458 .set_divider = _cyhal_clock_set_divider_unsupported,
2459 .get_sources = _cyhal_clock_get_sources_alt_sys_tick,
2460 .set_source = _cyhal_clock_set_source_alt_sys_tick,
2461 };
2462
2463 #if defined(COMPONENT_CAT1A)
2464 static const cyhal_clock_funcs_t FUNCS_FAST =
2465 {
2466 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY),
2467 .is_enabled = _cyhal_clock_is_enabled_true,
2468 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2469 .get_frequency = _cyhal_clock_get_frequency_fast,
2470 .set_frequency = _cyhal_clock_set_frequency_fast,
2471 .set_divider = _cyhal_clock_set_divider_fast,
2472 .get_sources = _cyhal_clock_get_sources_fast,
2473 .set_source = _cyhal_clock_set_source_unsupported,
2474 };
2475
2476 static const cyhal_clock_funcs_t FUNCS_SLOW =
2477 {
2478 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY),
2479 .is_enabled = _cyhal_clock_is_enabled_true,
2480 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2481 .get_frequency = _cyhal_clock_get_frequency_slow,
2482 .set_frequency = _cyhal_clock_set_frequency_slow,
2483 .set_divider = _cyhal_clock_set_divider_slow,
2484 .get_sources = _cyhal_clock_get_sources_slow,
2485 .set_source = _cyhal_clock_set_source_unsupported,
2486 };
2487 #elif defined(COMPONENT_CAT1B)
2488 #if SRSS_ECO_PRESENT
2489 static const cyhal_clock_funcs_t FUNCS_ECO_PRESCALER =
2490 {
2491 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_DIVIDER),
2492 .is_enabled = _cyhal_clock_is_enabled_true,
2493 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2494 .get_frequency = _cyhal_clock_get_frequency_eco_prescaler,
2495 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2496 .set_divider = _cyhal_clock_set_divider_eco_prescaler,
2497 .get_sources = _cyhal_clock_get_sources_eco_prescaler,
2498 .set_source = _cyhal_clock_set_source_unsupported,
2499 };
2500 #endif
2501
2502 #if SRSS_BACKUP_S40E_LPECO_PRESENT
2503 static const cyhal_clock_funcs_t FUNCS_LPECO_PRESCALER =
2504 {
2505 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_DIVIDER),
2506 .is_enabled = _cyhal_clock_is_enabled_true,
2507 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2508 .get_frequency = _cyhal_clock_get_frequency_lpeco_prescaler,
2509 .set_frequency = _cyhal_clock_set_frequency_unsupported,
2510 .set_divider = _cyhal_clock_set_divider_lpeco_prescaler,
2511 .get_sources = _cyhal_clock_get_sources_lpeco_prescaler,
2512 .set_source = _cyhal_clock_set_source_unsupported,
2513 };
2514 #endif
2515 #endif
2516
2517 static const cyhal_clock_funcs_t FUNCS_PERI =
2518 {
2519 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY),
2520 .is_enabled = _cyhal_clock_is_enabled_true,
2521 .set_enabled = _cyhal_clock_set_enabled_unsupported,
2522 .get_frequency = _cyhal_clock_get_frequency_peri,
2523 .set_frequency = _cyhal_clock_set_frequency_peri,
2524 .set_divider = _cyhal_clock_set_divider_peri,
2525 .get_sources = _cyhal_clock_get_sources_peri,
2526 .set_source = _cyhal_clock_set_source_unsupported,
2527 };
2528
2529 static const cyhal_clock_funcs_t FUNCS_PERIPHERAL =
2530 {
2531 .features = (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY),
2532 .is_enabled = _cyhal_clock_is_enabled_peripheral,
2533 .set_enabled = _cyhal_clock_set_enabled_peripheral,
2534 .get_frequency = _cyhal_clock_get_frequency_peripheral,
2535 .set_frequency = _cyhal_clock_set_frequency_peripheral,
2536 .set_divider = _cyhal_clock_set_divider_peripheral,
2537 .get_sources = _cyhal_clock_get_sources_peripheral,
2538 .set_source = _cyhal_clock_set_source_unsupported,
2539 };
2540
2541
2542 static const cyhal_clock_funcs_t FUNCS_EMPTY =
2543 {
2544 .features = CYHAL_CLOCK_FEATURE_NONE,
2545 .is_enabled = NULL,
2546 .set_enabled = NULL,
2547 .get_frequency = NULL,
2548 .set_frequency = NULL,
2549 .set_divider = NULL,
2550 .get_sources = NULL,
2551 .set_source = NULL,
2552 };
2553
_cyhal_clock_get_funcs_pathmux(void)2554 const void* _cyhal_clock_get_funcs_pathmux(void) { return &FUNCS_PATHMUX; }
2555 #if (SRSS_NUM_PLL > 0)
_cyhal_clock_get_funcs_pll(void)2556 const void* _cyhal_clock_get_funcs_pll(void) { return &FUNCS_PLL; }
2557 #endif
2558 // HF and peripheral functions are called directly from the public APIs and do not go through
2559 // the struct lookup. This allows them to get optimized out based on what the user calls. We
2560 // return FUNCS_EMPTY here so as to avoid unnecessarily pulling in all functions for those clocks.
_cyhal_clock_get_funcs_hf(void)2561 const void* _cyhal_clock_get_funcs_hf(void) { return &FUNCS_EMPTY/*FUNCS_HF*/; }
_cyhal_clock_get_funcs_peripheral(void)2562 const void* _cyhal_clock_get_funcs_peripheral(void) { return &FUNCS_EMPTY/*FUNCS_PERIPHERAL*/; }
2563
_cyhal_clock_get_funcs_all(cyhal_clock_block_t block)2564 static const cyhal_clock_funcs_t* _cyhal_clock_get_funcs_all(cyhal_clock_block_t block)
2565 {
2566 switch (block)
2567 {
2568 case CYHAL_CLOCK_BLOCK_IMO:
2569 return &FUNCS_IMO;
2570 #if SRSS_ECO_PRESENT
2571 case CYHAL_CLOCK_BLOCK_ECO:
2572 return &FUNCS_ECO;
2573 #endif
2574 case CYHAL_CLOCK_BLOCK_EXT:
2575 return &FUNCS_EXT;
2576 #if SRSS_ALTHF_PRESENT
2577 case CYHAL_CLOCK_BLOCK_ALTHF:
2578 return &FUNCS_ALTHF;
2579 #endif
2580 #if SRSS_ALTLF_PRESENT
2581 case CYHAL_CLOCK_BLOCK_ALTLF:
2582 return &FUNCS_ALTLF;
2583 #endif
2584 case CYHAL_CLOCK_BLOCK_ILO:
2585 return &FUNCS_ILO;
2586 #if _CYHAL_SRSS_PILO_PRESENT
2587 case CYHAL_CLOCK_BLOCK_PILO:
2588 return &FUNCS_PILO;
2589 #endif
2590 case CYHAL_CLOCK_BLOCK_WCO:
2591 return &FUNCS_WCO;
2592 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
2593 case CYHAL_CLOCK_BLOCK_MFO:
2594 return &FUNCS_MFO;
2595 #endif
2596 case CYHAL_CLOCK_BLOCK_PATHMUX:
2597 return &FUNCS_PATHMUX;
2598 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
2599 case CYHAL_CLOCK_BLOCK_FLL:
2600 return &FUNCS_FLL;
2601 #endif
2602 case CYHAL_CLOCK_BLOCK_LF:
2603 return &FUNCS_LF;
2604 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
2605 case CYHAL_CLOCK_BLOCK_MF:
2606 return &FUNCS_MF;
2607 #endif
2608 case CYHAL_CLOCK_BLOCK_HF:
2609 return &FUNCS_HF;
2610 case CYHAL_CLOCK_BLOCK_PUMP:
2611 return &FUNCS_PUMP;
2612 case CYHAL_CLOCK_BLOCK_BAK:
2613 return &FUNCS_BAK;
2614 case CYHAL_CLOCK_BLOCK_ALT_SYS_TICK:
2615 return &FUNCS_ALT_SYS_TICK;
2616 case CYHAL_CLOCK_BLOCK_PERI:
2617 return &FUNCS_PERI;
2618 #if defined(COMPONENT_CAT1A)
2619 #if (SRSS_NUM_PLL > 0)
2620 case CYHAL_CLOCK_BLOCK_PLL:
2621 return &FUNCS_PLL;
2622 #endif
2623 case CYHAL_CLOCK_BLOCK_TIMER:
2624 return &FUNCS_TIMER;
2625 case CYHAL_CLOCK_BLOCK_FAST:
2626 return &FUNCS_FAST;
2627 case CYHAL_CLOCK_BLOCK_SLOW:
2628 return &FUNCS_SLOW;
2629 #elif defined(COMPONENT_CAT1B)
2630 case CYHAL_CLOCK_BLOCK_IHO:
2631 return &FUNCS_IHO;
2632 #if (SRSS_NUM_PLL > 0)
2633 case CYHAL_CLOCK_BLOCK_PLL200:
2634 case CYHAL_CLOCK_BLOCK_PLL400:
2635 return &FUNCS_PLL;
2636 #endif
2637 #if SRSS_ECO_PRESENT
2638 case CYHAL_CLOCK_BLOCK_ECO_PRESCALER:
2639 return &FUNCS_ECO_PRESCALER;
2640 #endif
2641 #if SRSS_BACKUP_S40E_LPECO_PRESENT
2642 case CY_SYSCLK_CLKLF_IN_LPECO_PRESCALER:
2643 return &FUNCS_LPECO_PRESCALER;
2644 #endif
2645 #endif
2646 default:
2647 return &FUNCS_PERIPHERAL;
2648 }
2649 }
2650
2651
2652
2653 #define _CYHAL_CLOCK_CREATE(x,y) { .block = (CYHAL_CLOCK_BLOCK_##x), .channel = (y), .reserved = false, .funcs = &(FUNCS_##x) }
2654
2655 const cyhal_clock_t CYHAL_CLOCK_IMO = _CYHAL_CLOCK_CREATE(IMO, 0);
2656 const cyhal_clock_t CYHAL_CLOCK_EXT = _CYHAL_CLOCK_CREATE(EXT, 0);
2657 const cyhal_clock_t CYHAL_CLOCK_ILO = _CYHAL_CLOCK_CREATE(ILO, 0);
2658 const cyhal_clock_t CYHAL_CLOCK_LF = _CYHAL_CLOCK_CREATE(LF, 0);
2659 const cyhal_clock_t CYHAL_CLOCK_PUMP = _CYHAL_CLOCK_CREATE(PUMP, 0);
2660 const cyhal_clock_t CYHAL_CLOCK_BAK = _CYHAL_CLOCK_CREATE(BAK, 0);
2661 const cyhal_clock_t CYHAL_CLOCK_ALT_SYS_TICK = _CYHAL_CLOCK_CREATE(ALT_SYS_TICK, 0);
2662
2663 const cyhal_clock_t CYHAL_CLOCK_PATHMUX[SRSS_NUM_CLKPATH] =
2664 {
2665 _CYHAL_CLOCK_CREATE(PATHMUX, 0),
2666 #if (SRSS_NUM_CLKPATH > 1)
2667 _CYHAL_CLOCK_CREATE(PATHMUX, 1),
2668 #endif
2669 #if (SRSS_NUM_CLKPATH > 2)
2670 _CYHAL_CLOCK_CREATE(PATHMUX, 2),
2671 #endif
2672 #if (SRSS_NUM_CLKPATH > 3)
2673 _CYHAL_CLOCK_CREATE(PATHMUX, 3),
2674 #endif
2675 #if (SRSS_NUM_CLKPATH > 4)
2676 _CYHAL_CLOCK_CREATE(PATHMUX, 4),
2677 #endif
2678 #if (SRSS_NUM_CLKPATH > 5)
2679 _CYHAL_CLOCK_CREATE(PATHMUX, 5),
2680 #endif
2681 #if (SRSS_NUM_CLKPATH > 6)
2682 _CYHAL_CLOCK_CREATE(PATHMUX, 6),
2683 #endif
2684 #if (SRSS_NUM_CLKPATH > 7)
2685 _CYHAL_CLOCK_CREATE(PATHMUX, 7),
2686 #endif
2687 #if (SRSS_NUM_CLKPATH > 8)
2688 _CYHAL_CLOCK_CREATE(PATHMUX, 8),
2689 #endif
2690 #if (SRSS_NUM_CLKPATH > 9)
2691 _CYHAL_CLOCK_CREATE(PATHMUX, 9),
2692 #endif
2693 #if (SRSS_NUM_CLKPATH > 10)
2694 _CYHAL_CLOCK_CREATE(PATHMUX, 10),
2695 #endif
2696 #if (SRSS_NUM_CLKPATH > 11)
2697 _CYHAL_CLOCK_CREATE(PATHMUX, 11),
2698 #endif
2699 #if (SRSS_NUM_CLKPATH > 12)
2700 _CYHAL_CLOCK_CREATE(PATHMUX, 12),
2701 #endif
2702 #if (SRSS_NUM_CLKPATH > 13)
2703 _CYHAL_CLOCK_CREATE(PATHMUX, 13),
2704 #endif
2705 #if (SRSS_NUM_CLKPATH > 14)
2706 _CYHAL_CLOCK_CREATE(PATHMUX, 14),
2707 #endif
2708 #if (SRSS_NUM_CLKPATH > 15)
2709 _CYHAL_CLOCK_CREATE(PATHMUX, 15),
2710 #endif
2711 };
2712
2713 const cyhal_clock_t CYHAL_CLOCK_HF[SRSS_NUM_HFROOT] =
2714 {
2715 _CYHAL_CLOCK_CREATE(HF, 0),
2716 #if (SRSS_NUM_HFROOT > 1)
2717 _CYHAL_CLOCK_CREATE(HF, 1),
2718 #endif
2719 #if (SRSS_NUM_HFROOT > 2)
2720 _CYHAL_CLOCK_CREATE(HF, 2),
2721 #endif
2722 #if (SRSS_NUM_HFROOT > 3)
2723 _CYHAL_CLOCK_CREATE(HF, 3),
2724 #endif
2725 #if (SRSS_NUM_HFROOT > 4)
2726 _CYHAL_CLOCK_CREATE(HF, 4),
2727 #endif
2728 #if (SRSS_NUM_HFROOT > 5)
2729 _CYHAL_CLOCK_CREATE(HF, 5),
2730 #endif
2731 #if (SRSS_NUM_HFROOT > 6)
2732 _CYHAL_CLOCK_CREATE(HF, 6),
2733 #endif
2734 #if (SRSS_NUM_HFROOT > 7)
2735 _CYHAL_CLOCK_CREATE(HF, 7),
2736 #endif
2737 #if (SRSS_NUM_HFROOT > 8)
2738 _CYHAL_CLOCK_CREATE(HF, 8),
2739 #endif
2740 #if (SRSS_NUM_HFROOT > 9)
2741 _CYHAL_CLOCK_CREATE(HF, 9),
2742 #endif
2743 #if (SRSS_NUM_HFROOT > 10)
2744 _CYHAL_CLOCK_CREATE(HF, 10),
2745 #endif
2746 #if (SRSS_NUM_HFROOT > 11)
2747 _CYHAL_CLOCK_CREATE(HF, 11),
2748 #endif
2749 #if (SRSS_NUM_HFROOT > 12)
2750 _CYHAL_CLOCK_CREATE(HF, 12),
2751 #endif
2752 #if (SRSS_NUM_HFROOT > 13)
2753 _CYHAL_CLOCK_CREATE(HF, 13),
2754 #endif
2755 #if (SRSS_NUM_HFROOT > 14)
2756 _CYHAL_CLOCK_CREATE(HF, 14),
2757 #endif
2758 #if (SRSS_NUM_HFROOT > 15)
2759 _CYHAL_CLOCK_CREATE(HF, 15),
2760 #endif
2761 };
2762
2763 #if SRSS_ECO_PRESENT
2764 const cyhal_clock_t CYHAL_CLOCK_ECO = _CYHAL_CLOCK_CREATE(ECO, 0);
2765 #endif
2766 #if SRSS_ALTHF_PRESENT
2767 const cyhal_clock_t CYHAL_CLOCK_ALTHF = _CYHAL_CLOCK_CREATE(ALTHF, 0);
2768 #endif
2769 #if SRSS_ALTLF_PRESENT
2770 const cyhal_clock_t CYHAL_CLOCK_ALTLF = _CYHAL_CLOCK_CREATE(ALTLF, 0);
2771 #endif
2772 #if _CYHAL_SRSS_PILO_PRESENT
2773 const cyhal_clock_t CYHAL_CLOCK_PILO = _CYHAL_CLOCK_CREATE(PILO, 0);
2774 #endif
2775 #if SRSS_BACKUP_PRESENT
2776 const cyhal_clock_t CYHAL_CLOCK_WCO = _CYHAL_CLOCK_CREATE(WCO, 0);
2777 #endif
2778 #if defined(COMPONENT_CAT1B) || (SRSS_MFO_PRESENT)
2779 const cyhal_clock_t CYHAL_CLOCK_MFO = _CYHAL_CLOCK_CREATE(MFO, 0);
2780 const cyhal_clock_t CYHAL_CLOCK_MF = _CYHAL_CLOCK_CREATE(MF, 0);
2781 #endif
2782
2783 #if defined(COMPONENT_CAT1A) || (SRSS_FLL_PRESENT)
2784 const cyhal_clock_t CYHAL_CLOCK_FLL = _CYHAL_CLOCK_CREATE(FLL, 0);
2785 #endif
2786
2787 #if defined(COMPONENT_CAT1A)
2788 const cyhal_clock_t CYHAL_CLOCK_FAST = _CYHAL_CLOCK_CREATE(FAST, 0);
2789 const cyhal_clock_t CYHAL_CLOCK_PERI = _CYHAL_CLOCK_CREATE(PERI, 0);
2790 const cyhal_clock_t CYHAL_CLOCK_TIMER = _CYHAL_CLOCK_CREATE(TIMER, 0);
2791 const cyhal_clock_t CYHAL_CLOCK_SLOW = _CYHAL_CLOCK_CREATE(SLOW, 0);
2792
2793 #if (SRSS_NUM_PLL > 0)
2794 const cyhal_clock_t CYHAL_CLOCK_PLL[SRSS_NUM_PLL] =
2795 {
2796 _CYHAL_CLOCK_CREATE(PLL, 0),
2797 #if (SRSS_NUM_PLL > 1)
2798 _CYHAL_CLOCK_CREATE(PLL, 1),
2799 #endif
2800 #if (SRSS_NUM_PLL > 2)
2801 _CYHAL_CLOCK_CREATE(PLL, 2),
2802 #endif
2803 #if (SRSS_NUM_PLL > 3)
2804 _CYHAL_CLOCK_CREATE(PLL, 3),
2805 #endif
2806 #if (SRSS_NUM_PLL > 4)
2807 _CYHAL_CLOCK_CREATE(PLL, 4),
2808 #endif
2809 #if (SRSS_NUM_PLL > 5)
2810 _CYHAL_CLOCK_CREATE(PLL, 5),
2811 #endif
2812 #if (SRSS_NUM_PLL > 6)
2813 _CYHAL_CLOCK_CREATE(PLL, 6),
2814 #endif
2815 #if (SRSS_NUM_PLL > 7)
2816 _CYHAL_CLOCK_CREATE(PLL, 7),
2817 #endif
2818 #if (SRSS_NUM_PLL > 8)
2819 _CYHAL_CLOCK_CREATE(PLL, 8),
2820 #endif
2821 #if (SRSS_NUM_PLL > 9)
2822 _CYHAL_CLOCK_CREATE(PLL, 9),
2823 #endif
2824 #if (SRSS_NUM_PLL > 10)
2825 _CYHAL_CLOCK_CREATE(PLL, 10),
2826 #endif
2827 #if (SRSS_NUM_PLL > 11)
2828 _CYHAL_CLOCK_CREATE(PLL, 11),
2829 #endif
2830 #if (SRSS_NUM_PLL > 12)
2831 _CYHAL_CLOCK_CREATE(PLL, 12),
2832 #endif
2833 #if (SRSS_NUM_PLL > 13)
2834 _CYHAL_CLOCK_CREATE(PLL, 13),
2835 #endif
2836 #if (SRSS_NUM_PLL > 14)
2837 _CYHAL_CLOCK_CREATE(PLL, 14),
2838 #endif
2839 };
2840 #endif
2841
2842 #elif defined(COMPONENT_CAT1B)
2843 const cyhal_clock_t CYHAL_CLOCK_IHO = _CYHAL_CLOCK_CREATE(IHO, 0);
2844 #if SRSS_ECO_PRESENT
2845 const cyhal_clock_t CYHAL_CLOCK_ECO_PRESCALER = _CYHAL_CLOCK_CREATE(ECO_PRESCALER, 0);
2846 #endif
2847 #if SRSS_BACKUP_S40E_LPECO_PRESENT
2848 const cyhal_clock_t CYHAL_CLOCK_LPECO_PRESCALER = _CYHAL_CLOCK_CREATE(LPECO_PRESCALER, 0);
2849 #endif
2850
2851 const cyhal_clock_t CYHAL_CLOCK_PERI[CY_PERI_GROUP_NR] =
2852 {
2853 _CYHAL_CLOCK_CREATE(PERI, 0),
2854 #if (CY_PERI_GROUP_NR > 1)
2855 _CYHAL_CLOCK_CREATE(PERI, 1),
2856 #endif
2857 #if (CY_PERI_GROUP_NR > 2)
2858 _CYHAL_CLOCK_CREATE(PERI, 2),
2859 #endif
2860 #if (CY_PERI_GROUP_NR > 3)
2861 _CYHAL_CLOCK_CREATE(PERI, 3),
2862 #endif
2863 #if (CY_PERI_GROUP_NR > 4)
2864 _CYHAL_CLOCK_CREATE(PERI, 4),
2865 #endif
2866 #if (CY_PERI_GROUP_NR > 5)
2867 _CYHAL_CLOCK_CREATE(PERI, 5),
2868 #endif
2869 #if (CY_PERI_GROUP_NR > 6)
2870 _CYHAL_CLOCK_CREATE(PERI, 6),
2871 #endif
2872 #if (CY_PERI_GROUP_NR > 7)
2873 _CYHAL_CLOCK_CREATE(PERI, 7),
2874 #endif
2875 #if (CY_PERI_GROUP_NR > 8)
2876 _CYHAL_CLOCK_CREATE(PERI, 8),
2877 #endif
2878 #if (CY_PERI_GROUP_NR > 9)
2879 _CYHAL_CLOCK_CREATE(PERI, 9),
2880 #endif
2881 #if (CY_PERI_GROUP_NR > 10)
2882 _CYHAL_CLOCK_CREATE(PERI, 10),
2883 #endif
2884 #if (CY_PERI_GROUP_NR > 11)
2885 _CYHAL_CLOCK_CREATE(PERI, 11),
2886 #endif
2887 #if (CY_PERI_GROUP_NR > 12)
2888 _CYHAL_CLOCK_CREATE(PERI, 12),
2889 #endif
2890 #if (CY_PERI_GROUP_NR > 13)
2891 _CYHAL_CLOCK_CREATE(PERI, 13),
2892 #endif
2893 #if (CY_PERI_GROUP_NR > 14)
2894 _CYHAL_CLOCK_CREATE(PERI, 14),
2895 #endif
2896 #if (CY_PERI_GROUP_NR > 15)
2897 _CYHAL_CLOCK_CREATE(PERI, 15),
2898 #endif
2899 };
2900
2901 #if (SRSS_NUM_PLL200M > 0)
2902 const cyhal_clock_t CYHAL_CLOCK_PLL[SRSS_NUM_PLL200M] =
2903 {
2904 _CYHAL_CLOCK_CREATE(PLL200, 0),
2905 #if (SRSS_NUM_PLL200M > 1)
2906 _CYHAL_CLOCK_CREATE(PLL200, 1),
2907 #endif
2908 #if (SRSS_NUM_PLL200M > 2)
2909 _CYHAL_CLOCK_CREATE(PLL200, 2),
2910 #endif
2911 #if (SRSS_NUM_PLL200M > 3)
2912 _CYHAL_CLOCK_CREATE(PLL200, 3),
2913 #endif
2914 #if (SRSS_NUM_PLL200M > 4)
2915 _CYHAL_CLOCK_CREATE(PLL200, 4),
2916 #endif
2917 #if (SRSS_NUM_PLL200M > 5)
2918 _CYHAL_CLOCK_CREATE(PLL200, 5),
2919 #endif
2920 #if (SRSS_NUM_PLL200M > 6)
2921 _CYHAL_CLOCK_CREATE(PLL200, 6),
2922 #endif
2923 #if (SRSS_NUM_PLL200M > 7)
2924 _CYHAL_CLOCK_CREATE(PLL200, 7),
2925 #endif
2926 #if (SRSS_NUM_PLL200M > 8)
2927 _CYHAL_CLOCK_CREATE(PLL200, 8),
2928 #endif
2929 #if (SRSS_NUM_PLL200M > 9)
2930 _CYHAL_CLOCK_CREATE(PLL200, 9),
2931 #endif
2932 #if (SRSS_NUM_PLL200M > 10)
2933 _CYHAL_CLOCK_CREATE(PLL200, 10),
2934 #endif
2935 #if (SRSS_NUM_PLL200M > 11)
2936 _CYHAL_CLOCK_CREATE(PLL200, 11),
2937 #endif
2938 #if (SRSS_NUM_PLL200M > 12)
2939 _CYHAL_CLOCK_CREATE(PLL200, 12),
2940 #endif
2941 #if (SRSS_NUM_PLL200M > 13)
2942 _CYHAL_CLOCK_CREATE(PLL200, 13),
2943 #endif
2944 #if (SRSS_NUM_PLL200M > 14)
2945 _CYHAL_CLOCK_CREATE(PLL200, 14),
2946 #endif
2947 };
2948 #endif
2949
2950 #if (SRSS_NUM_PLL400M > 0)
2951 const cyhal_clock_t CYHAL_CLOCK_PLL[SRSS_NUM_PLL400M] =
2952 {
2953 _CYHAL_CLOCK_CREATE(PLL400, 0),
2954 #if (SRSS_NUM_PLL400M > 1)
2955 _CYHAL_CLOCK_CREATE(PLL400, 1),
2956 #endif
2957 #if (SRSS_NUM_PLL400M > 2)
2958 _CYHAL_CLOCK_CREATE(PLL400, 2),
2959 #endif
2960 #if (SRSS_NUM_PLL400M > 3)
2961 _CYHAL_CLOCK_CREATE(PLL400, 3),
2962 #endif
2963 #if (SRSS_NUM_PLL400M > 4)
2964 _CYHAL_CLOCK_CREATE(PLL400, 4),
2965 #endif
2966 #if (SRSS_NUM_PLL400M > 5)
2967 _CYHAL_CLOCK_CREATE(PLL400, 5),
2968 #endif
2969 #if (SRSS_NUM_PLL400M > 6)
2970 _CYHAL_CLOCK_CREATE(PLL400, 6),
2971 #endif
2972 #if (SRSS_NUM_PLL400M > 7)
2973 _CYHAL_CLOCK_CREATE(PLL400, 7),
2974 #endif
2975 #if (SRSS_NUM_PLL400M > 8)
2976 _CYHAL_CLOCK_CREATE(PLL400, 8),
2977 #endif
2978 #if (SRSS_NUM_PLL400M > 9)
2979 _CYHAL_CLOCK_CREATE(PLL400, 9),
2980 #endif
2981 #if (SRSS_NUM_PLL400M > 10)
2982 _CYHAL_CLOCK_CREATE(PLL400, 10),
2983 #endif
2984 #if (SRSS_NUM_PLL400M > 11)
2985 _CYHAL_CLOCK_CREATE(PLL400, 11),
2986 #endif
2987 #if (SRSS_NUM_PLL400M > 12)
2988 _CYHAL_CLOCK_CREATE(PLL400, 12),
2989 #endif
2990 #if (SRSS_NUM_PLL400M > 13)
2991 _CYHAL_CLOCK_CREATE(PLL400, 13),
2992 #endif
2993 #if (SRSS_NUM_PLL400M > 14)
2994 _CYHAL_CLOCK_CREATE(PLL400, 14),
2995 #endif
2996 };
2997 #endif
2998 #endif
2999
3000
3001
3002 /******************************************************************************
3003 **************************** Public API (clocks) *****************************
3004 *****************************************************************************/
3005
_cyhal_clock_allocate_channel(cyhal_clock_t * clock,cyhal_clock_block_t block,const void * funcs)3006 cy_rslt_t _cyhal_clock_allocate_channel(cyhal_clock_t *clock, cyhal_clock_block_t block, const void* funcs)
3007 {
3008 uint8_t maxChannels = (uint8_t)_cyhal_utils_get_clock_count(block);
3009 for (uint8_t i = 0; i < maxChannels; i++)
3010 {
3011 cyhal_resource_inst_t clock_resource = { CYHAL_RSC_CLOCK, block, i };
3012 if (CY_RSLT_SUCCESS == cyhal_hwmgr_reserve(&clock_resource))
3013 {
3014 clock->block = block;
3015 clock->channel = i;
3016 clock->reserved = true;
3017 clock->funcs = funcs;
3018 return CY_RSLT_SUCCESS;
3019 }
3020 }
3021 return CYHAL_HWMGR_RSLT_ERR_NONE_FREE;
3022 }
3023
cyhal_clock_get(cyhal_clock_t * clock,const cyhal_resource_inst_t * resource)3024 cy_rslt_t cyhal_clock_get(cyhal_clock_t *clock, const cyhal_resource_inst_t *resource)
3025 {
3026 CY_ASSERT(NULL != clock);
3027 CY_ASSERT(NULL != resource);
3028 CY_ASSERT(CYHAL_RSC_CLOCK == resource->type);
3029
3030 clock->block = (cyhal_clock_block_t)resource->block_num;
3031 clock->channel = resource->channel_num;
3032 clock->reserved = false;
3033 clock->funcs = _cyhal_clock_get_funcs_all((cyhal_clock_block_t)resource->block_num);
3034
3035 return CY_RSLT_SUCCESS;
3036 }
3037
cyhal_clock_reserve(cyhal_clock_t * clock,const cyhal_clock_t * clock_)3038 cy_rslt_t cyhal_clock_reserve(cyhal_clock_t *clock, const cyhal_clock_t *clock_)
3039 {
3040 CY_ASSERT(NULL != clock);
3041 CY_ASSERT(NULL != clock_);
3042
3043 cyhal_resource_inst_t clock_resource = { CYHAL_RSC_CLOCK, clock_->block, clock_->channel };
3044 cy_rslt_t rslt = cyhal_hwmgr_reserve(&clock_resource);
3045 if (CY_RSLT_SUCCESS == rslt)
3046 {
3047 memcpy(clock, clock_, sizeof(cyhal_clock_t));
3048 clock->reserved = true;
3049 }
3050 return rslt;
3051 }
3052
cyhal_clock_get_features(const cyhal_clock_t * clock)3053 cyhal_clock_feature_t cyhal_clock_get_features(const cyhal_clock_t *clock)
3054 {
3055 CY_ASSERT(NULL != clock);
3056
3057 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3058 {
3059 return (clock->channel == 0) // HF0 cannot be disabled
3060 ? (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_SOURCE | CYHAL_CLOCK_FEATURE_DIVIDER)
3061 : (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_SOURCE | CYHAL_CLOCK_FEATURE_DIVIDER);
3062 }
3063 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3064 return (cyhal_clock_feature_t)(CYHAL_CLOCK_FEATURE_ENABLE | CYHAL_CLOCK_FEATURE_DIVIDER | CYHAL_CLOCK_FEATURE_FREQUENCY);
3065 else
3066 return ((cyhal_clock_funcs_t*)clock->funcs)->features;
3067 }
3068
cyhal_clock_is_enabled(const cyhal_clock_t * clock)3069 bool cyhal_clock_is_enabled(const cyhal_clock_t *clock)
3070 {
3071 CY_ASSERT(NULL != clock);
3072
3073 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3074 return _cyhal_clock_is_enabled_hf(clock);
3075 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3076 return _cyhal_clock_is_enabled_peripheral(clock);
3077 else
3078 return ((cyhal_clock_funcs_t*)clock->funcs)->is_enabled(clock);
3079 }
3080
cyhal_clock_set_enabled(cyhal_clock_t * clock,bool enabled,bool wait_for_lock)3081 cy_rslt_t cyhal_clock_set_enabled(cyhal_clock_t *clock, bool enabled, bool wait_for_lock)
3082 {
3083 CY_ASSERT(NULL != clock);
3084
3085 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3086 return _cyhal_clock_set_enabled_hf(clock, enabled, wait_for_lock);
3087 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3088 return _cyhal_clock_set_enabled_peripheral(clock, enabled, wait_for_lock);
3089 else
3090 return ((cyhal_clock_funcs_t*)clock->funcs)->set_enabled(clock, enabled, wait_for_lock);
3091 }
3092
cyhal_clock_get_frequency(const cyhal_clock_t * clock)3093 uint32_t cyhal_clock_get_frequency(const cyhal_clock_t *clock)
3094 {
3095 CY_ASSERT(NULL != clock);
3096
3097 if (cyhal_clock_is_enabled(clock))
3098 {
3099 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3100 return _cyhal_clock_get_frequency_hf(clock);
3101 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3102 return _cyhal_clock_get_frequency_peripheral(clock);
3103 else
3104 return ((cyhal_clock_funcs_t*)clock->funcs)->get_frequency(clock);
3105 }
3106 return 0;
3107 }
3108
cyhal_clock_set_frequency(cyhal_clock_t * clock,uint32_t hz,const cyhal_clock_tolerance_t * tolerance)3109 cy_rslt_t cyhal_clock_set_frequency(cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance)
3110 {
3111 CY_ASSERT(NULL != clock);
3112
3113 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3114 return _cyhal_clock_set_frequency_unsupported(clock, hz, tolerance);
3115 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3116 return _cyhal_clock_set_frequency_peripheral(clock, hz, tolerance);
3117 else
3118 return ((cyhal_clock_funcs_t*)clock->funcs)->set_frequency(clock, hz, tolerance);
3119 }
3120
cyhal_clock_set_divider(cyhal_clock_t * clock,uint32_t divider)3121 cy_rslt_t cyhal_clock_set_divider(cyhal_clock_t *clock, uint32_t divider)
3122 {
3123 CY_ASSERT(NULL != clock);
3124
3125 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3126 return _cyhal_clock_set_divider_hf(clock, divider);
3127 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3128 return _cyhal_clock_set_divider_peripheral(clock, divider);
3129 else
3130 return ((cyhal_clock_funcs_t*)clock->funcs)->set_divider(clock, divider);
3131 }
3132
cyhal_clock_get_sources(const cyhal_clock_t * clock,const cyhal_resource_inst_t ** sources[],uint32_t * count)3133 cy_rslt_t cyhal_clock_get_sources(const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count)
3134 {
3135 CY_ASSERT(NULL != clock);
3136
3137 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3138 return _cyhal_clock_get_sources_hf(clock, sources, count);
3139 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3140 return _cyhal_clock_get_sources_peripheral(clock, sources, count);
3141 else
3142 return ((cyhal_clock_funcs_t*)clock->funcs)->get_sources(clock, sources, count);
3143 }
3144
cyhal_clock_set_source(cyhal_clock_t * clock,const cyhal_clock_t * source)3145 cy_rslt_t cyhal_clock_set_source(cyhal_clock_t *clock, const cyhal_clock_t *source)
3146 {
3147 CY_ASSERT(NULL != clock && NULL != source);
3148
3149 if (clock->block == CYHAL_CLOCK_BLOCK_HF)
3150 return _cyhal_clock_set_source_hf(clock, source);
3151 else if (clock->block < 4 * _CYHAL_CLOCK_PERI_GROUPS)
3152 return _cyhal_clock_set_source_unsupported(clock, source);
3153 else
3154 return ((cyhal_clock_funcs_t*)clock->funcs)->set_source(clock, source);
3155 }
3156
cyhal_clock_free(cyhal_clock_t * clock)3157 void cyhal_clock_free(cyhal_clock_t *clock)
3158 {
3159 CY_ASSERT(NULL != clock);
3160 CY_ASSERT(clock->reserved);
3161
3162 cyhal_resource_inst_t rsc = { CYHAL_RSC_CLOCK, clock->block, clock->channel };
3163 cyhal_hwmgr_free(&rsc);
3164 clock->reserved = false;
3165 }
3166
3167 #if defined(__cplusplus)
3168 }
3169 #endif
3170
3171 #endif // CYHAL_DRIVER_AVAILABLE_CLOCK
3172