PCNT - Pulse Counter#


Example#

The following example demonstrates basic usage of the PCNT peripheral in oversampling single input mode.

void pcnt_basic_example(void)
{
  // Configure PCNT with default settings for single input oversampling mode
  sl_hal_pcnt_init_t init = SL_HAL_PCNT_INIT_DEFAULT(SL_HAL_PCNT_MODE_OVS_SINGLE);

  // Initialize PCNT with our configuration
  sl_hal_pcnt_init(PCNT0, &init);

  // Enable the PCNT peripheral
  sl_hal_pcnt_enable(PCNT0);

  // Start the main counter
  sl_hal_pcnt_start_main_counter(PCNT0);

  // Wait for synchronization to complete
  sl_hal_pcnt_wait_sync(PCNT0);

  // Check if counter is running by reading status
  uint32_t status = sl_hal_pcnt_get_status(PCNT0);
  bool is_running = status & PCNT_STATUS_CNTRUNNING;

  if (is_running) {
    // Read current counter value
    uint32_t count_initial = sl_hal_pcnt_get_main_counter(PCNT0);

    // Optionally set counter to a specific value
    uint32_t count_new = count_initial + 10;
    sl_hal_pcnt_set_main_counter(PCNT0, count_new);

    // Read the updated counter value
    uint32_t count_after = sl_hal_pcnt_get_main_counter(PCNT0);

    // Application processing...

    // Reset the counter when needed
    sl_hal_pcnt_reset_counters(PCNT0);

    // Counter value should now be 0
    count_after = sl_hal_pcnt_get_main_counter(PCNT0);
  }

  // Stop the counter when done
  sl_hal_pcnt_stop_main_counter(PCNT0);
  sl_hal_pcnt_wait_sync(PCNT0);

  // Verify counter is stopped
  status = sl_hal_pcnt_get_status(PCNT0);
  is_running = status & PCNT_STATUS_CNTRUNNING;

  // Clean up - disable PCNT when no longer needed
  sl_hal_pcnt_disable(PCNT0);
}

Modules#

sl_hal_pcnt_init_t

Enumerations#

enum
SL_HAL_PCNT_MODE_OVS_SINGLE = _PCNT_CFG_MODE_OVSSINGLE
SL_HAL_PCNT_MODE_EXT_CLK_SINGLE = _PCNT_CFG_MODE_EXTCLKSINGLE
SL_HAL_PCNT_MODE_EXT_CLK_QUAD = _PCNT_CFG_MODE_EXTCLKQUAD
SL_HAL_PCNT_MODE_OVS_QUAD_1X = _PCNT_CFG_MODE_OVSQUAD1X
SL_HAL_PCNT_MODE_OVS_QUAD_2X = _PCNT_CFG_MODE_OVSQUAD2X
SL_HAL_PCNT_MODE_OVS_QUAD_4X = _PCNT_CFG_MODE_OVSQUAD4X
}

PCNT mode.

enum
SL_HAL_PCNT_COUNT_EVENT_BOTH = _PCNT_CTRL_CNTEV_BOTH
SL_HAL_PCNT_COUNT_EVENT_UP = _PCNT_CTRL_CNTEV_UP
SL_HAL_PCNT_COUNT_EVENT_DOWN = _PCNT_CTRL_CNTEV_DOWN
}

Counter event selection.

Functions#

void
sl_hal_pcnt_init(PCNT_TypeDef *pcnt, const sl_hal_pcnt_init_t *init)

Initialize the pulse counter (PCNT).

void
sl_hal_pcnt_reset(PCNT_TypeDef *pcnt)

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

void
sl_hal_pcnt_enable(PCNT_TypeDef *pcnt)

Enable the PCNT.

void
sl_hal_pcnt_disable(PCNT_TypeDef *pcnt)

Disable PCNT.

bool
sl_hal_pcnt_is_enabled(PCNT_TypeDef *pcnt)

Returns if the PCNT module is enabled or not.

void
sl_hal_pcnt_wait_ready(PCNT_TypeDef *pcnt)

Wait for disabling to finish.

void
sl_hal_pcnt_wait_sync(PCNT_TypeDef *pcnt)

Wait for ongoing sync of register(s) to the low-frequency domain to complete.

