PCNT - Pulse Counter

Description

Pulse Counter (PCNT) Peripheral API.

This module contains functions to control the PCNT peripheral of Silicon Labs 32-bit MCUs and SoCs. The PCNT decodes incoming pulses. The module has a quadrature mode which may be used to decode the speed and direction of a mechanical shaft.

Data Structures

struct  PCNT_Init_TypeDef
 Initialization structure.
 
struct  PCNT_Filter_TypeDef
 Filter initialization structure.
 
struct  PCNT_TCC_TypeDef
 TCC initialization structure.
 

Functions

uint32_t PCNT_CounterGet (PCNT_TypeDef *pcnt)
 Get the pulse counter value.
 
uint32_t PCNT_AuxCounterGet (PCNT_TypeDef *pcnt)
 Get the auxiliary counter value.
 
void PCNT_CounterReset (PCNT_TypeDef *pcnt)
 Reset PCNT counters and TOP register.
 
void PCNT_CounterTopSet (PCNT_TypeDef *pcnt, uint32_t count, uint32_t top)
 Set the counter and top values.
 
void PCNT_CounterSet (PCNT_TypeDef *pcnt, uint32_t count)
 Set a counter value.
 
void PCNT_Enable (PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode)
 Set PCNT operational mode.
 
bool PCNT_IsEnabled (PCNT_TypeDef *pcnt)
 Returns if the PCNT module is enabled or not.
 
void PCNT_FreezeEnable (PCNT_TypeDef *pcnt, bool enable)
 PCNT register synchronization freeze control.
 
void PCNT_Init (PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init)
 Initialize the pulse counter.
 
void PCNT_FilterConfiguration (PCNT_TypeDef *pcnt, const PCNT_Filter_TypeDef *config, bool enable)
 Set the filter configuration.
 
void PCNT_PRSInputEnable (PCNT_TypeDef *pcnt, PCNT_PRSInput_TypeDef prsInput, bool enable)
 Enable/disable the selected PRS input of PCNT.
 
void PCNT_TCCConfiguration (PCNT_TypeDef *pcnt, const PCNT_TCC_TypeDef *config)
 Set Triggered Compare and Clear configuration.
 
void PCNT_IntClear (PCNT_TypeDef *pcnt, uint32_t flags)
 Clear one or more pending PCNT interrupts.
 
void PCNT_IntDisable (PCNT_TypeDef *pcnt, uint32_t flags)
 Disable one or more PCNT interrupts.
 
void PCNT_IntEnable (PCNT_TypeDef *pcnt, uint32_t flags)
 Enable one or more PCNT interrupts.
 
uint32_t PCNT_IntGet (PCNT_TypeDef *pcnt)
 Get pending PCNT interrupt flags.
 
uint32_t PCNT_IntGetEnabled (PCNT_TypeDef *pcnt)
 Get enabled and pending PCNT interrupt flags.
 
void PCNT_IntSet (PCNT_TypeDef *pcnt, uint32_t flags)
 Set one or more pending PCNT interrupts from SW.
 
void PCNT_Reset (PCNT_TypeDef *pcnt)
 Reset PCNT to the same state that it was in after a hardware reset.
 
uint32_t PCNT_TopBufferGet (PCNT_TypeDef *pcnt)
 Get the pulse counter top buffer value.
 
void PCNT_TopBufferSet (PCNT_TypeDef *pcnt, uint32_t val)
 Set top buffer value.
 
uint32_t PCNT_TopGet (PCNT_TypeDef *pcnt)
 Get the pulse counter top value.
 
void PCNT_TopSet (PCNT_TypeDef *pcnt, uint32_t val)
 Set the top value.
 
void PCNT_Sync (PCNT_TypeDef *pcnt, uint32_t mask)
 Wait for an ongoing sync of register(s) to low-frequency domain to complete.
 

Macros

#define PCNT0_CNT_SIZE   (16)
 PCNT0 Counter register size.
 
#define PCNT1_CNT_SIZE   (16)
 PCNT1 Counter register size.
 
#define PCNT2_CNT_SIZE   (16)
 PCNT2 Counter register size.
 
#define PCNT_MODE_DISABLE   0xFF
 PCNT mode disable.
 
#define PCNT_CNT_EVENT_NONE   0xFF
 PCNT count event is none.
 
#define DEFAULT_DEBUG_HALT
 Default Debug.
 
#define DEFAULT_MODE   pcntModeDisable,
 Default Mode.
 
#define DEFAULT_HYST   false,
 Default Hysteresis.
 
