| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <adc.h> |
| #include <device.h> |
| #include <math.h> |
| #include <sensor.h> |
| #include <zephyr.h> |
| |
| #define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL |
| #include <logging/log.h> |
| LOG_MODULE_REGISTER(grove_temp); |
| |
| /* thermistor Nominal B-Constant */ |
| #if defined(CONFIG_GROVE_TEMPERATURE_SENSOR_V1_0) |
| #define B_CONST 3975 |
| #elif defined(CONFIG_GROVE_TEMPERATURE_SENSOR_V1_X) |
| #define B_CONST 4250 |
| #endif |
| |
| #define ADC_RESOLUTION 12 |
| |
| struct gts_data { |
| struct device *adc; |
| struct adc_channel_cfg ch10_cfg; |
| u8_t adc_buffer[4]; |
| }; |
| |
| static struct adc_sequence_options options = { |
| .extra_samplings = 0, |
| .interval_us = 15, |
| }; |
| |
| static struct adc_sequence adc_table = { |
| .options = &options, |
| }; |
| |
| static int gts_sample_fetch(struct device *dev, enum sensor_channel chan) |
| { |
| struct gts_data *drv_data = dev->driver_data; |
| |
| return adc_read(drv_data->adc, &adc_table); |
| } |
| |
| static int gts_channel_get(struct device *dev, |
| enum sensor_channel chan, |
| struct sensor_value *val) |
| { |
| struct gts_data *drv_data = dev->driver_data; |
| u16_t analog_val; |
| double dval; |
| |
| /* rescale sample from 12bit (Zephyr) to 10bit (Grove) */ |
| analog_val = ((u16_t)drv_data->adc_buffer[1] << 8) | |
| drv_data->adc_buffer[0]; |
| analog_val = analog_val >> 2; |
| |
| /* |
| * The formula for converting the analog value to degrees Celisus |
| * is taken from the sensor reference page: |
| * http://www.seeedstudio.com/wiki/Grove_-_Temperature_Sensor |
| */ |
| dval = 1 / (log(1023.0 / analog_val - 1.0) / B_CONST + |
| 1 / 298.15) - 273.15; |
| |
| val->val1 = (s32_t)dval; |
| val->val2 = ((s32_t)(dval * 1000000)) % 1000000; |
| |
| return 0; |
| } |
| |
| static const struct sensor_driver_api gts_api = { |
| .sample_fetch = >s_sample_fetch, |
| .channel_get = >s_channel_get, |
| }; |
| |
| static int gts_init(struct device *dev) |
| { |
| struct gts_data *drv_data = dev->driver_data; |
| |
| drv_data->adc = device_get_binding( |
| CONFIG_GROVE_TEMPERATURE_SENSOR_ADC_DEV_NAME); |
| if (drv_data->adc == NULL) { |
| LOG_ERR("Failed to get ADC device."); |
| return -EINVAL; |
| } |
| |
| /*Change following parameters according to board if necessary*/ |
| drv_data->ch10_cfg.channel_id = CONFIG_GROVE_TEMPERATURE_SENSOR_ADC_CHANNEL; |
| drv_data->ch10_cfg.differential = false; |
| drv_data->ch10_cfg.gain = ADC_GAIN_1, |
| drv_data->ch10_cfg.reference = ADC_REF_INTERNAL; |
| drv_data->ch10_cfg.acquisition_time = ADC_ACQ_TIME_DEFAULT; |
| adc_table.buffer = drv_data->adc_buffer; |
| adc_table.resolution = ADC_RESOLUTION; |
| adc_table.buffer_size = 4; |
| adc_table.channels = BIT(CONFIG_GROVE_TEMPERATURE_SENSOR_ADC_CHANNEL); |
| |
| adc_channel_setup(drv_data->adc, &drv_data->ch10_cfg); |
| |
| return 0; |
| } |
| |
| static struct gts_data gts_data; |
| |
| DEVICE_AND_API_INIT(gts_dev, CONFIG_GROVE_TEMPERATURE_SENSOR_NAME, >s_init, |
| >s_data, NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, |
| >s_api); |