1 /*
2 * Copyright 2020-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 /**
7 * @file Clock_Ip.c
8 * @version 2.0.0
9 *
10 * @brief CLOCK driver implementations.
11 * @details CLOCK driver implementations.
12 *
13 * @addtogroup CLOCK_DRIVER Clock Ip Driver
14 * @{
15 */
16
17 #ifdef __cplusplus
18 extern "C"{
19 #endif
20
21
22 /*==================================================================================================
23 * INCLUDE FILES
24 * 1) system and project includes
25 * 2) needed interfaces from external units
26 * 3) internal and external interfaces from this unit
27 ==================================================================================================*/
28
29 #include "Clock_Ip_Private.h"
30 #include "OsIf.h"
31
32 /*==================================================================================================
33 SOURCE FILE VERSION INFORMATION
34 ==================================================================================================*/
35 #define CLOCK_IP_VENDOR_ID_C 43
36 #define CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C 4
37 #define CLOCK_IP_AR_RELEASE_MINOR_VERSION_C 7
38 #define CLOCK_IP_AR_RELEASE_REVISION_VERSION_C 0
39 #define CLOCK_IP_SW_MAJOR_VERSION_C 2
40 #define CLOCK_IP_SW_MINOR_VERSION_C 0
41 #define CLOCK_IP_SW_PATCH_VERSION_C 0
42
43 /*==================================================================================================
44 * FILE VERSION CHECKS
45 ==================================================================================================*/
46 /* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same vendor */
47 #if (CLOCK_IP_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID)
48 #error "Clock_Ip.c and Clock_Ip_Private.h have different vendor ids"
49 #endif
50
51 /* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same Autosar version */
52 #if ((CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
53 (CLOCK_IP_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
54 (CLOCK_IP_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
55 )
56 #error "AutoSar Version Numbers of Clock_Ip.c and Clock_Ip_Private.h are different"
57 #endif
58
59 /* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same Software version */
60 #if ((CLOCK_IP_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \
61 (CLOCK_IP_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \
62 (CLOCK_IP_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \
63 )
64 #error "Software Version Numbers of Clock_Ip.c and Clock_Ip_Private.h are different"
65 #endif
66
67 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
68 /* Check if Clock_Ip.c file and OsIf.h file are of the same Autosar version */
69 #if ((CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
70 (CLOCK_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION))
71 #error "AutoSar Version Numbers of Clock_Ip.c and OsIf.h are different"
72 #endif
73 #endif
74
75 /*==================================================================================================
76 * LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
77 ==================================================================================================*/
78
79 /*!
80 * @brief Clock ip driver context
81 */
82 typedef struct
83 {
84 boolean ClockTreeIsConsumingPll; /**< Clock tree is using a PLL output. */
85 boolean WaitStatesAreSupported; /**< Wait states are supported. */
86 uint8 HwPllsNo; /**< Number of plls . */
87 uint8 HwDfsNo; /**< Number of fractional dividers . */
88
89 } Clock_Ip_DriverContextType;
90
91 /*==================================================================================================
92 * LOCAL MACROS
93 ==================================================================================================*/
94 #define CLOCK_IP_WAIT_STATES_DELAY 0XEFFFFFFFU
95
96 /*==================================================================================================
97 * LOCAL CONSTANTS
98 ==================================================================================================*/
99 /* Clock start initialized section data */
100 #define MCU_START_SEC_VAR_CLEARED_UNSPECIFIED
101 #include "Mcu_MemMap.h"
102
103 #if !((CLOCK_IP_CMU_INFO_SIZE > 0U) || defined(CLOCK_IP_CGU_INTERRUPT))
104 static const Clock_Ip_ClockConfigType *Clock_Ip_pxConfig; /* Reference to the current clock configuration */
105 #endif
106
107 /* Clock stop initialized section data */
108 #define MCU_STOP_SEC_VAR_CLEARED_UNSPECIFIED
109 #include "Mcu_MemMap.h"
110 /*==================================================================================================
111 * LOCAL VARIABLES
112 ==================================================================================================*/
113 /* Clock start initialized section data */
114 #define MCU_START_SEC_VAR_CLEARED_BOOLEAN
115 #include "Mcu_MemMap.h"
116
117 static boolean FunctionWasCalled;
118
119 /* Clock stop initialized section data */
120 #define MCU_STOP_SEC_VAR_CLEARED_BOOLEAN
121 #include "Mcu_MemMap.h"
122
123 /* Clock start initialized section data */
124 #define MCU_START_SEC_VAR_CLEARED_UNSPECIFIED
125 #include "Mcu_MemMap.h"
126
127 static Clock_Ip_DriverContextType DriverContext;
128
129 /* Clock stop initialized section data */
130 #define MCU_STOP_SEC_VAR_CLEARED_UNSPECIFIED
131 #include "Mcu_MemMap.h"
132 /*==================================================================================================
133 * GLOBAL CONSTANTS
134 ==================================================================================================*/
135
136 /*==================================================================================================
137 * GLOBAL VARIABLES
138 ==================================================================================================*/
139 /* Clock start initialized section data */
140 #define MCU_START_SEC_VAR_CLEARED_UNSPECIFIED
141 #include "Mcu_MemMap.h"
142
143 #if (CLOCK_IP_CMU_INFO_SIZE > 0U) || defined(CLOCK_IP_CGU_INTERRUPT)
144 const Clock_Ip_ClockConfigType *Clock_Ip_pxConfig; /* Reference to the current clock configuration */
145 #endif
146
147 /* Clock stop initialized section data */
148 #define MCU_STOP_SEC_VAR_CLEARED_UNSPECIFIED
149 #include "Mcu_MemMap.h"
150
151 /* Clock start initialized section data */
152 #define MCU_START_SEC_VAR_INIT_BOOLEAN
153 #include "Mcu_MemMap.h"
154
155 boolean Clock_Ip_bSentFromUpdateDriverContext = TRUE;
156
157 /* Clock stop initialized section data */
158 #define MCU_STOP_SEC_VAR_INIT_BOOLEAN
159 #include "Mcu_MemMap.h"
160
161 #if CLOCK_IP_CONFIGURED_FREQUENCIES_COUNT > 0U
162
163 /* Clock start initialized section data */
164 #define MCU_START_SEC_VAR_CLEARED_8
165 #include "Mcu_MemMap.h"
166
167 uint8 Clock_Ip_FreqIds[CLOCK_IP_FEATURE_NAMES_NO];
168
169 /* Clock stop initialized section data */
170 #define MCU_STOP_SEC_VAR_CLEARED_8
171 #include "Mcu_MemMap.h"
172
173 #endif /* CLOCK_IP_CONFIGURED_FREQUENCIES_COUNT > 0U */
174 /*==================================================================================================
175 * LOCAL FUNCTION PROTOTYPES
176 ==================================================================================================*/
177
178 #define MCU_START_SEC_CODE
179 #include "Mcu_MemMap.h"
180
181 static void Clock_Ip_NotificatonsEmptyCallback(Clock_Ip_NotificationType Notification, Clock_Ip_NameType ClockName);
182 static void Clock_Ip_ResetClockConfiguration(Clock_Ip_ClockConfigType const * Config);
183 static void Clock_Ip_UpdateDriverContext(Clock_Ip_ClockConfigType const * Config);
184 static void Clock_Ip_CallEmptyCallbacks(void);
185 static void Clock_Ip_SetWaitStates(void);
186
187 #if (defined(CLOCK_IP_DEV_ERROR_DETECT) && (CLOCK_IP_DEV_ERROR_DETECT == STD_ON))
188 static void Clock_Ip_CheckClockConfiguration(Clock_Ip_ClockConfigType const * Config);
189 static void Clock_Ip_CheckIrcoscClocks(Clock_Ip_ClockConfigType const * Config);
190 static void Clock_Ip_CheckXoscClocks(Clock_Ip_ClockConfigType const * Config);
191 static void Clock_Ip_CheckPllClocks(Clock_Ip_ClockConfigType const * Config);
192 static void Clock_Ip_CheckExtSigClocks(Clock_Ip_ClockConfigType const * Config);
193 static void Clock_Ip_CheckSelectorClocks(Clock_Ip_ClockConfigType const * Config);
194 static void Clock_Ip_CheckDividerClocks(Clock_Ip_ClockConfigType const * Config);
195 static void Clock_Ip_CheckDividerTriggerClocks(Clock_Ip_ClockConfigType const * Config);
196 static void Clock_Ip_CheckFracDividerClocks(Clock_Ip_ClockConfigType const * Config);
197 static void Clock_Ip_CheckGateClocks(Clock_Ip_ClockConfigType const * Config);
198 static void Clock_Ip_CheckPcfsClocks(Clock_Ip_ClockConfigType const * Config);
199 static void Clock_Ip_CheckCmuClocks(Clock_Ip_ClockConfigType const * Config);
200 #endif
201
202 /* Clock Report Error Callback */
203 static Clock_Ip_NotificationsCallbackType Clock_Ip_pfkNotificationsCallback = Clock_Ip_NotificatonsEmptyCallback;
204
205 #define MCU_STOP_SEC_CODE
206 #include "Mcu_MemMap.h"
207
208 /*==================================================================================================
209 * LOCAL VARIABLES
210 ==================================================================================================*/
211
212 /*==================================================================================================
213 * LOCAL FUNCTIONS
214 ==================================================================================================*/
215
216 /* Clock start section code */
217 #define MCU_START_SEC_CODE
218
219 #include "Mcu_MemMap.h"
220
221 /*FUNCTION**********************************************************************
222 *
223 * Function Name : Clock_Ip_NotificatonsEmptyCallback.
224 * Description : Notification clock call back.
225 *
226 *END**************************************************************************/
Clock_Ip_NotificatonsEmptyCallback(Clock_Ip_NotificationType Notification,Clock_Ip_NameType ClockName)227 static void Clock_Ip_NotificatonsEmptyCallback( Clock_Ip_NotificationType Notification,
228 Clock_Ip_NameType ClockName
229 )
230 {
231 /* No implementation */
232 (void)Notification;
233 (void)ClockName;
234 }
235
236 /*FUNCTION**********************************************************************
237 *
238 * Function Name : Clock_Ip_UpdateDriverContext.
239 * Description : Updates context of the driver, internal memory, clock objects.
240 *
241 *END**************************************************************************/
Clock_Ip_UpdateDriverContext(Clock_Ip_ClockConfigType const * Config)242 static void Clock_Ip_UpdateDriverContext(Clock_Ip_ClockConfigType const * Config)
243 {
244 uint8 Index;
245 (void)Config;
246 Clock_Ip_bSentFromUpdateDriverContext = TRUE;
247 /* Initialize clock objects */
248 Clock_Ip_Command(Clock_Ip_pxConfig, CLOCK_IP_INITIALIZE_CLOCK_OBJECTS_COMMAND);
249
250 for (Index = 0U; Index < Config->ExtClksCount; Index++) /* Set external signal frequency. */
251 {
252 Clock_Ip_SetExternalSignalFrequency(Config->ExtClks[Index].Name, Config->ExtClks[Index].Value);
253 }
254
255 /* Call empty callbacks */
256 Clock_Ip_CallEmptyCallbacks();
257
258 #if CLOCK_IP_CONFIGURED_FREQUENCIES_COUNT > 0U
259
260 for (Index = 1U; Index < Config->ConfigureFrequenciesCount; Index++)
261 {
262 Clock_Ip_FreqIds[Config->ConfiguredFrequencies[Index].Name] = Index;
263 }
264
265 #endif /* CLOCK_IP_CONFIGURED_FREQUENCIES_COUNT > 0U */
266 }
267
268 #if (defined(CLOCK_IP_DEV_ERROR_DETECT))
269 #if (CLOCK_IP_DEV_ERROR_DETECT == STD_ON)
270 /*FUNCTION**********************************************************************
271 *
272 * Function Name : Clock_Ip_CheckIrcoscClocks
273 * Description : Checks clock names from ircoscs array
274 *
275 *END**************************************************************************/
Clock_Ip_CheckIrcoscClocks(Clock_Ip_ClockConfigType const * Config)276 static void Clock_Ip_CheckIrcoscClocks(Clock_Ip_ClockConfigType const * Config)
277 {
278 #if CLOCK_IP_IRCOSCS_COUNT > 1U
279 uint32 Index;
280 #endif
281 if (Config->IrcoscsCount != 0U)
282 {
283 #if CLOCK_IP_IRCOSCS_COUNT > 1U
284 if (Config->IrcoscsCount > 1U)
285 {
286 for (Index = 0U; Index < (Config->IrcoscsCount - 1U); Index++)
287 {
288 CLOCK_IP_DEV_ASSERT(((uint32)Config->Ircoscs[Index].Name) < ((uint32)Config->Ircoscs[Index+1U].Name));
289 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Ircoscs[Index].Name] & CLOCK_IP_IRCOSC_OBJECT) != 0U);
290 }
291 }
292 #endif
293 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Ircoscs[Config->IrcoscsCount - 1U].Name] & CLOCK_IP_IRCOSC_OBJECT) != 0U);
294 }
295 }
296
297 /*FUNCTION**********************************************************************
298 *
299 * Function Name : Clock_Ip_CheckXoscClocks
300 * Description : Checks clock names from xoscs array
301 *
302 *END**************************************************************************/
Clock_Ip_CheckXoscClocks(Clock_Ip_ClockConfigType const * Config)303 static void Clock_Ip_CheckXoscClocks(Clock_Ip_ClockConfigType const * Config)
304 {
305 #if CLOCK_IP_XOSCS_COUNT > 1U
306 uint32 Index;
307 #endif
308
309 if (Config->XoscsCount != 0U)
310 {
311 #if CLOCK_IP_XOSCS_COUNT > 1U
312 if (Config->XoscsCount > 1U)
313 {
314 for (Index = 0U; Index < (Config->XoscsCount - 1U); Index++)
315 {
316 CLOCK_IP_DEV_ASSERT(((uint32)Config->Xoscs[Index].Name) < ((uint32)Config->Xoscs[Index+1U].Name));
317 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Xoscs[Index].Name] & CLOCK_IP_XOSC_OBJECT) != 0U);
318 }
319 }
320 #endif
321 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Xoscs[Config->XoscsCount - 1U].Name] & CLOCK_IP_XOSC_OBJECT) != 0U);
322 }
323 }
324
325 /*FUNCTION**********************************************************************
326 *
327 * Function Name : Clock_Ip_CheckPllClocks
328 * Description : Checks clock names from plls array
329 *
330 *END**************************************************************************/
Clock_Ip_CheckPllClocks(Clock_Ip_ClockConfigType const * Config)331 static void Clock_Ip_CheckPllClocks(Clock_Ip_ClockConfigType const * Config)
332 {
333 #if CLOCK_IP_PLLS_COUNT > 1U
334 uint32 Index;
335 #endif
336 if (Config->PllsCount != 0U)
337 {
338 #if CLOCK_IP_PLLS_COUNT > 1U
339 if (Config->PllsCount > 1U)
340 {
341 for (Index = 0U; Index < (Config->PllsCount - 1U); Index++)
342 {
343 CLOCK_IP_DEV_ASSERT(((uint32)Config->Plls[Index].Name) < ((uint32)Config->Plls[Index+1U].Name));
344 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Plls[Index].Name] & CLOCK_IP_PLL_OBJECT) != 0U);
345 }
346 }
347 #endif
348 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Plls[Config->PllsCount - 1U].Name] & CLOCK_IP_PLL_OBJECT) != 0U);
349 }
350 }
351
352 /*FUNCTION**********************************************************************
353 *
354 * Function Name : Clock_Ip_CheckExtSigClocks
355 * Description : Checks clock names from ext signal clocks array
356 *
357 *END**************************************************************************/
Clock_Ip_CheckExtSigClocks(Clock_Ip_ClockConfigType const * Config)358 static void Clock_Ip_CheckExtSigClocks(Clock_Ip_ClockConfigType const * Config)
359 {
360 #if CLOCK_IP_EXT_CLKS_NO > 1U
361 uint32 Index;
362 #endif
363 if (Config->ExtClksCount != 0U)
364 {
365 #if CLOCK_IP_EXT_CLKS_NO > 1U
366 if (Config->ExtClksCount > 1U)
367 {
368 for (Index = 0U; Index < (Config->ExtClksCount - 1U); Index++)
369 {
370 CLOCK_IP_DEV_ASSERT(((uint32)Config->ExtClks[Index].Name) < ((uint32)Config->ExtClks[Index+1U].Name));
371 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->ExtClks[Index].Name] & CLOCK_IP_EXT_SIG_OBJECT) != 0U);
372 }
373 }
374 #endif
375 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->ExtClks[Config->ExtClksCount - 1U].Name] & CLOCK_IP_EXT_SIG_OBJECT) != 0U);
376 }
377 }
378
379 /*FUNCTION**********************************************************************
380 *
381 * Function Name : Clock_Ip_CheckSelectorClocks
382 * Description : Checks clock names from selectors array
383 *
384 *END**************************************************************************/
Clock_Ip_CheckSelectorClocks(Clock_Ip_ClockConfigType const * Config)385 static void Clock_Ip_CheckSelectorClocks(Clock_Ip_ClockConfigType const * Config)
386 {
387 uint32 Index;
388
389 if (Config->SelectorsCount != 0U)
390 {
391 if (Config->SelectorsCount > 1U)
392 {
393 for (Index = 0U; Index < (Config->SelectorsCount - 1U); Index++)
394 {
395 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Selectors[Index].Name] & CLOCK_IP_SELECTOR_OBJECT) != 0U);
396 }
397 }
398 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Selectors[Config->SelectorsCount - 1U].Name] & CLOCK_IP_SELECTOR_OBJECT) != 0U);
399 }
400 }
401
402 /*FUNCTION**********************************************************************
403 *
404 * Function Name : Clock_Ip_CheckDividerClocks
405 * Description : Checks clock names from dividers array
406 *
407 *END**************************************************************************/
Clock_Ip_CheckDividerClocks(Clock_Ip_ClockConfigType const * Config)408 static void Clock_Ip_CheckDividerClocks(Clock_Ip_ClockConfigType const * Config)
409 {
410 uint32 Index;
411
412 if (Config->DividersCount != 0U)
413 {
414 if (Config->DividersCount > 1U)
415 {
416 for (Index = 0U; Index < (Config->DividersCount - 1U); Index++)
417 {
418 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Dividers[Index].Name] & CLOCK_IP_DIVIDER_OBJECT) != 0U);
419 }
420 }
421 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Dividers[Config->DividersCount - 1U].Name] & CLOCK_IP_DIVIDER_OBJECT) != 0U);
422 }
423 }
424
425 /*FUNCTION**********************************************************************
426 *
427 * Function Name : Check_DividerTrigger_Clocks
428 * Description : Checks clock names from divider triggers array
429 *
430 *END**************************************************************************/
Clock_Ip_CheckDividerTriggerClocks(Clock_Ip_ClockConfigType const * Config)431 static void Clock_Ip_CheckDividerTriggerClocks(Clock_Ip_ClockConfigType const * Config)
432 {
433 #if CLOCK_IP_DIVIDER_TRIGGERS_COUNT > 1U
434 uint32 Index;
435 #endif
436
437 if (Config->DividerTriggersCount != 0U)
438 {
439 #if CLOCK_IP_DIVIDER_TRIGGERS_COUNT > 1U
440 if (Config->DividerTriggersCount > 1U)
441 {
442 for (Index = 0U; Index < (Config->DividerTriggersCount - 1U); Index++)
443 {
444 CLOCK_IP_DEV_ASSERT(((uint32)Config->DividerTriggers[Index].Name) < ((uint32)Config->DividerTriggers[Index+1U].Name));
445 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->DividerTriggers[Index].Name] & CLOCK_IP_DIVIDER_TRIGGER_OBJECT) != 0U);
446 }
447 }
448 #endif
449 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->DividerTriggers[Config->DividerTriggersCount - 1U].Name] & CLOCK_IP_DIVIDER_TRIGGER_OBJECT) != 0U);
450 }
451 }
452
453 /*FUNCTION**********************************************************************
454 *
455 * Function Name : Check_FracDivider_Clocks
456 * Description : Checks clock names from fractional divider array
457 *
458 *END**************************************************************************/
Clock_Ip_CheckFracDividerClocks(Clock_Ip_ClockConfigType const * Config)459 static void Clock_Ip_CheckFracDividerClocks(Clock_Ip_ClockConfigType const * Config)
460 {
461 #if CLOCK_IP_FRACTIONAL_DIVIDERS_COUNT > 1U
462 uint32 Index;
463 #endif
464
465 if (Config->FracDivsCount != 0U)
466 {
467 #if CLOCK_IP_FRACTIONAL_DIVIDERS_COUNT > 1U
468 if (Config->FracDivsCount > 1U)
469 {
470 for (Index = 0U; Index < (Config->FracDivsCount - 1U); Index++)
471 {
472 CLOCK_IP_DEV_ASSERT(((uint32)Config->FracDivs[Index].Name) < ((uint32)Config->FracDivs[Index+1U].Name));
473 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->FracDivs[Index].Name] & CLOCK_IP_FRAC_DIV_OBJECT) != 0U);
474 }
475 }
476 #endif
477 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->FracDivs[Config->FracDivsCount - 1U].Name] & CLOCK_IP_FRAC_DIV_OBJECT) != 0U);
478 }
479 }
480
481 /*FUNCTION**********************************************************************
482 *
483 * Function Name : Clock_Ip_CheckGateClocks
484 * Description : Checks clock names from gates array
485 *
486 *END**************************************************************************/
Clock_Ip_CheckGateClocks(Clock_Ip_ClockConfigType const * Config)487 static void Clock_Ip_CheckGateClocks(Clock_Ip_ClockConfigType const * Config)
488 {
489 uint32 Index;
490
491 if (Config->GatesCount != 0U)
492 {
493 if (Config->GatesCount > 1U)
494 {
495 for (Index = 0U; Index < (Config->GatesCount - 1U); Index++)
496 {
497 CLOCK_IP_DEV_ASSERT(((uint32)Config->Gates[Index].Name) < ((uint32)Config->Gates[Index+1U].Name));
498 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Gates[Index].Name] & CLOCK_IP_GATE_OBJECT) != 0U);
499 }
500 }
501 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Gates[Config->GatesCount - 1U].Name] & CLOCK_IP_GATE_OBJECT) != 0U);
502 }
503 }
504
505 /*FUNCTION**********************************************************************
506 *
507 * Function Name : Clock_Ip_CheckPcfsClocks
508 * Description : Checks clock names from pcfs array
509 *
510 *END**************************************************************************/
Clock_Ip_CheckPcfsClocks(Clock_Ip_ClockConfigType const * Config)511 static void Clock_Ip_CheckPcfsClocks(Clock_Ip_ClockConfigType const * Config)
512 {
513 uint32 Index;
514
515 if (Config->PcfsCount != 0U)
516 {
517 if (Config->PcfsCount > 1U)
518 {
519 for (Index = 0U; Index < (Config->PcfsCount - 1U); Index++)
520 {
521 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Pcfs[Index].Name] & CLOCK_IP_PCFS_OBJECT) != 0U);
522 }
523 }
524 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Pcfs[Config->PcfsCount - 1U].Name] & CLOCK_IP_PCFS_OBJECT) != 0U);
525 }
526 }
527
528 /*FUNCTION**********************************************************************
529 *
530 * Function Name : Clock_Ip_CheckCmuClocks
531 * Description : Checks clock names from cmu array
532 *
533 *END**************************************************************************/
Clock_Ip_CheckCmuClocks(Clock_Ip_ClockConfigType const * Config)534 static void Clock_Ip_CheckCmuClocks(Clock_Ip_ClockConfigType const * Config)
535 {
536 uint32 Index;
537
538 if (Config->CmusCount != 0U)
539 {
540 if (Config->CmusCount > 1U)
541 {
542 for (Index = 0U; Index < (Config->CmusCount - 1U); Index++)
543 {
544 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Cmus[Index].Name] & CLOCK_IP_CMU_OBJECT) != 0U);
545 }
546 }
547 CLOCK_IP_DEV_ASSERT((Clock_Ip_au8ClockNameTypes[Config->Cmus[Config->CmusCount - 1U].Name] & CLOCK_IP_CMU_OBJECT) != 0U);
548 }
549 }
550 #endif
551 #endif
552
553 #define CLOCK_IP_NO_CALLBACK 0U
554
555 /* Call empty callbacks to improve CCOV*/
Clock_Ip_CallEmptyCallbacks(void)556 static void Clock_Ip_CallEmptyCallbacks(void)
557 {
558
559 if (FALSE == FunctionWasCalled)
560 {
561 FunctionWasCalled = TRUE;
562
563 Clock_Ip_axCmuCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR, 0U);
564 Clock_Ip_axCmuCallbacks[CLOCK_IP_NO_CALLBACK].Disable(RESERVED_CLK);
565
566 Clock_Ip_axDividerCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
567
568 Clock_Ip_axDividerTriggerCallbacks[CLOCK_IP_NO_CALLBACK].Configure(NULL_PTR);
569
570 Clock_Ip_axExtOscCallbacks[CLOCK_IP_NO_CALLBACK].Reset(NULL_PTR);
571
572 Clock_Ip_axFracDivCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
573 (void)Clock_Ip_axFracDivCallbacks[CLOCK_IP_NO_CALLBACK].Complete(RESERVED_CLK);
574
575 Clock_Ip_axGateCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
576 Clock_Ip_axGateCallbacks[CLOCK_IP_NO_CALLBACK].Update(RESERVED_CLK,FALSE);
577
578 Clock_Ip_axIntOscCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
579
580 Clock_Ip_axPllCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
581 (void)Clock_Ip_axPllCallbacks[CLOCK_IP_NO_CALLBACK].Complete(RESERVED_CLK);
582
583 Clock_Ip_axSelectorCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR);
584
585 Clock_Ip_axPcfsCallbacks[CLOCK_IP_NO_CALLBACK].Set(NULL_PTR, 0U);
586 }
587 }
588
Clock_Ip_ResetClockConfiguration(Clock_Ip_ClockConfigType const * Config)589 static void Clock_Ip_ResetClockConfiguration(Clock_Ip_ClockConfigType const * Config)
590 {
591 uint32 CallbackIndex;
592 uint32 Index;
593
594 for (Index = Config->SelectorsCount ; Index > 0U; Index--) /* Ramp down all selectors from configuration to SAFE_CLOCK */
595 {
596 CallbackIndex = Clock_Ip_au8SelectorCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Selectors[Index - 1U].Name][CLOCK_IP_CALLBACK]];
597 Clock_Ip_axSelectorCallbacks[CallbackIndex].Reset(&Config->Selectors[Index - 1U]);
598 }
599
600 for (Index = Config->FracDivsCount; Index > 0U; Index--) /* Put in reset state all fractional dividers from configuration */
601 {
602 CallbackIndex = Clock_Ip_au8FractionalDividerCallbackIndex[Clock_Ip_au8ClockFeatures[Config->FracDivs[Index - 1U].Name][CLOCK_IP_CALLBACK]];
603 Clock_Ip_axFracDivCallbacks[CallbackIndex].Reset(&Config->FracDivs[Index - 1U]);
604 }
605
606 for (Index = Config->PllsCount; Index > 0U; Index--) /* Power down all plls from configuration */
607 {
608 CallbackIndex = Clock_Ip_au8PllCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Plls[Index - 1U].Name][CLOCK_IP_CALLBACK]];
609 Clock_Ip_axPllCallbacks[CallbackIndex].Reset(&Config->Plls[Index - 1U]);
610 }
611
612 for (Index = Config->XoscsCount; Index > 0U; Index--) /* Power down all xoscs from configuration */
613 {
614 CallbackIndex = Clock_Ip_au8XoscCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Xoscs[Index - 1U].Name][CLOCK_IP_CALLBACK]];
615 Clock_Ip_axExtOscCallbacks[CallbackIndex].Reset(&Config->Xoscs[Index - 1U]);
616 }
617 }
618
619 #if (defined(CLOCK_IP_DEV_ERROR_DETECT))
620 #if (CLOCK_IP_DEV_ERROR_DETECT == STD_ON)
Clock_Ip_CheckClockConfiguration(Clock_Ip_ClockConfigType const * Config)621 static void Clock_Ip_CheckClockConfiguration(Clock_Ip_ClockConfigType const * Config)
622 {
623 Clock_Ip_CheckIrcoscClocks(Config);
624 Clock_Ip_CheckXoscClocks(Config);
625 Clock_Ip_CheckPllClocks(Config);
626 Clock_Ip_CheckExtSigClocks(Config);
627 Clock_Ip_CheckSelectorClocks(Config);
628 Clock_Ip_CheckDividerClocks(Config);
629 Clock_Ip_CheckDividerTriggerClocks(Config);
630 Clock_Ip_CheckFracDividerClocks(Config);
631 Clock_Ip_CheckGateClocks(Config);
632 Clock_Ip_CheckPcfsClocks(Config);
633 Clock_Ip_CheckCmuClocks(Config);
634 }
635 #endif
636 #endif
637 /*==================================================================================================
638 * GLOBAL FUNCTIONS
639 ==================================================================================================*/
640
641 /*FUNCTION******************************************************************************
642 *
643 * Function Name : Clock_Ip_Init
644 *
645 * Description : Set clock configuration according to pre-defined structure.
646 * This function sets system to target clock configuration; It sets the
647 * clock modules registers for clock mode change.
648 *
649 * If external clock is used in the target mode, please make sure it is
650 * enabled, for example, if the external oscillator is used, please setup correctly.
651 *
652 * @implements Clock_Ip_Init_Activity
653 * END**********************************************************************************/
Clock_Ip_Init(Clock_Ip_ClockConfigType const * Config)654 Clock_Ip_StatusType Clock_Ip_Init(Clock_Ip_ClockConfigType const * Config)
655 {
656 Clock_Ip_StatusType ClockStatus = CLOCK_IP_ERROR;
657
658 Clock_Ip_PllStatusType PllStatus;
659
660 (void)Clock_Ip_au8XoscCallbackIndex;
661 (void)Clock_Ip_axExtOscCallbacks;
662 (void)Clock_Ip_au8IrcoscCallbackIndex;
663 (void)Clock_Ip_axIntOscCallbacks;
664 (void)Clock_Ip_au8PcfsCallbackIndex;
665 (void)Clock_Ip_axPcfsCallbacks;
666 (void)Clock_Ip_au8DividerCallbackIndex;
667 (void)Clock_Ip_axDividerCallbacks;
668
669 (void)CLOCK_IP_MODULE_INSTANCE;
670 (void)CLOCK_IP_CALLBACK;
671 (void)CLOCK_IP_EXTENSION_INDEX;
672 (void)CLOCK_IP_POWER_MODE_INDEX;
673 (void)CLOCK_IP_SELECTOR_INDEX;
674 (void)CLOCK_IP_DIVIDER_INDEX;
675 (void)CLOCK_IP_GATE_INDEX;
676 (void)CLOCK_IP_PCFS_INDEX;
677 (void)CLOCK_IP_CMU_INDEX;
678
679 #if (defined(CLOCK_IP_ENABLE_USER_MODE_SUPPORT))
680 #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT)
681 /* Set user access allowed for Clock */
682 Clock_Ip_Command(Config, CLOCK_IP_SET_USER_ACCESS_ALLOWED_COMMAND);
683 #endif
684 #endif
685 CLOCK_IP_DEV_ASSERT(NULL_PTR != Config);
686
687 Clock_Ip_InitClock(Config);
688
689 if (DriverContext.ClockTreeIsConsumingPll)
690 {
691 PllStatus = Clock_Ip_GetPllStatus();
692 if (CLOCK_IP_PLL_LOCKED == PllStatus)
693 {
694 Clock_Ip_DistributePll();
695 ClockStatus = CLOCK_IP_SUCCESS;
696 }
697 }
698 else
699 {
700 ClockStatus = CLOCK_IP_SUCCESS;
701 }
702
703 return ClockStatus;
704 }
705
706 /*FUNCTION******************************************************************************
707 *
708 * Function Name : Clock_Ip_InitClock
709 *
710 * Description : Set the PLL and other MCU specific clock options.
711 * This function initializes the PLL and other MCU specific clock options.
712 * The clock configuration parameters are provided via the configuration structure.
713 *
714 * This function shall start the PLL lock procedure (if PLL
715 * shall be initialized) and shall return without waiting until the PLL is locked.
716 *
717 * @implements Clock_Ip_InitClock_Activity
718 * END**********************************************************************************/
Clock_Ip_InitClock(Clock_Ip_ClockConfigType const * Config)719 void Clock_Ip_InitClock(Clock_Ip_ClockConfigType const * Config)
720 {
721 uint32 CallbackIndex;
722 uint32 Index;
723
724 #if (defined(CLOCK_IP_DEV_ERROR_DETECT) && (CLOCK_IP_DEV_ERROR_DETECT == STD_ON))
725 /* Check clock elements from clock configuration */
726 Clock_Ip_CheckClockConfiguration(Config);
727 #endif
728
729 CLOCK_IP_DEV_ASSERT(NULL_PTR != Config);
730
731 /* Save the current clock configuration to be used by "Clock_Ip_DistributePllClock". */
732 Clock_Ip_pxConfig = Config;
733
734 /* Platform specific initialization:
735 * DFS reset, FIRC_CLK configuration etc. */
736 Clock_Ip_Command(Config, CLOCK_IP_INITIALIZE_PLATFORM_COMMAND);
737
738 /* Clear all the settings for CMU0/1/2... */
739 /* In case one clock configuration has the CMU disabled, then need to make the transition to
740 reset state of CMU modules. */
741 if (NULL_PTR != Clock_Ip_pxConfig)
742 {
743 for (Index = 0U; Index < Config->CmusCount; Index++) /* Reset all clock monitor units from previous configuration. */
744 {
745 CallbackIndex = Clock_Ip_au8CmuCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Cmus[Index].Name][CLOCK_IP_CALLBACK]];
746 Clock_Ip_axCmuCallbacks[CallbackIndex].Reset(&Config->Cmus[Index]);
747 }
748 }
749
750 /*********************************************************************
751 *** Ramp down to safe configuration. Reset elements from clock tree:
752 *** selectors, fractional dividers, plls and xoscs
753 ***********************************************************************/
754 Clock_Ip_ResetClockConfiguration(Config);
755
756 /*******************************************************
757 *** Load the new configuration. Selectors that might
758 *** be clocked from PLLs shouldn't be configured.
759 *******************************************************/
760
761 for (Index = 0U; Index < Config->IrcoscsCount; Index++) /* Set internal oscillators from configuration */
762 {
763 CallbackIndex = Clock_Ip_au8IrcoscCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Ircoscs[Index].Name][CLOCK_IP_CALLBACK]];
764 Clock_Ip_axIntOscCallbacks[CallbackIndex].Set(&Config->Ircoscs[Index]);
765 }
766
767 for (Index = 0U; Index < Config->XoscsCount; Index++) /* Configure all xoscs from configuration */
768 {
769 CallbackIndex = Clock_Ip_au8XoscCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Xoscs[Index].Name][CLOCK_IP_CALLBACK]];
770 Clock_Ip_axExtOscCallbacks[CallbackIndex].Set(&Config->Xoscs[Index]);
771 }
772
773 /* Initialize clock objects, internal driver data */
774 Clock_Ip_UpdateDriverContext(Config);
775
776 /* Configure the PCFS */
777 for (Index = 0U; Index < Config->PcfsCount; Index++) /* Configure all progressive frequency switching clocks from configuration */
778 {
779 CallbackIndex = Clock_Ip_au8PcfsCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Pcfs[Index].Name][CLOCK_IP_CALLBACK]];
780 Clock_Ip_axPcfsCallbacks[CallbackIndex].Set(&Config->Pcfs[Index], Index);
781 }
782
783 /* Configure the clock divider triggers that are under MCU control */
784 for (Index = 0U; Index < Config->DividerTriggersCount; Index++) /* Set divider triggers from configuration. */
785 {
786 CallbackIndex = Clock_Ip_au8DividerTriggerCallbackIndex[Clock_Ip_au8ClockFeatures[Config->DividerTriggers[Index].Name][CLOCK_IP_CALLBACK]];
787 Clock_Ip_axDividerTriggerCallbacks[CallbackIndex].Configure(&Config->DividerTriggers[Index]);
788 }
789
790 /* Configure the clock dividers that are under MCU control */
791 for (Index = 0U; Index < Config->DividersCount; Index++) /* Set dividers from configuration. */
792 {
793 CallbackIndex = Clock_Ip_au8DividerCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Dividers[Index].Name][CLOCK_IP_CALLBACK]];
794 Clock_Ip_axDividerCallbacks[CallbackIndex].Set(&Config->Dividers[Index]);
795 }
796
797 /* Trigger update for all divider trigger that are under MCU control */
798 for (Index = 0U; Index < Config->DividerTriggersCount; Index++) /* Set divider triggers from configuration. */
799 {
800 CallbackIndex = Clock_Ip_au8DividerTriggerCallbackIndex[Clock_Ip_au8ClockFeatures[Config->DividerTriggers[Index].Name][CLOCK_IP_CALLBACK]];
801 Clock_Ip_axDividerTriggerCallbacks[CallbackIndex].TriggerUpdate(&Config->DividerTriggers[Index]);
802 }
803
804 /* Configure PLL clock generators */
805 for (Index = 0U; Index < Config->PllsCount; Index++) /* Configure all plls from configuration asynchronously. Do not enable. */
806 {
807 CallbackIndex = Clock_Ip_au8PllCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Plls[Index].Name][CLOCK_IP_CALLBACK]];
808 Clock_Ip_axPllCallbacks[CallbackIndex].Set(&Config->Plls[Index]);
809 }
810
811 for (Index = 0U; Index < Config->CmusCount; Index++) /* Set the Clock Monitoring Units that are under mcu control. Cmus are not enabled. */
812 {
813 CallbackIndex = Clock_Ip_au8CmuCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Cmus[Index].Name][CLOCK_IP_CALLBACK]];
814 Clock_Ip_axCmuCallbacks[CallbackIndex].Set(&Config->Cmus[Index], Index);
815 }
816
817 for (Index = 0U; Index < Config->XoscsCount; Index++) /* Wait for all xoscs from configuration to lock */
818 {
819 CallbackIndex = Clock_Ip_au8XoscCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Xoscs[Index].Name][CLOCK_IP_CALLBACK]];
820 Clock_Ip_axExtOscCallbacks[CallbackIndex].Complete(&Config->Xoscs[Index]);
821 }
822
823 /* Configure PLL clock generators */
824 for (Index = 0U; Index < Config->PllsCount; Index++) /* Enable plls according to configuration asynchronously. Do not wait. */
825 {
826 CallbackIndex = Clock_Ip_au8PllCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Plls[Index].Name][CLOCK_IP_CALLBACK]];
827 Clock_Ip_axPllCallbacks[CallbackIndex].Enable(&Config->Plls[Index]);
828 }
829
830 /* Configure fractional dividers */
831 /* Note: The DFS configuration might actually need to be done after we
832 * know that the PLLs are all locked in "Clock_Ip_GetPllStatus". */
833 for (Index = 0U; Index < Config->FracDivsCount; Index++) /* Configure all fractional dividers from configuration asynchronously. Do not wait. */
834 {
835 CallbackIndex = Clock_Ip_au8FractionalDividerCallbackIndex[Clock_Ip_au8ClockFeatures[Config->FracDivs[Index].Name][CLOCK_IP_CALLBACK]];
836 Clock_Ip_axFracDivCallbacks[CallbackIndex].Set(&Config->FracDivs[Index]);
837 }
838
839 DriverContext.ClockTreeIsConsumingPll = FALSE; /* Check if clock tree is using a PLL output */
840 #if (defined(CLOCK_IP_SUPPORTS_WAIT_STATES))
841 #if(CLOCK_IP_SUPPORTS_WAIT_STATES == STD_ON)
842 DriverContext.WaitStatesAreSupported = TRUE; /* Wait states are supported */
843 #else
844 DriverContext.WaitStatesAreSupported = FALSE; /* Wait states are not supported */
845 #endif /*CLOCK_IP_SUPPORTS_WAIT_STATES == STD_ON */
846 #else
847 DriverContext.WaitStatesAreSupported = FALSE; /* Wait states are not supported */
848 #endif /* #if (defined(CLOCK_IP_SUPPORTS_WAIT_STATES)) */
849 DriverContext.HwPllsNo = CLOCK_IP_NUMBER_OF_HARDWARE_PLL; /* Number of plls */
850 DriverContext.HwDfsNo = CLOCK_IP_NUMBER_OF_HARDWARE_DFS; /* Number of fractional dividers */
851
852
853 /* Configure wait states */
854 Clock_Ip_SetWaitStates();
855
856
857 /* Switch the clock multiplexers under MCU control to the configured source clocks */
858 /* Note: if the configured source clock of a ClockMux is the output clock of a PLL/DFS,
859 * the configuration will be skipped and the respective ClockMux will be switched in
860 * the "Clock_Ip_DistributePllClock" function instead, when the source clock will have
861 * stabilized already. */
862 for (Index = 0U; Index < Config->SelectorsCount; Index++) /* Set only if selected inputs are not clocked from PLLs */
863 {
864 if ((PLL_TYPE != Clock_Ip_aeSourceTypeClockName[Config->Selectors[Index].Value]))
865 {
866
867 CallbackIndex = Clock_Ip_au8SelectorCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Selectors[Index].Name][CLOCK_IP_CALLBACK]];
868 Clock_Ip_axSelectorCallbacks[CallbackIndex].Set(&Config->Selectors[Index]);
869 }
870 else
871 {
872 /* At least one mux is consuming pll */
873 DriverContext.ClockTreeIsConsumingPll = TRUE;
874 }
875 }
876
877 /* Check if the clock tree is using a PLL output */
878 if ( FALSE == DriverContext.ClockTreeIsConsumingPll )
879 {
880 for (Index = 0U; Index < Config->GatesCount; Index++) /* Set clock gates that are under clock control. */
881 {
882 CallbackIndex = Clock_Ip_au8GateCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Gates[Index].Name][CLOCK_IP_CALLBACK]];
883 Clock_Ip_axGateCallbacks[CallbackIndex].Set(&Config->Gates[Index]);
884 }
885
886 /* Enable the Clock Monitoring Units ( CMU0 .. n ) according to configuration. */
887 for (Index = 0U; Index < Config->CmusCount; Index++)
888 {
889 CallbackIndex = Clock_Ip_au8CmuCallbackIndex[Clock_Ip_au8ClockFeatures[Config->Cmus[Index].Name][CLOCK_IP_CALLBACK]];
890 Clock_Ip_axCmuCallbacks[CallbackIndex].Enable(&Config->Cmus[Index]);
891 }
892 /* Disable safe clock if it is supported by platform and it is configured/required. */
893 /* Note: Safe clock is the fast internal oscillator clock. It is clocking the clock tree until pll is distributed.
894 * At the end of configuration it can be disabled if it is supported on this platform and required/configured. */
895 Clock_Ip_Command(Config, CLOCK_IP_DISABLE_SAFE_CLOCK_COMMAND);
896 }
897 else
898 {
899 /* The clock tree is using at least one PLL/DFS output clock as source. */
900 /* The user must wait until the PLLs and DFSs are locked by polling Clock_Ip_GetPllStatus */
901 /* and then call "Clock_Ip_DistributePllClock" */
902 }
903 }
904
905 /*FUNCTION******************************************************************************
906 *
907 * Function Name : Clock_Ip_GetPllStatus
908 * Description : This function configures all clocks according to a clock configuration.
909 * If no configuration is received, no change will be processed in HW and clock driver
910 * will calculate frequencies only.
911 *
912 * @implements Clock_Ip_GetPllStatus_Activity
913 * END**********************************************************************************/
Clock_Ip_GetPllStatus(void)914 Clock_Ip_PllStatusType Clock_Ip_GetPllStatus(void)
915 {
916 Clock_Ip_PllStatusType RetValue = CLOCK_IP_PLL_STATUS_UNDEFINED;
917 Clock_Ip_PllStatusReturnType PllStatus;
918 Clock_Ip_DfsStatusType DfsStatus;
919
920 uint32 Index;
921 uint32 CallbackIndex;
922
923 for (Index = 0U; Index < DriverContext.HwPllsNo; Index++)
924 {
925 CallbackIndex = Clock_Ip_au8PllCallbackIndex[Clock_Ip_au8ClockFeatures[Clock_Ip_aeHwPllName[Index]][CLOCK_IP_CALLBACK]];
926 PllStatus = Clock_Ip_axPllCallbacks[CallbackIndex].Complete(Clock_Ip_aeHwPllName[Index]);
927 if (STATUS_PLL_UNLOCKED == PllStatus)
928 {
929 RetValue = CLOCK_IP_PLL_UNLOCKED;
930 break;
931 }
932 else
933 {
934 if (STATUS_PLL_LOCKED == PllStatus)
935 {
936 RetValue = CLOCK_IP_PLL_LOCKED;
937 }
938 }
939 }
940
941 if (CLOCK_IP_PLL_LOCKED == RetValue)
942 {
943 for (Index = 0U; Index < DriverContext.HwDfsNo; Index++)
944 {
945 CallbackIndex = Clock_Ip_au8FractionalDividerCallbackIndex[Clock_Ip_au8ClockFeatures[Clock_Ip_aeHwDfsName[Index]][CLOCK_IP_CALLBACK]];
946 DfsStatus = Clock_Ip_axFracDivCallbacks[CallbackIndex].Complete(Clock_Ip_aeHwDfsName[Index]);
947 if (STATUS_DFS_UNLOCKED == DfsStatus)
948 {
949 RetValue = CLOCK_IP_PLL_UNLOCKED;
950 break;
951 }
952 }
953 }
954
955 return RetValue;
956 }
957
958 /*FUNCTION******************************************************************************
959 *
960 * Function Name : Clock_Ip_DistributePll
961 * Description : Function completes the PLL configuration and then activates the PLL clock to Mcu
962 * The function will not distribute the PLL clock if the driver state does not allow it, or the PLL is not stable.
963 *
964 * @implements Clock_Ip_DistributePll_Activity
965 * END**********************************************************************************/
Clock_Ip_DistributePll(void)966 void Clock_Ip_DistributePll(void)
967 {
968
969 uint32 Index;
970 uint32 CallbackIndex;
971
972 CLOCK_IP_DEV_ASSERT(NULL_PTR != Clock_Ip_pxConfig);
973 /* 'Clock_Ip_pxConfig' is set by Clock_Ip_InitClock().
974 * It doesn't make sense to call PLL distribution without clock initialization. */
975 if (NULL_PTR != Clock_Ip_pxConfig)
976 {
977 for (Index = 0U; Index < Clock_Ip_pxConfig->SelectorsCount; Index++) /* Set only if selected inputs are clocked from PLLs */
978 {
979 if (PLL_TYPE == Clock_Ip_aeSourceTypeClockName[Clock_Ip_pxConfig->Selectors[Index].Value])
980 {
981
982 CallbackIndex = Clock_Ip_au8SelectorCallbackIndex[Clock_Ip_au8ClockFeatures[Clock_Ip_pxConfig->Selectors[Index].Name][CLOCK_IP_CALLBACK]];
983 Clock_Ip_axSelectorCallbacks[CallbackIndex].Set(&Clock_Ip_pxConfig->Selectors[Index]);
984 }
985 }
986
987 /* In the case of PLL is enabled but PLL clock source is not used by any clock Mux.
988 So, no need to re-configure for CMUs, because they are configured by Clock_Ip_InitClock */
989 /* Check if the clock tree is using a PLL output */
990 if ( DriverContext.ClockTreeIsConsumingPll )
991 {
992 for (Index = 0U; Index < Clock_Ip_pxConfig->GatesCount; Index++) /* Set clock gates that are under clock control. */
993 {
994 CallbackIndex = Clock_Ip_au8GateCallbackIndex[Clock_Ip_au8ClockFeatures[Clock_Ip_pxConfig->Gates[Index].Name][CLOCK_IP_CALLBACK]];
995 Clock_Ip_axGateCallbacks[CallbackIndex].Set(&Clock_Ip_pxConfig->Gates[Index]);
996 }
997
998 /* Enable the Clock Monitoring Units ( CMU0 .. n ) according to configuration. */
999 for (Index = 0U; Index < Clock_Ip_pxConfig->CmusCount; Index++)
1000 {
1001 CallbackIndex = Clock_Ip_au8CmuCallbackIndex[Clock_Ip_au8ClockFeatures[Clock_Ip_pxConfig->Cmus[Index].Name][CLOCK_IP_CALLBACK]];
1002 Clock_Ip_axCmuCallbacks[CallbackIndex].Enable(&Clock_Ip_pxConfig->Cmus[Index]);
1003 }
1004
1005 /* Disable safe clock if it is supported by platform and it is configured/required. */
1006 /* Note: Safe clock is the fast internal oscillator clock. It is clocking the clock tree until pll is distributed.
1007 * At the end of configuration it can be disabled if it is supported on this platform and required/configured. */
1008 Clock_Ip_Command(Clock_Ip_pxConfig, CLOCK_IP_DISABLE_SAFE_CLOCK_COMMAND);
1009 }
1010 }
1011 }
1012
1013 /*FUNCTION******************************************************************************
1014 *
1015 * Function Name : Clock_Ip_DisableClockMonitor
1016 * Description : Disables a clock monitor.
1017 *
1018 * @implements Clock_Ip_DisableClockMonitor_Activity
1019 * END**********************************************************************************/
Clock_Ip_DisableClockMonitor(Clock_Ip_NameType ClockName)1020 void Clock_Ip_DisableClockMonitor(Clock_Ip_NameType ClockName)
1021 {
1022
1023 uint32 CallbackIndex;
1024
1025 CallbackIndex = Clock_Ip_au8CmuCallbackIndex[Clock_Ip_au8ClockFeatures[ClockName][CLOCK_IP_CALLBACK]];
1026 Clock_Ip_axCmuCallbacks[CallbackIndex].Disable(ClockName);
1027 }
1028
1029 /*FUNCTION******************************************************************************
1030 *
1031 * Function Name : Clock_Ip_InstallNotificationsCallback
1032 * Description : This function installs a callback for clock notifications.
1033 *
1034 * @implements Clock_Ip_InstallNotificationsCallback_Activity
1035 * END**********************************************************************************/
Clock_Ip_InstallNotificationsCallback(Clock_Ip_NotificationsCallbackType Callback)1036 void Clock_Ip_InstallNotificationsCallback(Clock_Ip_NotificationsCallbackType Callback)
1037 {
1038 CLOCK_IP_DEV_ASSERT(NULL_PTR != Callback);
1039
1040 Clock_Ip_pfkNotificationsCallback = Callback;
1041 }
1042
1043 /*FUNCTION******************************************************************************
1044 *
1045 * Function Name : Clock_Ip_DisableModuleClock
1046 * Description : Disables clock for a peripheral.
1047 *
1048 * @implements Clock_Ip_DisableModuleClock_Activity
1049 * END**********************************************************************************/
Clock_Ip_DisableModuleClock(Clock_Ip_NameType ClockName)1050 void Clock_Ip_DisableModuleClock(Clock_Ip_NameType ClockName)
1051 {
1052
1053 uint32 CallbackIndex;
1054
1055 CallbackIndex = Clock_Ip_au8GateCallbackIndex[Clock_Ip_au8ClockFeatures[ClockName][CLOCK_IP_CALLBACK]];
1056 Clock_Ip_axGateCallbacks[CallbackIndex].Update(ClockName,TRUE);
1057 }
1058
1059 /*FUNCTION******************************************************************************
1060 *
1061 * Function Name : Clock_Ip_EnableModuleClock
1062 * Description : Enable clock for a peripheral.
1063 *
1064 * @implements Clock_Ip_EnableModuleClock_Activity
1065 * END**********************************************************************************/
Clock_Ip_EnableModuleClock(Clock_Ip_NameType ClockName)1066 void Clock_Ip_EnableModuleClock(Clock_Ip_NameType ClockName)
1067 {
1068
1069 uint32 CallbackIndex;
1070
1071 CallbackIndex = Clock_Ip_au8GateCallbackIndex[Clock_Ip_au8ClockFeatures[ClockName][CLOCK_IP_CALLBACK]];
1072 Clock_Ip_axGateCallbacks[CallbackIndex].Update(ClockName,FALSE);
1073 }
1074
1075
1076 #ifdef CLOCK_IP_POWER_MODE_CHANGE_NOTIFICATION
1077 #if (CLOCK_IP_POWER_MODE_CHANGE_NOTIFICATION == STD_ON)
1078 /*FUNCTION******************************************************************************
1079 *
1080 * Function Name : Clock_Ip_PowerModeChangeNotification
1081 * Description : Notifies clock driver when a power mode is changed.
1082 *
1083 * @implements Clock_Ip_PowerModeChangeNotification_Activity
1084 * END**********************************************************************************/
Clock_Ip_PowerModeChangeNotification(Clock_Ip_PowerModesType PowerMode,Clock_Ip_PowerNotificationType Notification)1085 void Clock_Ip_PowerModeChangeNotification(Clock_Ip_PowerModesType PowerMode,Clock_Ip_PowerNotificationType Notification)
1086 {
1087 Clock_Ip_bSentFromUpdateDriverContext = FALSE;
1088 Clock_Ip_Command(Clock_Ip_pxConfig, CLOCK_IP_INITIALIZE_CLOCK_OBJECTS_COMMAND);
1089
1090 Clock_Ip_ClockPowerModeChangeNotification(PowerMode, Notification);
1091 }
1092 #endif
1093 #endif
1094
1095
1096 #if (defined(CLOCK_IP_GET_FREQUENCY_API))
1097 #if (CLOCK_IP_GET_FREQUENCY_API == STD_ON)
1098 /*FUNCTION**********************************************************************
1099 *
1100 * Function Name : Clock_Ip_GetClockFrequency
1101 * Description : This function returns the frequency of a given clock
1102 *
1103 * @implements Clock_Ip_GetClockFrequency_Activity
1104 * END**************************************************************************/
Clock_Ip_GetClockFrequency(Clock_Ip_NameType ClockName)1105 uint32 Clock_Ip_GetClockFrequency(Clock_Ip_NameType ClockName)
1106 {
1107 #if (defined(CLOCK_IP_DEV_ERROR_DETECT))
1108 #if (CLOCK_IP_DEV_ERROR_DETECT == STD_ON)
1109 CLOCK_IP_DEV_ASSERT((((uint32)ClockName) < ((uint32)CLOCK_IP_NAMES_NO)) && (THE_LAST_PRODUCER_CLK != ClockName));
1110 #endif
1111 #endif
1112 return Clock_Ip_GetFreq(ClockName);
1113 }
1114 #endif
1115 #endif
1116
1117
1118
1119 /*FUNCTION**********************************************************************
1120 *
1121 * Function Name : Clock_Ip_SetWaitStates
1122 * Description : Hardware wait states are not supported, checking function.
1123 *
1124 *END**************************************************************************/
Clock_Ip_SetWaitStates(void)1125 static void Clock_Ip_SetWaitStates(void)
1126 {
1127 uint32 Counter = CLOCK_IP_WAIT_STATES_DELAY;
1128
1129 /* HW doesn't support wait states configuration */
1130 if (DriverContext.WaitStatesAreSupported)
1131 {
1132 #if (defined(CLOCK_IP_DEV_ERROR_DETECT))
1133 #if (CLOCK_IP_DEV_ERROR_DETECT == STD_ON)
1134 /* Error, software shouldn't reach this point,
1135 hardware doesn't support wait states */
1136 CLOCK_IP_DEV_ASSERT(FALSE);
1137 #endif
1138 #endif
1139 /* Wait states are not supported by HW,
1140 insert a delay . */
1141
1142 do
1143 {
1144 Counter--;
1145 }
1146 while(Counter > 0u);
1147 }
1148 }
1149
1150
1151 /*FUNCTION**********************************************************************
1152 *
1153 * Function Name : Clock_Ip_ReportClockErrors
1154 * Description : Report clock error
1155 *
1156 *END**************************************************************************/
Clock_Ip_ReportClockErrors(Clock_Ip_NotificationType Error,Clock_Ip_NameType ClockName)1157 void Clock_Ip_ReportClockErrors(Clock_Ip_NotificationType Error, Clock_Ip_NameType ClockName)
1158 {
1159 Clock_Ip_pfkNotificationsCallback(Error,ClockName);
1160 }
1161
1162 /*FUNCTION**********************************************************************
1163 *
1164 * Function Name : Clock_Ip_StartTimeout
1165 * Description : Checks for timeout condition
1166 *
1167 *END**************************************************************************/
Clock_Ip_StartTimeout(uint32 * StartTimeOut,uint32 * ElapsedTimeOut,uint32 * TimeoutTicksOut,uint32 TimeoutUs)1168 void Clock_Ip_StartTimeout(uint32 *StartTimeOut,
1169 uint32 *ElapsedTimeOut,
1170 uint32 *TimeoutTicksOut,
1171 uint32 TimeoutUs)
1172 {
1173 *StartTimeOut = OsIf_GetCounter(CLOCK_IP_TIMEOUT_TYPE);
1174 *ElapsedTimeOut = 0U;
1175 *TimeoutTicksOut = OsIf_MicrosToTicks(TimeoutUs, CLOCK_IP_TIMEOUT_TYPE);
1176 }
1177
1178 /*FUNCTION**********************************************************************
1179 *
1180 * Function Name : Clock_Ip_TimeoutExpired
1181 * Description : Checks for timeout expiration condition
1182 *
1183 *END**************************************************************************/
Clock_Ip_TimeoutExpired(uint32 * StartTimeInOut,uint32 * ElapsedTimeInOut,uint32 TimeoutTicks)1184 boolean Clock_Ip_TimeoutExpired(uint32 *StartTimeInOut,
1185 uint32 *ElapsedTimeInOut,
1186 uint32 TimeoutTicks)
1187 {
1188 boolean RetVal = FALSE;
1189 *ElapsedTimeInOut += OsIf_GetElapsed(StartTimeInOut, CLOCK_IP_TIMEOUT_TYPE);
1190
1191 if (*ElapsedTimeInOut >= TimeoutTicks)
1192 {
1193 RetVal = TRUE;
1194 }
1195 return RetVal;
1196 }
1197
1198 /*FUNCTION**********************************************************************
1199 *
1200 * Function Name : Clock_Ip_WriteRegisterValues
1201 * Description : Write register values
1202 *
1203 *END**************************************************************************/
1204 #if (defined(CLOCK_IP_REGISTER_VALUES_OPTIMIZATION) && (CLOCK_IP_REGISTER_VALUES_OPTIMIZATION == STD_ON))
Clock_Ip_WriteRegisterValues(const Clock_Ip_RegisterIndexType * Indexes)1205 void Clock_Ip_WriteRegisterValues(const Clock_Ip_RegisterIndexType *Indexes)
1206 {
1207 uint32 *RegAddr;
1208 uint32 RegData;
1209 uint32 Index;
1210
1211 CLOCK_IP_DEV_ASSERT(NULL_PTR != Clock_Ip_pxConfig);
1212 /* 'Clock_Ip_pxConfig' is set by Clock_Ip_InitClock().
1213 * It doesn't make sense to call this function without clock initialization. */
1214 if (NULL_PTR != Clock_Ip_pxConfig)
1215 {
1216 /* Register values array must be valid */
1217 CLOCK_IP_DEV_ASSERT(NULL_PTR != Clock_Ip_pxConfig->RegValues);
1218
1219 /* Valus of indexes must be valid */
1220 CLOCK_IP_DEV_ASSERT(Indexes->StartIndex < Indexes->EndIndex);
1221
1222 for (Index = Indexes->StartIndex; Index < Indexes->EndIndex; Index++)
1223 {
1224 RegAddr = (*Clock_Ip_pxConfig->RegValues)[Index].RegisterAddr;
1225 RegData = (*Clock_Ip_pxConfig->RegValues)[Index].RegisterData;
1226 *RegAddr = RegData;
1227 }
1228 }
1229 }
1230 #endif
1231
1232 /* Clock stop section code */
1233 #define MCU_STOP_SEC_CODE
1234
1235 #include "Mcu_MemMap.h"
1236
1237 #ifdef __cplusplus
1238 }
1239 #endif
1240
1241 /** @} */
1242