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-2019 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_cmp.h"
0010 
0011 /* Component ID definition, used by tools. */
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.cmp"
0014 #endif
0015 
0016 /*******************************************************************************
0017  * Prototypes
0018  ******************************************************************************/
0019 /*!
0020  * @brief Get instance number for CMP module.
0021  *
0022  * @param base CMP peripheral base address
0023  */
0024 static uint32_t CMP_GetInstance(CMP_Type *base);
0025 
0026 /*******************************************************************************
0027  * Variables
0028  ******************************************************************************/
0029 /*! @brief Pointers to CMP bases for each instance. */
0030 static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
0031 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0032 /*! @brief Pointers to CMP clocks for each instance. */
0033 static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
0034 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0035 
0036 /*******************************************************************************
0037  * Codes
0038  ******************************************************************************/
0039 static uint32_t CMP_GetInstance(CMP_Type *base)
0040 {
0041     uint32_t instance;
0042 
0043     /* Find the instance index from base address mappings. */
0044     for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++)
0045     {
0046         if (s_cmpBases[instance] == base)
0047         {
0048             break;
0049         }
0050     }
0051 
0052     assert(instance < ARRAY_SIZE(s_cmpBases));
0053 
0054     return instance;
0055 }
0056 
0057 /*!
0058  * brief Initializes the CMP.
0059  *
0060  * This function initializes the CMP module. The operations included are as follows.
0061  * - Enabling the clock for CMP module.
0062  * - Configuring the comparator.
0063  * - Enabling the CMP module.
0064  * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for
0065  * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP.
0066  *
0067  * param base   CMP peripheral base address.
0068  * param config Pointer to the configuration structure.
0069  */
0070 void CMP_Init(CMP_Type *base, const cmp_config_t *config)
0071 {
0072     assert(NULL != config);
0073 
0074     uint8_t tmp8;
0075 
0076 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0077     /* Enable the clock. */
0078     CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
0079 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0080 
0081     /* Configure. */
0082     CMP_Enable(base, false); /* Disable the CMP module during configuring. */
0083     /* CMPx_CR1. */
0084     tmp8 = (uint8_t)(base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK));
0085     if (true == config->enableHighSpeed)
0086     {
0087         tmp8 |= CMP_CR1_PMODE_MASK;
0088     }
0089     if (true == config->enableInvertOutput)
0090     {
0091         tmp8 |= CMP_CR1_INV_MASK;
0092     }
0093     if (true == config->useUnfilteredOutput)
0094     {
0095         tmp8 |= CMP_CR1_COS_MASK;
0096     }
0097     if (true == config->enablePinOut)
0098     {
0099         tmp8 |= CMP_CR1_OPE_MASK;
0100     }
0101 #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
0102     if (true == config->enableTriggerMode)
0103     {
0104         tmp8 |= CMP_CR1_TRIGM_MASK;
0105     }
0106     else
0107     {
0108         tmp8 &= ~(uint8_t)CMP_CR1_TRIGM_MASK;
0109     }
0110 #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
0111     base->CR1 = tmp8;
0112 
0113     /* CMPx_CR0. */
0114     tmp8 = base->CR0 & ~(uint8_t)CMP_CR0_HYSTCTR_MASK;
0115     tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
0116     base->CR0 = tmp8;
0117 
0118     CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
0119 }
0120 
0121 /*!
0122  * brief De-initializes the CMP module.
0123  *
0124  * This function de-initializes the CMP module. The operations included are as follows.
0125  * - Disabling the CMP module.
0126  * - Disabling the clock for CMP module.
0127  *
0128  * This function disables the clock for the CMP.
0129  * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the
0130  * clock for the CMP, ensure that all the CMP instances are not used.
0131  *
0132  * param base CMP peripheral base address.
0133  */
0134 void CMP_Deinit(CMP_Type *base)
0135 {
0136     /* Disable the CMP module. */
0137     CMP_Enable(base, false);
0138 
0139 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0140     /* Disable the clock. */
0141     CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
0142 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0143 }
0144 
0145 /*!
0146  * brief Initializes the CMP user configuration structure.
0147  *
0148  * This function initializes the user configuration structure to these default values.
0149  * code
0150  *   config->enableCmp           = true;
0151  *   config->hysteresisMode      = kCMP_HysteresisLevel0;
0152  *   config->enableHighSpeed     = false;
0153  *   config->enableInvertOutput  = false;
0154  *   config->useUnfilteredOutput = false;
0155  *   config->enablePinOut        = false;
0156  *   config->enableTriggerMode   = false;
0157  * endcode
0158  * param config Pointer to the configuration structure.
0159  */
0160 void CMP_GetDefaultConfig(cmp_config_t *config)
0161 {
0162     assert(NULL != config);
0163 
0164     /* Initializes the configure structure to zero. */
0165     (void)memset(config, 0, sizeof(*config));
0166 
0167     config->enableCmp           = true; /* Enable the CMP module after initialization. */
0168     config->hysteresisMode      = kCMP_HysteresisLevel0;
0169     config->enableHighSpeed     = false;
0170     config->enableInvertOutput  = false;
0171     config->useUnfilteredOutput = false;
0172     config->enablePinOut        = false;
0173 #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
0174     config->enableTriggerMode = false;
0175 #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
0176 }
0177 
0178 /*!
0179  * brief  Sets the input channels for the comparator.
0180  *
0181  * This function sets the input channels for the comparator.
0182  * Note that two input channels cannot be set the same way in the application. When the user selects the same input
0183  * from the analog mux to the positive and negative port, the comparator is disabled automatically.
0184  *
0185  * param  base            CMP peripheral base address.
0186  * param  positiveChannel Positive side input channel number. Available range is 0-7.
0187  * param  negativeChannel Negative side input channel number. Available range is 0-7.
0188  */
0189 void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
0190 {
0191     uint8_t tmp8 = base->MUXCR;
0192 
0193     tmp8 &= ~(uint8_t)(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
0194     tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
0195     base->MUXCR = tmp8;
0196 }
0197 
0198 #if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
0199 /*!
0200  * brief Enables/disables the DMA request for rising/falling events.
0201  *
0202  * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
0203  * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from
0204  * the CMP
0205  * if the DMA is disabled.
0206  *
0207  * param base CMP peripheral base address.
0208  * param enable Enables or disables the feature.
0209  */
0210 void CMP_EnableDMA(CMP_Type *base, bool enable)
0211 {
0212     uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
0213 
0214     if (enable)
0215     {
0216         tmp8 |= CMP_SCR_DMAEN_MASK;
0217     }
0218     else
0219     {
0220         tmp8 &= ~(uint8_t)CMP_SCR_DMAEN_MASK;
0221     }
0222     base->SCR = tmp8;
0223 }
0224 #endif /* FSL_FEATURE_CMP_HAS_DMA */
0225 
0226 /*!
0227  * brief  Configures the filter.
0228  *
0229  * param  base   CMP peripheral base address.
0230  * param  config Pointer to the configuration structure.
0231  */
0232 void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
0233 {
0234     assert(NULL != config);
0235 
0236     uint8_t tmp8;
0237 
0238 #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
0239     /* Choose the clock source for sampling. */
0240     if (config->enableSample)
0241     {
0242         base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
0243     }
0244     else
0245     {
0246         base->CR1 &= (uint8_t)(~CMP_CR1_SE_MASK); /* Choose the internal divided bus clock. */
0247     }
0248 #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
0249     /* Set the filter count. */
0250     tmp8 = (uint8_t)(base->CR0 & ~CMP_CR0_FILTER_CNT_MASK);
0251     tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
0252     base->CR0 = tmp8;
0253     /* Set the filter period. It is used as the divider to bus clock. */
0254     base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
0255 }
0256 
0257 /*!
0258  * brief Configures the internal DAC.
0259  *
0260  * param base   CMP peripheral base address.
0261  * param config Pointer to the configuration structure. "NULL" disables the feature.
0262  */
0263 void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
0264 {
0265     uint8_t tmp8 = 0U;
0266 
0267     if (NULL == config)
0268     {
0269         /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
0270         base->DACCR = 0U;
0271         return;
0272     }
0273     /* CMPx_DACCR. */
0274     tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
0275     if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
0276     {
0277         tmp8 |= CMP_DACCR_VRSEL_MASK;
0278     }
0279     tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
0280 
0281     base->DACCR = tmp8;
0282 }
0283 
0284 /*!
0285  * brief Enables the interrupts.
0286  *
0287  * param base    CMP peripheral base address.
0288  * param mask    Mask value for interrupts. See "_cmp_interrupt_enable".
0289  */
0290 void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
0291 {
0292     uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
0293 
0294     if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
0295     {
0296         tmp8 |= CMP_SCR_IER_MASK;
0297     }
0298     if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
0299     {
0300         tmp8 |= CMP_SCR_IEF_MASK;
0301     }
0302     base->SCR = tmp8;
0303 }
0304 
0305 /*!
0306  * brief Disables the interrupts.
0307  *
0308  * param base    CMP peripheral base address.
0309  * param mask    Mask value for interrupts. See "_cmp_interrupt_enable".
0310  */
0311 void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
0312 {
0313     uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
0314 
0315     if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
0316     {
0317         tmp8 &= ~(uint8_t)CMP_SCR_IER_MASK;
0318     }
0319     if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
0320     {
0321         tmp8 &= ~(uint8_t)CMP_SCR_IEF_MASK;
0322     }
0323     base->SCR = tmp8;
0324 }
0325 
0326 /*!
0327  * brief  Gets the status flags.
0328  *
0329  * param  base     CMP peripheral base address.
0330  *
0331  * return          Mask value for the asserted flags. See "_cmp_status_flags".
0332  */
0333 uint32_t CMP_GetStatusFlags(CMP_Type *base)
0334 {
0335     uint32_t ret32 = 0U;
0336 
0337     if (0U != (CMP_SCR_CFR_MASK & base->SCR))
0338     {
0339         ret32 |= (uint32_t)kCMP_OutputRisingEventFlag;
0340     }
0341     if (0U != (CMP_SCR_CFF_MASK & base->SCR))
0342     {
0343         ret32 |= (uint32_t)kCMP_OutputFallingEventFlag;
0344     }
0345     if (0U != (CMP_SCR_COUT_MASK & base->SCR))
0346     {
0347         ret32 |= (uint32_t)kCMP_OutputAssertEventFlag;
0348     }
0349     return ret32;
0350 }
0351 
0352 /*!
0353  * brief Clears the status flags.
0354  *
0355  * param base     CMP peripheral base address.
0356  * param mask     Mask value for the flags. See "_cmp_status_flags".
0357  */
0358 void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
0359 {
0360     uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
0361 
0362     if (0U != ((uint32_t)kCMP_OutputRisingEventFlag & mask))
0363     {
0364         tmp8 |= CMP_SCR_CFR_MASK;
0365     }
0366     if (0U != ((uint32_t)kCMP_OutputFallingEventFlag & mask))
0367     {
0368         tmp8 |= CMP_SCR_CFF_MASK;
0369     }
0370     base->SCR = tmp8;
0371 }