#define DEFAULT_CDIR   true,
 Default counter direction.
 
#define DEFAULT_CNTEV   pcntCntEventUp,
 Default count event.
 
#define DEFAULT_AUXCNTEV   pcntCntEventNone,
 Default auxiliary count event.
 
#define DEFAULT_PRS_CH   pcntPRSCh0,
 Default selected PRS channel as S0IN and S1IN.
 
#define PCNT_INIT_DEFAULT
 Default configuration for PCNT initialization structure.
 
#define PCNT_FILTER_DEFAULT
 Default configuration for PCNT initialization structure.
 
#define PCNT_TCC_DEFAULT
 TCC Default.
 

Enumerations

enum  PCNT_Mode_TypeDef {
  pcntModeDisable = _PCNT_CTRL_MODE_DISABLE,
  pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE,
  pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE,
  pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD,
  pcntModeOvsQuad1 = _PCNT_CTRL_MODE_OVSQUAD1X,
  pcntModeOvsQuad2 = _PCNT_CTRL_MODE_OVSQUAD2X,
  pcntModeOvsQuad4 = _PCNT_CTRL_MODE_OVSQUAD4X
}
 Mode selection.
 
enum  PCNT_CntEvent_TypeDef {
  pcntCntEventBoth = _PCNT_CTRL_CNTEV_BOTH,
  pcntCntEventUp = _PCNT_CTRL_CNTEV_UP,
  pcntCntEventDown = _PCNT_CTRL_CNTEV_DOWN,
  pcntCntEventNone = _PCNT_CTRL_CNTEV_NONE
}
 Counter event selection.
 
enum  PCNT_PRSSel_TypeDef {
  pcntPRSCh0 = 0,
  pcntPRSCh1 = 1,
  pcntPRSCh2 = 2,
  pcntPRSCh3 = 3,
  pcntPRSCh4 = 4,
  pcntPRSCh5 = 5,
  pcntPRSCh6 = 6,
  pcntPRSCh7 = 7,
  pcntPRSCh8 = 8,
  pcntPRSCh9 = 9,
  pcntPRSCh10 = 10,
  pcntPRSCh11 = 11,
  pcntPRSCh12 = 12,
  pcntPRSCh13 = 13,
  pcntPRSCh14 = 14,
  pcntPRSCh15 = 15
}
 PRS sources for s0PRS and s1PRS.
 
enum  PCNT_PRSInput_TypeDef {
  pcntPRSInputS0 = 0,
  pcntPRSInputS1 = 1
}
 PRS inputs of PCNT.
 
enum  PCNT_TCCMode_TypeDef {
  tccModeDisabled = _PCNT_CTRL_TCCMODE_DISABLED,
  tccModeLFA = _PCNT_CTRL_TCCMODE_LFA,
  tccModePRS = _PCNT_CTRL_TCCMODE_PRS
}
 Modes for Triggered Compare and Clear module.
 
enum  PCNT_TCCPresc_Typedef {
  tccPrescDiv1 = _PCNT_CTRL_TCCPRESC_DIV1,
  tccPrescDiv2 = _PCNT_CTRL_TCCPRESC_DIV2,
  tccPrescDiv4 = _PCNT_CTRL_TCCPRESC_DIV4,
  tccPrescDiv8 = _PCNT_CTRL_TCCPRESC_DIV8
}
 Prescaler values for LFA compare and clear events.
 
enum  PCNT_TCCComp_Typedef {
  tccCompLTOE = _PCNT_CTRL_TCCCOMP_LTOE,
  tccCompGTOE = _PCNT_CTRL_TCCCOMP_GTOE,
  tccCompRange = _PCNT_CTRL_TCCCOMP_RANGE
}
 Compare modes for TCC module.
 

Function Documentation

◆ PCNT_CounterGet()

uint32_t PCNT_CounterGet ( PCNT_TypeDef *  pcnt)
inline

Get the pulse counter value.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
Returns
Current pulse counter value.

◆ PCNT_AuxCounterGet()

uint32_t PCNT_AuxCounterGet ( PCNT_TypeDef *  pcnt)
inline

Get the auxiliary counter value.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
Returns
Current auxiliary counter value.

◆ PCNT_CounterReset()

void PCNT_CounterReset ( PCNT_TypeDef *  pcnt)

Reset PCNT counters and TOP register.

Note
Notice that special SYNCBUSY handling is not applicable for the RSTEN bit of the control register, so we don't need to wait for it when only modifying RSTEN. (It would mean undefined wait time if clocked by an external clock.) The SYNCBUSY bit will however be set, leading to a synchronization in the LF domain, with, in reality, no changes.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.

