1 | /* |
2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
3 | * Copyright 2016-2021 NXP |
4 | * All rights reserved. |
5 | * |
6 | * SPDX-License-Identifier: BSD-3-Clause |
7 | */ |
8 | |
9 | #include "fsl_enc.h" |
10 | |
11 | /******************************************************************************* |
12 | * Definitions |
13 | ******************************************************************************/ |
14 | |
15 | /* Component ID definition, used by tools. */ |
16 | #ifndef FSL_COMPONENT_ID |
17 | #define FSL_COMPONENT_ID "platform.drivers.enc" |
18 | #endif |
19 | |
20 | #define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK) |
21 | #if (defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
22 | #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK) |
23 | #else |
24 | #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK) |
25 | #endif |
26 | |
27 | /******************************************************************************* |
28 | * Prototypes |
29 | ******************************************************************************/ |
30 | /*! |
31 | * @brief Get instance number for ENC module. |
32 | * |
33 | * @param base ENC peripheral base address |
34 | */ |
35 | static uint32_t ENC_GetInstance(ENC_Type *base); |
36 | |
37 | /******************************************************************************* |
38 | * Variables |
39 | ******************************************************************************/ |
40 | /*! @brief Pointers to ENC bases for each instance. */ |
41 | static ENC_Type *const s_encBases[] = ENC_BASE_PTRS; |
42 | |
43 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
44 | /*! @brief Pointers to ENC clocks for each instance. */ |
45 | static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS; |
46 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
47 | |
48 | /******************************************************************************* |
49 | * Code |
50 | ******************************************************************************/ |
51 | static uint32_t ENC_GetInstance(ENC_Type *base) |
52 | { |
53 | uint32_t instance; |
54 | |
55 | /* Find the instance index from base address mappings. */ |
56 | for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++) |
57 | { |
58 | if (s_encBases[instance] == base) |
59 | { |
60 | break; |
61 | } |
62 | } |
63 | |
64 | assert(instance < ARRAY_SIZE(s_encBases)); |
65 | |
66 | return instance; |
67 | } |
68 | |
69 | /*! |
70 | * brief Initialization for the ENC module. |
71 | * |
72 | * This function is to make the initialization for the ENC module. It should be called firstly before any operation to |
73 | * the ENC with the operations like: |
74 | * - Enable the clock for ENC module. |
75 | * - Configure the ENC's working attributes. |
76 | * |
77 | * param base ENC peripheral base address. |
78 | * param config Pointer to configuration structure. See to "enc_config_t". |
79 | */ |
80 | void ENC_Init(ENC_Type *base, const enc_config_t *config) |
81 | { |
82 | assert(NULL != config); |
83 | |
84 | uint16_t tmp16; |
85 | |
86 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
87 | /* Enable the clock. */ |
88 | CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]); |
89 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
90 | |
91 | /* ENC_CTRL. */ |
92 | tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK | |
93 | ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK)); |
94 | /* For HOME trigger. */ |
95 | if (kENC_HOMETriggerDisabled != config->HOMETriggerMode) |
96 | { |
97 | tmp16 |= ENC_CTRL_HIP_MASK; |
98 | if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode) |
99 | { |
100 | tmp16 |= ENC_CTRL_HNE_MASK; |
101 | } |
102 | } |
103 | /* For encoder work mode. */ |
104 | if (config->enableReverseDirection) |
105 | { |
106 | tmp16 |= ENC_CTRL_REV_MASK; |
107 | } |
108 | if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode) |
109 | { |
110 | tmp16 |= ENC_CTRL_PH1_MASK; |
111 | } |
112 | /* For INDEX trigger. */ |
113 | if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode) |
114 | { |
115 | tmp16 |= ENC_CTRL_XIP_MASK; |
116 | if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode) |
117 | { |
118 | tmp16 |= ENC_CTRL_XNE_MASK; |
119 | } |
120 | } |
121 | /* Watchdog. */ |
122 | if (config->enableWatchdog) |
123 | { |
124 | tmp16 |= ENC_CTRL_WDE_MASK; |
125 | base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */ |
126 | } |
127 | base->CTRL = tmp16; |
128 | |
129 | /* ENC_FILT. */ |
130 | base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod); |
131 | |
132 | /* ENC_CTRL2. */ |
133 | tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK | |
134 | ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK)); |
135 | if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode) |
136 | { |
137 | tmp16 |= ENC_CTRL2_OUTCTL_MASK; |
138 | } |
139 | if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition) |
140 | { |
141 | tmp16 |= ENC_CTRL2_REVMOD_MASK; |
142 | } |
143 | if (config->enableModuloCountMode) |
144 | { |
145 | tmp16 |= ENC_CTRL2_MOD_MASK; |
146 | /* Set modulus value. */ |
147 | base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */ |
148 | base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */ |
149 | } |
150 | if (config->enableTRIGGERClearPositionCounter) |
151 | { |
152 | tmp16 |= ENC_CTRL2_UPDPOS_MASK; |
153 | } |
154 | if (config->enableTRIGGERClearHoldPositionCounter) |
155 | { |
156 | tmp16 |= ENC_CTRL2_UPDHLD_MASK; |
157 | } |
158 | base->CTRL2 = tmp16; |
159 | |
160 | #if (defined(FSL_FEATURE_ENC_HAS_CTRL3) && FSL_FEATURE_ENC_HAS_CTRL3) |
161 | /* ENC_CTRL3. */ |
162 | tmp16 = base->CTRL3 & (uint16_t)(~(ENC_CTRL3_PMEN_MASK | ENC_CTRL3_PRSC_MASK)); |
163 | if (config->enablePeriodMeasurementFunction) |
164 | { |
165 | tmp16 |= ENC_CTRL3_PMEN_MASK; |
166 | /* Set prescaler value. */ |
167 | tmp16 |= ((uint16_t)config->prescalerValue << ENC_CTRL3_PRSC_SHIFT); |
168 | } |
169 | base->CTRL3 = tmp16; |
170 | #endif |
171 | |
172 | /* ENC_UCOMP & ENC_LCOMP. */ |
173 | base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */ |
174 | base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */ |
175 | |
176 | /* ENC_UINIT & ENC_LINIT. */ |
177 | base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */ |
178 | base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */ |
179 | } |
180 | |
181 | /*! |
182 | * brief De-initialization for the ENC module. |
183 | * |
184 | * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with |
185 | * the operations like: |
186 | * - Disable the clock for ENC module. |
187 | * |
188 | * param base ENC peripheral base address. |
189 | */ |
190 | void ENC_Deinit(ENC_Type *base) |
191 | { |
192 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
193 | /* Disable the clock. */ |
194 | CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]); |
195 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
196 | } |
197 | |
198 | /*! |
199 | * brief Get an available pre-defined settings for ENC's configuration. |
200 | * |
201 | * This function initializes the ENC configuration structure with an available settings, the default value are: |
202 | * code |
203 | * config->enableReverseDirection = false; |
204 | * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; |
205 | * config->HOMETriggerMode = kENC_HOMETriggerDisabled; |
206 | * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; |
207 | * config->enableTRIGGERClearPositionCounter = false; |
208 | * config->enableTRIGGERClearHoldPositionCounter = false; |
209 | * config->enableWatchdog = false; |
210 | * config->watchdogTimeoutValue = 0U; |
211 | * config->filterCount = 0U; |
212 | * config->filterSamplePeriod = 0U; |
213 | * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; |
214 | * config->positionCompareValue = 0xFFFFFFFFU; |
215 | * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; |
216 | * config->enableModuloCountMode = false; |
217 | * config->positionModulusValue = 0U; |
218 | * config->positionInitialValue = 0U; |
219 | * config->prescalerValue = kENC_ClockDiv1; |
220 | * config->enablePeriodMeasurementFunction = true; |
221 | * endcode |
222 | * param config Pointer to a variable of configuration structure. See to "enc_config_t". |
223 | */ |
224 | void ENC_GetDefaultConfig(enc_config_t *config) |
225 | { |
226 | assert(NULL != config); |
227 | |
228 | /* Initializes the configure structure to zero. */ |
229 | (void)memset(config, 0, sizeof(*config)); |
230 | |
231 | config->enableReverseDirection = false; |
232 | config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; |
233 | config->HOMETriggerMode = kENC_HOMETriggerDisabled; |
234 | config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; |
235 | config->enableTRIGGERClearPositionCounter = false; |
236 | config->enableTRIGGERClearHoldPositionCounter = false; |
237 | config->enableWatchdog = false; |
238 | config->watchdogTimeoutValue = 0U; |
239 | config->filterCount = 0U; |
240 | config->filterSamplePeriod = 0U; |
241 | config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; |
242 | config->positionCompareValue = 0xFFFFFFFFU; |
243 | config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; |
244 | config->enableModuloCountMode = false; |
245 | config->positionModulusValue = 0U; |
246 | config->positionInitialValue = 0U; |
247 | #if (defined(FSL_FEATURE_ENC_HAS_CTRL3) && FSL_FEATURE_ENC_HAS_CTRL3) |
248 | config->prescalerValue = kENC_ClockDiv1; |
249 | config->enablePeriodMeasurementFunction = true; |
250 | #endif |
251 | } |
252 | |
253 | /*! |
254 | * brief Load the initial position value to position counter. |
255 | * |
256 | * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and |
257 | * LPOS), so that to provide the consistent operation the position counter registers. |
258 | * |
259 | * param base ENC peripheral base address. |
260 | */ |
261 | void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base) |
262 | { |
263 | uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS); |
264 | |
265 | tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */ |
266 | base->CTRL = tmp16; |
267 | } |
268 | |
269 | /*! |
270 | * brief Enable and configure the self test function. |
271 | * |
272 | * This function is to enable and configuration the self test function. It controls and sets the frequency of a |
273 | * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module. |
274 | * It is a factory test feature; however, it may be useful to customers' software development and testing. |
275 | * |
276 | * param base ENC peripheral base address. |
277 | * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable. |
278 | */ |
279 | void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config) |
280 | { |
281 | uint16_t tmp16 = 0U; |
282 | |
283 | if (NULL == config) /* Pass "NULL" to disable the feature. */ |
284 | { |
285 | tmp16 = 0U; |
286 | } |
287 | else |
288 | { |
289 | tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) | |
290 | ENC_TST_TEST_COUNT(config->signalCount); |
291 | if (kENC_SelfTestDirectionNegative == config->signalDirection) |
292 | { |
293 | tmp16 |= ENC_TST_QDN_MASK; |
294 | } |
295 | } |
296 | |
297 | base->TST = tmp16; |
298 | } |
299 | |
300 | /*! |
301 | * brief Enable watchdog for ENC module. |
302 | * |
303 | * param base ENC peripheral base address |
304 | * param enable Enables or disables the watchdog |
305 | */ |
306 | void ENC_EnableWatchdog(ENC_Type *base, bool enable) |
307 | { |
308 | uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK)); |
309 | |
310 | if (enable) |
311 | { |
312 | tmp16 |= ENC_CTRL_WDE_MASK; |
313 | } |
314 | base->CTRL = tmp16; |
315 | } |
316 | |
317 | /*! |
318 | * brief Get the status flags. |
319 | * |
320 | * param base ENC peripheral base address. |
321 | * |
322 | * return Mask value of status flags. For available mask, see to "_enc_status_flags". |
323 | */ |
324 | uint32_t ENC_GetStatusFlags(ENC_Type *base) |
325 | { |
326 | uint32_t ret32 = 0U; |
327 | |
328 | /* ENC_CTRL. */ |
329 | if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL)) |
330 | { |
331 | ret32 |= (uint32_t)kENC_HOMETransitionFlag; |
332 | } |
333 | if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL)) |
334 | { |
335 | ret32 |= (uint32_t)kENC_INDEXPulseFlag; |
336 | } |
337 | if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL)) |
338 | { |
339 | ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag; |
340 | } |
341 | if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL)) |
342 | { |
343 | ret32 |= (uint32_t)kENC_PositionCompareFlag; |
344 | } |
345 | |
346 | /* ENC_CTRL2. */ |
347 | #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
348 | if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2)) |
349 | { |
350 | ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag; |
351 | } |
352 | #endif |
353 | if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2)) |
354 | { |
355 | ret32 |= (uint32_t)kENC_PositionRollOverFlag; |
356 | } |
357 | if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2)) |
358 | { |
359 | ret32 |= (uint32_t)kENC_PositionRollUnderFlag; |
360 | } |
361 | if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2)) |
362 | { |
363 | ret32 |= (uint32_t)kENC_LastCountDirectionFlag; |
364 | } |
365 | |
366 | return ret32; |
367 | } |
368 | |
369 | /*! |
370 | * brief Clear the status flags. |
371 | * |
372 | * param base ENC peripheral base address. |
373 | * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags". |
374 | */ |
375 | void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask) |
376 | { |
377 | uint32_t tmp16 = 0U; |
378 | |
379 | /* ENC_CTRL. */ |
380 | if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask)) |
381 | { |
382 | tmp16 |= ENC_CTRL_HIRQ_MASK; |
383 | } |
384 | if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask)) |
385 | { |
386 | tmp16 |= ENC_CTRL_XIRQ_MASK; |
387 | } |
388 | if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask)) |
389 | { |
390 | tmp16 |= ENC_CTRL_DIRQ_MASK; |
391 | } |
392 | if (0U != ((uint32_t)kENC_PositionCompareFlag & mask)) |
393 | { |
394 | tmp16 |= ENC_CTRL_CMPIRQ_MASK; |
395 | } |
396 | if (0U != tmp16) |
397 | { |
398 | base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); |
399 | } |
400 | |
401 | /* ENC_CTRL2. */ |
402 | tmp16 = 0U; |
403 | #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
404 | if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask)) |
405 | { |
406 | tmp16 |= ENC_CTRL2_SABIRQ_MASK; |
407 | } |
408 | #endif |
409 | if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask)) |
410 | { |
411 | tmp16 |= ENC_CTRL2_ROIRQ_MASK; |
412 | } |
413 | if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask)) |
414 | { |
415 | tmp16 |= ENC_CTRL2_RUIRQ_MASK; |
416 | } |
417 | if (0U != tmp16) |
418 | { |
419 | base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); |
420 | } |
421 | } |
422 | |
423 | /*! |
424 | * brief Enable the interrupts. |
425 | * |
426 | * param base ENC peripheral base address. |
427 | * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable". |
428 | */ |
429 | void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask) |
430 | { |
431 | uint32_t tmp16 = 0U; |
432 | |
433 | /* ENC_CTRL. */ |
434 | if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) |
435 | { |
436 | tmp16 |= ENC_CTRL_HIE_MASK; |
437 | } |
438 | if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) |
439 | { |
440 | tmp16 |= ENC_CTRL_XIE_MASK; |
441 | } |
442 | if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) |
443 | { |
444 | tmp16 |= ENC_CTRL_DIE_MASK; |
445 | } |
446 | if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) |
447 | { |
448 | tmp16 |= ENC_CTRL_CMPIE_MASK; |
449 | } |
450 | if (tmp16 != 0U) |
451 | { |
452 | base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); |
453 | } |
454 | /* ENC_CTRL2. */ |
455 | tmp16 = 0U; |
456 | #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
457 | if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) |
458 | { |
459 | tmp16 |= ENC_CTRL2_SABIE_MASK; |
460 | } |
461 | #endif |
462 | if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) |
463 | { |
464 | tmp16 |= ENC_CTRL2_ROIE_MASK; |
465 | } |
466 | if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) |
467 | { |
468 | tmp16 |= ENC_CTRL2_RUIE_MASK; |
469 | } |
470 | if (tmp16 != 0U) |
471 | { |
472 | base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); |
473 | } |
474 | } |
475 | |
476 | /*! |
477 | * brief Disable the interrupts. |
478 | * |
479 | * param base ENC peripheral base address. |
480 | * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable". |
481 | */ |
482 | void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask) |
483 | { |
484 | uint16_t tmp16 = 0U; |
485 | |
486 | /* ENC_CTRL. */ |
487 | if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) |
488 | { |
489 | tmp16 |= ENC_CTRL_HIE_MASK; |
490 | } |
491 | if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) |
492 | { |
493 | tmp16 |= ENC_CTRL_XIE_MASK; |
494 | } |
495 | if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) |
496 | { |
497 | tmp16 |= ENC_CTRL_DIE_MASK; |
498 | } |
499 | if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) |
500 | { |
501 | tmp16 |= ENC_CTRL_CMPIE_MASK; |
502 | } |
503 | if (0U != tmp16) |
504 | { |
505 | base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16); |
506 | } |
507 | /* ENC_CTRL2. */ |
508 | tmp16 = 0U; |
509 | #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
510 | if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) |
511 | { |
512 | tmp16 |= ENC_CTRL2_SABIE_MASK; |
513 | } |
514 | #endif |
515 | if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) |
516 | { |
517 | tmp16 |= ENC_CTRL2_ROIE_MASK; |
518 | } |
519 | if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) |
520 | { |
521 | tmp16 |= ENC_CTRL2_RUIE_MASK; |
522 | } |
523 | if (tmp16 != 0U) |
524 | { |
525 | base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16); |
526 | } |
527 | } |
528 | |
529 | /*! |
530 | * brief Get the enabled interrupts' flags. |
531 | * |
532 | * param base ENC peripheral base address. |
533 | * |
534 | * return Mask value of enabled interrupts. |
535 | */ |
536 | uint32_t ENC_GetEnabledInterrupts(ENC_Type *base) |
537 | { |
538 | uint32_t ret32 = 0U; |
539 | |
540 | /* ENC_CTRL. */ |
541 | if (0U != (ENC_CTRL_HIE_MASK & base->CTRL)) |
542 | { |
543 | ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable; |
544 | } |
545 | if (0U != (ENC_CTRL_XIE_MASK & base->CTRL)) |
546 | { |
547 | ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable; |
548 | } |
549 | if (0U != (ENC_CTRL_DIE_MASK & base->CTRL)) |
550 | { |
551 | ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable; |
552 | } |
553 | if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL)) |
554 | { |
555 | ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable; |
556 | } |
557 | /* ENC_CTRL2. */ |
558 | #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) |
559 | if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2)) |
560 | { |
561 | ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable; |
562 | } |
563 | #endif |
564 | if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2)) |
565 | { |
566 | ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable; |
567 | } |
568 | if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2)) |
569 | { |
570 | ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable; |
571 | } |
572 | return ret32; |
573 | } |
574 | |
575 | /*! |
576 | * brief Set initial position value for ENC module. |
577 | * |
578 | * param base ENC peripheral base address |
579 | * param value Positive initial value |
580 | */ |
581 | void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value) |
582 | { |
583 | base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */ |
584 | base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */ |
585 | } |
586 | |
587 | /*! |
588 | * brief Get the current position counter's value. |
589 | * |
590 | * param base ENC peripheral base address. |
591 | * |
592 | * return Current position counter's value. |
593 | */ |
594 | uint32_t ENC_GetPositionValue(ENC_Type *base) |
595 | { |
596 | uint32_t ret32; |
597 | |
598 | ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */ |
599 | ret32 <<= 16U; |
600 | ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ |
601 | |
602 | return ret32; |
603 | } |
604 | |
605 | /*! |
606 | * brief Get the hold position counter's value. |
607 | * |
608 | * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold |
609 | * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to |
610 | * be attained. |
611 | * |
612 | * param base ENC peripheral base address. |
613 | * |
614 | * return Hold position counter's value. |
615 | */ |
616 | uint32_t ENC_GetHoldPositionValue(ENC_Type *base) |
617 | { |
618 | uint32_t ret32; |
619 | |
620 | ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */ |
621 | ret32 <<= 16U; |
622 | ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ |
623 | |
624 | return ret32; |
625 | } |
626 | |