Analog Peripherals Low-Power Instance#

The ultra-low-power (ULP) analog peripherals on the SiWx917 enable applications to monitor analog signals while the system operates in low-power modes such as PS2. The ULP analog-to-digital converter (ADC) and ULP digital-to-analog converter (DAC) provide reduced sampling rates and simplified analog front ends to minimize current consumption while maintaining reliable conversions.

This section explains how ULP analog peripherals behave across power states, how to configure them for low-power operation, and how to save and restore configurations during sleep and wake cycles.

Why Use ULP Analog Peripherals#

ULP analog peripherals minimize energy consumption and are well suited for battery-powered and always-on monitoring applications.

Key Advantages#

  • Extended battery life through lower current consumption.

  • Continuous sensor monitoring in IoT edge applications.

  • Always-on functionality with minimal wake-up latency.

How ULP Analog Peripherals Work#

ULP peripherals achieve efficiency by using dedicated power and clock domains that remain active during low-power states.

Core Characteristics#

  • Independent ULP clock. Operates even when the main system clock is gated.

  • Reduced sampling rate. Lower maximum throughput to minimize switching losses.

  • Optimized architecture. Simplified analog front ends for energy-efficient signal conversion.

Achieving Low Power with PS2, PS3, and PS4 States#

The SiWx917 system-on-chip (SoC) supports multiple power states that balance performance and energy consumption.

Power State

Description

Analog Peripheral Availability

PS4

Full-performance active mode

Standard ADC/DAC + ULP ADC/DAC

PS3

Medium-power state

ULP ADC/DAC active

PS2/PS1

Low-power sleep state

ULP ADC/DAC operational

PS0

Deep sleep (minimum leakage)

ADC/DAC disabled

ULP ADC in Power States#

Example: PS4 and PS3#

sl_adc_channel_config_t adc_config_ps4 = {
  .num_of_channel_enable = 1,
  .adc_ch_offset = 0,
  .adc_scan_rate = 1000,   // 1000 SPS in PS4
};
sl_status_t status = sl_si91x_adc_init(adc_config_ps4, adc_config, vref_value);

Example: PS2#

sl_adc_channel_config_t ulp_adc_config = {
  .num_of_channel_enable = 1,
  .adc_ch_offset = 0,
  .adc_scan_rate = 100,    // 100 SPS in PS2
};
status = sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS2);
  if (status != SL_STATUS_OK) {
    DEBUGOUT("sl_si91x_power_manager_add_ps_requirement: Error Code : %lu \n", status);
    break;
  }
status = sl_si91x_adc_init(ulp_adc_config, adc_config, vref_value);

Tip: In PS2, ULP ADCs can continue periodic sampling with minimal current draw.

ULP DAC in Power States#

Example: Low-Power DAC#

sl_dac_config_t ulp_dac_config = {
  .operating_mode = SL_DAC_STATIC_MODE,
  .dac_sample_rate = 100000,  // Reduced rate
  .dac_pin = ULP_GPIO_4,
  .dac_port = 0
};
status = sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS2);
  if (status != SL_STATUS_OK) {
    DEBUGOUT("sl_si91x_power_manager_add_ps_requirement: Error Code : %lu \n", status);
    break;
  }
float ulp_vref = 1.8f;        // Lower reference voltage reduces power
status = sl_si91x_dac_set_configuration(ulp_dac_config, ulp_vref);

ULP Peripheral Specifications#

ULP ADC#

Parameter

ULP Value

Standard Value

Maximum sampling rate

63 KSPS

2.5 MSPS

Resolution

12-bit

12-bit

Channels

Up to 16

Up to 16

Input range

0 V – VREF

0 V – VREF

Clock frequency

1–20 MHz

20–40 MHz

ULP DAC#

Parameter

ULP Value

Standard Value

Max sample rate

500 KSPS

5 MSPS

Resolution

10-bit

10-bit

Output range

0 V – VREF

0 V – VREF

Min load impedance

10 kΩ

1 kΩ

Reconfiguring Peripherals Across Sleep/Wake Cycles#

When transitioning between active and sleep states, save peripheral configuration data to ensure consistent behavior after wake-up.

ADC Example: Save and Restore#

static sl_adc_config_t saved_adc_config;
static sl_adc_channel_config_t saved_channel_config;
static float saved_vref_value;

void adc_save_configuration(void) {
  saved_adc_config = current_adc_config;
  saved_channel_config = current_channel_config;
  saved_vref_value = current_vref_value;
  sl_si91x_adc_deinit(current_adc_config);
}

void adc_restore_configuration(void) {
  sl_status_t status = sl_si91x_adc_init(saved_channel_config, saved_adc_config, saved_vref_value);
  if (status == SL_STATUS_OK)
    sl_si91x_adc_register_event_callback(adc_callback_handler);
}

DAC Example: Save and Restore#

static sl_dac_config_t saved_dac_config;
static sl_dac_clock_config_t saved_dac_clock;
static float saved_dac_vref;

void dac_save_configuration(void) {
  saved_dac_config = current_dac_config;
  saved_dac_clock = current_dac_clock;
  saved_dac_vref = current_dac_vref;
  sl_si91x_dac_deinit();
}

void dac_restore_configuration(void) {
  sl_status_t status = sl_si91x_dac_init(&saved_dac_clock);
  if (status == SL_STATUS_OK)
    sl_si91x_dac_set_configuration(saved_dac_config, saved_dac_vref);
  sl_si91x_dac_register_event_callback(dac_callback_handler);
}

Example: Full Sleep Transition#

void enter_low_power_mode(void) {
  adc_save_configuration();
  dac_save_configuration();

  if (require_analog_in_sleep) {
    sl_adc_config_t ulp_config = {.operation_mode = SL_ADC_STATIC_MODE, .num_of_channel_enable = 1};
    sl_adc_channel_config_t ulp_channel = {.adc_scan_rate = 10};
    sl_si91x_adc_init(ulp_channel, ulp_config, 1.8f);
  }

  sl_power_manager_sleep();
}

void wake_from_low_power_mode(void) {
  adc_restore_configuration();
  dac_restore_configuration();
  printf("Analog peripherals restored after sleep\n");
}

Power Management Best Practices#

  1. Enable peripherals only when required.

  2. Use the lowest feasible sampling rate.

  3. Select ULP GPIO pins for analog signals in low-power modes.

  4. Batch analog operations to reduce wake-ups.

  5. Use wake triggers (ULP ADC thresholds or interrupts) for event-driven operation.

  6. Lower the reference voltage (VREF) when possible to reduce current draw.