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