The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
mbed 2
This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.
Diff: TARGET_TB_SENSE_1/TOOLCHAIN_GCC_ARM/em_pcnt.h
- Revision:
- 171:3a7713b1edbc
- Parent:
- 160:5571c4ff569f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TARGET_TB_SENSE_1/TOOLCHAIN_GCC_ARM/em_pcnt.h Thu Nov 08 11:45:42 2018 +0000 @@ -0,0 +1,603 @@ +/***************************************************************************//** + * @file em_pcnt.h + * @brief Pulse Counter (PCNT) peripheral API + * @version 5.3.3 + ******************************************************************************* + * # License + * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.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: Silicon Labs has no + * obligation to support this Software. Silicon Labs 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. + * + * Silicon Labs 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_PCNT_H +#define EM_PCNT_H + +#include "em_device.h" +#if defined(PCNT_COUNT) && (PCNT_COUNT > 0) + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************//** + * @addtogroup emlib + * @{ + ******************************************************************************/ + +/***************************************************************************//** + * @addtogroup PCNT + * @{ + ******************************************************************************/ + +/******************************************************************************* + ******************************* DEFINES *********************************** + ******************************************************************************/ +/** PCNT0 Counter register size. */ +#if defined(_EFM32_GECKO_FAMILY) +#define PCNT0_CNT_SIZE (8) /* PCNT0 counter is 8 bits. */ +#else +#define PCNT0_CNT_SIZE (16) /* PCNT0 counter is 16 bits. */ +#endif + +#ifdef PCNT1 +/** PCNT1 Counter register size. */ +#define PCNT1_CNT_SIZE (8) /* PCNT1 counter is 8 bits. */ +#endif + +#ifdef PCNT2 +/** PCNT2 Counter register size. */ +#define PCNT2_CNT_SIZE (8) /* PCNT2 counter is 8 bits. */ +#endif + +/******************************************************************************* + ******************************** ENUMS ************************************ + ******************************************************************************/ + +/** Mode selection. */ +typedef enum { + /** Disable pulse counter. */ + pcntModeDisable = _PCNT_CTRL_MODE_DISABLE, + + /** Single input LFACLK oversampling mode (available in EM0-EM2). */ + pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE, + + /** Externally clocked single input counter mode (available in EM0-EM3). */ + pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE, + + /** Externally clocked quadrature decoder mode (available in EM0-EM3). */ + pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD, + +#if defined(_PCNT_CTRL_MODE_OVSQUAD1X) + /** LFACLK oversampling quadrature decoder 1X mode (available in EM0-EM2). */ + pcntModeOvsQuad1 = _PCNT_CTRL_MODE_OVSQUAD1X, + + /** LFACLK oversampling quadrature decoder 2X mode (available in EM0-EM2). */ + pcntModeOvsQuad2 = _PCNT_CTRL_MODE_OVSQUAD2X, + + /** LFACLK oversampling quadrature decoder 4X mode (available in EM0-EM2). */ + pcntModeOvsQuad4 = _PCNT_CTRL_MODE_OVSQUAD4X, +#endif +} PCNT_Mode_TypeDef; + +#if defined(_PCNT_CTRL_CNTEV_MASK) +/** Counter event selection. + * Note: unshifted values are being used for enumeration because multiple + * configuration structure members use this type definition. */ +typedef enum { + /** Counts up on up-count and down on down-count events. */ + pcntCntEventBoth = _PCNT_CTRL_CNTEV_BOTH, + + /** Only counts up on up-count events. */ + pcntCntEventUp = _PCNT_CTRL_CNTEV_UP, + + /** Only counts down on down-count events. */ + pcntCntEventDown = _PCNT_CTRL_CNTEV_DOWN, + + /** Never counts. */ + pcntCntEventNone = _PCNT_CTRL_CNTEV_NONE +} PCNT_CntEvent_TypeDef; +#endif + +#if defined(_PCNT_INPUT_MASK) +/** PRS sources for @p s0PRS and @p s1PRS. */ +typedef enum { + pcntPRSCh0 = 0, /**< PRS channel 0. */ + pcntPRSCh1 = 1, /**< PRS channel 1. */ + pcntPRSCh2 = 2, /**< PRS channel 2. */ + pcntPRSCh3 = 3, /**< PRS channel 3. */ +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH4) + pcntPRSCh4 = 4, /**< PRS channel 4. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH5) + pcntPRSCh5 = 5, /**< PRS channel 5. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH6) + pcntPRSCh6 = 6, /**< PRS channel 6. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH7) + pcntPRSCh7 = 7, /**< PRS channel 7. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH8) + pcntPRSCh8 = 8, /**< PRS channel 8. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH9) + pcntPRSCh9 = 9, /**< PRS channel 9. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH10) + pcntPRSCh10 = 10, /**< PRS channel 10. */ +#endif +#if defined(PCNT_INPUT_S0PRSSEL_PRSCH11) + pcntPRSCh11 = 11 /**< PRS channel 11. */ +#endif +} PCNT_PRSSel_TypeDef; + +/** PRS inputs of PCNT. */ +typedef enum { + pcntPRSInputS0 = 0, /** PRS input 0. */ + pcntPRSInputS1 = 1 /** PRS input 1. */ +} PCNT_PRSInput_TypeDef; +#endif + +/******************************************************************************* + ******************************* STRUCTS *********************************** + ******************************************************************************/ + +/** Init structure. */ +typedef struct { + /** Mode to operate in. */ + PCNT_Mode_TypeDef mode; + + /** Initial counter value (refer to reference manual for max value allowed). + * Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes. + * If using #pcntModeExtSingle or #pcntModeExtQuad modes, the counter + * value is reset to HW reset value. */ + uint32_t counter; + + /** Initial top value (refer to reference manual for max value allowed). + * Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes. + * If using #pcntModeExtSingle or #pcntModeExtQuad modes, the top + * value is reset to HW reset value. */ + uint32_t top; + + /** Polarity of incoming edge. + * @li #pcntModeExtSingle mode - if false, positive edges are counted, + * otherwise negative edges. + * @li #pcntModeExtQuad mode - if true, counting direction is inverted. */ + bool negEdge; + + /** Counting direction, only applicable for #pcntModeOvsSingle and + * #pcntModeExtSingle modes. */ + bool countDown; + + /** Enable filter, only available in #pcntModeOvs* modes. */ + bool filter; + +#if defined(PCNT_CTRL_HYST) + /** Set to true to enable hysteresis. When its enabled, the PCNT will always + * overflow and underflow to TOP/2. */ + bool hyst; + + /** Set to true to enable S1 to determine the direction of counting in + * OVSSINGLE or EXTCLKSINGLE modes. @n + * When S1 is high, the count direction is given by CNTDIR, and when S1 is + * low, the count direction is the opposite. */ + bool s1CntDir; + + /** Selects whether the regular counter responds to up-count events, + * down-count events, both or none. */ + PCNT_CntEvent_TypeDef cntEvent; + + /** Selects whether the auxiliary counter responds to up-count events, + * down-count events, both or none. */ + PCNT_CntEvent_TypeDef auxCntEvent; + + /** Select PRS channel as input to S0IN in PCNTx_INPUT register. */ + PCNT_PRSSel_TypeDef s0PRS; + + /** Select PRS channel as input to S1IN in PCNTx_INPUT register. */ + PCNT_PRSSel_TypeDef s1PRS; +#endif +} PCNT_Init_TypeDef; + +#if !defined(PCNT_CTRL_HYST) +/** Default config for PCNT init structure. */ +#define PCNT_INIT_DEFAULT \ + { \ + pcntModeDisable, /* Disabled by default. */ \ + _PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \ + _PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \ + false, /* Use positive edge. */ \ + false, /* Up-counting. */ \ + false /* Filter disabled. */ \ + } +#else +/** Default config for PCNT init structure. */ +#define PCNT_INIT_DEFAULT \ + { \ + pcntModeDisable, /* Disabled by default. */ \ + _PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \ + _PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \ + false, /* Use positive edge. */ \ + false, /* Up-counting. */ \ + false, /* Filter disabled. */ \ + false, /* Hysteresis disabled. */ \ + true, /* Counter direction is given by CNTDIR. */ \ + pcntCntEventUp, /* Regular counter counts up on upcount events. */ \ + pcntCntEventNone, /* Auxiliary counter doesn't respond to events. */ \ + pcntPRSCh0, /* PRS channel 0 selected as S0IN. */ \ + pcntPRSCh0 /* PRS channel 0 selected as S1IN. */ \ + } +#endif + +#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) +/** Filter initialization structure */ +typedef struct { + /** Used only in OVSINGLE and OVSQUAD1X-4X modes. To use this, enable the filter through + * setting filter to true during PCNT_Init(). Filter length = (filtLen + 5) LFACLK cycles. */ + uint8_t filtLen; + + /** When set, removes flutter from Quaddecoder inputs S0IN and S1IN. + * Available only in OVSQUAD1X-4X modes. */ + bool flutterrm; +} PCNT_Filter_TypeDef; +#endif + +/** Default config for PCNT init structure. */ +#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) +#define PCNT_FILTER_DEFAULT \ + { \ + 0, /* Default length is 5 LFACLK cycles */ \ + false /* No flutter removal */ \ + } +#endif + +#if defined(PCNT_CTRL_TCCMODE_DEFAULT) + +/** Modes for Triggered Compare and Clear module */ +typedef enum { + /** Triggered compare and clear not enabled. */ + tccModeDisabled = _PCNT_CTRL_TCCMODE_DISABLED, + + /** Compare and clear performed on each (optionally prescaled) LFA clock cycle. */ + tccModeLFA = _PCNT_CTRL_TCCMODE_LFA, + + /** Compare and clear performed on PRS edges. Polarity defined by prsPolarity. */ + tccModePRS = _PCNT_CTRL_TCCMODE_PRS +} PCNT_TCCMode_TypeDef; + +/** Prescaler values for LFA compare and clear events. Only has effect when TCC mode is LFA. */ +typedef enum { + /** Compare and clear event each LFA cycle. */ + tccPrescDiv1 = _PCNT_CTRL_TCCPRESC_DIV1, + + /** Compare and clear event every other LFA cycle. */ + tccPrescDiv2 = _PCNT_CTRL_TCCPRESC_DIV2, + + /** Compare and clear event every 4th LFA cycle. */ + tccPrescDiv4 = _PCNT_CTRL_TCCPRESC_DIV4, + + /** Compare and clear event every 8th LFA cycle. */ + tccPrescDiv8 = _PCNT_CTRL_TCCPRESC_DIV8 +} PCNT_TCCPresc_Typedef; + +/** Compare modes for TCC module */ +typedef enum { + /** Compare match if PCNT_CNT is less than, or equal to PCNT_TOP. */ + tccCompLTOE = _PCNT_CTRL_TCCCOMP_LTOE, + + /** Compare match if PCNT_CNT is greater than or equal to PCNT_TOP. */ + tccCompGTOE = _PCNT_CTRL_TCCCOMP_GTOE, + + /** Compare match if PCNT_CNT is less than, or equal to PCNT_TOP[15:8]], and greater + * than, or equal to PCNT_TOP[7:0]. */ + tccCompRange = _PCNT_CTRL_TCCCOMP_RANGE +} PCNT_TCCComp_Typedef; + +/** TCC initialization structure */ +typedef struct { + /** Mode to operate in. */ + PCNT_TCCMode_TypeDef mode; + + /** Prescaler value for LFACLK in LFA mode */ + PCNT_TCCPresc_Typedef prescaler; + + /** Choose the event that will trigger a clear */ + PCNT_TCCComp_Typedef compare; + + /** PRS input to TCC module, either for gating the PCNT clock, triggering the TCC comparison, or both. */ + PCNT_PRSSel_TypeDef tccPRS; + + /** TCC PRS input polarity. @n + * False = Rising edge for comparison trigger, and PCNT clock gated when the PRS signal is high. @n + * True = Falling edge for comparison trigger, and PCNT clock gated when the PRS signal is low. */ + bool prsPolarity; + + /** Enable gating PCNT input clock through TCC PRS signal. + * Polarity selection is done through prsPolarity. */ + bool prsGateEnable; +} PCNT_TCC_TypeDef; + +#define PCNT_TCC_DEFAULT \ + { \ + tccModeDisabled, /* Disabled by default */ \ + tccPrescDiv1, /* Do not prescale LFA clock in LFA mode */ \ + tccCompLTOE, /* Clear when CNT <= TOP */ \ + pcntPRSCh0, /* Select PRS channel 0 as input to TCC */ \ + false, /* PRS polarity is rising edge, and gate when 1 */ \ + false /* Do not gate the PCNT counter input */ \ + } + +#endif +/* defined(PCNT_CTRL_TCCMODE_DEFAULT) */ + +/******************************************************************************* + ***************************** PROTOTYPES ********************************** + ******************************************************************************/ + +/***************************************************************************//** + * @brief + * Get pulse counter value. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * Current pulse counter value. + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_CounterGet(PCNT_TypeDef *pcnt) +{ + return pcnt->CNT; +} + +#if defined(_PCNT_AUXCNT_MASK) +/***************************************************************************//** + * @brief + * Get auxiliary counter value. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * Current auxiliary counter value. + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_AuxCounterGet(PCNT_TypeDef *pcnt) +{ + return pcnt->AUXCNT; +} +#endif + +void PCNT_CounterReset(PCNT_TypeDef *pcnt); +void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top); + +/***************************************************************************//** + * @brief + * Set counter value. + * + * @details + * The pulse counter is disabled while changing counter value, and reenabled + * (if originally enabled) when counter value has been set. + * + * @note + * This function will stall until synchronization to low frequency domain is + * completed. For that reason, it should normally not be used when using + * an external clock to clock the PCNT module, since stall time may be + * undefined in that case. The counter should normally only be set when + * operating in (or about to enable) #pcntModeOvsSingle mode. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @param[in] count + * Value to set in counter register. + ******************************************************************************/ +__STATIC_INLINE void PCNT_CounterSet(PCNT_TypeDef *pcnt, uint32_t count) +{ + PCNT_CounterTopSet(pcnt, count, pcnt->TOP); +} + +void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode); +void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable); +void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init); + +#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) +void PCNT_FilterConfiguration(PCNT_TypeDef *pcnt, const PCNT_Filter_TypeDef *config, bool enable); +#endif + +#if defined(_PCNT_INPUT_MASK) +void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt, + PCNT_PRSInput_TypeDef prsInput, + bool enable); +#endif + +#if defined(PCNT_CTRL_TCCMODE_DEFAULT) +void PCNT_TCCConfiguration(PCNT_TypeDef *pcnt, const PCNT_TCC_TypeDef *config); +#endif +/***************************************************************************//** + * @brief + * Clear one or more pending PCNT interrupts. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @param[in] flags + * Pending PCNT interrupt source to clear. Use a bitwise logic OR combination + * of valid interrupt flags for the PCNT module (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE void PCNT_IntClear(PCNT_TypeDef *pcnt, uint32_t flags) +{ + pcnt->IFC = flags; +} + +/***************************************************************************//** + * @brief + * Disable one or more PCNT interrupts. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @param[in] flags + * PCNT interrupt sources to disable. Use a bitwise logic OR combination of + * valid interrupt flags for the PCNT module (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE void PCNT_IntDisable(PCNT_TypeDef *pcnt, uint32_t flags) +{ + pcnt->IEN &= ~flags; +} + +/***************************************************************************//** + * @brief + * Enable one or more PCNT interrupts. + * + * @note + * Depending on the use, a pending interrupt may already be set prior to + * enabling the interrupt. Consider using PCNT_IntClear() prior to enabling + * if such a pending interrupt should be ignored. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @param[in] flags + * PCNT interrupt sources to enable. Use a bitwise logic OR combination of + * valid interrupt flags for the PCNT module (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE void PCNT_IntEnable(PCNT_TypeDef *pcnt, uint32_t flags) +{ + pcnt->IEN |= flags; +} + +/***************************************************************************//** + * @brief + * Get pending PCNT interrupt flags. + * + * @note + * The event bits are not cleared by the use of this function. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * PCNT interrupt sources pending. A bitwise logic OR combination of valid + * interrupt flags for the PCNT module (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_IntGet(PCNT_TypeDef *pcnt) +{ + return pcnt->IF; +} + +/***************************************************************************//** + * @brief + * Get enabled and pending PCNT interrupt flags. + * + * @details + * Useful for handling more interrupt sources in the same interrupt handler. + * + * @note + * The event bits are not cleared by the use of this function. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * Pending and enabled PCNT interrupt sources. + * The return value is the bitwise AND combination of + * - the OR combination of enabled interrupt sources in PCNT_IEN_nnn + * register (PCNT_IEN_nnn) and + * - the OR combination of valid interrupt flags of the PCNT module + * (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_IntGetEnabled(PCNT_TypeDef *pcnt) +{ + uint32_t ien; + + /* Store pcnt->IEN in temporary variable in order to define explicit order + * of volatile accesses. */ + ien = pcnt->IEN; + + /* Bitwise AND of pending and enabled interrupts */ + return pcnt->IF & ien; +} + +/***************************************************************************//** + * @brief + * Set one or more pending PCNT interrupts from SW. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @param[in] flags + * PCNT interrupt sources to set to pending. Use a bitwise logic OR combination + * of valid interrupt flags for the PCNT module (PCNT_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE void PCNT_IntSet(PCNT_TypeDef *pcnt, uint32_t flags) +{ + pcnt->IFS = flags; +} + +void PCNT_Reset(PCNT_TypeDef *pcnt); + +/***************************************************************************//** + * @brief + * Get pulse counter top buffer value. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * Current pulse counter top buffer value. + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_TopBufferGet(PCNT_TypeDef *pcnt) +{ + return pcnt->TOPB; +} + +void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val); + +/***************************************************************************//** + * @brief + * Get pulse counter top value. + * + * @param[in] pcnt + * Pointer to PCNT peripheral register block. + * + * @return + * Current pulse counter top value. + ******************************************************************************/ +__STATIC_INLINE uint32_t PCNT_TopGet(PCNT_TypeDef *pcnt) +{ + return pcnt->TOP; +} + +void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val); + +/** @} (end addtogroup PCNT) */ +/** @} (end addtogroup emlib) */ + +#ifdef __cplusplus +} +#endif + +#endif /* defined(PCNT_COUNT) && (PCNT_COUNT > 0) */ +#endif /* EM_PCNT_H */