blob: b71eb215977fe94d004e505025dba4820d663f01 [file] [log] [blame]
/*
* Copyright (c) 2020 Libre Solar Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/adc.h>
#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif
#define ADC_NUM_CHANNELS DT_PROP_LEN(DT_PATH(zephyr_user), io_channels)
#if ADC_NUM_CHANNELS > 2
#error "Currently only 1 or 2 channels supported in this sample"
#endif
#if ADC_NUM_CHANNELS == 2 && !DT_SAME_NODE( \
DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), io_channels, 0), \
DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), io_channels, 1))
#error "Channels have to use the same ADC."
#endif
#define ADC_NODE DT_PHANDLE(DT_PATH(zephyr_user), io_channels)
/* Common settings supported by most ADCs */
#define ADC_RESOLUTION 12
#define ADC_GAIN ADC_GAIN_1
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT
#ifdef CONFIG_ADC_NRFX_SAADC
#define ADC_INPUT_POS_OFFSET SAADC_CH_PSELP_PSELP_AnalogInput0
#else
#define ADC_INPUT_POS_OFFSET 0
#endif
/* Get the numbers of up to two channels */
static uint8_t channel_ids[ADC_NUM_CHANNELS] = {
DT_IO_CHANNELS_INPUT_BY_IDX(DT_PATH(zephyr_user), 0),
#if ADC_NUM_CHANNELS == 2
DT_IO_CHANNELS_INPUT_BY_IDX(DT_PATH(zephyr_user), 1)
#endif
};
static int16_t sample_buffer[ADC_NUM_CHANNELS];
struct adc_channel_cfg channel_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
/* channel ID will be overwritten below */
.channel_id = 0,
.differential = 0
};
struct adc_sequence sequence = {
/* individual channels will be added below */
.channels = 0,
.buffer = sample_buffer,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(sample_buffer),
.resolution = ADC_RESOLUTION,
};
void main(void)
{
int err;
const struct device *dev_adc = DEVICE_DT_GET(ADC_NODE);
if (!device_is_ready(dev_adc)) {
printk("ADC device not found\n");
return;
}
/*
* Configure channels individually prior to sampling
*/
for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++) {
channel_cfg.channel_id = channel_ids[i];
#ifdef CONFIG_ADC_CONFIGURABLE_INPUTS
channel_cfg.input_positive = ADC_INPUT_POS_OFFSET + channel_ids[i];
#endif
adc_channel_setup(dev_adc, &channel_cfg);
sequence.channels |= BIT(channel_ids[i]);
}
int32_t adc_vref = adc_ref_internal(dev_adc);
while (1) {
/*
* Read sequence of channels (fails if not supported by MCU)
*/
err = adc_read(dev_adc, &sequence);
if (err != 0) {
printk("ADC reading failed with error %d.\n", err);
return;
}
printk("ADC reading:");
for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++) {
int32_t raw_value = sample_buffer[i];
printk(" %d", raw_value);
if (adc_vref > 0) {
/*
* Convert raw reading to millivolts if driver
* supports reading of ADC reference voltage
*/
int32_t mv_value = raw_value;
adc_raw_to_millivolts(adc_vref, ADC_GAIN,
ADC_RESOLUTION, &mv_value);
printk(" = %d mV ", mv_value);
}
}
printk("\n");
k_sleep(K_MSEC(1000));
}
}