/* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT seeed_grove_temperature #include #include #include #include #include #include #include LOG_MODULE_REGISTER(grove_temp, CONFIG_SENSOR_LOG_LEVEL); /* The effect of gain and reference voltage must cancel. */ #ifdef CONFIG_ADC_NRFX_SAADC #define GROVE_GAIN ADC_GAIN_1_4 #define GROVE_REF ADC_REF_VDD_1_4 #define GROVE_RESOLUTION 12 #else #define GROVE_GAIN ADC_GAIN_1 #define GROVE_REF ADC_REF_VDD_1 #define GROVE_RESOLUTION 12 #endif struct gts_data { struct adc_channel_cfg ch_cfg; uint16_t raw; }; struct gts_config { const struct device *adc; int16_t b_const; uint8_t adc_channel; }; 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(const struct device *dev, enum sensor_channel chan) { const struct gts_config *cfg = dev->config; return adc_read(cfg->adc, &adc_table); } static int gts_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { struct gts_data *drv_data = dev->data; const struct gts_config *cfg = dev->config; double dval; /* * The formula for converting the analog value to degrees Celsius * is taken from the sensor reference page: * http://www.seeedstudio.com/wiki/Grove_-_Temperature_Sensor */ dval = (1 / (log((BIT(GROVE_RESOLUTION) - 1.0) / drv_data->raw - 1.0) / cfg->b_const + (1 / 298.15))) - 273.15; val->val1 = (int32_t)dval; val->val2 = ((int32_t)(dval * 1000000)) % 1000000; return 0; } static DEVICE_API(sensor, gts_api) = { .sample_fetch = >s_sample_fetch, .channel_get = >s_channel_get, }; static int gts_init(const struct device *dev) { struct gts_data *drv_data = dev->data; const struct gts_config *cfg = dev->config; if (!device_is_ready(cfg->adc)) { LOG_ERR("ADC device is not ready."); return -EINVAL; } /*Change following parameters according to board if necessary*/ drv_data->ch_cfg = (struct adc_channel_cfg){ .gain = GROVE_GAIN, .reference = GROVE_REF, .acquisition_time = ADC_ACQ_TIME_DEFAULT, .channel_id = cfg->adc_channel, #ifdef CONFIG_ADC_NRFX_SAADC .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + cfg->adc_channel, #endif }; adc_table.buffer = &drv_data->raw; adc_table.buffer_size = sizeof(drv_data->raw); adc_table.resolution = GROVE_RESOLUTION; adc_table.channels = BIT(cfg->adc_channel); adc_channel_setup(cfg->adc, &drv_data->ch_cfg); return 0; } #define GTS_DEFINE(inst) \ static struct gts_data gts_data_##inst; \ \ static const struct gts_config gts_cfg_##inst = { \ .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \ .b_const = (IS_ENABLED(DT_INST_PROP(inst, v1p0)) \ ? 3975 \ : 4250), \ .adc_channel = DT_INST_IO_CHANNELS_INPUT(inst), \ }; \ \ SENSOR_DEVICE_DT_INST_DEFINE(inst, >s_init, NULL, \ >s_data_##inst, >s_cfg_##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, >s_api); \ DT_INST_FOREACH_STATUS_OKAY(GTS_DEFINE)