1 /*
2  * Copyright 2020-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 /**
7 *   @file       Clock_Ip_IntOsc.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 #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 
30 #include "Clock_Ip_Private.h"
31 
32 /*==================================================================================================
33                                SOURCE FILE VERSION INFORMATION
34 ==================================================================================================*/
35 #define CLOCK_IP_INTOSC_VENDOR_ID_C                      43
36 #define CLOCK_IP_INTOSC_AR_RELEASE_MAJOR_VERSION_C       4
37 #define CLOCK_IP_INTOSC_AR_RELEASE_MINOR_VERSION_C       7
38 #define CLOCK_IP_INTOSC_AR_RELEASE_REVISION_VERSION_C    0
39 #define CLOCK_IP_INTOSC_SW_MAJOR_VERSION_C               3
40 #define CLOCK_IP_INTOSC_SW_MINOR_VERSION_C               0
41 #define CLOCK_IP_INTOSC_SW_PATCH_VERSION_C               0
42 
43 /*==================================================================================================
44 *                                     FILE VERSION CHECKS
45 ==================================================================================================*/
46 /* Check if Clock_Ip_IntOsc.c file and Clock_Ip_Private.h file are of the same vendor */
47 #if (CLOCK_IP_INTOSC_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID)
48     #error "Clock_Ip_IntOsc.c and Clock_Ip_Private.h have different vendor ids"
49 #endif
50 
51 /* Check if Clock_Ip_IntOsc.c file and Clock_Ip_Private.h file are of the same Autosar version */
52 #if ((CLOCK_IP_INTOSC_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
53      (CLOCK_IP_INTOSC_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
54      (CLOCK_IP_INTOSC_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
55     )
56     #error "AutoSar Version Numbers of Clock_Ip_IntOsc.c and Clock_Ip_Private.h are different"
57 #endif
58 
59 /* Check if Clock_Ip_IntOsc.c file and Clock_Ip_Private.h file are of the same Software version */
60 #if ((CLOCK_IP_INTOSC_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \
61      (CLOCK_IP_INTOSC_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \
62      (CLOCK_IP_INTOSC_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \
63     )
64     #error "Software Version Numbers of Clock_Ip_IntOsc.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 *                                    LOCAL FUNCTION PROTOTYPES
100 ==================================================================================================*/
101 
102 static void Clock_Ip_InternalOscillatorEmpty(Clock_Ip_IrcoscConfigType const* Config);
103 static void Clock_Ip_InternalOscillatorEmpty_Disable(Clock_Ip_NameType Name);
104 #ifdef CLOCK_IP_FIRC_STDBY_ENABLE
105 static void Clock_Ip_SetFircStdby(Clock_Ip_IrcoscConfigType const* Config);
106 static void Clock_Ip_EnableFircStdby(Clock_Ip_IrcoscConfigType const* Config);
107 static void Clock_Ip_DisableFircStdby(Clock_Ip_NameType Name);
108 #endif
109 #ifdef CLOCK_IP_SIRC_STDBY_ENABLE
110 static void Clock_Ip_SetSircStdby(Clock_Ip_IrcoscConfigType const* Config);
111 static void Clock_Ip_EnableSircStdby(Clock_Ip_IrcoscConfigType const* Config);
112 static void Clock_Ip_DisableSircStdby(Clock_Ip_NameType Name);
113 #endif
114 #ifdef CLOCK_IP_FIRC_DIV_SEL_HSEb_CONFIG_REG_GPR
115 static void Clock_Ip_SetFircDivSelHSEb(Clock_Ip_IrcoscConfigType const* Config);
116 #endif
117 /* Clock stop section code */
118 #define MCU_STOP_SEC_CODE
119 
120 #include "Mcu_MemMap.h"
121 /*==================================================================================================
122 *                                         LOCAL FUNCTIONS
123 ==================================================================================================*/
124 
125 /* Clock start section code */
126 #define MCU_START_SEC_CODE
127 
128 #include "Mcu_MemMap.h"
129 
Clock_Ip_InternalOscillatorEmpty(Clock_Ip_IrcoscConfigType const * Config)130 static void Clock_Ip_InternalOscillatorEmpty(Clock_Ip_IrcoscConfigType const* Config)
131 {
132     (void)Config;
133     /* No implementation */
134 }
Clock_Ip_InternalOscillatorEmpty_Disable(Clock_Ip_NameType Name)135 static void Clock_Ip_InternalOscillatorEmpty_Disable(Clock_Ip_NameType Name)
136 {
137     (void)Name;
138     /* No implementation */
139 }
140 
141 #ifdef CLOCK_IP_FIRC_STDBY_ENABLE
142 /* Set Firc in Standby mode */
Clock_Ip_SetFircStdby(Clock_Ip_IrcoscConfigType const * Config)143 static void Clock_Ip_SetFircStdby(Clock_Ip_IrcoscConfigType const* Config)
144 {
145     if (NULL_PTR != Config)
146     {
147         if (Config->Enable != 0U)
148         {
149             IP_FIRC->STDBY_ENABLE |= FIRC_STDBY_ENABLE_STDBY_EN_MASK;
150         }
151         else
152         {
153             IP_FIRC->STDBY_ENABLE &= ~FIRC_STDBY_ENABLE_STDBY_EN_MASK;
154         }
155     }
156 }
157 /* Enable Firc in Standby mode */
Clock_Ip_EnableFircStdby(Clock_Ip_IrcoscConfigType const * Config)158 static void Clock_Ip_EnableFircStdby(Clock_Ip_IrcoscConfigType const* Config)
159 {
160     (void)Config;
161     IP_FIRC->STDBY_ENABLE |= FIRC_STDBY_ENABLE_STDBY_EN_MASK;
162 }
163 /* Disable Firc in Standby mode */
Clock_Ip_DisableFircStdby(Clock_Ip_NameType Name)164 static void Clock_Ip_DisableFircStdby(Clock_Ip_NameType Name)
165 {
166     (void)Name;
167     IP_FIRC->STDBY_ENABLE &= ~FIRC_STDBY_ENABLE_STDBY_EN_MASK;
168 }
169 #endif
170 
171 #ifdef CLOCK_IP_SIRC_STDBY_ENABLE
172 /* Set Sirc in Standby mode  */
Clock_Ip_SetSircStdby(Clock_Ip_IrcoscConfigType const * Config)173 static void Clock_Ip_SetSircStdby(Clock_Ip_IrcoscConfigType const* Config)
174 {
175     if (NULL_PTR != Config)
176     {
177         if (Config->Enable != 0U)
178         {
179             IP_SIRC->MISCELLANEOUS_IN |= SIRC_MISCELLANEOUS_IN_STANDBY_ENABLE_MASK;
180         }
181         else
182         {
183             IP_SIRC->MISCELLANEOUS_IN &= ~SIRC_MISCELLANEOUS_IN_STANDBY_ENABLE_MASK;
184         }
185     }
186 }
187 /* Enable Sirc in Standby mode */
Clock_Ip_EnableSircStdby(Clock_Ip_IrcoscConfigType const * Config)188 static void Clock_Ip_EnableSircStdby(Clock_Ip_IrcoscConfigType const* Config)
189 {
190     (void)Config;
191     IP_SIRC->MISCELLANEOUS_IN |= SIRC_MISCELLANEOUS_IN_STANDBY_ENABLE_MASK;
192 }
193 /* Disable Sirc in Standby mode */
Clock_Ip_DisableSircStdby(Clock_Ip_NameType Name)194 static void Clock_Ip_DisableSircStdby(Clock_Ip_NameType Name)
195 {
196     (void)Name;
197     IP_SIRC->MISCELLANEOUS_IN &= ~SIRC_MISCELLANEOUS_IN_STANDBY_ENABLE_MASK;
198 }
199 #endif
200 
201 
202 #ifdef CLOCK_IP_FIRC_DIV_SEL_HSEb_CONFIG_REG_GPR
203 #define CLOCK_IP_WFI_EXECUTED MC_ME_PRTN0_CORE2_STAT_WFI_MASK
204 #define CLOCK_IP_APP_CAN_WRITE 5U
205 /* Set Firc Div Sel */
Clock_Ip_SetFircDivSelHSEb(Clock_Ip_IrcoscConfigType const * Config)206 static void Clock_Ip_SetFircDivSelHSEb(Clock_Ip_IrcoscConfigType const* Config)
207 {
208     uint32 RegValue;
209     uint32 DividerValue = 0U;
210 
211     boolean TimeoutOccurred = FALSE;
212     uint32 StartTime;
213     uint32 ElapsedTime;
214     uint32 TimeoutTicks;
215     uint32 WfiStatus;
216 
217     if (NULL_PTR != Config)
218     {
219         switch(Config->Range)
220         {
221             case CLOCK_IP_SUPPORTS_48MHZ_FREQUENCY:
222                 DividerValue = 3U;
223                 break;
224             case CLOCK_IP_SUPPORTS_24MHZ_FREQUENCY:
225                 DividerValue = 1U;
226                 break;
227             case CLOCK_IP_SUPPORTS_3MHZ_FREQUENCY:
228                 DividerValue = 2U;
229                 break;
230             default:
231                 /* No option in hardware for this value */
232                 break;
233         }
234 
235         /* If divider value option from configuration is valid */
236         if (DividerValue != 0U)
237         {
238             /* Application can write this divider */
239             if ( ((IP_CONFIGURATION_GPR->CONFIG_REG_GPR & CONFIGURATION_GPR_CONFIG_REG_GPR_APP_CORE_ACC_MASK)>>CONFIGURATION_GPR_CONFIG_REG_GPR_APP_CORE_ACC_SHIFT) == CLOCK_IP_APP_CAN_WRITE)
240             {
241                 /* Before access to CONFIG_REG_GPR register, driver should wait for Secure BAF to go in WFI
242                    by reading register PRTN0_CORE2_STAT. Wfi status will be checked. */
243                 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
244                 /* Wait for acknowledge to be cleared. */
245                 do
246                 {
247                     WfiStatus = (IP_MC_ME->PRTN0_CORE2_STAT & MC_ME_PRTN0_CORE2_STAT_WFI_MASK);
248                     TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
249                 }
250                 while ((CLOCK_IP_WFI_EXECUTED != WfiStatus) && (FALSE == TimeoutOccurred));
251 
252                 if (FALSE == TimeoutOccurred)
253                 {
254                     RegValue = IP_CONFIGURATION_GPR->CONFIG_REG_GPR;
255                     RegValue &= ~CONFIGURATION_GPR_CONFIG_REG_GPR_FIRC_DIV_SEL_MASK;
256                     RegValue |= CONFIGURATION_GPR_CONFIG_REG_GPR_FIRC_DIV_SEL(DividerValue);
257                     IP_CONFIGURATION_GPR->CONFIG_REG_GPR = RegValue;
258                 }
259                 else
260                 {
261                     Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
262                 }
263             }
264             else
265             {
266                 /* HSE firmware doesn't allow to write FIRC post divider. Firc range cannot be set as it's configured. */
267                 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_WRITE_PROTECTION_ERROR, Config->Name);
268             }
269         }
270     }
271     else
272     {
273         (void)RegValue;
274         (void)DividerValue;
275         (void)TimeoutOccurred;
276         (void)StartTime;
277         (void)ElapsedTime;
278         (void)TimeoutTicks;
279         (void)WfiStatus;
280     }
281 }
282 #endif
283 
284 
285 
286 /*==================================================================================================
287 *                                        GLOBAL FUNCTIONS
288 ==================================================================================================*/
289 /* Clock stop section code */
290 #define MCU_STOP_SEC_CODE
291 
292 #include "Mcu_MemMap.h"
293 
294 /*==================================================================================================
295 *                                        GLOBAL CONSTANTS
296 ==================================================================================================*/
297 /* Clock start constant section data */
298 #define MCU_START_SEC_CONST_UNSPECIFIED
299 
300 #include "Mcu_MemMap.h"
301 
302 const Clock_Ip_IntOscCallbackType Clock_Ip_axIntOscCallbacks[CLOCK_IP_IRCOSC_CALLBACKS_COUNT] =
303 {
304     {
305         Clock_Ip_InternalOscillatorEmpty,          /* Set */
306         Clock_Ip_InternalOscillatorEmpty,          /* Enable */
307         Clock_Ip_InternalOscillatorEmpty_Disable,  /* Disable */
308     },
309 #ifdef CLOCK_IP_FIRC_STDBY_ENABLE
310     {
311         Clock_Ip_SetFircStdby,                     /* Set */
312         Clock_Ip_EnableFircStdby,                  /* Enable */
313         Clock_Ip_DisableFircStdby,                 /* Disable */
314     },
315 #endif
316 #ifdef CLOCK_IP_SIRC_STDBY_ENABLE
317     {
318         Clock_Ip_SetSircStdby,                     /* Set */
319         Clock_Ip_EnableSircStdby,                  /* Enable */
320         Clock_Ip_DisableSircStdby,                 /* Disable */
321     },
322 #endif
323 #ifdef CLOCK_IP_FIRC_DIV_SEL_HSEb_CONFIG_REG_GPR
324     {
325         Clock_Ip_SetFircDivSelHSEb,                     /* Set */
326         Clock_Ip_InternalOscillatorEmpty,               /* Enable */
327         Clock_Ip_InternalOscillatorEmpty_Disable,       /* Disable */
328     },
329 #endif
330 };
331 
332 
333 
334 
335 /* Clock stop constant section data */
336 #define MCU_STOP_SEC_CONST_UNSPECIFIED
337 
338 #include "Mcu_MemMap.h"
339 
340 #ifdef __cplusplus
341 }
342 #endif
343 
344 /** @} */
345