I'm working with the NRF9160 DK and have found the sample times for the ADC to be abnormally long. I am sampling three channels and seeing a total time for the ADC read of 80+us when I'm expecting something on the order of 15us. I have experimented with many different settings and configurations and not found any way to improve it.
Here is my configuration
#include <hal/nrf_saadc.h>
#define ADC_DEVICE_NAME DT_ADC_0_NAME
#define ADC_RESOLUTION 10
#define ADC_GAIN ADC_GAIN_1_6
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 3)
#define ADC_1ST_CHANNEL_ID 0
#define ADC_1ST_CHANNEL_INPUT NRF_SAADC_INPUT_AIN0
#define ADC_2ND_CHANNEL_ID 2
#define ADC_2ND_CHANNEL_INPUT NRF_SAADC_INPUT_AIN2
#define ADC_3RD_CHANNEL_ID 3
#define ADC_3RD_CHANNEL_INPUT NRF_SAADC_INPUT_AIN3
static const struct adc_channel_cfg m_1st_channel_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = NRF_SAADC_ACQTIME_3US,
.channel_id = ADC_1ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = ADC_1ST_CHANNEL_INPUT,
#endif
};
static const struct adc_channel_cfg m_2nd_channel_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = NRF_SAADC_ACQTIME_3US,
.channel_id = ADC_2ND_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = ADC_2ND_CHANNEL_INPUT,
#endif
};
static const struct adc_channel_cfg m_3rd_channel_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = NRF_SAADC_ACQTIME_3US,
.channel_id = ADC_3RD_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = ADC_3RD_CHANNEL_INPUT,
#endif
};
Here is the channel set up:
adc_dev = device_get_binding("ADC_0");
if (!adc_dev) {
printk("device_get_binding ADC_0 failed\n");
}
err = adc_channel_setup(adc_dev, &m_1st_channel_cfg);
if (err) {
printk("Error in adc setup: %d\n", err);
}
err = adc_channel_setup(adc_dev, &m_2nd_channel_cfg);
if (err) {
printk("Error in adc setup: %d\n", err);
}
err = adc_channel_setup(adc_dev, &m_3rd_channel_cfg);
if (err) {
printk("Error in adc setup: %d\n", err);
}
And here is where I'm sampling:
static int adc_sample(void)
{
int ret;
const struct adc_sequence_options options = {
.interval_us = 0,
.extra_samplings = 0,
};
const struct adc_sequence sequence = {
.channels = BIT(ADC_1ST_CHANNEL_ID) | BIT(ADC_2ND_CHANNEL_ID) | BIT(ADC_3RD_CHANNEL_ID),
.buffer = m_sample_buffer,
.buffer_size = sizeof(m_sample_buffer),
.resolution = ADC_RESOLUTION,
.oversampling = 0,
.calibrate = false,
.options = &options,
};
if (!adc_dev) {
return -1;
}
gpio_pin_write(gpio_dev, 10, 1);
ret = adc_read(adc_dev, &sequence);
gpio_pin_write(gpio_dev, 10, 0);
/*printk("ADC read err: %d\n", ret);
/* Print the AIN0 values */
/*for (int i = 0; i < BUFFER_SIZE; i++) {
float adc_voltage = 0;
adc_voltage = (float)(((float)m_sample_buffer[i] / 1023.0f) *
3600.0f);
printk("ADC raw value: %d\n", m_sample_buffer[i]);
printf("Measured voltage: %f mV\n", adc_voltage);
}
*/
return ret;
}