The SAADC driver includes two layers: the hardware access layer (HAL) and the driver layer (DRV).
The hardware access layer provides basic APIs for accessing the registers of the SAADC peripheral. See the API documentation for the SAADC HAL for details.
The driver layer provides APIs on a higher level than the HAL. See the API documentation for the SAADC driver for details.
Key features include:
- Blocking function to convert one sample on a single channel.
- Non-blocking function for triggering conversion on all enabled channels to a provided buffer.
- Double buffering: you can set up two buffers, and conversion to the new buffer starts immediately after the first one is filled.
- PAN-28 (scan mode not functional) workaround inside the driver: scan mode is emulated inside the driver, resulting in an interrupt being generated at every conversion on every channel.
- Optimal performance with interrupt only at the end of buffer conversion is achieved only on a single channel due to PAN-28.
Driver configuration
The SAADC default configuration is located in
nrf_drv_config.h
. The SAADC must be explicitly enabled in
nrf_drv_config.h
before the driver can be used. If
nrf_drv_saadc_init
is called with a NULL pointer to the configuration structure, the default configuration from
nrf_drv_config.h
is used. You must provide an event handler function during initialization.
Driver configuration includes:
- Resolution
- Enabling or disabling oversampling
- Interrupt priority level
- Note
- If oversampling is enabled, only one channel can be enabled. nrf_drv_saadc_channel_init asserts if this condition is not met.
Each channel is configured independently. Channels are configured and enabled by the function nrf_drv_saadc_channel_init . NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE or NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL can be used to build a default configuration for a channel.
Example:
nrf_drv_saadc_gpio_to_ain can be used to convert a GPIO pin number to an analog input number.
Using the SAADC driver
The SAADC driver can be used in blocking mode or non-blocking mode.
Blocking mode
The function nrf_drv_saadc_sample_convert is blocking and returns when the requested channel is sampled. The channel must be initialized before it can be used. If the SAADC is busy, the function returns with an error. In blocking mode, the driver does not use the peripheral interrupt and there is no context switching inside the driver.
Non-blocking mode
The function nrf_drv_saadc_buffer_convert can be used to start conversion in non-blocking mode. The function returns immediately after the buffer is configured. If the driver is busy, it returns with an error. nrf_drv_saadc_buffer_convert sets the SAADC up for conversion, but does not trigger sampling. To trigger sampling, call the function nrf_drv_saadc_sample or, through PPI, use the task SAMPLE from SAADC. nrf_drv_saadc_sample_task_get can be used to get the task address. Single sampling triggers conversion on all initialized channels. When the requested buffer is filled with samples, an event of type NRF_DRV_SAADC_EVT_DONE is generated.
Example for sampling triggered by the CPU:
Example for setting up sampling by PPI:
The driver supports double buffering, which means that nrf_drv_saadc_buffer_convert can be called twice and the buffer that is provided in the second call will be used immediately after the first one is filled.
Continuous conversion can be achieved by setting up two buffers and calling nrf_drv_saadc_buffer_convert again in the event handler to switch between them later.
Example for setting up two buffers:
Example for setting up a completed buffer again in the event handler:
To configure the SAADC to continue conversion to the second buffer, SAADC interrupts must be handled. However, if only one channel is used, EasyDMA could automatically start processing using the second buffer if PPI is used to bind SAADC END events with the SAADC START task. This is not done by the driver because it is only controlling the SAADC peripheral, but it can be done in the application code.
Limits
The driver can generate events of type NRF_DRV_SAADC_EVT_LIMIT if the converted sample on a given channel is exceeding a limit. You can set two limits per channel: high and low. The function nrf_drv_saadc_limits_set can be used to configure these limits. The function sets both limits; if only one limit should be enabled, the second can be disabled by using NRF_DRV_SAADC_LIMITH_DISABLED for the high limit or NRF_DRV_SAADC_LIMITL_DISABLED for the low limit.
The limit event will be generated by every sample that exceeds the limit. If this is not desired, it can be disabled in the event handler.