1 /*
2 * Copyright 2020-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 /**
7 * @file Clock_Ip_Divider.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 #include "Clock_Ip_Private.h"
30
31
32 /*==================================================================================================
33 SOURCE FILE VERSION INFORMATION
34 ==================================================================================================*/
35 #define CLOCK_IP_DIVIDER_VENDOR_ID_C 43
36 #define CLOCK_IP_DIVIDER_AR_RELEASE_MAJOR_VERSION_C 4
37 #define CLOCK_IP_DIVIDER_AR_RELEASE_MINOR_VERSION_C 7
38 #define CLOCK_IP_DIVIDER_AR_RELEASE_REVISION_VERSION_C 0
39 #define CLOCK_IP_DIVIDER_SW_MAJOR_VERSION_C 3
40 #define CLOCK_IP_DIVIDER_SW_MINOR_VERSION_C 0
41 #define CLOCK_IP_DIVIDER_SW_PATCH_VERSION_C 0
42
43 /*==================================================================================================
44 * FILE VERSION CHECKS
45 ==================================================================================================*/
46 /* Check if Clock_Ip_Divider.c file and Clock_Ip_Private.h file are of the same vendor */
47 #if (CLOCK_IP_DIVIDER_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID)
48 #error "Clock_Ip_Divider.c and Clock_Ip_Private.h have different vendor ids"
49 #endif
50
51 /* Check if Clock_Ip_Divider.c file and Clock_Ip_Private.h file are of the same Autosar version */
52 #if ((CLOCK_IP_DIVIDER_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
53 (CLOCK_IP_DIVIDER_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
54 (CLOCK_IP_DIVIDER_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
55 )
56 #error "AutoSar Version Numbers of Clock_Ip_Divider.c and Clock_Ip_Private.h are different"
57 #endif
58
59 /* Check if Clock_Ip_Divider.c file and Clock_Ip_Private.h file are of the same Software version */
60 #if ((CLOCK_IP_DIVIDER_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \
61 (CLOCK_IP_DIVIDER_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \
62 (CLOCK_IP_DIVIDER_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \
63 )
64 #error "Software Version Numbers of Clock_Ip_Divider.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 * LOCAL FUNCTION PROTOTYPES
101 ==================================================================================================*/
102
103 static void Clock_Ip_Callback_DividerEmpty(Clock_Ip_DividerConfigType const* Config);
104 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE
105 static void Clock_Ip_SetCgmXDeDivStatWithoutPhase(Clock_Ip_DividerConfigType const* Config);
106 #endif
107 #ifdef CLOCK_IP_PLL_PLL0DIV_DE_DIV_OUTPUT
108 static void Clock_Ip_SetPllPll0divDeDivOutput(Clock_Ip_DividerConfigType const* Config);
109 #endif
110
111 #ifdef CLOCK_IP_PLL_PLLDV_ODIV2_OUTPUT
112 static void Clock_Ip_SetPllPlldvOdiv2Output(Clock_Ip_DividerConfigType const* Config);
113 #endif
114
115
116
117 /* Clock stop section code */
118 #define MCU_STOP_SEC_CODE
119
120 #include "Mcu_MemMap.h"
121 /*==================================================================================================
122 * LOCAL FUNCTIONS
123 ==================================================================================================*/
124 #define MCU_START_SEC_CODE
125 /* Clock start section code */
126
127 #include "Mcu_MemMap.h"
128
Clock_Ip_Callback_DividerEmpty(Clock_Ip_DividerConfigType const * Config)129 static void Clock_Ip_Callback_DividerEmpty(Clock_Ip_DividerConfigType const* Config)
130 {
131 (void)Config;
132 /* No implementation */
133 }
134
135 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE
Clock_Ip_SetCgmXDeDivStatWithoutPhase(Clock_Ip_DividerConfigType const * Config)136 static void Clock_Ip_SetCgmXDeDivStatWithoutPhase(Clock_Ip_DividerConfigType const* Config)
137 {
138 uint32 Instance;
139 uint32 SelectorIndex;
140 uint32 DividerIndex;
141
142 uint32 DividerMask;
143 uint32 DividerShift;
144
145 uint32 RegValue;
146 boolean TimeoutOccurred = FALSE;
147 uint32 StartTime;
148 uint32 ElapsedTime;
149 uint32 TimeoutTicks;
150 uint32 DividerStatus;
151
152 if (NULL_PTR != Config)
153 {
154 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
155 SelectorIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_SELECTOR_INDEX];
156 DividerIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_DIVIDER_INDEX];
157 DividerMask = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueMask;
158 DividerShift = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueShift;
159
160 /* Program divider value */
161 if (Config->Value != 0U)
162 {
163 RegValue = Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex];
164 RegValue &= ~DividerMask;
165 RegValue |= (((Config->Value-1U) << DividerShift) & DividerMask);
166 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] = RegValue;
167
168 #ifdef CLOCK_IP_DIVIDER_HAVE_DIV_FMT
169 if((Instance == 0U) && (SelectorIndex == 2U) && (DividerIndex == 2U))
170 {
171 IP_MC_CGM_0->MUX_2_DC_2 &= ~MC_CGM_MUX_2_DC_2_DIV_FMT_MASK;
172 }
173 else if((Instance == 4U) && (SelectorIndex == 2U) && (DividerIndex == 2U))
174 {
175 IP_MC_CGM_4->MUX_2_DC_2 &= ~MC_CGM_MUX_2_DC_2_DIV_FMT_MASK;
176 }
177 else
178 {
179 /* Do nothing */
180 }
181 #endif
182 }
183
184 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
185 /* Wait for acknowledge to be cleared. */
186 do
187 {
188 DividerStatus = (Clock_Ip_apxCgm[Instance][SelectorIndex]->MUX_DIV_UPD_STAT & MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_MASK);
189 TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
190 }
191 while ((MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_PENDING == DividerStatus) && (FALSE == TimeoutOccurred));
192
193 if (FALSE == TimeoutOccurred)
194 {
195 /* Enable or Disable the Clock Divider */
196 if (Config->Value != 0U)
197 {
198 /* Enable divider */
199 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] |= MC_CGM_MUX_DC_DE_MASK;
200 }
201 else
202 {
203 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] &= ~MC_CGM_MUX_DC_DE_MASK;
204 }
205 }
206 else
207 {
208 /* Report timeout error */
209 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
210 }
211 }
212 else
213 {
214 (void)Instance;
215 (void)SelectorIndex;
216 (void)DividerIndex;
217 (void)DividerMask;
218 (void)DividerShift;
219 (void)RegValue;
220 (void)TimeoutOccurred;
221 (void)StartTime;
222 (void)ElapsedTime;
223 (void)TimeoutTicks;
224 (void)DividerStatus;
225 }
226 }
227 #endif
228
229 #ifdef CLOCK_IP_PLL_PLL0DIV_DE_DIV_OUTPUT
Clock_Ip_SetPllPll0divDeDivOutput(Clock_Ip_DividerConfigType const * Config)230 static void Clock_Ip_SetPllPll0divDeDivOutput(Clock_Ip_DividerConfigType const* Config)
231 {
232 uint32 Instance;
233 uint32 DividerIndex;
234 uint32 RegValue;
235
236 if (NULL_PTR != Config)
237 {
238 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
239 DividerIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_DIVIDER_INDEX];
240 /* Disable divider */
241 CLOCK_IP_DEV_ASSERT(!(Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex] & PLL_PLLODIV_DE_MASK));
242 /* Check if divider is enabled */
243 if (Config->Value != 0U)
244 {
245 RegValue = Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex];
246 RegValue |= PLL_PLLODIV_DE_MASK;
247 RegValue &= ~PLL_PLLODIV_DIV_MASK;
248 RegValue |= PLL_PLLODIV_DIV(Config->Value - 1U);
249 Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex] = RegValue;
250 }
251 }
252 else
253 {
254 (void)Instance;
255 (void)DividerIndex;
256 (void)RegValue;
257 }
258 }
259 #endif
260
261 #ifdef CLOCK_IP_PLL_PLLDV_ODIV2_OUTPUT
262 /* Set Pll Odiv2 configuration to register */
Clock_Ip_SetPllPlldvOdiv2Output(Clock_Ip_DividerConfigType const * Config)263 static void Clock_Ip_SetPllPlldvOdiv2Output(Clock_Ip_DividerConfigType const* Config)
264 {
265 uint32 Instance;
266 uint32 RegValue;
267 uint32 DividerValue;
268
269 if (NULL_PTR != Config)
270 {
271 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
272 DividerValue = (Config->Value != 0U) ? Config->Value : 1U;
273
274 RegValue = Clock_Ip_apxPll[Instance].PllInstance->PLLDV;
275 RegValue &= ~PLL_PLLDV_ODIV2_MASK;
276 RegValue |= PLL_PLLDV_ODIV2(DividerValue);
277 Clock_Ip_apxPll[Instance].PllInstance->PLLDV = RegValue;
278 }
279 else
280 {
281 (void)Instance;
282 (void)RegValue;
283 (void)DividerValue;
284 }
285 }
286 #endif
287
288
289
290 /*==================================================================================================
291 * GLOBAL FUNCTIONS
292 ==================================================================================================*/
293
294
295 /* Clock stop section code */
296 #define MCU_STOP_SEC_CODE
297
298 #include "Mcu_MemMap.h"
299
300 /*==================================================================================================
301 * GLOBAL CONSTANTS
302 ==================================================================================================*/
303
304 /* Clock start constant section data */
305 #define MCU_START_SEC_CONST_UNSPECIFIED
306
307 #include "Mcu_MemMap.h"
308
309 const Clock_Ip_DividerCallbackType Clock_Ip_axDividerCallbacks[CLOCK_IP_DIVIDER_CALLBACKS_COUNT] =
310 {
311 {
312 Clock_Ip_Callback_DividerEmpty, /* Set */
313 },
314 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE
315 {
316 Clock_Ip_SetCgmXDeDivStatWithoutPhase, /* Set */
317 },
318 #endif
319 #ifdef CLOCK_IP_PLL_PLL0DIV_DE_DIV_OUTPUT
320 {
321 Clock_Ip_SetPllPll0divDeDivOutput, /* Set */
322 },
323 #endif /* CLOCK_IP_PLL_PLL0DIV_DE_DIV_OUTPUT */
324 #ifdef CLOCK_IP_PLL_PLLDV_ODIV2_OUTPUT
325 {
326 Clock_Ip_SetPllPlldvOdiv2Output, /* Set */
327 },
328 #endif /* CLOCK_IP_PLL_PLLDV_ODIV2_OUTPUT */
329
330 };
331
332 /* Clock stop constant section data */
333 #define MCU_STOP_SEC_CONST_UNSPECIFIED
334
335 #include "Mcu_MemMap.h"
336
337
338 #ifdef __cplusplus
339 }
340 #endif
341
342 /** @} */
343