1 /*
2  * Copyright 2021-2022 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 /**
7 *   @file       Clock_Ip_ExtOsc.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 
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               0
40 #define CLOCK_IP_EXTOSC_SW_MINOR_VERSION_C               9
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 
117 
118 
119 
120 /* Clock stop section code */
121 #define MCU_STOP_SEC_CODE
122 
123 #include "Mcu_MemMap.h"
124 /*==================================================================================================
125 *                                         LOCAL FUNCTIONS
126 ==================================================================================================*/
127 
128 /* Clock start section code */
129 #define MCU_START_SEC_CODE
130 
131 #include "Mcu_MemMap.h"
132 
Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const * Config)133 static void Clock_Ip_ExternalOscillatorEmpty(Clock_Ip_XoscConfigType const* Config)
134 {
135     (void)Config;
136     /* No implementation */
137 }
Clock_Ip_DisableClockIpExternalOscillatorEmpty(Clock_Ip_NameType XoscName)138 static void Clock_Ip_DisableClockIpExternalOscillatorEmpty(Clock_Ip_NameType XoscName)
139 {
140     (void)XoscName;
141     /* No implementation */
142 }
143 
144 
145 
146 
147 #ifdef CLOCK_IP_FXOSC_OSCON_BYP_EOCV_GM_SEL
Clock_Ip_ResetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)148 static void Clock_Ip_ResetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
149 {
150     uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
151 
152     /* Disable FXOSC */
153     Clock_Ip_apxXosc[Instance]->CTRL &= ~FXOSC_CTRL_OSCON_MASK;
154 }
155 
156 /* Set Fxosc configuration to register */
Clock_Ip_SetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)157 static void Clock_Ip_SetFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
158 {
159     uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
160 
161     if (Config->Enable != 0U)
162     {
163         Clock_Ip_apxXosc[Instance]->CTRL =
164            (
165             FXOSC_CTRL_OSCON(1U)                                                |
166             FXOSC_CTRL_OSC_BYP(Config->BypassOption)                            |
167             FXOSC_CTRL_EOCV(Config->StartupDelay)                               |
168             FXOSC_CTRL_GM_SEL(Config->TransConductance)                         |
169             FXOSC_CTRL_COMP_EN(Config->CompEn)
170            );
171     }
172 #ifdef CLOCK_IP_GET_FREQUENCY_API
173 #if (CLOCK_IP_GET_FREQUENCY_API == STD_ON)
174     Clock_Ip_SetExternalOscillatorFrequency(Config->Name,Config->Freq);
175 #endif
176 #endif
177 }
Clock_Ip_CompleteFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)178 static void Clock_Ip_CompleteFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
179 {
180     boolean TimeoutOccurred = FALSE;
181     uint32 StartTime;
182     uint32 ElapsedTime;
183     uint32 TimeoutTicks;
184     uint32 FxoscStatus;
185     uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
186 
187     if (Config->Enable != 0U)
188     {
189         /* This assumes that FXOSC_CTRL[COMP_EN] = 1 and FXOSC_CTRL[OSC_BYP] = 0 (i.e. crystal clock/oscillator output). */
190         /* In bypass mode (i.e. EXTAL output), FXOSC_CTRL[COMP_EN] = 0 and FXOSC_CTRL[OSC_BYP] = 1, which means that
191            we cannot check for stabilization. This shifts the responsibility of waiting for a stable clock to the
192            upper layers. */
193         if (Config->CompEn != 0U)
194         {
195             if(0U == Config->BypassOption)
196             {
197                 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
198                 /* Wait until xosc is locked */
199                 do
200                 {
201                     FxoscStatus = ((Clock_Ip_apxXosc[Instance]->STAT & FXOSC_STAT_OSC_STAT_MASK) >> FXOSC_STAT_OSC_STAT_SHIFT);
202                     TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
203                 }
204                 while ((0U == FxoscStatus) && (FALSE == TimeoutOccurred));
205 
206                 if (TimeoutOccurred)
207                 {
208                     /* Report timeout error */
209                     Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
210                 }
211             }
212             else
213             {
214                 /* Invalid FXOSC configuration: FXOSC_CTRL[COMP_EN] = 1 enforces FXOSC_CTRL[OSC_BYP] = 0. */
215                 /* Report timeout error */
216                 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_FXOSC_CONFIGURATION_ERROR, Config->Name);
217             }
218         }
219     }
220 }
Clock_Ip_DisableFxoscOsconBypEocvGmSel(Clock_Ip_NameType XoscName)221 static void Clock_Ip_DisableFxoscOsconBypEocvGmSel(Clock_Ip_NameType XoscName)
222 {
223     uint32 Instance = Clock_Ip_au8ClockFeatures[XoscName][CLOCK_IP_MODULE_INSTANCE];
224 
225     /* Disable SOSC. */
226     Clock_Ip_apxXosc[Instance]->CTRL &= ~FXOSC_CTRL_OSCON_MASK;
227 }
Clock_Ip_EnableFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const * Config)228 static void Clock_Ip_EnableFxoscOsconBypEocvGmSel(Clock_Ip_XoscConfigType const* Config)
229 {
230     uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
231 
232     if (1U == Config->Enable)
233     {
234         /* Enable SOSC. */
235         Clock_Ip_apxXosc[Instance]->CTRL |= FXOSC_CTRL_OSCON_MASK;
236     }
237 }
238 #endif
239 
240 
241 /*==================================================================================================
242 *                                        GLOBAL FUNCTIONS
243 ==================================================================================================*/
244 
245 /* Clock stop section code */
246 #define MCU_STOP_SEC_CODE
247 
248 #include "Mcu_MemMap.h"
249 
250 /*==================================================================================================
251 *                                        GLOBAL CONSTANTS
252 ==================================================================================================*/
253 /* Clock start constant section data */
254 #define MCU_START_SEC_CONST_UNSPECIFIED
255 
256 #include "Mcu_MemMap.h"
257 
258 const Clock_Ip_ExtOscCallbackType Clock_Ip_axExtOscCallbacks[CLOCK_IP_XOSC_CALLBACKS_COUNT] =
259 {
260     {
261         Clock_Ip_ExternalOscillatorEmpty,        /* Reset */
262         Clock_Ip_ExternalOscillatorEmpty,        /* Set */
263         Clock_Ip_ExternalOscillatorEmpty,        /* Complete */
264         Clock_Ip_DisableClockIpExternalOscillatorEmpty, /* Disable */
265         Clock_Ip_ExternalOscillatorEmpty,        /* Enable */
266     },
267 #ifdef CLOCK_IP_FXOSC_OSCON_BYP_EOCV_GM_SEL
268     {
269         Clock_Ip_ResetFxoscOsconBypEocvGmSel,        /* Reset */
270         Clock_Ip_SetFxoscOsconBypEocvGmSel,          /* Set */
271         Clock_Ip_CompleteFxoscOsconBypEocvGmSel,     /* Complete */
272         Clock_Ip_DisableFxoscOsconBypEocvGmSel,      /* Disable */
273         Clock_Ip_EnableFxoscOsconBypEocvGmSel,       /* Enable */
274     },
275 #endif
276 };
277 
278 /* Clock stop constant section data */
279 #define MCU_STOP_SEC_CONST_UNSPECIFIED
280 
281 #include "Mcu_MemMap.h"
282 
283 
284 
285 #ifdef __cplusplus
286 }
287 #endif
288 
289 /** @} */
290