common/sensor/dev/ast_adc.c (143 lines of code) (raw):

#include <stdio.h> #include "sensor.h" #include "sensor_def.h" #include "pal.h" #include "plat_gpio.h" #include <zephyr.h> #include <sys/printk.h> #include <drivers/adc.h> enum adc_device_idx { adc0, adc1, ADC_NUM }; #define ADC_CHANNEL_NUM 8 #define BUFFER_SIZE 1 #if DT_NODE_EXISTS(DT_NODELABEL(adc0)) #define DEV_ADC0 #endif #if DT_NODE_EXISTS(DT_NODELABEL(adc1)) #define DEV_ADC1 #endif #define ADC_RESOLUTION 10 #define ADC_CALIBRATE 0 #define ADC_GAIN ADC_GAIN_1 #define ADC_REFERENCE ADC_REF_INTERNAL #define ADC_ACQUISITION_TIME ADC_ACQ_TIME_DEFAULT static const struct device *dev_adc[ADC_NUM]; static int16_t sample_buffer[BUFFER_SIZE]; static int is_ready[2]; static void init_adc_dev() { #ifdef DEV_ADC0 dev_adc[adc0] = device_get_binding("ADC0"); if (!(device_is_ready(dev_adc[adc0]))) printk("<warn> ADC[%d] device not ready!\n", adc0); else is_ready[adc0] = 1; #endif #ifdef DEV_ADC1 dev_adc[adc1] = device_get_binding("ADC1"); if (!(device_is_ready(dev_adc[adc1]))) printk("<warn> ADC[%d] device not ready!\n", adc1); else is_ready[adc1] = 1; #endif } static bool adc_read_mv(uint8_t sensor_num, uint32_t index, uint32_t channel, int *adc_val) { if (!adc_val) return false; if (index >= ADC_NUM) { printk("<error> ADC[%d] is invalid device!\n", index); return false; } if (!is_ready[index]) { printk("<error> ADC[%d] is not ready to read!\n", index); return false; } int err, retval; static struct adc_sequence sequence; sequence.channels = BIT(channel); sequence.buffer = sample_buffer; sequence.buffer_size = sizeof(sample_buffer); sequence.resolution = ADC_RESOLUTION; sequence.calibrate = ADC_CALIBRATE; static struct adc_channel_cfg channel_cfg; channel_cfg.gain = ADC_GAIN; channel_cfg.reference = ADC_REFERENCE; channel_cfg.acquisition_time = ADC_ACQUISITION_TIME; channel_cfg.channel_id = channel; channel_cfg.differential = 0; retval = adc_channel_setup(dev_adc[index], &channel_cfg); if (retval) { printk("<error> ADC[%d] with sensor[0x%x] channel set fail\n", index, sensor_num); return false; } err = adc_read(dev_adc[index], &sequence); if (err != 0) { printk("<error> ADC[%d] with sensor[0x%x] reading fail with error %d\n", index, sensor_num, err); return false; } int32_t raw_value = sample_buffer[0]; int32_t ref_mv = adc_get_ref(dev_adc[index]); if (ref_mv <= 0) { printk("<error> ADC[%d] with sensor[0x%x] ref-mv get fail\n", index, sensor_num); return false; } *adc_val = raw_value; adc_raw_to_millivolts(ref_mv, channel_cfg.gain, sequence.resolution, adc_val); return true; } uint8_t ast_adc_read(uint8_t sensor_num, int *reading) { if (!reading) return SENSOR_UNSPECIFIED_ERROR; sensor_cfg *cfg = &sensor_config[SensorNum_SensorCfg_map[sensor_num]]; uint8_t chip = cfg->port / ADC_CHANNEL_NUM; uint8_t number = cfg->port % ADC_CHANNEL_NUM; int val = 1; if (!adc_read_mv(sensor_num, chip, number, &val)) return SENSOR_FAIL_TO_ACCESS; val = val * cfg->arg0 / cfg->arg1; sensor_val *sval = (sensor_val *)reading; sval->integer = (val / 1000) & 0xFFFF; sval->fraction = (val % 1000) & 0xFFFF; return SENSOR_READ_SUCCESS; } uint8_t ast_adc_init(uint8_t sensor_num) { if (!sensor_config[SensorNum_SensorCfg_map[sensor_num]].init_args) { printk("<error> ADC init args not provide!\n"); return SENSOR_INIT_UNSPECIFIED_ERROR; } adc_asd_init_arg *init_args = (adc_asd_init_arg *)sensor_config[SensorNum_SensorCfg_map[sensor_num]].init_args; if (init_args->is_init) goto skip_init; init_adc_dev(); if (!is_ready[0] && !is_ready[1]) { printk("<error> Both of ADC0 and ADC1 are not ready to use!\n"); return SENSOR_INIT_UNSPECIFIED_ERROR; } static struct adc_channel_cfg channel_cfg; channel_cfg.gain = ADC_GAIN; channel_cfg.reference = ADC_REFERENCE; channel_cfg.acquisition_time = ADC_ACQUISITION_TIME; channel_cfg.channel_id = 0; channel_cfg.differential = 0; static struct adc_sequence sequence; sequence.channels = 0; sequence.buffer = sample_buffer; sequence.buffer_size = sizeof(sample_buffer); sequence.resolution = ADC_RESOLUTION; sequence.calibrate = ADC_CALIBRATE; for (uint8_t i = 0; i < ADC_NUM; i++) { if (!is_ready[i]) continue; channel_cfg.channel_id = i; adc_channel_setup(dev_adc[i], &channel_cfg); sequence.channels |= BIT(i); } init_args->is_init = true; skip_init: sensor_config[SensorNum_SensorCfg_map[sensor_num]].read = ast_adc_read; return SENSOR_INIT_SUCCESS; }