1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 /**
7 * @file Clock_Ip_Divider.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
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 0
40 #define CLOCK_IP_DIVIDER_SW_MINOR_VERSION_C 9
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_CGM_X_DE_DIV_STAT_WITHOUT_PHASE_WITH_TRIGGER
108 static void Clock_Ip_SetCgmXDeDivStatWithoutPhaseWithTrigger(Clock_Ip_DividerConfigType const* Config);
109 #endif
110 #ifdef CLOCK_IP_PLLDIG_PLL0DIV_DE_DIV_OUTPUT
111 static void Clock_Ip_SetPlldigPll0divDeDivOutput(Clock_Ip_DividerConfigType const* Config);
112 #endif
113
114
115 /* Clock stop section code */
116 #define MCU_STOP_SEC_CODE
117
118 #include "Mcu_MemMap.h"
119 /*==================================================================================================
120 * LOCAL FUNCTIONS
121 ==================================================================================================*/
122 #define MCU_START_SEC_CODE
123 /* Clock start section code */
124
125 #include "Mcu_MemMap.h"
126
Clock_Ip_Callback_DividerEmpty(Clock_Ip_DividerConfigType const * Config)127 static void Clock_Ip_Callback_DividerEmpty(Clock_Ip_DividerConfigType const* Config)
128 {
129 (void)Config;
130 /* No implementation */
131 }
132
133 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE
Clock_Ip_SetCgmXDeDivStatWithoutPhase(Clock_Ip_DividerConfigType const * Config)134 static void Clock_Ip_SetCgmXDeDivStatWithoutPhase(Clock_Ip_DividerConfigType const* Config)
135 {
136 uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
137 uint32 SelectorIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_SELECTOR_INDEX];
138 uint32 DividerIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_DIVIDER_INDEX];
139
140 uint32 DividerMask = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueMask;
141 uint32 DividerShift = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueShift;
142
143 uint32 RegValue;
144 boolean TimeoutOccurred = FALSE;
145 uint32 StartTime;
146 uint32 ElapsedTime;
147 uint32 TimeoutTicks;
148 uint32 DividerStatus;
149
150 /* Program divider value */
151 if (Config->Value != 0U)
152 {
153 RegValue = Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex];
154 RegValue &= ~DividerMask;
155 RegValue |= (((Config->Value-1U) << DividerShift) & DividerMask);
156 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] = RegValue;
157
158 #ifdef CLOCK_IP_DIVIDER_HAVE_DIV_FMT
159 if((Instance == 0U) && (SelectorIndex == 2U) && (DividerIndex == 2U))
160 {
161 IP_MC_CGM_0->MUX_2_DC_2 &= ~MC_CGM_MUX_2_DC_2_DIV_FMT_MASK;
162 }
163 else if((Instance == 4U) && (SelectorIndex == 2U) && (DividerIndex == 2U))
164 {
165 IP_MC_CGM_4->MUX_2_DC_2 &= ~MC_CGM_MUX_2_DC_2_DIV_FMT_MASK;
166 }
167 else
168 {
169 /* Do nothing */
170 }
171 #endif
172 }
173
174 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
175 /* Wait for acknowledge to be cleared. */
176 do
177 {
178 DividerStatus = (Clock_Ip_apxCgm[Instance][SelectorIndex]->MUX_DIV_UPD_STAT & MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_MASK);
179 TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
180 }
181 while ((MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_PENDING == DividerStatus) && (FALSE == TimeoutOccurred));
182
183 if (FALSE == TimeoutOccurred)
184 {
185 /* Enable or Disable the Clock Divider */
186 if (Config->Value != 0U)
187 {
188 /* Enable divider */
189 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] |= MC_CGM_MUX_DC_DE_MASK;
190 }
191 else
192 {
193 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] &= ~MC_CGM_MUX_DC_DE_MASK;
194 }
195 }
196 else
197 {
198 /* Report timeout error */
199 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
200 }
201 }
202 #endif
203
204 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE_WITH_TRIGGER
Clock_Ip_SetCgmXDeDivStatWithoutPhaseWithTrigger(Clock_Ip_DividerConfigType const * Config)205 static void Clock_Ip_SetCgmXDeDivStatWithoutPhaseWithTrigger(Clock_Ip_DividerConfigType const* Config)
206 {
207 uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
208 uint32 SelectorIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_SELECTOR_INDEX];
209 uint32 DividerIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_DIVIDER_INDEX];
210
211 uint32 DividerMask = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueMask;
212 uint32 DividerShift = Clock_Ip_axFeatureExtensions[Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_EXTENSION_INDEX]].DividerValueShift;
213
214 uint32 RegValue;
215 boolean TimeoutOccurred = FALSE;
216 uint32 StartTime;
217 uint32 ElapsedTime;
218 uint32 TimeoutTicks;
219 uint32 DividerStatus;
220
221 /* Program divider value */
222 if (Config->Value != 0U)
223 {
224 RegValue = Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex];
225 RegValue &= ~DividerMask;
226 RegValue |= ((Config->Value-1U) << DividerShift) & DividerMask;
227 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] = RegValue;
228 }
229
230 /* Immediate update is triggered. */
231 if ((Clock_Ip_apxCgm[Instance][SelectorIndex]->MUX_DIV_TRIG_CTRL & MC_CGM_MUX_DIV_TRIG_CTRL_TCTL_MASK) != MC_CGM_MUX_DIV_TRIG_CTRL_COMMON_TRIGGER_DIVIDER_UPDATE)
232 {
233 Clock_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_IP_TIMEOUT_VALUE_US);
234 /* Wait for acknowledge to be cleared. */
235 do
236 {
237 DividerStatus = (Clock_Ip_apxCgm[Instance][SelectorIndex]->MUX_DIV_UPD_STAT & MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_MASK);
238 TimeoutOccurred = Clock_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
239 }
240 while ((MC_CGM_MUX_DIV_UPD_STAT_DIV_STAT_PENDING == DividerStatus) && (FALSE == TimeoutOccurred));
241 }
242
243 if (FALSE == TimeoutOccurred)
244 {
245 /* Enable or Disable the Clock Divider */
246 if (Config->Value != 0U)
247 {
248 /* Enable divider */
249 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] |= MC_CGM_MUX_DC_DE_MASK;
250 }
251 else
252 {
253 Clock_Ip_apxCgm[Instance][SelectorIndex]->Divider[DividerIndex] &= ~MC_CGM_MUX_DC_DE_MASK;
254 }
255 }
256 else
257 {
258 /* Report timeout error */
259 Clock_Ip_ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, Config->Name);
260 }
261 }
262 #endif
263
264 #ifdef CLOCK_IP_PLLDIG_PLL0DIV_DE_DIV_OUTPUT
Clock_Ip_SetPlldigPll0divDeDivOutput(Clock_Ip_DividerConfigType const * Config)265 static void Clock_Ip_SetPlldigPll0divDeDivOutput(Clock_Ip_DividerConfigType const* Config)
266 {
267
268 uint32 Instance = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_MODULE_INSTANCE];
269 uint32 DividerIndex = Clock_Ip_au8ClockFeatures[Config->Name][CLOCK_IP_DIVIDER_INDEX];
270 uint32 RegValue;
271
272 /* Check that divider is already disabled */
273 CLOCK_IP_DEV_ASSERT(!(Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex] & PLLDIG_PLLODIV_DE_MASK));
274
275 /* Check if divider is enabled */
276 if (Config->Value != 0U)
277 {
278 RegValue = Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex];
279 RegValue |= PLLDIG_PLLODIV_DE_MASK;
280 RegValue &= ~PLLDIG_PLLODIV_DIV_MASK;
281 RegValue |= PLLDIG_PLLODIV_DIV(Config->Value - 1U);
282 Clock_Ip_apxPll[Instance].PllInstance->PLLODIV[DividerIndex] = RegValue;
283 }
284 }
285 #endif
286
287
288
289 /*==================================================================================================
290 * GLOBAL FUNCTIONS
291 ==================================================================================================*/
292
293 /* Clock stop section code */
294 #define MCU_STOP_SEC_CODE
295
296 #include "Mcu_MemMap.h"
297
298 /*==================================================================================================
299 * GLOBAL CONSTANTS
300 ==================================================================================================*/
301
302 /* Clock start constant section data */
303 #define MCU_START_SEC_CONST_UNSPECIFIED
304
305 #include "Mcu_MemMap.h"
306
307 const Clock_Ip_DividerCallbackType Clock_Ip_axDividerCallbacks[CLOCK_IP_DIVIDER_CALLBACKS_COUNT] =
308 {
309 {
310 Clock_Ip_Callback_DividerEmpty, /* Set */
311 },
312 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE
313 {
314 Clock_Ip_SetCgmXDeDivStatWithoutPhase, /* Set */
315 },
316 #endif
317 #ifdef CLOCK_IP_CGM_X_DE_DIV_STAT_WITHOUT_PHASE_WITH_TRIGGER
318 {
319 Clock_Ip_SetCgmXDeDivStatWithoutPhaseWithTrigger, /* Set */
320 },
321 #endif
322 #ifdef CLOCK_IP_PLLDIG_PLL0DIV_DE_DIV_OUTPUT
323 {
324 Clock_Ip_SetPlldigPll0divDeDivOutput, /* Set */
325 },
326 #endif
327 };
328
329 /* Clock stop constant section data */
330 #define MCU_STOP_SEC_CONST_UNSPECIFIED
331
332 #include "Mcu_MemMap.h"
333
334
335 #ifdef __cplusplus
336 }
337 #endif
338
339 /** @} */
340