Usage Scenarios - ADC and DAC#

Overview#

This section presents practical usage scenarios for the analog-to-digital converter (ADC) and digital-to-analog converter (DAC) on the SiWx917. Each scenario demonstrates how to select the appropriate mode (static, FIFO, high performance, or ultra-low power), configure the peripheral, and implement common sampling or output patterns.

Each scenario includes:

  • The intended use case

  • Recommended configuration choices

  • Code examples that illustrate the workflow

Use Case 1: ADC Single-Channel Blocking Mode#

When to Use#

Use static mode for:

  • Low-rate measurements

  • Simple sensor polling

  • Applications where the CPU can wait for each conversion

In this mode, the ADC performs one conversion at a time and reads the result synchronously.

Implementation Steps#

Step 1. Initialize the ADC#

#include "sl_si91x_adc.h"

sl_adc_channel_config_t adc_channel_config = {0};
sl_adc_config_t adc_config = {
  .operation_mode = SL_ADC_STATIC_MODE,
  .num_of_channel_enable = 1
};
float vref_value = 3.3f;

sl_status_t status = sl_si91x_adc_init(adc_channel_config, adc_config, vref_value);

Step 2. Register a Callback (Optional)#

static void adc_callback(uint8_t channel_no, uint8_t event) {
  if (event == SL_ADC_DATA_READY) {
    // Handle conversion complete event
  }
}
sl_si91x_adc_register_event_callback(adc_callback);

Step 3. Start ADC Conversion#

status = sl_si91x_adc_start(adc_config);

Step 4. Read Data (Blocking Mode)#

int16_t adc_data;
uint8_t channel_id = 0;

status = sl_si91x_adc_read_data(adc_config, &channel_id, &adc_data);
if (status == SL_STATUS_OK) {
  printf("ADC Channel %d: %d\n", channel_id, adc_data);
}

Use Case 2: DAC Static Mode (Constant Output)#

When to Use#

Use static mode to generate:

  • Bias voltages

  • Sensor excitation levels

  • DC reference outputs

Implementation Steps#

Step 1. Initialize the DAC#

#include "sl_si91x_dac.h"

sl_dac_clock_config_t dac_clock = {
  .soc_pll_clock = 80000000,
  .soc_pll_reference_clock = 40000000,
  .division_factor = 0
};
sl_si91x_dac_init(&dac_clock);

Step 2. Configure the DAC#

sl_dac_config_t dac_config = {
  .operating_mode = SL_DAC_STATIC_MODE,
  .dac_sample_rate = 1000000,
  .dac_pin = ULP_GPIO_4,
  .dac_port = 0
};
float vref_value = 3.3f;
sl_si91x_dac_set_configuration(dac_config, vref_value);

Step 3. Write Output Data#

int16_t dac_value = 2048; // Mid-scale output
sl_si91x_dac_write_data(dac_value, 1);

Use Case 3: DAC FIFO Mode (Waveform Generation)#

When to Use#

Use FIFO mode for generating:

  • Sine waves

  • Triangle or sawtooth waveforms

  • Arbitrary waveforms

  • High-rate analog outputs

Implementation Steps#

Step 1. Configure DAC for FIFO Mode#

sl_dac_config_t dac_config = {
  .operating_mode = SL_DAC_FIFO_MODE,
  .dac_sample_rate = 5000000,
  .dac_fifo_threshold = 4,
  .dac_pin = ULP_GPIO_4,
  .dac_port = 0
};
sl_si91x_dac_set_configuration(dac_config, vref_value);

Step 2. Register DAC Callback#

static void dac_fifo_callback(uint8_t event) {
  if (event == SL_DAC_FIFO_EMPTY) {
    int16_t waveform_data[256];
    // Generate new waveform data here
    sl_si91x_dac_write_data(waveform_data, 256);
  }
}
sl_si91x_dac_register_event_callback(dac_fifo_callback);

Step 3. Start DAC Output#

int16_t sine_wave[100];
for (int i = 0; i < 100; i++) {
  sine_wave[i] = (int16_t)(2048 + 2047 * sin(2 * M_PI * i / 100));
}
sl_si91x_dac_write_data(sine_wave, 100);

Use Case 4: ULP ADC for Low-Power Operation#

This scenario demonstrates how to use the ultra-low-power (ULP) ADC for energy-efficient sampling in low-power modes.

Implementation Steps#

Step 1. Initialize ULP ADC#

#include "sl_si91x_ulp_adc.h"
#include "sl_si91x_power_manager.h"

sl_adc_channel_config_t ulp_adc_config = {0};
sl_adc_config_t adc_config = {
  .operation_mode = SL_ADC_STATIC_MODE,
  .num_of_channel_enable = 1
};

// switching the power state to PS2 mode.
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;
}
sl_si91x_adc_init(ulp_adc_config, adc_config, 3.3f);

Step 2. Read Low-Power Data#

int16_t adc_data;
uint8_t channel_id = 0;
sl_si91x_adc_read_data(adc_config, &channel_id, &adc_data);

Use Case 5: ULP DAC for Low-Power Analog Output#

This scenario covers ULP DAC configuration for battery-powered applications that require persistent analog output during sleep.

Implementation Steps#

Step 1. Initialize ULP DAC#

#include "sl_si91x_ulp_dac.h"

sl_dac_clock_config_t ulp_dac_clock = {
  .soc_pll_clock = 20000000,//RC 20MHz clock
  .soc_pll_reference_clock = 20000000, //RC 20MHz clock
  .division_factor = 2
};
sl_si91x_dac_init(&ulp_dac_clock);

Step 2. Configure ULP DAC#

sl_dac_config_t ulp_dac_config = {
  .operating_mode = SL_DAC_STATIC_MODE,
  .dac_sample_rate = 100000,
  .dac_pin = ULP_GPIO_4,
  .dac_port = 0
};
float ulp_vref = 1.8f;
sl_si91x_dac_set_configuration(ulp_dac_config, ulp_vref);

Performance Summary#

Parameter

HP ADC/DAC

ULP ADC/DAC

ADC Sampling Rate

2.5 MSPS

63 KSPS

DAC Sampling Rate

5 MSPS

500 KSPS

ADC FIFO Depth

16 samples

16 samples

DAC FIFO Depth

8 samples

8 samples

ADC Resolution

12-bit

12-bit

DAC Resolution

10-bit

10-bit

Power Consumption (Active)

500–800 µA

50–500 µA

Voltage Range

1.8–3.6 V

1.8–3.6 V