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