◆ PCNT_CounterTopSet()

void PCNT_CounterTopSet ( PCNT_TypeDef *  pcnt,
uint32_t  count,
uint32_t  top 
)

Set the counter and top values.

The pulse counter is disabled while changing these values and reenabled (if originally enabled) when values have 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 an external clock is used for the PCNT module, since stall time may be undefined. The counter should normally only be set when operating in (or about to enable) pcntModeOvsSingle mode.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]countA value to set in the counter register.
[in]topA value to set in the top register.

◆ PCNT_CounterSet()

void PCNT_CounterSet ( PCNT_TypeDef *  pcnt,
uint32_t  count 
)
inline

Set a counter value.

Pulse counter is disabled while changing counter value and re-enabled (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.
Parameters
[in]pcntPointer to the PCNT peripheral register block.
[in]countValue to set in counter register.

◆ PCNT_Enable()

void PCNT_Enable ( PCNT_TypeDef *  pcnt,
PCNT_Mode_TypeDef  mode 
)

Set PCNT operational mode.

Notice that this function does not do any configuration. Setting operational mode is normally only required after initialization is done, and if not done as part of initialization or if requiring to disable/reenable pulse counter.

Note
This function may stall until synchronization to low-frequency domain is completed. For that reason, it should normally not be used when an external clock is used for the PCNT module, since stall time may be undefined.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]modeAn operational mode to use for PCNT.

◆ PCNT_IsEnabled()

bool PCNT_IsEnabled ( PCNT_TypeDef *  pcnt)

Returns if the PCNT module is enabled or not.

Notice that this function does not do any configuration.

Parameters
[in]pcntA pointer to the PCNT peripheral register block.
Returns
Returns TRUE if the module is enabled.

◆ PCNT_FreezeEnable()

void PCNT_FreezeEnable ( PCNT_TypeDef *  pcnt,
bool  enable 
)

PCNT register synchronization freeze control.

Some PCNT registers require synchronization into the low-frequency (LF) domain. The freeze feature allows for several registers to be modified before passing them to the LF domain simultaneously, which takes place when the freeze mode is disabled.

Note
When enabling freeze mode, this function will wait for all current ongoing PCNT synchronization to the LF domain to complete (normally synchronization will not be in progress). However, for this reason, when using freeze mode, modifications of registers requiring the LF synchronization should be done within one freeze enable/disable block to avoid unnecessary stalling.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]enable
  • True - enable freeze, modified registers are not propagated to the LF domain.
  • False - disables freeze, modified registers are propagated to LF domain.

◆ PCNT_Init()

void PCNT_Init ( PCNT_TypeDef *  pcnt,
const PCNT_Init_TypeDef init 
)

Initialize the pulse counter.

This function will configure the pulse counter. The clock selection is configured as follows, depending on operational mode:

Notice that the LFACLK must be enabled in all modes, since some basic setup is done with this clock even if the external pin clock usage mode is chosen. The pulse counter clock for the selected instance must also be enabled prior to initialization.

Notice that pins used by the PCNT module must be properly configured by the user explicitly through setting the ROUTE register for the PCNT to work as intended.

Writing to CNT will not occur in external clock modes (EXTCLKQUAD and EXTCLKSINGLE) because the external clock rate is unknown. The user should handle it manually depending on the application.

TOPB is written for all modes but in external clock mode it will take 3 external clock cycles to sync to TOP.

Note
Initializing requires synchronization into the low-frequency domain. This may cause a delay.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]initA pointer to the initialization structure.

◆ PCNT_FilterConfiguration()

void PCNT_FilterConfiguration ( PCNT_TypeDef *  pcnt,
const PCNT_Filter_TypeDef config,
bool  enable 
)

Set the filter configuration.

This function will configure the PCNT input filter when the PCNT mode is configured to take an LFA-derived clock as an input clock.

Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]configA pointer to the configuration structure to be applied.
[in]enableIndicates whether to enable or disable filtering.

◆ PCNT_PRSInputEnable()

void PCNT_PRSInputEnable ( PCNT_TypeDef *  pcnt,
PCNT_PRSInput_TypeDef  prsInput,
bool  enable 
)

Enable/disable the selected PRS input of PCNT.

Notice that this function does not do any configuration.

Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]prsInputPRS input (S0 or S1) of the selected PCNT module.
[in]enableSet to true to enable, false to disable the selected PRS input.

◆ PCNT_TCCConfiguration()

void PCNT_TCCConfiguration ( PCNT_TypeDef *  pcnt,
const PCNT_TCC_TypeDef config 
)