uint32_t
sl_hal_pcnt_get_status(PCNT_TypeDef *pcnt)

Get status values for the PCNT.

void
sl_hal_pcnt_enable_interrupts(PCNT_TypeDef *pcnt, uint32_t flags)

Enable one or more PCNT interrupts.

void
sl_hal_pcnt_disable_interrupts(PCNT_TypeDef *pcnt, uint32_t flags)

Disable one or more PCNT interrupts.

void
sl_hal_pcnt_clear_interrupts(PCNT_TypeDef *pcnt, uint32_t flags)

Clear one or more pending PCNT interrupts.

void
sl_hal_pcnt_set_interrupts(PCNT_TypeDef *pcnt, uint32_t flags)

Set one or more pending PCNT interrupts from SW.

uint32_t

Get pending PCNT interrupt flags.

uint32_t

Get enabled and pending PCNT interrupt flags.

void
sl_hal_pcnt_lock(PCNT_TypeDef *pcnt)

Lock PCNT registers.

void
sl_hal_pcnt_unlock(PCNT_TypeDef *pcnt)

Unlock PCNT registers.

void
sl_hal_pcnt_set_top_buffer(PCNT_TypeDef *pcnt, uint32_t value)

Set the top value buffer.

uint32_t
sl_hal_pcnt_get_top_buffer(PCNT_TypeDef *pcnt)

Get the top value buffer.

void
sl_hal_pcnt_set_top(PCNT_TypeDef *pcnt, uint32_t value)

Set the top value.

uint32_t
sl_hal_pcnt_get_top(PCNT_TypeDef *pcnt)

Get the top value.

void
sl_hal_pcnt_start_main_counter(PCNT_TypeDef *pcnt)

Start PCNT main counter.

void
sl_hal_pcnt_stop_main_counter(PCNT_TypeDef *pcnt)

Stop PCNT main counter.

void
sl_hal_pcnt_set_main_counter(PCNT_TypeDef *pcnt, uint32_t value)

Set a counter value.

uint32_t
sl_hal_pcnt_get_main_counter(PCNT_TypeDef *pcnt)

Get the main counter value.

void
sl_hal_pcnt_start_aux_counter(PCNT_TypeDef *pcnt)

Start PCNT auxiliary counter.

void
sl_hal_pcnt_stop_aux_counter(PCNT_TypeDef *pcnt)

Stop PCNT auxiliary counter.

uint32_t
sl_hal_pcnt_get_aux_counter(PCNT_TypeDef *pcnt)

Get the auxiliary counter value.

void
sl_hal_pcnt_reset_counters(PCNT_TypeDef *pcnt)

Reset PCNT counters.

Macros#

#define
SL_HAL_PCNT_REF_VALID (pcnt_ref)

Check if PCNT module is valid.

#define
SL_HAL_PCNT_MAX_COUNT (pcnt_ref)

Return PCNT module max count.

#define
SL_HAL_PCNT_INIT_DEFAULT (init_mode)

Default configuration for PCNT initialization structure.

Enumeration Documentation#

sl_hal_pcnt_mode_t#

sl_hal_pcnt_mode_t

PCNT mode.

Enumerator
SL_HAL_PCNT_MODE_OVS_SINGLE

Single input LFACLK oversampling mode (available in EM0-EM3).

SL_HAL_PCNT_MODE_EXT_CLK_SINGLE

Externally clocked single input counter mode (available in EM0-EM3).

SL_HAL_PCNT_MODE_EXT_CLK_QUAD

Externally clocked quadrature decoder mode (available in EM0-EM3).

SL_HAL_PCNT_MODE_OVS_QUAD_1X

LFACLK oversampling quadrature decoder 1X mode (available in EM0-EM3).

SL_HAL_PCNT_MODE_OVS_QUAD_2X

LFACLK oversampling quadrature decoder 2X mode (available in EM0-EM3).

SL_HAL_PCNT_MODE_OVS_QUAD_4X

LFACLK oversampling quadrature decoder 4X mode (available in EM0-EM3).


sl_hal_pcnt_count_event_t#

sl_hal_pcnt_count_event_t

Counter event selection.

Enumerator
SL_HAL_PCNT_COUNT_EVENT_BOTH

