2013-01-08 22:40:58 +08:00
|
|
|
|
/***************************************************************************//**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Analog Comparator (ACMP) peripheral API
|
|
|
|
|
* @author Energy Micro AS
|
|
|
|
|
* @version 3.0.0
|
|
|
|
|
*******************************************************************************
|
|
|
|
|
* @section License
|
|
|
|
|
* <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
|
|
|
|
|
*******************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
|
|
|
* including commercial applications, and to alter it and redistribute it
|
|
|
|
|
* freely, subject to the following restrictions:
|
|
|
|
|
*
|
|
|
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
|
|
|
* claim that you wrote the original software.
|
|
|
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
|
* misrepresented as being the original software.
|
|
|
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
*
|
|
|
|
|
* 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 __EM_ACMP_H
|
|
|
|
|
#define __EM_ACMP_H
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include "em_part.h"
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/***************************************************************************//**
|
|
|
|
|
* @addtogroup EM_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,
|
|
|
|
|
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
|
|
|
|
|
/** DAC0 channel 0 */
|
|
|
|
|
acmpChannelDAC0Ch0 = _ACMP_INPUTSEL_NEGSEL_DAC0CH0,
|
|
|
|
|
/** DAC0 channel 1 */
|
|
|
|
|
acmpChannelDAC0Ch1 = _ACMP_INPUTSEL_NEGSEL_DAC0CH1,
|
|
|
|
|
#endif
|
|
|
|
|
} ACMP_Channel_TypeDef;
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
****************************** STRUCTS ************************************
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/** Capsense initialization structure. */
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
/** Full bias current. See the ACMP chapter about bias and response time in
|
|
|
|
|
* the reference manual for details. */
|
|
|
|
|
bool fullBias;
|
|
|
|
|
|
|
|
|
|
/** Half bias current. See the ACMP chapter about bias and response time in
|
|
|
|
|
* the reference manual for details. */
|
|
|
|
|
bool halfBias;
|
|
|
|
|
|
|
|
|
|
/** Bias current. See the ACMP chapter about bias and response time 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;
|
|
|
|
|
|
|
|
|
|
/** If true, ACMP is being enabled after configuration. */
|
|
|
|
|
bool enable;
|
|
|
|
|
} ACMP_CapsenseInit_TypeDef;
|
|
|
|
|
|
|
|
|
|
/** Default config for capacitive sense mode initialization. */
|
|
|
|
|
#define ACMP_CAPSENSE_INIT_DEFAULT \
|
|
|
|
|
{ false, /* fullBias */ \
|
|
|
|
|
false, /* halfBias */ \
|
|
|
|
|
0x7, /* biasProg */ \
|
|
|
|
|
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
|
|
|
|
|
acmpHysteresisLevel5, \
|
|
|
|
|
acmpResistor3, \
|
|
|
|
|
false, /* low power reference */ \
|
|
|
|
|
0x3D, /* VDD level */ \
|
|
|
|
|
true /* Enable after init. */ \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** ACMP initialization structure. */
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
/** Full bias current. See the ACMP chapter about bias and response time in
|
|
|
|
|
* the reference manual for details. */
|
|
|
|
|
bool fullBias;
|
|
|
|
|
|
|
|
|
|
/** Half bias current. See the ACMP chapter about bias and response time in
|
|
|
|
|
* the reference manual for details. */
|
|
|
|
|
bool halfBias;
|
|
|
|
|
|
|
|
|
|
/** Bias current. See the ACMP chapter about bias and response time 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;
|
|
|
|
|
|
|
|
|
|
/** If true, ACMP is being enabled after configuration. */
|
|
|
|
|
bool enable;
|
|
|
|
|
} ACMP_Init_TypeDef;
|
|
|
|
|
|
|
|
|
|
/** Default config for ACMP regular initialization. */
|
|
|
|
|
#define ACMP_INIT_DEFAULT \
|
|
|
|
|
{ false, /* fullBias */ \
|
|
|
|
|
false, /* halfBias */ \
|
|
|
|
|
0x7, /* biasProg */ \
|
|
|
|
|
false, /* No interrupt on falling edge. */ \
|
|
|
|
|
false, /* No interrupt on rising edge. */ \
|
|
|
|
|
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
|
|
|
|
|
acmpHysteresisLevel5, \
|
|
|
|
|
false, /* Disabled emitting inactive value during warmup. */ \
|
|
|
|
|
false, /* low power reference */ \
|
|
|
|
|
0x3D, /* VDD level */ \
|
|
|
|
|
true /* Enable after init. */ \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
***************************** 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_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 bitwise logic 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 bitwise logic 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 bitwise logic 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 bitwise logic 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
|
|
|
|
|
* Get enabled and pending ACMP interrupt flags.
|
|
|
|
|
* Useful for handling more interrupt sources in the same interrupt handler.
|
|
|
|
|
*
|
|
|
|
|
* @param[in] usart
|
|
|
|
|
* Pointer to ACMP peripheral register block.
|
|
|
|
|
*
|
|
|
|
|
* @note
|
|
|
|
|
* Interrupt flags are not cleared by the use of this function.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* Pending and enabled ACMP interrupt sources.
|
|
|
|
|
* The return value is the bitwise AND combination of
|
|
|
|
|
* - the OR combination of enabled interrupt sources in ACMPx_IEN_nnn
|
|
|
|
|
* register (ACMPx_IEN_nnn) and
|
|
|
|
|
* - the OR combination of valid interrupt flags of the ACMP module
|
|
|
|
|
* (ACMPx_IF_nnn).
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
__STATIC_INLINE uint32_t ACMP_IntGetEnabled(ACMP_TypeDef *acmp)
|
|
|
|
|
{
|
|
|
|
|
uint32_t tmp;
|
|
|
|
|
|
|
|
|
|
/* Store ACMPx->IEN in temporary variable in order to define explicit order
|
|
|
|
|
* of volatile accesses. */
|
|
|
|
|
tmp = acmp->IEN;
|
|
|
|
|
|
|
|
|
|
/* Bitwise AND of pending and enabled interrupts */
|
|
|
|
|
return acmp->IF & tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************//**
|
|
|
|
|
* @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 bitwise logic 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 EM_Library) */
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif /* __EM_ACMP_H */
|