Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:58

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2021 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_enc.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.enc"
0018 #endif
0019 
0020 #define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK)
0021 #if (defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0022 #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK)
0023 #else
0024 #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK)
0025 #endif
0026 
0027 /*******************************************************************************
0028  * Prototypes
0029  ******************************************************************************/
0030 /*!
0031  * @brief Get instance number for ENC module.
0032  *
0033  * @param base ENC peripheral base address
0034  */
0035 static uint32_t ENC_GetInstance(ENC_Type *base);
0036 
0037 /*******************************************************************************
0038  * Variables
0039  ******************************************************************************/
0040 /*! @brief Pointers to ENC bases for each instance. */
0041 static ENC_Type *const s_encBases[] = ENC_BASE_PTRS;
0042 
0043 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0044 /*! @brief Pointers to ENC clocks for each instance. */
0045 static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS;
0046 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0047 
0048 /*******************************************************************************
0049  * Code
0050  ******************************************************************************/
0051 static uint32_t ENC_GetInstance(ENC_Type *base)
0052 {
0053     uint32_t instance;
0054 
0055     /* Find the instance index from base address mappings. */
0056     for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++)
0057     {
0058         if (s_encBases[instance] == base)
0059         {
0060             break;
0061         }
0062     }
0063 
0064     assert(instance < ARRAY_SIZE(s_encBases));
0065 
0066     return instance;
0067 }
0068 
0069 /*!
0070  * brief Initialization for the ENC module.
0071  *
0072  * This function is to make the initialization for the ENC module. It should be called firstly before any operation to
0073  * the ENC with the operations like:
0074  *  - Enable the clock for ENC module.
0075  *  - Configure the ENC's working attributes.
0076  *
0077  * param base   ENC peripheral base address.
0078  * param config Pointer to configuration structure. See to "enc_config_t".
0079  */
0080 void ENC_Init(ENC_Type *base, const enc_config_t *config)
0081 {
0082     assert(NULL != config);
0083 
0084     uint16_t tmp16;
0085 
0086 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0087     /* Enable the clock. */
0088     CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]);
0089 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0090 
0091     /* ENC_CTRL. */
0092     tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK |
0093                                       ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK));
0094     /* For HOME trigger. */
0095     if (kENC_HOMETriggerDisabled != config->HOMETriggerMode)
0096     {
0097         tmp16 |= ENC_CTRL_HIP_MASK;
0098         if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode)
0099         {
0100             tmp16 |= ENC_CTRL_HNE_MASK;
0101         }
0102     }
0103     /* For encoder work mode. */
0104     if (config->enableReverseDirection)
0105     {
0106         tmp16 |= ENC_CTRL_REV_MASK;
0107     }
0108     if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode)
0109     {
0110         tmp16 |= ENC_CTRL_PH1_MASK;
0111     }
0112     /* For INDEX trigger. */
0113     if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode)
0114     {
0115         tmp16 |= ENC_CTRL_XIP_MASK;
0116         if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode)
0117         {
0118             tmp16 |= ENC_CTRL_XNE_MASK;
0119         }
0120     }
0121     /* Watchdog. */
0122     if (config->enableWatchdog)
0123     {
0124         tmp16 |= ENC_CTRL_WDE_MASK;
0125         base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */
0126     }
0127     base->CTRL = tmp16;
0128 
0129     /* ENC_FILT. */
0130     base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod);
0131 
0132     /* ENC_CTRL2. */
0133     tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK |
0134                                        ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK));
0135     if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode)
0136     {
0137         tmp16 |= ENC_CTRL2_OUTCTL_MASK;
0138     }
0139     if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition)
0140     {
0141         tmp16 |= ENC_CTRL2_REVMOD_MASK;
0142     }
0143     if (config->enableModuloCountMode)
0144     {
0145         tmp16 |= ENC_CTRL2_MOD_MASK;
0146         /* Set modulus value. */
0147         base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */
0148         base->LMOD = (uint16_t)(config->positionModulusValue);        /* Lower 16 bits. */
0149     }
0150     if (config->enableTRIGGERClearPositionCounter)
0151     {
0152         tmp16 |= ENC_CTRL2_UPDPOS_MASK;
0153     }
0154     if (config->enableTRIGGERClearHoldPositionCounter)
0155     {
0156         tmp16 |= ENC_CTRL2_UPDHLD_MASK;
0157     }
0158     base->CTRL2 = tmp16;
0159 
0160 #if (defined(FSL_FEATURE_ENC_HAS_CTRL3) && FSL_FEATURE_ENC_HAS_CTRL3)
0161     /* ENC_CTRL3. */
0162     tmp16 = base->CTRL3 & (uint16_t)(~(ENC_CTRL3_PMEN_MASK | ENC_CTRL3_PRSC_MASK));
0163     if (config->enablePeriodMeasurementFunction)
0164     {
0165         tmp16 |= ENC_CTRL3_PMEN_MASK;
0166         /* Set prescaler value. */
0167         tmp16 |= ((uint16_t)config->prescalerValue << ENC_CTRL3_PRSC_SHIFT);
0168     }
0169     base->CTRL3 = tmp16;
0170 #endif
0171 
0172     /* ENC_UCOMP & ENC_LCOMP. */
0173     base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */
0174     base->LCOMP = (uint16_t)(config->positionCompareValue);        /* Lower 16 bits. */
0175 
0176     /* ENC_UINIT & ENC_LINIT. */
0177     base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */
0178     base->LINIT = (uint16_t)(config->positionInitialValue);        /* Lower 16 bits. */
0179 }
0180 
0181 /*!
0182  * brief De-initialization for the ENC module.
0183  *
0184  * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with
0185  * the operations like:
0186  *  - Disable the clock for ENC module.
0187  *
0188  * param base ENC peripheral base address.
0189  */
0190 void ENC_Deinit(ENC_Type *base)
0191 {
0192 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0193     /* Disable the clock. */
0194     CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]);
0195 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0196 }
0197 
0198 /*!
0199  * brief Get an available pre-defined settings for ENC's configuration.
0200  *
0201  * This function initializes the ENC configuration structure with an available settings, the default value are:
0202  * code
0203  *   config->enableReverseDirection                = false;
0204  *   config->decoderWorkMode                       = kENC_DecoderWorkAsNormalMode;
0205  *   config->HOMETriggerMode                       = kENC_HOMETriggerDisabled;
0206  *   config->INDEXTriggerMode                      = kENC_INDEXTriggerDisabled;
0207  *   config->enableTRIGGERClearPositionCounter     = false;
0208  *   config->enableTRIGGERClearHoldPositionCounter = false;
0209  *   config->enableWatchdog                        = false;
0210  *   config->watchdogTimeoutValue                  = 0U;
0211  *   config->filterCount                           = 0U;
0212  *   config->filterSamplePeriod                    = 0U;
0213  *   config->positionMatchMode                     = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
0214  *   config->positionCompareValue                  = 0xFFFFFFFFU;
0215  *   config->revolutionCountCondition              = kENC_RevolutionCountOnINDEXPulse;
0216  *   config->enableModuloCountMode                 = false;
0217  *   config->positionModulusValue                  = 0U;
0218  *   config->positionInitialValue                  = 0U;
0219  *   config->prescalerValue                        = kENC_ClockDiv1;
0220  *   config->enablePeriodMeasurementFunction       = true;
0221  * endcode
0222  * param config Pointer to a variable of configuration structure. See to "enc_config_t".
0223  */
0224 void ENC_GetDefaultConfig(enc_config_t *config)
0225 {
0226     assert(NULL != config);
0227 
0228     /* Initializes the configure structure to zero. */
0229     (void)memset(config, 0, sizeof(*config));
0230 
0231     config->enableReverseDirection                = false;
0232     config->decoderWorkMode                       = kENC_DecoderWorkAsNormalMode;
0233     config->HOMETriggerMode                       = kENC_HOMETriggerDisabled;
0234     config->INDEXTriggerMode                      = kENC_INDEXTriggerDisabled;
0235     config->enableTRIGGERClearPositionCounter     = false;
0236     config->enableTRIGGERClearHoldPositionCounter = false;
0237     config->enableWatchdog                        = false;
0238     config->watchdogTimeoutValue                  = 0U;
0239     config->filterCount                           = 0U;
0240     config->filterSamplePeriod                    = 0U;
0241     config->positionMatchMode                     = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
0242     config->positionCompareValue                  = 0xFFFFFFFFU;
0243     config->revolutionCountCondition              = kENC_RevolutionCountOnINDEXPulse;
0244     config->enableModuloCountMode                 = false;
0245     config->positionModulusValue                  = 0U;
0246     config->positionInitialValue                  = 0U;
0247 #if (defined(FSL_FEATURE_ENC_HAS_CTRL3) && FSL_FEATURE_ENC_HAS_CTRL3)
0248     config->prescalerValue                  = kENC_ClockDiv1;
0249     config->enablePeriodMeasurementFunction = true;
0250 #endif
0251 }
0252 
0253 /*!
0254  * brief Load the initial position value to position counter.
0255  *
0256  * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and
0257  * LPOS), so that to provide the consistent operation the position counter registers.
0258  *
0259  * param base ENC peripheral base address.
0260  */
0261 void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base)
0262 {
0263     uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS);
0264 
0265     tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */
0266     base->CTRL = tmp16;
0267 }
0268 
0269 /*!
0270  * brief Enable and configure the self test function.
0271  *
0272  * This function is to enable and configuration the self test function. It controls and sets the frequency of a
0273  * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module.
0274  * It is a factory test feature; however, it may be useful to customers' software development and testing.
0275  *
0276  * param base   ENC peripheral base address.
0277  * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable.
0278  */
0279 void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config)
0280 {
0281     uint16_t tmp16 = 0U;
0282 
0283     if (NULL == config) /* Pass "NULL" to disable the feature. */
0284     {
0285         tmp16 = 0U;
0286     }
0287     else
0288     {
0289         tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) |
0290                 ENC_TST_TEST_COUNT(config->signalCount);
0291         if (kENC_SelfTestDirectionNegative == config->signalDirection)
0292         {
0293             tmp16 |= ENC_TST_QDN_MASK;
0294         }
0295     }
0296 
0297     base->TST = tmp16;
0298 }
0299 
0300 /*!
0301  * brief Enable watchdog for ENC module.
0302  *
0303  * param base ENC peripheral base address
0304  * param enable Enables or disables the watchdog
0305  */
0306 void ENC_EnableWatchdog(ENC_Type *base, bool enable)
0307 {
0308     uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK));
0309 
0310     if (enable)
0311     {
0312         tmp16 |= ENC_CTRL_WDE_MASK;
0313     }
0314     base->CTRL = tmp16;
0315 }
0316 
0317 /*!
0318  * brief  Get the status flags.
0319  *
0320  * param  base ENC peripheral base address.
0321  *
0322  * return      Mask value of status flags. For available mask, see to "_enc_status_flags".
0323  */
0324 uint32_t ENC_GetStatusFlags(ENC_Type *base)
0325 {
0326     uint32_t ret32 = 0U;
0327 
0328     /* ENC_CTRL. */
0329     if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL))
0330     {
0331         ret32 |= (uint32_t)kENC_HOMETransitionFlag;
0332     }
0333     if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL))
0334     {
0335         ret32 |= (uint32_t)kENC_INDEXPulseFlag;
0336     }
0337     if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL))
0338     {
0339         ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag;
0340     }
0341     if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL))
0342     {
0343         ret32 |= (uint32_t)kENC_PositionCompareFlag;
0344     }
0345 
0346     /* ENC_CTRL2. */
0347 #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0348     if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2))
0349     {
0350         ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag;
0351     }
0352 #endif
0353     if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2))
0354     {
0355         ret32 |= (uint32_t)kENC_PositionRollOverFlag;
0356     }
0357     if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2))
0358     {
0359         ret32 |= (uint32_t)kENC_PositionRollUnderFlag;
0360     }
0361     if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2))
0362     {
0363         ret32 |= (uint32_t)kENC_LastCountDirectionFlag;
0364     }
0365 
0366     return ret32;
0367 }
0368 
0369 /*!
0370  * brief Clear the status flags.
0371  *
0372  * param base ENC peripheral base address.
0373  * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags".
0374  */
0375 void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask)
0376 {
0377     uint32_t tmp16 = 0U;
0378 
0379     /* ENC_CTRL. */
0380     if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask))
0381     {
0382         tmp16 |= ENC_CTRL_HIRQ_MASK;
0383     }
0384     if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask))
0385     {
0386         tmp16 |= ENC_CTRL_XIRQ_MASK;
0387     }
0388     if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask))
0389     {
0390         tmp16 |= ENC_CTRL_DIRQ_MASK;
0391     }
0392     if (0U != ((uint32_t)kENC_PositionCompareFlag & mask))
0393     {
0394         tmp16 |= ENC_CTRL_CMPIRQ_MASK;
0395     }
0396     if (0U != tmp16)
0397     {
0398         base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
0399     }
0400 
0401     /* ENC_CTRL2. */
0402     tmp16 = 0U;
0403 #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0404     if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask))
0405     {
0406         tmp16 |= ENC_CTRL2_SABIRQ_MASK;
0407     }
0408 #endif
0409     if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask))
0410     {
0411         tmp16 |= ENC_CTRL2_ROIRQ_MASK;
0412     }
0413     if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask))
0414     {
0415         tmp16 |= ENC_CTRL2_RUIRQ_MASK;
0416     }
0417     if (0U != tmp16)
0418     {
0419         base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
0420     }
0421 }
0422 
0423 /*!
0424  * brief Enable the interrupts.
0425  *
0426  * param base ENC peripheral base address.
0427  * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable".
0428  */
0429 void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask)
0430 {
0431     uint32_t tmp16 = 0U;
0432 
0433     /* ENC_CTRL. */
0434     if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
0435     {
0436         tmp16 |= ENC_CTRL_HIE_MASK;
0437     }
0438     if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
0439     {
0440         tmp16 |= ENC_CTRL_XIE_MASK;
0441     }
0442     if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
0443     {
0444         tmp16 |= ENC_CTRL_DIE_MASK;
0445     }
0446     if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
0447     {
0448         tmp16 |= ENC_CTRL_CMPIE_MASK;
0449     }
0450     if (tmp16 != 0U)
0451     {
0452         base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
0453     }
0454     /* ENC_CTRL2. */
0455     tmp16 = 0U;
0456 #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0457     if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
0458     {
0459         tmp16 |= ENC_CTRL2_SABIE_MASK;
0460     }
0461 #endif
0462     if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
0463     {
0464         tmp16 |= ENC_CTRL2_ROIE_MASK;
0465     }
0466     if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
0467     {
0468         tmp16 |= ENC_CTRL2_RUIE_MASK;
0469     }
0470     if (tmp16 != 0U)
0471     {
0472         base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
0473     }
0474 }
0475 
0476 /*!
0477  * brief Disable the interrupts.
0478  *
0479  * param base ENC peripheral base address.
0480  * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable".
0481  */
0482 void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask)
0483 {
0484     uint16_t tmp16 = 0U;
0485 
0486     /* ENC_CTRL. */
0487     if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
0488     {
0489         tmp16 |= ENC_CTRL_HIE_MASK;
0490     }
0491     if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
0492     {
0493         tmp16 |= ENC_CTRL_XIE_MASK;
0494     }
0495     if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
0496     {
0497         tmp16 |= ENC_CTRL_DIE_MASK;
0498     }
0499     if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
0500     {
0501         tmp16 |= ENC_CTRL_CMPIE_MASK;
0502     }
0503     if (0U != tmp16)
0504     {
0505         base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16);
0506     }
0507     /* ENC_CTRL2. */
0508     tmp16 = 0U;
0509 #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0510     if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
0511     {
0512         tmp16 |= ENC_CTRL2_SABIE_MASK;
0513     }
0514 #endif
0515     if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
0516     {
0517         tmp16 |= ENC_CTRL2_ROIE_MASK;
0518     }
0519     if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
0520     {
0521         tmp16 |= ENC_CTRL2_RUIE_MASK;
0522     }
0523     if (tmp16 != 0U)
0524     {
0525         base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16);
0526     }
0527 }
0528 
0529 /*!
0530  * brief  Get the enabled interrupts' flags.
0531  *
0532  * param  base ENC peripheral base address.
0533  *
0534  * return      Mask value of enabled interrupts.
0535  */
0536 uint32_t ENC_GetEnabledInterrupts(ENC_Type *base)
0537 {
0538     uint32_t ret32 = 0U;
0539 
0540     /* ENC_CTRL. */
0541     if (0U != (ENC_CTRL_HIE_MASK & base->CTRL))
0542     {
0543         ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable;
0544     }
0545     if (0U != (ENC_CTRL_XIE_MASK & base->CTRL))
0546     {
0547         ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable;
0548     }
0549     if (0U != (ENC_CTRL_DIE_MASK & base->CTRL))
0550     {
0551         ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable;
0552     }
0553     if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL))
0554     {
0555         ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable;
0556     }
0557     /* ENC_CTRL2. */
0558 #if !(defined(FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT) && FSL_FEATURE_ENC_HAS_NO_CTRL2_SAB_INT)
0559     if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2))
0560     {
0561         ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable;
0562     }
0563 #endif
0564     if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2))
0565     {
0566         ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable;
0567     }
0568     if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2))
0569     {
0570         ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable;
0571     }
0572     return ret32;
0573 }
0574 
0575 /*!
0576  * brief Set initial position value for ENC module.
0577  *
0578  * param base ENC peripheral base address
0579  * param value Positive initial value
0580  */
0581 void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value)
0582 {
0583     base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */
0584     base->LINIT = (uint16_t)(value);        /* Set lower 16 bits. */
0585 }
0586 
0587 /*!
0588  * brief  Get the current position counter's value.
0589  *
0590  * param  base ENC peripheral base address.
0591  *
0592  * return     Current position counter's value.
0593  */
0594 uint32_t ENC_GetPositionValue(ENC_Type *base)
0595 {
0596     uint32_t ret32;
0597 
0598     ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */
0599     ret32 <<= 16U;
0600     ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
0601 
0602     return ret32;
0603 }
0604 
0605 /*!
0606  * brief  Get the hold position counter's value.
0607  *
0608  * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
0609  * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
0610  * be attained.
0611  *
0612  * param  base ENC peripheral base address.
0613  *
0614  * return      Hold position counter's value.
0615  */
0616 uint32_t ENC_GetHoldPositionValue(ENC_Type *base)
0617 {
0618     uint32_t ret32;
0619 
0620     ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */
0621     ret32 <<= 16U;
0622     ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
0623 
0624     return ret32;
0625 }