336 lines
12 KiB
C
336 lines
12 KiB
C
|
/***************************************************************************//**
|
|||
|
* @file
|
|||
|
* @brief Analog Comparator (ACMP) peripheral API for EFM32.
|
|||
|
* @author Energy Micro AS
|
|||
|
* @version 1.3.0
|
|||
|
*******************************************************************************
|
|||
|
* @section License
|
|||
|
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
|
|||
|
*******************************************************************************
|
|||
|
*
|
|||
|
* This source code is the property of Energy Micro AS. The source and compiled
|
|||
|
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
|||
|
*
|
|||
|
* This copyright notice may not be removed from the source code nor changed.
|
|||
|
*
|
|||
|
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
|||
|
* obligation to support this Software. Energy Micro AS is providing the
|
|||
|
* Software "AS IS", with no express or implied warranties of any kind,
|
|||
|
* including, but not limited to, any implied warranties of merchantability
|
|||
|
* or fitness for any particular purpose or warranties against infringement
|
|||
|
* of any proprietary rights of a third party.
|
|||
|
*
|
|||
|
* Energy Micro AS will not be liable for any consequential, incidental, or
|
|||
|
* special damages, or any other relief, or for any claim by any third party,
|
|||
|
* arising from your use of this Software.
|
|||
|
*
|
|||
|
******************************************************************************/
|
|||
|
#ifndef __EFM32_ACMP_H
|
|||
|
#define __EFM32_ACMP_H
|
|||
|
|
|||
|
#include <stdint.h>
|
|||
|
#include <stdbool.h>
|
|||
|
#include "efm32.h"
|
|||
|
|
|||
|
#ifdef __cplusplus
|
|||
|
extern "C" {
|
|||
|
#endif
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @addtogroup EFM32_Library
|
|||
|
* @{
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @addtogroup ACMP
|
|||
|
* @{
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
******************************** ENUMS ************************************
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/** Resistor values used for capacative sense. See the datasheet for your
|
|||
|
* device for details on each resistor value. */
|
|||
|
typedef enum
|
|||
|
{
|
|||
|
/** resistor value 0 */
|
|||
|
acmpResistor0 = _ACMP_INPUTSEL_CSRESSEL_RES0,
|
|||
|
/** resistor value 1 */
|
|||
|
acmpResistor1 = _ACMP_INPUTSEL_CSRESSEL_RES1,
|
|||
|
/** resistor value 2 */
|
|||
|
acmpResistor2 = _ACMP_INPUTSEL_CSRESSEL_RES2,
|
|||
|
/** resistor value 3 */
|
|||
|
acmpResistor3 = _ACMP_INPUTSEL_CSRESSEL_RES3
|
|||
|
} ACMP_CapsenseResistor_TypeDef;
|
|||
|
|
|||
|
/** Hysteresis level. See datasheet for your device for details on each
|
|||
|
* level. */
|
|||
|
typedef enum
|
|||
|
{
|
|||
|
acmpHysteresisLevel0 = _ACMP_CTRL_HYSTSEL_HYST0, /**< Hysteresis level 0 */
|
|||
|
acmpHysteresisLevel1 = _ACMP_CTRL_HYSTSEL_HYST1, /**< Hysteresis level 1 */
|
|||
|
acmpHysteresisLevel2 = _ACMP_CTRL_HYSTSEL_HYST2, /**< Hysteresis level 2 */
|
|||
|
acmpHysteresisLevel3 = _ACMP_CTRL_HYSTSEL_HYST3, /**< Hysteresis level 3 */
|
|||
|
acmpHysteresisLevel4 = _ACMP_CTRL_HYSTSEL_HYST4, /**< Hysteresis level 4 */
|
|||
|
acmpHysteresisLevel5 = _ACMP_CTRL_HYSTSEL_HYST5, /**< Hysteresis level 5 */
|
|||
|
acmpHysteresisLevel6 = _ACMP_CTRL_HYSTSEL_HYST6, /**< Hysteresis level 6 */
|
|||
|
acmpHysteresisLevel7 = _ACMP_CTRL_HYSTSEL_HYST7 /**< Hysteresis level 7 */
|
|||
|
} ACMP_HysteresisLevel_TypeDef;
|
|||
|
|
|||
|
/** ACMP warmup time. The delay is measured in HFPERCLK cycles and should
|
|||
|
* be at least 10 us. */
|
|||
|
typedef enum
|
|||
|
{
|
|||
|
/** 4 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime4 = _ACMP_CTRL_WARMTIME_4CYCLES,
|
|||
|
/** 8 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime8 = _ACMP_CTRL_WARMTIME_8CYCLES,
|
|||
|
/** 16 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime16 = _ACMP_CTRL_WARMTIME_16CYCLES,
|
|||
|
/** 32 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime32 = _ACMP_CTRL_WARMTIME_32CYCLES,
|
|||
|
/** 64 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime64 = _ACMP_CTRL_WARMTIME_64CYCLES,
|
|||
|
/** 128 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime128 = _ACMP_CTRL_WARMTIME_128CYCLES,
|
|||
|
/** 256 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime256 = _ACMP_CTRL_WARMTIME_256CYCLES,
|
|||
|
/** 512 HFPERCLK cycles warmup */
|
|||
|
acmpWarmTime512 = _ACMP_CTRL_WARMTIME_512CYCLES
|
|||
|
} ACMP_WarmTime_TypeDef;
|
|||
|
|
|||
|
/** ACMP inputs. Note that scaled VDD and bandgap references can only be used
|
|||
|
* as negative inputs. */
|
|||
|
typedef enum
|
|||
|
{
|
|||
|
/** Channel 0 */
|
|||
|
acmpChannel0 = _ACMP_INPUTSEL_NEGSEL_CH0,
|
|||
|
/** Channel 1 */
|
|||
|
acmpChannel1 = _ACMP_INPUTSEL_NEGSEL_CH1,
|
|||
|
/** Channel 2 */
|
|||
|
acmpChannel2 = _ACMP_INPUTSEL_NEGSEL_CH2,
|
|||
|
/** Channel 3 */
|
|||
|
acmpChannel3 = _ACMP_INPUTSEL_NEGSEL_CH3,
|
|||
|
/** Channel 4 */
|
|||
|
acmpChannel4 = _ACMP_INPUTSEL_NEGSEL_CH4,
|
|||
|
/** Channel 5 */
|
|||
|
acmpChannel5 = _ACMP_INPUTSEL_NEGSEL_CH5,
|
|||
|
/** Channel 6 */
|
|||
|
acmpChannel6 = _ACMP_INPUTSEL_NEGSEL_CH6,
|
|||
|
/** Channel 7 */
|
|||
|
acmpChannel7 = _ACMP_INPUTSEL_NEGSEL_CH7,
|
|||
|
/** 1.25V internal reference */
|
|||
|
acmpChannel1V25 = _ACMP_INPUTSEL_NEGSEL_1V25,
|
|||
|
/** 2.5V internal reference */
|
|||
|
acmpChannel2V5 = _ACMP_INPUTSEL_NEGSEL_2V5,
|
|||
|
/** Scaled VDD reference */
|
|||
|
acmpChannelVDD = _ACMP_INPUTSEL_NEGSEL_VDD
|
|||
|
} ACMP_Channel_TypeDef;
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
****************************** STRUCTS ************************************
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/** Capsense initialization structure. */
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
/** Full bias current. See section 23.3.2 in the reference manual
|
|||
|
* for details. */
|
|||
|
bool fullBias;
|
|||
|
|
|||
|
/** Half bias current. See section 23.3.2 in the reference manual
|
|||
|
* for details. */
|
|||
|
bool halfBias;
|
|||
|
|
|||
|
/** Bias current. See section 23.3.2 in the reference manual for
|
|||
|
* details. Valid values are in the range 0-7. */
|
|||
|
uint32_t biasProg;
|
|||
|
|
|||
|
/** Warmup time. This is measured in HFPERCLK cycles and should be
|
|||
|
* about 10us in wall clock time. */
|
|||
|
ACMP_WarmTime_TypeDef warmTime;
|
|||
|
|
|||
|
/** Hysteresis level */
|
|||
|
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
|
|||
|
|
|||
|
/** Resistor used in the capacative sensing circuit. For values see
|
|||
|
* your device datasheet. */
|
|||
|
ACMP_CapsenseResistor_TypeDef resistor;
|
|||
|
|
|||
|
/** Low power reference enabled. This setting, if enabled, reduces the
|
|||
|
* power used by the VDD and bandgap references. */
|
|||
|
bool lowPowerReferenceEnabled;
|
|||
|
|
|||
|
/** Vdd reference value. VDD_SCALED = VDD <20> VDDLEVEL <20> 50mV/3.8V.
|
|||
|
* Valid values are in the range 0-63. */
|
|||
|
uint32_t vddLevel;
|
|||
|
} ACMP_CapsenseInit_TypeDef;
|
|||
|
|
|||
|
/** Default config for capacitive sense on the STK */
|
|||
|
#define ACMP_CAPSENSE_STK_DEFAULT \
|
|||
|
{ false, /* fullBias */ \
|
|||
|
false, /* halfBias */ \
|
|||
|
0xF, /* biasProg */ \
|
|||
|
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
|
|||
|
acmpHysteresisLevel5, \
|
|||
|
acmpResistor3, \
|
|||
|
false, /* low power reference */ \
|
|||
|
0x3D /* VDD level */ \
|
|||
|
}
|
|||
|
|
|||
|
/** ACMP initialization structure. */
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
/** Full bias current. See section 23.3.2 in the reference manual
|
|||
|
* for details. */
|
|||
|
bool fullBias;
|
|||
|
|
|||
|
/** Half bias current. See section 23.3.2 in the reference manual
|
|||
|
* for details. */
|
|||
|
bool halfBias;
|
|||
|
|
|||
|
/** Bias current. See section 23.3.2 in the reference manual for
|
|||
|
* details. Valid values are in the range 0-7. */
|
|||
|
uint32_t biasProg;
|
|||
|
|
|||
|
/** Enable setting the interrupt flag on falling edge */
|
|||
|
bool interruptOnFallingEdge;
|
|||
|
|
|||
|
/** Enable setting the interrupt flag on rising edge */
|
|||
|
bool interruptOnRisingEdge;
|
|||
|
|
|||
|
/** Warmup time. This is measured in HFPERCLK cycles and should be
|
|||
|
* about 10us in wall clock time. */
|
|||
|
ACMP_WarmTime_TypeDef warmTime;
|
|||
|
|
|||
|
/** Hysteresis level */
|
|||
|
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
|
|||
|
|
|||
|
/** Inactive value emitted by the ACMP during warmup */
|
|||
|
bool inactiveValue;
|
|||
|
|
|||
|
/** Low power reference enabled. This setting, if enabled, reduces the
|
|||
|
* power used by the VDD and bandgap references. */
|
|||
|
bool lowPowerReferenceEnabled;
|
|||
|
|
|||
|
/** Vdd reference value. VDD_SCALED = VDD <20> VDDLEVEL <20> 50mV/3.8V.
|
|||
|
* Valid values are in the range 0-63. */
|
|||
|
uint32_t vddLevel;
|
|||
|
} ACMP_Init_TypeDef;
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
***************************** PROTOTYPES **********************************
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init);
|
|||
|
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel);
|
|||
|
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, ACMP_Channel_TypeDef posSel);
|
|||
|
void ACMP_Disable(ACMP_TypeDef *acmp);
|
|||
|
void ACMP_DisableNoReset(ACMP_TypeDef *acmp);
|
|||
|
void ACMP_Enable(ACMP_TypeDef *acmp);
|
|||
|
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert);
|
|||
|
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init);
|
|||
|
void ACMP_Reset(ACMP_TypeDef *acmp);
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @brief
|
|||
|
* Clear one or more pending ACMP interrupts.
|
|||
|
*
|
|||
|
* @param[in] acmp
|
|||
|
* Pointer to ACMP peripheral register block.
|
|||
|
*
|
|||
|
* @param[in] flags
|
|||
|
* Pending ACMP interrupt source to clear. Use a logical OR combination
|
|||
|
* of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
|||
|
******************************************************************************/
|
|||
|
static __INLINE void ACMP_IntClear(ACMP_TypeDef *acmp, uint32_t flags)
|
|||
|
{
|
|||
|
acmp->IFC = flags;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @brief
|
|||
|
* Disable one or more ACMP interrupts.
|
|||
|
*
|
|||
|
* @param[in] acmp
|
|||
|
* Pointer to ACMP peripheral register block.
|
|||
|
*
|
|||
|
* @param[in] flags
|
|||
|
* ACMP interrupt sources to disable. Use a logical OR combination of
|
|||
|
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
|||
|
******************************************************************************/
|
|||
|
static __INLINE void ACMP_IntDisable(ACMP_TypeDef *acmp, uint32_t flags)
|
|||
|
{
|
|||
|
acmp->IEN &= ~(flags);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @brief
|
|||
|
* Enable one or more ACMP interrupts.
|
|||
|
*
|
|||
|
* @note
|
|||
|
* Depending on the use, a pending interrupt may already be set prior to
|
|||
|
* enabling the interrupt. Consider using ACMP_IntClear() prior to enabling
|
|||
|
* if such a pending interrupt should be ignored.
|
|||
|
*
|
|||
|
* @param[in] acmp
|
|||
|
* Pointer to ACMP peripheral register block.
|
|||
|
*
|
|||
|
* @param[in] flags
|
|||
|
* ACMP interrupt sources to enable. Use a logical OR combination of
|
|||
|
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
|||
|
******************************************************************************/
|
|||
|
static __INLINE void ACMP_IntEnable(ACMP_TypeDef *acmp, uint32_t flags)
|
|||
|
{
|
|||
|
acmp->IEN |= flags;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @brief
|
|||
|
* Get pending ACMP interrupt flags.
|
|||
|
*
|
|||
|
* @note
|
|||
|
* The event bits are not cleared by the use of this function.
|
|||
|
*
|
|||
|
* @param[in] acmp
|
|||
|
* Pointer to ACMP peripheral register block.
|
|||
|
*
|
|||
|
* @return
|
|||
|
* ACMP interrupt sources pending. A logical OR combination of valid
|
|||
|
* interrupt flags for the ACMP module (ACMP_IF_nnn).
|
|||
|
******************************************************************************/
|
|||
|
static __INLINE uint32_t ACMP_IntGet(ACMP_TypeDef *acmp)
|
|||
|
{
|
|||
|
return(acmp->IF);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************//**
|
|||
|
* @brief
|
|||
|
* Set one or more pending ACMP interrupts from SW.
|
|||
|
*
|
|||
|
* @param[in] acmp
|
|||
|
* Pointer to ACMP peripheral register block.
|
|||
|
*
|
|||
|
* @param[in] flags
|
|||
|
* ACMP interrupt sources to set to pending. Use a logical OR combination
|
|||
|
* of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
|
|||
|
******************************************************************************/
|
|||
|
static __INLINE void ACMP_IntSet(ACMP_TypeDef *acmp, uint32_t flags)
|
|||
|
{
|
|||
|
acmp->IFS = flags;
|
|||
|
}
|
|||
|
|
|||
|
/** @} (end addtogroup ACMP) */
|
|||
|
/** @} (end addtogroup EFM32_Library) */
|
|||
|
|
|||
|
#ifdef __cplusplus
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#endif /* __EFM32_ACMP_H */
|