Ultra-Low-Power (ULP) Timer Initialization and Configuration#

The SiWx917 Software Development Kit (SDK) provides a complete Ultra-Low-Power (ULP) Timer driver with flexible configuration options.
The driver supports multiple timer instances, operating modes, and clock sources, allowing you to design precise and energy-efficient timing solutions.

This guide explains how to initialize and configure ULP Timer peripherals using Simplicity Studio and the WiSeConnect SDK.
Each ULP Timer instance is a 32-bit timer that supports one-shot or periodic operation, suitable for both simple periodic events and complex timing sequences.

For details on SDK usage and development, see the WiSeConnect v3.x SDK Documentation.

Startup Sequence#

The startup sequence prepares the ULP Timer subsystem for operation.It outlines the key steps to configure timers, set parameters, and generate initialization code before running your application.

Step-by-Step ULP Timer Configuration in Simplicity Studio#

Follow these steps to configure and initialize ULP Timer peripherals in Simplicity Studio.

Step 1. Create or Open Your Project#

  1. Launch Simplicity Studio.

  2. Create a new project for your SiWx917 device or open an existing one.

  3. Select a ULP Timer example project from the WiSeConnect SDK.

  4. Connect your SiWx917 evaluation board. Simplicity Studio automatically detects it.

    Board auto-detectionBoard auto-detection
    Figure: Automatic board detection in Simplicity Studio

  5. In Example Projects and Demos, search for ULP Timer examples.ULP Timer example searchULP Timer example search Figure: Searching for ULP Timer projects

  6. Click Create to import the project into your workspace.

  7. Review the included documentation (readme.md) to understand the project’s purpose.

ULP Timer Example ProjectULP Timer Example Project
Figure: Example ULP Timer project in Simplicity Studio

Typical Directory Structure:

Folder/File

Description

autogen/

Auto-generated configuration files (headers, linker scripts).

config/

Platform-specific configuration headers.

resources/

Documentation images and resources.

simplicity_sdk_*/

Simplicity SDK platform layer and third-party libraries.

platform/

Hardware abstraction layer (HAL), CMSIS RTOS, and common libraries

wiseconnect3_sdk_*/

WiSeConnect SDK components and libraries.

app.c / app.h

Main application source and header files.

ulp_timer_example.c / .h

Example implementation of ULP Timer configuration.

main.c

Application entry point.

sl_si91x_ulp_timer.slcp

Main configuration file.

sl_si91x_ulp_timer.pintool

Pin configuration for ULP Timer signals.

sl_si91x_ulp_timer.slps

Project set file for managing related solutions.

readme.md

Example usage guide.

Step 2. Add the ULP Timer Component#

  1. Open the .slcp configuration file.

  2. Select the Software Components tab.

  3. Search for ULP Timer.

  4. Add the required instance (for example, Timer 0 or Timer 1).

  5. To add more timers, select Add New Instance.

Step 3. Configure the ULP Timer Using Universal Configurator (UC)#

Use the Universal Configurator (UC) to define timer parameters.

  1. Click Configure to open the ULP Timer configuration window.

  2. Set the following parameters:

    Parameter

    Description

    Timer Type

    Select Down counter, 1 µs resolution, or 256 µs resolution.

    Timer Mode

    Choose One-shot (single event) or Periodic (repeating event).

    Timer Direction

    Set Up or Down counting direction.

ULP Timer Configuration WindowULP Timer Configuration Window
Figure: ULP Timer configuration in UC

Configuration Parameters#

This section describes the configuration structures and enumerations used by the Ultra-Low-Power (ULP) Timer API.
These definitions allow you to configure each timer instance, select operating modes, and specify clock sources for the SiWx917 device.

Configuration Structure#

The ulp_timer_config_t structure defines parameters for initializing and configuring an individual ULP Timer instance.

typedef struct {
  uint8_t  timer_num;          ///< Timer instance number. See ::ulp_timer_instance_t for valid values.
  uint8_t  timer_mode;         ///< Timer operating mode. See ::ulp_timer_mode_t for possible values.
  uint8_t  timer_type;         ///< Timer type selection. See ::ulp_timer_type_t for supported configurations.
  uint32_t timer_match_value;  ///< Match value in microseconds (SL_ULP_TIMER_MATCH_VALUE). Defines the timeout or delay period.
  uint8_t  timer_direction;    ///< Counting direction. See ::ulp_timer_direction_t for options.
} ulp_timer_config_t;

Usage: Initialize this structure before calling ULP Timer configuration APIs. Each member corresponds to a parameter selectable in the Universal Configurator (UC).

ULP Timer Instances#

The following enumeration identifies the available ULP Timer instances.

typedef enum {
  ULP_TIMER_0,    ///< ULP Timer 0 Instance
  ULP_TIMER_1,    ///< ULP Timer 1 Instance
  ULP_TIMER_2,    ///< ULP Timer 2 Instance
  ULP_TIMER_3,    ///< ULP Timer 3 Instance
  ULP_TIMER_LAST, ///< Last member of the enum for validation
} ulp_timer_instance_t;

