1 /*
2  * Copyright 2020-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 /**
7 *   @file       Clock_Ip_ExtOsc.c
8 *   @version    3.0.0
9 *
10 *   @brief   CLOCK driver implementations.
11 *   @details CLOCK driver implementations.
12 *
13 *   @addtogroup CLOCK_DRIVER Clock Ip Driver
14 *   @{
15 */
16 
17 
18 #ifdef __cplusplus
19 extern "C"{
20 #endif
21 
22 
23 /*==================================================================================================
24 *                                          INCLUDE FILES
25 * 1) system and project includes
26 * 2) needed interfaces from external units
27 * 3) internal and external interfaces from this unit
28 ==================================================================================================*/
29 
30 #include "Clock_Ip_Private.h"
31 
32 /*==================================================================================================
33                                SOURCE FILE VERSION INFORMATION
34 ==================================================================================================*/
35 #define CLOCK_IP_EXTOSC_VENDOR_ID_C                      43
36 #define CLOCK_IP_EXTOSC_AR_RELEASE_MAJOR_VERSION_C       4
37 #define CLOCK_IP_EXTOSC_AR_RELEASE_MINOR_VERSION_C       7
38 #define CLOCK_IP_EXTOSC_AR_RELEASE_REVISION_VERSION_C    0
39 #define CLOCK_IP_EXTOSC_SW_MAJOR_VERSION_C               3
40 #define CLOCK_IP_EXTOSC_SW_MINOR_VERSION_C               0
41 #define CLOCK_IP_EXTOSC_SW_PATCH_VERSION_C               0
42 
43 /*==================================================================================================
44 *                                     FILE VERSION CHECKS
45 ==================================================================================================*/
46 /* Check if Clock_Ip_ExtOsc.c file and Clock_Ip_Private.h file are of the same vendor */
47 #if (CLOCK_IP_EXTOSC_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID)
48     #error "Clock_Ip_ExtOsc.c and Clock_Ip_Private.h have different vendor ids"
49 #endif
50 
51 /* Check if Clock_Ip_ExtOsc.c file and Clock_Ip_Private.h file are of the same Autosar version */
52 #if ((CLOCK_IP_EXTOSC_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
53      (CLOCK_IP_EXTOSC_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
54      (CLOCK_IP_EXTOSC_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
55     )
56     #error "AutoSar Version Numbers of Clock_Ip_ExtOsc.c and Clock_Ip_Private.h are different"
57 #endif
58 
59 /* Check if Clock_Ip_ExtOsc.c file and Clock_Ip_Private.h file are of the same Software version */
60 #if ((CLOCK_IP_EXTOSC_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \
61      (CLOCK_IP_EXTOSC_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \
62      (CLOCK_IP_EXTOSC_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \
63     )
64     #error "Software Version Numbers of Clock_Ip_ExtOsc.c and Clock_Ip_Private.h are different"
65 #endif
66 
67 /*==================================================================================================
68 *                           LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
69 ==================================================================================================*/
70 
71 /*==================================================================================================
72 *                                          LOCAL MACROS
73 ==================================================================================================*/
74 
75 /*==================================================================================================
76 *                                         LOCAL CONSTANTS
77 ==================================================================================================*/
78 
79 /*==================================================================================================
80 *                                         LOCAL VARIABLES
81 ==================================================================================================*/
82 
83 /*==================================================================================================
84 *                                        GLOBAL CONSTANTS
85 ==================================================================================================*/
86 
87 /*==================================================================================================
88 *                                        GLOBAL VARIABLES
89 ==================================================================================================*/
90 
91 /*==================================================================================================
92 *                                    GLOBAL FUNCTION PROTOTYPES
93 ==================================================================================================*/
94 /* Clock start section code */
95 #define MCU_START_SEC_CODE
96 
97 #include "Mcu_MemMap.h"
98 
99 
100 
101 /*==================================================================================================
102 *                                    LOCAL FUNCTION PROTOTYPES
103 ==================================================================================================*/
104 
105 static void Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const* Config);
106 static void Clock_Ip_DisableClockIpExternalOscillatorEmpty(Clock_Ip_NameType XoscName);
107 
108 #ifdef CLOCK_IP_FXOSC_OSCON_BYP_EOCV_GM_SEL
109 static void Clock_Ip_ResetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config);
110 static void Clock_Ip_SetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config);
111 static void Clock_Ip_CompleteFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config);
112 static void Clock_Ip_DisableFxoscOsconBypEocvGmSel(Clock_Ip_NameType XoscName);
113 static void Clock_Ip_EnableFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config);
114 #endif
115 static void Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const* Config);
116 #ifdef CLOCK_IP_SXOSC_OSCON_EOCV
117 static void Clock_Ip_ResetSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config);
118 static void Clock_Ip_SetSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config);
119 static void Clock_Ip_CompleteSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config);
120 static void Clock_Ip_DisableSxoscOsconEocv(Clock_Ip_NameType XoscName);
121 static void Clock_Ip_EnableSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config);
122 #endif
123 
124 
125 
126 
127 /* Clock stop section code */
128 #define MCU_STOP_SEC_CODE
129 
130 #include "Mcu_MemMap.h"
131 /*==================================================================================================
132 *                                         LOCAL FUNCTIONS
133 ==================================================================================================*/
134 
135 /* Clock start section code */
136 #define MCU_START_SEC_CODE
137 
138 #include "Mcu_MemMap.h"
139 
Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const * Config)140 static void Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const* Config)
141 {
142     (void)Config;
143     /* No implementation */
144 }
Clock_Ip_DisableClockIpExternalOscillatorEmpty(Clock_Ip_NameType XoscName)145 static void Clock_Ip_DisableClockIpExternalOscillatorEmpty(Clock_Ip_NameType XoscName)
146 {
147     (void)XoscName;
148     /* No implementation */
149 }
150 
151 
152 
153 
154 #ifdef CLOCK_IP_FXOSC_OSCON_BYP_EOCV_GM_SEL
Clock_Ip_ResetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)155 static void Clock_Ip_ResetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
156 {
157     uint32 Instance;
158 
159     if (NULL_PTR != Config)
160     {
161         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
162 
163         /* Disable FXOSC */
164         Clock_Ip_apxXosc[Instance]->CTRL &= ~FXOSC_CTRL_OSCON_MASK;
165     }
166     else
167     {
168         (void)Instance;
169     }
170 }
171 
172 /* Set Fxosc configuration to register */
Clock_Ip_SetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)173 static void Clock_Ip_SetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
174 {
175     uint32 Instance;
176 
177     if (NULL_PTR != Config)
178     {
179         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
180 
181         if (Config->Enable != 0U)
182         {
183             Clock_Ip_apxXosc[Instance]->CTRL =
184                (
185                 FXOSC_CTRL_OSCON(1U)                                                |
186                 FXOSC_CTRL_OSC_BYP(Config->BypassOption)                            |
187                 FXOSC_CTRL_EOCV(Config->StartupDelay)                               |
188                 FXOSC_CTRL_GM_SEL(Config->TransConductance)                         |
189                 FXOSC_CTRL_COMP_EN(Config->CompEn)                                  |
190         #ifdef CLOCK_IP_FXOSC_ALC_SUPPORTED
191             #if (CLOCK_IP_FXOSC_ALC_SUPPORTED == STD_ON)
192                 FXOSC_CTRL_ALC_D(Config->AutoLevelController)
193             #else
194                 (0U)
195             #endif
196         #else
197                 (0U)
198         #endif
199                );
200         }
201     #ifdef CLOCK_IP_GET_FREQUENCY_API
202     #if (CLOCK_IP_GET_FREQUENCY_API == STD_ON)
203         Clock_Ip_SetExternalOscillatorFrequency(Config->Name,Config->Freq);
204     #endif
205     #endif
206     }
207     else
208     {
209         (void)Instance;
210     }
211 }
Clock_Ip_CompleteFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)212 static void Clock_Ip_CompleteFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
213 {
214     boolean TimeoutOccurred = FALSE;
215     uint32 StartTime;
216     uint32 ElapsedTime;
217     uint32 TimeoutTicks;
218     uint32 FxoscStatus;
219     uint32 Instance;
220 
221     if (NULL_PTR != Config)
222     {
223         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
224 
225         if (Config->Enable != 0U)
226         {
227             /* This assumes that FXOSC_CTRL[COMP_EN] = 1 and FXOSC_CTRL[OSC_BYP] = 0 (i.e. crystal clock/oscillator output). */
228             /* In bypass mode (i.e. EXTAL output), FXOSC_CTRL[COMP_EN] = 0 and FXOSC_CTRL[OSC_BYP] = 1, which means that
229                we cannot check for stabilization. This shifts the responsibility of waiting for a stable clock to the
230                upper layers. */
231             if (Config->CompEn != 0U)
232             {
233                 if(0U == Config->BypassOption)
234                 {
235                     Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
236                     /* Wait until xosc is locked */
237                     do
238                     {
239                         FxoscStatus = ((Clock_Ip_apxXosc[Instance]->STAT & FXOSC_STAT_OSC_STAT_MASK) >> FXOSC_STAT_OSC_STAT_SHIFT);
240                         TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
241                     }
242                     while ((0U == FxoscStatus) && (FALSE == TimeoutOccurred));
243 
244                     if (TimeoutOccurred)
245                     {
246                         /* Report timeout error */
247                         Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
248                     }
249                 }
250                 else
251                 {
252                     /* Invalid FXOSC configuration: FXOSC_CTRL[COMP_EN] = 1 enforces FXOSC_CTRL[OSC_BYP] = 0. */
253                     /* Report timeout error */
254                     Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_FXOSC_CONFIGURATION_ERROR, Config->Name);
255                 }
256             }
257         }
258     }
259     else
260     {
261         (void)TimeoutOccurred;
262         (void)StartTime;
263         (void)ElapsedTime;
264         (void)TimeoutTicks;
265         (void)FxoscStatus;
266         (void)Instance;
267     }
268 }
Clock_Ip_DisableFxoscOsconBypEocvGmSel(Clock_Ip_NameType XoscName)269 static void Clock_Ip_DisableFxoscOsconBypEocvGmSel(Clock_Ip_NameType XoscName)
270 {
271     uint32 Instance = Clock_Ip_au8ClockFeatures[XoscName][CLOCK_IP_MODULE_INSTANCE];
272 
273     /* Disable SOSC. */
274     Clock_Ip_apxXosc[Instance]->CTRL &= ~FXOSC_CTRL_OSCON_MASK;
275 }
Clock_Ip_EnableFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)276 static void Clock_Ip_EnableFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
277 {
278     uint32 Instance;
279 
280     if (NULL_PTR != Config)
281     {
282         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
283 
284         if (1U == Config->Enable)
285         {
286             /* Enable SOSC. */
287             Clock_Ip_apxXosc[Instance]->CTRL |= FXOSC_CTRL_OSCON_MASK;
288         }
289     }
290     else
291     {
292         (void)Instance;
293     }
294 }
295 #endif
296 
297 #ifdef CLOCK_IP_SXOSC_OSCON_EOCV
Clock_Ip_ResetSxoscOsconEocv(Clock_Ip_XoscConfigType const * Config)298 static void Clock_Ip_ResetSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config)
299 {
300     uint32 Instance;
301 
302     if (NULL_PTR != Config)
303     {
304         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
305 
306         /* Disable SXOSC */
307         Clock_Ip_apxXosc[Instance]->CTRL &= ~FXOSC_CTRL_OSCON_MASK;
308     }
309     else
310     {
311         (void)Instance;
312     }
313 }
314 
315 /* Set Sxosc configuration to register */
Clock_Ip_SetSxoscOsconEocv(Clock_Ip_XoscConfigType const * Config)316 static void Clock_Ip_SetSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config)
317 {
318     uint32 Instance;
319 
320     if (NULL_PTR != Config)
321     {
322         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
323 
324         if (Config->Enable != 0U)
325         {
326             Clock_Ip_apxXosc[Instance]->CTRL =
327                (SXOSC_SXOSC_CTRL_OSCON(1U)                                                |
328                 SXOSC_SXOSC_CTRL_EOCV(Config->StartupDelay)
329                );
330         }
331     #ifdef CLOCK_IP_GET_FREQUENCY_API
332     #if (CLOCK_IP_GET_FREQUENCY_API == STD_ON)
333         Clock_Ip_SetExternalOscillatorFrequency(Config->Name,Config->Freq);
334     #endif
335     #endif
336     }
337     else
338     {
339         (void)Instance;
340     }
341 }
Clock_Ip_CompleteSxoscOsconEocv(Clock_Ip_XoscConfigType const * Config)342 static void Clock_Ip_CompleteSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config)
343 {
344     boolean TimeoutOccurred = FALSE;
345     uint32 StartTime;
346     uint32 ElapsedTime;
347     uint32 TimeoutTicks;
348     uint32 SxoscStatus;
349     uint32 Instance;
350 
351     if (NULL_PTR != Config)
352     {
353         Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
354 
355         if (Config->Enable != 0U)
356         {
357             if(0U == Config->BypassOption)
358             {
359                 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
360                 /* Wait until xosc is locked */
361                 do
362                 {
363                     SxoscStatus = ((Clock_Ip_apxXosc[Instance]->STAT & SXOSC_SXOSC_STAT_OSC_STAT_MASK) >> SXOSC_SXOSC_STAT_OSC_STAT_SHIFT);
364                     TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
365                 }
366                 while ((0U == SxoscStatus) && (FALSE == TimeoutOccurred));
367 
368                 if (TimeoutOccurred)
369                 {
370                     /* Report timeout error */
371                     Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
372                 }
373             }
374             else
375             {
376                 /* Invalid FXOSC configuration: FXOSC_CTRL[COMP_EN] = 1 enforces FXOSC_CTRL[OSC_BYP] = 0. */
377                 /* Report timeout error */
378                 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_FXOSC_CONFIGURATION_ERROR, Config->Name);
379             }
380         }
381     }
382     else
383     {
384         (void)TimeoutOccurred;
385         (void)StartTime;
386         (void)ElapsedTime;
387         (void)TimeoutTicks;
388         (void)SxoscStatus;
389         (void)Instance;
390     }
391 }
392 
393 /* Disable Sxosc */
Clock_Ip_DisableSxoscOsconEocv(Clock_Ip_NameType XoscName)394 static void Clock_Ip_DisableSxoscOsconEocv(Clock_Ip_NameType XoscName)
395 {
396     (void)XoscName;
397 }
398 
399 /* Enable Sxosc */
Clock_Ip_EnableSxoscOsconEocv(Clock_Ip_XoscConfigType const * Config)400 static void Clock_Ip_EnableSxoscOsconEocv(Clock_Ip_XoscConfigType const* Config)
401 {
402     (void)Config;
403 }
404 #endif
405 
406 
407 /*==================================================================================================
408 *                                        GLOBAL FUNCTIONS
409 ==================================================================================================*/
410 
411 /* Clock stop section code */
412 #define MCU_STOP_SEC_CODE
413 
414 #include "Mcu_MemMap.h"
415 
416 /*==================================================================================================
417 *                                        GLOBAL CONSTANTS
418 ==================================================================================================*/
419 /* Clock start constant section data */
420 #define MCU_START_SEC_CONST_UNSPECIFIED
421 
422 #include "Mcu_MemMap.h"
423 
424 const Clock_Ip_ExtOscCallbackType Clock_Ip_axExtOscCallbacks[CLOCK_IP_XOSC_CALLBACKS_COUNT] =
425 {
426     {
427         Clock_Ip_ExternalOscillatorEmpty,        /* Reset */
428         Clock_Ip_ExternalOscillatorEmpty,        /* Set */
429         Clock_Ip_ExternalOscillatorEmpty,        /* Complete */
430         Clock_Ip_DisableClockIpExternalOscillatorEmpty, /* Disable */
431         Clock_Ip_ExternalOscillatorEmpty,        /* Enable */
432     },
433 #ifdef CLOCK_IP_FXOSC_OSCON_BYP_EOCV_GM_SEL
434     {
435         Clock_Ip_ResetFxoscOsconBypEocvGmSel,        /* Reset */
436         Clock_Ip_SetFxoscOsconBypEocvGmSel,          /* Set */
437         Clock_Ip_CompleteFxoscOsconBypEocvGmSel,     /* Complete */
438         Clock_Ip_DisableFxoscOsconBypEocvGmSel,      /* Disable */
439         Clock_Ip_EnableFxoscOsconBypEocvGmSel,       /* Enable */
440     },
441 #endif
442 #ifdef CLOCK_IP_SXOSC_OSCON_EOCV
443     {
444         Clock_Ip_ResetSxoscOsconEocv,                /* Reset */
445         Clock_Ip_SetSxoscOsconEocv,                  /* Set */
446         Clock_Ip_CompleteSxoscOsconEocv,             /* Complete */
447         Clock_Ip_DisableSxoscOsconEocv,              /* Disable */
448         Clock_Ip_EnableSxoscOsconEocv,               /* Enable */
449     },
450 #endif
451 };
452 
453 /* Clock stop constant section data */
454 #define MCU_STOP_SEC_CONST_UNSPECIFIED
455 
456 #include "Mcu_MemMap.h"
457 
458 
459 
460 #ifdef __cplusplus
461 }
462 #endif
463 
464 /** @} */
465