Counts up on up-count and down on down-count events.

SL_HAL_PCNT_COUNT_EVENT_UP

Only counts up on up-count events.

SL_HAL_PCNT_COUNT_EVENT_DOWN

Only counts down on down-count events.


Function Documentation#

sl_hal_pcnt_init#

void sl_hal_pcnt_init (PCNT_TypeDef * pcnt, const sl_hal_pcnt_init_t * init)

Initialize the pulse counter (PCNT).

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

const sl_hal_pcnt_init_t *[in]init

Pointer to the initialization structure.

Notice that the EM23GRPACLK 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.


sl_hal_pcnt_reset#

void sl_hal_pcnt_reset (PCNT_TypeDef * pcnt)

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

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.


sl_hal_pcnt_enable#

void sl_hal_pcnt_enable (PCNT_TypeDef * pcnt)

Enable the PCNT.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.


sl_hal_pcnt_disable#

void sl_hal_pcnt_disable (PCNT_TypeDef * pcnt)

Disable PCNT.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.


sl_hal_pcnt_is_enabled#

bool sl_hal_pcnt_is_enabled (PCNT_TypeDef * pcnt)

Returns if the PCNT module is enabled or not.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Returns true if the module is enabled.


sl_hal_pcnt_wait_ready#

void sl_hal_pcnt_wait_ready (PCNT_TypeDef * pcnt)

Wait for disabling to finish.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.


sl_hal_pcnt_wait_sync#

void sl_hal_pcnt_wait_sync (PCNT_TypeDef * pcnt)

Wait for ongoing sync of register(s) to the low-frequency domain to complete.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.


sl_hal_pcnt_get_status#

uint32_t sl_hal_pcnt_get_status (PCNT_TypeDef * pcnt)

Get status values for the PCNT.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Current status values.


sl_hal_pcnt_enable_interrupts#

void sl_hal_pcnt_enable_interrupts (PCNT_TypeDef * pcnt, uint32_t flags)

Enable one or more PCNT interrupts.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]flags

PCNT interrupt source(s) to enable. Use one or more valid interrupt flags for the PCNT module (PCNT_IF_nnn) OR'ed together.


sl_hal_pcnt_disable_interrupts#

void sl_hal_pcnt_disable_interrupts (PCNT_TypeDef * pcnt, uint32_t flags)

Disable one or more PCNT interrupts.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]flags

PCNT interrupt source(s) to disable. Use one or more valid interrupt flags for the PCNT module (PCNT_IF_nnn) OR'ed together.


sl_hal_pcnt_clear_interrupts#

void sl_hal_pcnt_clear_interrupts (PCNT_TypeDef * pcnt, uint32_t flags)

Clear one or more pending PCNT interrupts.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]flags

Pending PCNT interrupt source(s) to clear. Use one or more valid interrupt flags for the PCNT module (PCNT_IF_nnn) OR'ed together.


sl_hal_pcnt_set_interrupts#

void sl_hal_pcnt_set_interrupts (PCNT_TypeDef * pcnt, uint32_t flags)

Set one or more pending PCNT interrupts from SW.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]flags

PCNT interrupt source(s) to set to pending. Use one or more valid interrupt flags for the PCNT module (PCNT_IF_nnn) OR'ed together.


sl_hal_pcnt_get_pending_interrupts#

uint32_t sl_hal_pcnt_get_pending_interrupts (PCNT_TypeDef * pcnt)

Get pending PCNT interrupt flags.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Note

  • Event bits are not cleared by this function.

Returns

  • PCNT interrupt source(s) pending. Returns one or more valid interrupt flags for the PCNT module (PCNT_IF_nnn) OR'ed together.


sl_hal_pcnt_get_enabled_pending_interrupts#

uint32_t sl_hal_pcnt_get_enabled_pending_interrupts (PCNT_TypeDef * pcnt)

Get enabled and pending PCNT interrupt flags.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

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

Note

  • Interrupt flags are not cleared by this function.

Returns

  • Pending and enabled PCNT interrupt sources. The return value is the bitwise AND combination of

    • the OR combination of enabled interrupt sources in PCNTx_IEN_nnn register (PCNTx_IEN_nnn) and

    • the OR combination of valid interrupt flags of the PCNT module (PCNTx_IF_nnn).


