/* * @brief LPC15xx Analog comparator driver * * @note * Copyright(C) NXP Semiconductors, 2014 * All rights reserved. * * @par * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * LPC products. This software is supplied "AS IS" without any warranties of * any kind, and NXP Semiconductors and its licenser disclaim any and * all warranties, express or implied, including all implied warranties of * merchantability, fitness for a particular purpose and non-infringement of * intellectual property rights. NXP Semiconductors assumes no responsibility * or liability for the use of the software, conveys no license or rights under any * patent, copyright, mask work right, or any other intellectual property rights in * or to any products. NXP Semiconductors reserves the right to make changes * in the software without notification. NXP Semiconductors also makes no * representation or warranty that such application will be suitable for the * specified use without further testing or modification. * * @par * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, under NXP Semiconductors' and its * licensor's relevant copyrights in the software, without fee, provided that it * is used in conjunction with NXP Semiconductors microcontrollers. This * copyright, permission, and disclaimer notice must appear in all copies of * this code. */ #ifndef __ACMP_15XX_H_ #define __ACMP_15XX_H_ #ifdef __cplusplus extern "C" { #endif /** @defgroup ACMP_15XX CHIP: LPC15xx Analog Comparator driver * @ingroup CHIP_15XX_Drivers * @{ */ /** * @brief Analog Comparator channel register block structure */ typedef struct { __IO uint32_t CMP; /*!< Individual Comparator control register */ __IO uint32_t CMPFILTR; /*!< Individual Comparator Filter registers */ } CMP_REG_T; /** * @brief Analog Comparator register block structure */ typedef struct { /*!< ACMP Structure */ __IO uint32_t CTRL; /*!< Comparator block control register */ __IO CMP_REG_T ACMP[4]; /*!< Individual Comparator registers */ } LPC_CMP_T; /* Bit definitions for block control register */ #define ACMP_ROSCCTL_BIT (1 << 8) /* Ring Oscillator control bit */ #define ACMP_EXTRESET_BIT (1 << 9) /* Reset source for ring oscillator 0 - Internal, 1 - External pin */ /* Bit definitions for compare register */ #define ACMP_CMPEN_BIT (1 << 0) /* Comparator enable bit */ #define ACMP_INTEN_BIT (1 << 2) /* Comparator Interrupt enable bit */ #define ACMP_STATUS_BIT (1 << 3) /* Comparator status, reflects the state of the comparator output */ #define ACMP_COMPVMSEL_MASK (0x7 << 4) /* Mask for VM Input selection */ #define ACMP_COMPVPSEL_MASK (0x7 << 8) /* Mask for VP Input selection */ #define ACMP_HYSTERESIS_MASK (0x3 << 13) /* Mask for Hysterisis Control */ #define ACMP_INTPOL_BIT (1 << 15) /* Polarity of CMP output for interrupt 0 - Not Inverted, 1 - Inverted */ #define ACMP_INTTYPE_BIT (1 << 16) /* Interrupt Type 0 - Edge, 1 - Level */ #define ACMP_INTEDGE_MASK (0x3 << 17) /* Mask for Interrupt edge selection */ #define ACMP_INTFLAG_BIT (1 << 19) /* Interrupt Flag bit */ #define ACMP_LADENAB_BIT (1 << 20) /* Voltage ladder enable bit */ #define ACMP_LADREF_BIT (1 << 22) /* Voltage reference select bit for voltage ladder */ #define ACMP_LADSEL_MASK (0x1F << 24) /* Reference voltage selection mask for ladder */ #define ACMP_PROPDLY_MASK (0x3 << 29) /* Propogation delay mask */ /* Bit definitions for comparator filter register */ #define ACMP_SMODE_MASK (0x3 << 0) /* Mask for digital filter sample mode */ #define ACMP_CLKDIV_MASK (0x7 << 2) /* Mask for comparator clock */ /** Edge selection for comparator */ typedef enum { ACMP_EDGESEL_FALLING = (0 << 17), /* Set the COMPEDGE bit on falling edge */ ACMP_EDGESEL_RISING = (1 << 17), /* Set the COMPEDGE bit on rising edge */ ACMP_EDGESEL_BOTH = (2 << 17) /* Set the COMPEDGE bit on falling and rising edges */ } CHIP_ACMP_EDGESEL_T; /** Hysteresis selection for comparator */ typedef enum { ACMP_HYS_NONE = (0 << 13), /* No hysteresis (the output will switch as the voltages cross) */ ACMP_HYS_5MV = (1 << 13), /* 5mV hysteresis */ ACMP_HYS_10MV = (2 << 13), /* 10mV hysteresis */ ACMP_HYS_15MV = (3 << 13) /* 20mV hysteresis */ } CHIP_ACMP_HYS_T; /** * Analog Comparator positive input values */ typedef enum CHIP_ACMP_POS_INPUT { ACMP_POSIN_VREF_DIV = (0 << 8), /*!< Voltage ladder output */ ACMP_POSIN_ACMP_I1 = (1 << 8), /*!< ACMP_I1 pin */ ACMP_POSIN_ACMP_I2 = (2 << 8), /*!< ACMP_I2 pin */ ACMP_POSIN_ACMP_I3 = (3 << 8), /*!< ACMP_I3 pin */ ACMP_POSIN_ACMP_I4 = (4 << 8), /*!< ACMP_I4 pin */ ACMP_POSIN_INT_REF = (5 << 8), /*!< Internal reference voltage */ ACMP_POSIN_ADCIN_1 = (6 << 8), /*!< ADC Input or Temperature sensor varies with comparator */ ACMP_POSIN_ADCIN_2 = (7 << 8) /*!< ADC Input varies with comparator */ } CHIP_ACMP_POS_INPUT_T; /** * Analog Comparator negative input values */ typedef enum CHIP_ACMP_NEG_INPUT { ACMP_NEGIN_VREF_DIV = (0 << 4), /*!< Voltage ladder output */ ACMP_NEGIN_ACMP_I1 = (1 << 4), /*!< ACMP_I1 pin */ ACMP_NEGIN_ACMP_I2 = (2 << 4), /*!< ACMP_I2 pin */ ACMP_NEGIN_ACMP_I3 = (3 << 4), /*!< ACMP_I3 pin */ ACMP_NEGIN_ACMP_I4 = (4 << 4), /*!< ACMP_I4 pin */ ACMP_NEGIN_INT_REF = (5 << 4), /*!< Internal reference voltage */ ACMP_NEGIN_ADCIN_1 = (6 << 4), /*!< ADC Input or Temperature sensor varies with comparator */ ACMP_NEGIN_ADCIN_2 = (7 << 4) /*!< ADC Input varies with comparator */ } CHIP_ACMP_NEG_INPUT_T; /** * Analog Comparator sample mode values */ typedef enum { ACMP_SMODE_0 = 0, /*!< Bypass filter */ ACMP_SMODE_1, /*!< Reject pulses shorter than 1 filter clock cycle */ ACMP_SMODE_2, /*!< Reject pulses shorter than 2 filter clock cycle */ ACMP_SMODE_3 /*!< Reject pulses shorter than 3 filter clock cycle */ } CHIP_ACMP_SMODE_T; /** * Analog Comparator clock divider values */ typedef enum { ACMP_CLKDIV_1 = (0x0 << 2), /*!< Use CMP_PCLK */ ACMP_CLKDIV_2 = (0x1 << 2), /*!< Use CMP_PCLK/2 */ ACMP_CLKDIV_4 = (0x2 << 2), /*!< Use CMP_PCLK/4 */ ACMP_CLKDIV_8 = (0x3 << 2), /*!< Use CMP_PCLK/8 */ ACMP_CLKDIV_16 = (0x4 << 2), /*!< Use CMP_PCLK/16 */ ACMP_CLKDIV_32 = (0x5 << 2), /*!< Use CMP_PCLK/32 */ ACMP_CLKDIV_64 = (0x6 << 2) /*!< Use CMP_PCLK/64 */ } CHIP_ACMP_CLKDIV_T; /** * @brief Initializes the ACMP * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ void Chip_ACMP_Init(LPC_CMP_T *pACMP); /** * @brief Deinitializes the ACMP * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ void Chip_ACMP_Deinit(LPC_CMP_T *pACMP); /** * @brief Enable the comparator * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_EnableComp(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_CMPEN_BIT; } /** * @brief Disable the comparator * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_DisableComp(LPC_CMP_T *pACMP, uint8_t index) { pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_CMPEN_BIT; } /** * @brief Enable the interrupt for the comparator * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_EnableCompInt(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTEN_BIT; } /** * @brief Disable the interrupt for the comparator * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_DisableCompInt(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTEN_BIT; } /** * @brief Returns the current comparator status * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return TRUE if ACMP_STATUS_BIT is set else returns FALSE */ STATIC INLINE bool Chip_ACMP_GetCompStatus(LPC_CMP_T *pACMP, uint8_t index) { return (pACMP->ACMP[index].CMP & ACMP_STATUS_BIT) != 0; } /** * @brief Selects positive voltage input * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param Posinput: one of the positive input voltage sources * @return Nothing */ void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_POS_INPUT_T Posinput); /** * @brief Selects negative voltage input * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param Neginput: one of the negative input voltage sources * @return Nothing */ void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_NEG_INPUT_T Neginput); /** * @brief Selects hysteresis level * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param hys : Selected Hysteresis level * @return Nothing */ void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_HYS_T hys); /** * @brief Set the ACMP interrupt polarity (INTPOL bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_SetIntPolarity(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTPOL_BIT; } /** * @brief Clear the ACMP interrupt polarity (INTPOL bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_ClearIntPolarity(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTPOL_BIT; } /** * @brief Set the ACMP interrupt type as edge (INTTYPE bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_SetIntTypeEdge(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_INTTYPE_BIT; } /** * @brief Set the ACMP interrupt type as level (INTTYPE bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_SetIntTypeLevel(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_INTTYPE_BIT; } /** * @brief Sets up ACMP edge selection * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param edgeSel : Edge selection value * @return Nothing */ void Chip_ACMP_SetIntEdgeSelection(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_EDGESEL_T edgeSel); /** * @brief Get the ACMP interrupt flag bit(INTFLAG bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return TRUE if ACMP_INTFLAG_BIT is set else returns FALSE */ STATIC INLINE bool Chip_ACMP_GetIntFlag(LPC_CMP_T *pACMP, uint8_t index) { return (pACMP->ACMP[index].CMP & ACMP_INTFLAG_BIT) != 0; } /** * @brief Clears the ACMP interrupt flag bit (INTFLAG bit) * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_ClearIntFlag(LPC_CMP_T *pACMP, uint8_t index) { pACMP->ACMP[index].CMP |= ACMP_INTFLAG_BIT; } /** * @brief Helper function for setting up ACMP voltage settings * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param Posinput : one of the positive input voltage sources * @param Neginput : one of the negative input voltage sources * @param hys : Selected Hysteresis level * @return Nothing */ void Chip_ACMP_SetupACMPRefs(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_POS_INPUT_T Posinput, CHIP_ACMP_NEG_INPUT_T Neginput, CHIP_ACMP_HYS_T hys); /** * @brief Helper function for setting up ACMP interrupt settings * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param level : interrupt type false - edge, true - level * @param invert : polarity of CMP output for interrupt, false - Not Inverted, true - Inverted * @param edgeSel : Edge selection value * @return Nothing */ void Chip_ACMP_SetupACMPInt(LPC_CMP_T *pACMP, uint8_t index, bool level, bool invert, CHIP_ACMP_EDGESEL_T edgeSel); /** * @brief Sets up voltage ladder * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param ladsel : Voltage ladder value (0 .. 31) * @param ladrefVDDCMP : Selects the reference voltage Vref for the voltage ladder * true for VDD, false for VDDCMP pin * @return Nothing */ void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint8_t index, uint32_t ladsel, bool ladrefVDDCMP); /** * @brief Enables voltage ladder * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_EnableVoltLadder(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) | ACMP_LADENAB_BIT; } /** * @brief Disables voltage ladder * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @return Nothing */ STATIC INLINE void Chip_ACMP_DisableVoltLadder(LPC_CMP_T *pACMP, uint8_t index) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = (pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_LADENAB_BIT; } /** * @brief Set propogation delay for comparator output * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param delay : propogation delay (0 - 2), 0 is short delay more power consumption * @return Nothing */ STATIC INLINE void Chip_ACMP_SetPropagationDelay(LPC_CMP_T *pACMP, uint8_t index, uint8_t delay) { /* Make sure interrupt flag is not set during read write operation */ pACMP->ACMP[index].CMP = ((pACMP->ACMP[index].CMP & ~ACMP_INTFLAG_BIT) & ~ACMP_PROPDLY_MASK) | ((uint32_t) delay << 29); } /** * @brief Set filter sample mode * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param mode : sample mode enum value * @return Nothing */ STATIC INLINE void Chip_ACMP_SetSampleMode(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_SMODE_T mode) { pACMP->ACMP[index].CMPFILTR = (pACMP->ACMP[index].CMPFILTR & ~ACMP_SMODE_MASK) | (uint32_t) mode; } /** * @brief Set clock divider * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param div : SysClk divider enum value * @return Nothing */ STATIC INLINE void Chip_ACMP_SetClockDiv(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_CLKDIV_T div) { pACMP->ACMP[index].CMPFILTR = (pACMP->ACMP[index].CMPFILTR & ~ACMP_CLKDIV_MASK) | (uint32_t) div; } /** * @brief Setup Comparator filter register * @param pACMP : Pointer to Analog Comparator block * @param index : index to the comparator (0 - 3) * @param mode : sample mode enum value * @param div : SysClk divider enum value * @return Nothing */ STATIC INLINE void Chip_ACMP_SetCompFiltReg(LPC_CMP_T *pACMP, uint8_t index, CHIP_ACMP_SMODE_T mode, CHIP_ACMP_CLKDIV_T div) { pACMP->ACMP[index].CMPFILTR = (uint32_t) mode | (uint32_t) div; } /** * @brief Set Ring Oscillator control bit, ROSC output is set by ACMP1 and reset by ACMP0 * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ STATIC INLINE void Chip_ACMP_SetRingOscCtl(LPC_CMP_T *pACMP) { pACMP->CTRL |= ACMP_ROSCCTL_BIT; } /** * @brief Clear Ring Oscillator control bit, ROSC output is set by ACMP0 and reset by ACMP1 * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ STATIC INLINE void Chip_ACMP_ClearRingOscCtl(LPC_CMP_T *pACMP) { pACMP->CTRL &= ~ACMP_ROSCCTL_BIT; } /** * @brief Set Ring Oscillator Reset Source to Internal * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ STATIC INLINE void Chip_ACMP_SetROscResetSrcInternal(LPC_CMP_T *pACMP) { pACMP->CTRL &= ~ACMP_EXTRESET_BIT; } /** * @brief Set Ring Oscillator Reset Source to External * @param pACMP : Pointer to Analog Comparator block * @return Nothing */ STATIC INLINE void Chip_ACMP_SetROscResetSrcExternal(LPC_CMP_T *pACMP) { pACMP->CTRL |= ACMP_EXTRESET_BIT; } /** * @} */ #ifdef __cplusplus } #endif #endif /* __ACMP_15XX_H_ */