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