sl_hal_pcnt_lock#

void sl_hal_pcnt_lock (PCNT_TypeDef * pcnt)

Lock PCNT registers.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Note

  • When PCNT registers are locked PCNT_CFG, PCNT_EN, PCNT_SWRST, PCNT_CMD, PCNT_CTRL, PCNT_OVSCTRL, PCNT_CNT, PCNT_TOP, and PCNT_TOPB registers cannot be written to.


sl_hal_pcnt_unlock#

void sl_hal_pcnt_unlock (PCNT_TypeDef * pcnt)

Unlock PCNT registers.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to thePCNT peripheral register block.


sl_hal_pcnt_set_top_buffer#

void sl_hal_pcnt_set_top_buffer (PCNT_TypeDef * pcnt, uint32_t value)

Set the top value buffer.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]value

Value to set in top value buffer register.

When top value buffer register is updated, value is loaded into top value register at the next wrap around. This feature is useful in order to update top value safely when PCNT is running. This won't happen if SL_HAL_PCNT_COUNT_EVENT_BOTH is used.


sl_hal_pcnt_get_top_buffer#

uint32_t sl_hal_pcnt_get_top_buffer (PCNT_TypeDef * pcnt)

Get the top value buffer.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Current top value buffer.


sl_hal_pcnt_set_top#

void sl_hal_pcnt_set_top (PCNT_TypeDef * pcnt, uint32_t value)

Set the top value.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]value

Value to set in top value register.


sl_hal_pcnt_get_top#

uint32_t sl_hal_pcnt_get_top (PCNT_TypeDef * pcnt)

Get the top value.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Current top value.


sl_hal_pcnt_start_main_counter#

void sl_hal_pcnt_start_main_counter (PCNT_TypeDef * pcnt)

Start PCNT main counter.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

This function will send a start command to the PCNT peripheral. The PCNT peripheral will use some LF clock ticks before the command is executed. The sl_hal_pcnt_wait_sync() function can be used to wait for the start command to be executed.


sl_hal_pcnt_stop_main_counter#

void sl_hal_pcnt_stop_main_counter (PCNT_TypeDef * pcnt)

Stop PCNT main counter.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

This function will send a stop command to the PCNT peripheral. The PCNT peripheral will use some LF clock ticks before the command is executed. The sl_hal_pcnt_wait_sync() function can be used to wait for the stop command to be executed.


sl_hal_pcnt_set_main_counter#

void sl_hal_pcnt_set_main_counter (PCNT_TypeDef * pcnt, uint32_t value)

Set a counter value.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

uint32_t[in]value

Value to set in counter register.

Note

  • This function could 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.


sl_hal_pcnt_get_main_counter#

uint32_t sl_hal_pcnt_get_main_counter (PCNT_TypeDef * pcnt)

Get the main counter value.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Current main counter value.


sl_hal_pcnt_start_aux_counter#

void sl_hal_pcnt_start_aux_counter (PCNT_TypeDef * pcnt)

Start PCNT auxiliary counter.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

This function will send a start command to the PCNT peripheral. The PCNT peripheral will use some LF clock ticks before the command is executed. The sl_hal_pcnt_wait_sync() function can be used to wait for the start command to be executed.


sl_hal_pcnt_stop_aux_counter#

void sl_hal_pcnt_stop_aux_counter (PCNT_TypeDef * pcnt)

Stop PCNT auxiliary counter.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

This function will send a stop command to the PCNT peripheral. The PCNT peripheral will use some LF clock ticks before the command is executed. The sl_hal_pcnt_wait_sync() function can be used to wait for the stop command to be executed.


sl_hal_pcnt_get_aux_counter#

uint32_t sl_hal_pcnt_get_aux_counter (PCNT_TypeDef * pcnt)

Get the auxiliary counter value.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

Pointer to the PCNT peripheral register block.

Returns

  • Current auxiliary counter value.


sl_hal_pcnt_reset_counters#

void sl_hal_pcnt_reset_counters (PCNT_TypeDef * pcnt)

Reset PCNT counters.

Parameters
TypeDirectionArgument NameDescription
PCNT_TypeDef *[in]pcnt

A pointer to the PCNT peripheral register block.