Note: Each ULP Timer instance operates independently and can be configured with unique parameters.

ULP Timer Modes#

The ulp_timer_mode_t enumeration defines available timer operation modes

typedef enum {
  ULP_TIMER_MODE_ONESHOT,  ///< ULP Timer one-shot mode
  ULP_TIMER_MODE_PERIODIC, ///< ULP Timer periodic mode
  ULP_TIMER_MODE_LAST,     ///< Last member of the enum for validation
} ulp_timer_mode_t;

Tip: Use one-shot mode for single-time events and periodic mode for recurring operations like sensor polling or LED blinking.

ULP Timer Types#

The ulp_timer_type_t enumeration specifies the timer’s timing resolution and counter behavior.

typedef enum {
  ULP_TIMER_TYP_DEFAULT, ///< ULP Timer normal down counter type
  ULP_TIMER_TYP_1US,     ///< ULP Timer one microsecond type
  ULP_TIMER_TYP_256US,   ///< ULP Timer 256 microsecond type
  ULP_TIMER_TYP_LAST,    ///< Last member of the enum for validation
} ulp_timer_type_t;

Note: Select 1 µs mode for high-precision timing and 256 µs mode for long-duration, low-power applications.

Clock Sources#

The ulp_timer_clk_input_source_t enumeration defines all possible clock sources available for the ULP Timer.

typedef enum {
  ULP_TIMER_REF_CLK_SRC,        ///< Reference clock input source
  ULP_TIMER_32KHZ_RO_CLK_SRC,   ///< 32 kHz RO clock input source
  ULP_TIMER_32KHZ_RC_CLK_SRC,   ///< 32 kHz RC clock input source
  ULP_TIMER_32KHZ_XTAL_CLK_SRC, ///< 32 kHz XTAL clock input source
  ULP_TIMER_MHZ_RC_CLK_SRC,     ///< 32 MHz RC clock input source
  ULP_TIMER_20MHZ_RO_CLK_SRC,   ///< 20 MHz RO clock input source
  ULP_TIMER_ULP_CLK_SRC_LAST,   ///< Last member of the enum for validation
} ulp_timer_clk_input_source_t;

Clock Source Configuration Structure#

The ulp_timer_clk_src_config_t structure specifies the clock source and synchronization settings for the ULP Timer.

typedef struct {
  uint8_t ulp_timer_clk_type; ///< true to enable static and false to enable dynamic clock type, ef ulp_timer_clock_t
  boolean_t ulp_timer_sync_to_ulpss_pclk; ///< true to enable and false to disable ULP timer in synchronous mode to ULPSS pclk
  uint8_t ulp_timer_clk_input_src; ///< Timer input clock source, ef ulp_timer_clk_input_source_t for possible values
  boolean_t ulp_timer_skip_switch_time; ///< true to wait and false to skip waiting for switching timer clock
} ulp_timer_clk_src_config_t;

Usage: Use this structure to configure the clock domain and synchronization mode for each timer instance. For most applications, static clock selection with synchronization disabled provides the best balance between performance and power efficiency.

Step 4. Generate Initialization Code#

When you add or modify ULP Timer components, Simplicity Studio automatically generates the required driver and configuration files.
These files define initialization parameters, clock source configurations, and timer setup routines.

  • In the Universal Configurator (UC) window, select View Source to preview the auto-generated configuration code.

ULP Timer Auto-generated Initialization CodeULP Timer Auto-generated Initialization Code
Figure: Example of auto-generated ULP Timer initialization code

Step 5. Initialize ULP Timer in Your application#

You can initialize and start the ULP Timer directly in your application using the WiSeConnect SDK APIs.

Driver File Locations:

/wiseconnect3_sdk_<version>/components/device/silabs/si91x/mcu/drivers/unified_api/inc/sl_si91x_ulp_timer.h
/wiseconnect3_sdk_<version>/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_ulp_timer.c

The generated configuration structure is available in your project’s autogen/ directory.

ULP Timer autogen configULP Timer autogen config

Example Code: The following example shows how to initialize and start a ULP Timer instance using the SDK APIs. The example also demonstrates how to handle configuration across different power states (PS4 and PS2).