Set Triggered Compare and Clear configuration.

This function will configure the PCNT TCC (Triggered Compare and Clear) module. This module can, upon a configurable trigger source, compare the current counter value with the configured TOP value. Upon match, the counter will be reset and the TCC PRS output and TCC interrupt flag will be set.

Since there is a comparison with the TOP value, the counter will not stop counting nor wrap when hitting the TOP value, but it will keep on counting until its maximum value. Then, it will not wrap, but stop counting and set the overflow flag.

Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]configA pointer to the configuration structure to be applied.

◆ PCNT_IntClear()

void PCNT_IntClear ( PCNT_TypeDef *  pcnt,
uint32_t  flags 
)
inline

Clear one or more pending PCNT interrupts.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
[in]flagsPending PCNT interrupt source to clear. Use a bitwise logic OR combination of valid interrupt flags for the PCNT module (PCNT_IF_nnn).

◆ PCNT_IntDisable()

void PCNT_IntDisable ( PCNT_TypeDef *  pcnt,
uint32_t  flags 
)
inline

Disable one or more PCNT interrupts.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
[in]flagsPCNT interrupt sources to disable. Use a bitwise logic OR combination of valid interrupt flags for PCNT module (PCNT_IF_nnn).

◆ PCNT_IntEnable()

void PCNT_IntEnable ( PCNT_TypeDef *  pcnt,
uint32_t  flags 
)
inline

Enable one or more PCNT interrupts.

Note
Depending on the use, a pending interrupt may already be set prior to enabling the interrupt. To ignore a pending interrupt, consider using PCNT_IntClear() prior to enabling the interrupt.
Parameters
[in]pcntPointer to the PCNT peripheral register block.
[in]flagsPCNT interrupt sources to enable. Use a bitwise logic OR combination of valid interrupt flags for PCNT module (PCNT_IF_nnn).

◆ PCNT_IntGet()

uint32_t PCNT_IntGet ( PCNT_TypeDef *  pcnt)
inline

Get pending PCNT interrupt flags.

Note
The event bits are not cleared by the use of this function.
Parameters
[in]pcntPointer to the PCNT peripheral register block.
Returns
PCNT interrupt sources pending. A bitwise logic OR combination of valid interrupt flags for PCNT module (PCNT_IF_nnn).

◆ PCNT_IntGetEnabled()

uint32_t PCNT_IntGetEnabled ( PCNT_TypeDef *  pcnt)
inline

Get enabled and pending PCNT interrupt flags.

Useful for handling more interrupt sources in the same interrupt handler.

Note
The event bits are not cleared by the use of this function.
Parameters
[in]pcntPointer to thePCNT peripheral register block.
Returns
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).

◆ PCNT_IntSet()

void PCNT_IntSet ( PCNT_TypeDef *  pcnt,
uint32_t  flags 
)
inline

Set one or more pending PCNT interrupts from SW.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
[in]flagsPCNT interrupt sources to set to pending. Use a bitwise logic OR combination of valid interrupt flags for PCNT module (PCNT_IF_nnn).

◆ PCNT_Reset()

void PCNT_Reset ( PCNT_TypeDef *  pcnt)

Reset PCNT to the same state that it was in after a hardware reset.

Notice the LFACLK must be enabled, since some basic reset is done with this clock. The pulse counter clock for the selected instance must also be enabled prior to initialization.

Note
The ROUTE register is NOT reset by this function to allow for centralized setup of this feature.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.

◆ PCNT_TopBufferGet()

uint32_t PCNT_TopBufferGet ( PCNT_TypeDef *  pcnt)
inline

Get the pulse counter top buffer value.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
Returns
Current pulse counter top buffer value.

◆ PCNT_TopBufferSet()

void PCNT_TopBufferSet ( PCNT_TypeDef *  pcnt,
uint32_t  val 
)

Set top buffer value.

Note
This function may stall until synchronization to low-frequency domain is completed. For that reason, it should normally not be used when an external clock is used for the PCNT module since stall time may be undefined.
Parameters
[in]pcntA pointer to the PCNT peripheral register block.
[in]valA value to set in the top buffer register.

◆ PCNT_TopGet()

uint32_t PCNT_TopGet ( PCNT_TypeDef *  pcnt)
inline

Get the pulse counter top value.

Parameters
[in]pcntPointer to the PCNT peripheral register block.
Returns
Current pulse counter top value.

◆ PCNT_TopSet()

void PCNT_TopSet ( PCNT_TypeDef *  pcnt,
uint32_t