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 |