status = sl_si91x_ulp_timer_init(&sl_timer_clk_handle);
    if (status != SL_STATUS_OK) {
      DEBUGOUT("sl_si91x_ulp_timer_init : Invalid Parameters, Error Code : %lu \n", status);
      break;
    }
    DEBUGOUT("Successfully Configured ULP-timer clock input source \n");
    if (current_power_state == SL_SI91X_POWER_MANAGER_PS4) {
      DEBUGOUT("Timer executing at PS4 state \n");
      // Get match value
      status = sl_si91x_ulp_timer_get_match_value(SL_ULP_TIMER_HANDLE.timer_type, TIME_IN_MICROSECONDS, &match_value);
      if (status != SL_STATUS_OK) {
        DEBUGOUT("sl_si91x_ulp_timer_get_match_value : Invalid Parameters Error "
                 "Code : %lu \n",
                 status);
        break;
      } else {
        DEBUGOUT("Successfully match value is fetched\n");
      }
      // Updating timer match-value
      SL_ULP_TIMER_HANDLE.timer_match_value = match_value;
      // Configuring timer instance parameters: mode-periodic, type-1us,
      // match-value: 1second
      status = sl_si91x_ulp_timer_set_configuration(&(SL_ULP_TIMER_HANDLE));
      if (status != SL_STATUS_OK) {
        DEBUGOUT("sl_si91x_ulp_timer_set_configuration : Invalid Parameters "
                 "Error Code : %lu \n",
                 status);
        break;
      }
      DEBUGOUT("Successfully Configured ULP-timer parameters with mhz "
               "parameters \n");
    } else if (current_power_state == SL_SI91X_POWER_MANAGER_PS2) {
      status = sl_si91x_ulp_timer_get_match_value(SL_ULP_TIMER_HANDLE.timer_type, TIME_IN_MICROSECONDS, &match_value);
      if (status != SL_STATUS_OK) {
        DEBUGOUT("sl_si91x_ulp_timer_get_match_value : Invalid Parameters Error "
                 "Code : %lu \n",
                 status);
        break;
      } else {
        DEBUGOUT("Successfully match value is fetched\n");
      }
      // Updating timer match-value
      SL_ULP_TIMER_HANDLE.timer_match_value = match_value;
      // Configuring timer instance parameters: mode-periodic, type-1us,
      // match-value: 1second
      status = sl_si91x_ulp_timer_set_configuration(&(SL_ULP_TIMER_HANDLE));
      if (status != SL_STATUS_OK) {
        DEBUGOUT("sl_si91x_ulp_timer_set_configuration : Invalid Parameters "
                 "Error Code : %lu \n",
                 status);
        break;
      }
      DEBUGOUT("Successfully Configured ULP-timer parameters with 20mhz "
               "parameters \n");
    }
    // Registering timeout callback for the selected timer instance, which will
    // also enable its interrupt
    status = sl_si91x_ulp_timer_register_timeout_callback(ULP_TIMER_INSTANCE, &(SL_ULP_TIMER_CALLBACK));
    if (status != SL_STATUS_OK) {
      DEBUGOUT("sl_si91x_ulp_timer_timeout_callback_register : Invalid "
               "Parameters Error Code : %lu \n",
               status);
      break;
    }
    DEBUGOUT("Successfully Registered timer instance timeout callback \n");
    // Starting Timer instance with default parameters
    status = sl_si91x_ulp_timer_start(ULP_TIMER_INSTANCE);
    if (status != SL_STATUS_OK) {
      DEBUGOUT("sl_si91x_ulp_timer_start : Invalid Parameters Error Code : %lu \n", status);
      break;
    }
    DEBUGOUT("Successfully started ulp-timer instance with default parameters \n");

Step 7. Customize for Advanced Use Cases#

You can extend ULP Timer functionality by modifying the generated configuration or initialization code to meet specific application requirements.

Common advanced use cases include:

  • Adding custom callback functions to handle timeout or wake events.

  • Integrating Direct Memory Access (DMA) for automated data transfers.

  • Dynamically adjusting timer frequency or resolution based on power state.

  • Implementing multi-timer synchronization for complex scheduling.

For detailed implementation examples, see the ULP Timer Usage Scenarios section in the SDK documentation.

Tip: Advanced customization enables tighter power optimization and more precise timing control in high-efficiency designs.

Step 8. Build, Flash, and Test#

After configuration, build, flash, and verify your ULP Timer setup using Simplicity Studio or compatible terminal applications.

Step-by-Step Procedure#

  1. Build the Project

    Compile your application in Simplicity Studio.
    ULP Timer build projectULP Timer build project
    Figure: Building the ULP Timer project in Simplicity Studio

  2. Flash the Firmware

    Flash the compiled firmware to your SiWx917 device.
    ULP Timer flash deviceULP Timer flash device
    ULP Timer program fileULP Timer program file
    Figure: Flashing firmware to the SiWx917 board

  3. Verify ULP Timer Operation

    Use Simplicity Studio’s Virtual COM (VCOM) Console or an external terminal program to monitor logs and verify timer functionality.

    • Open the Connected Devices View
      Connected devicesConnected devices

    • Connect to the Target Board
      Connect devicesConnect devices

    • Launch the Console
      Launch consoleLaunch console

    • View Console Settings
      Console settingsConsole settings

Viewing the Console Output#

  1. Open the console and select the serial1 tab.

  2. Place your cursor in the entry field at the bottom.

  3. Press Enter to wake the console and view runtime logs.

Example ULP Timer Log Output:

ULP Timer logsULP Timer logs
Figure: Example output from ULP Timer log messages

Note: You can also use third-party terminal applications such as Tera Term or PuTTY to monitor serial output.

References#