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