drivers: sensors: Add driver for LM35

Add a driver implementation for the LM35 ADC temperature sensor

Signed-off-by: Renato Soma <renatoys08@gmail.com>
This commit is contained in:
Renato Soma 2024-02-14 14:31:00 -03:00 committed by Fabio Baltieri
parent f3c93e0302
commit da7b65735e
6 changed files with 147 additions and 0 deletions

View file

@ -81,6 +81,7 @@ add_subdirectory_ifdef(CONFIG_LIS2DU12 lis2du12)
add_subdirectory_ifdef(CONFIG_LIS2DW12 lis2dw12)
add_subdirectory_ifdef(CONFIG_LIS2MDL lis2mdl)
add_subdirectory_ifdef(CONFIG_LIS3MDL lis3mdl)
add_subdirectory_ifdef(CONFIG_LM35 lm35)
add_subdirectory_ifdef(CONFIG_LM75 lm75)
add_subdirectory_ifdef(CONFIG_LM77 lm77)
add_subdirectory_ifdef(CONFIG_LPS2XDF lps2xdf)

View file

@ -161,6 +161,7 @@ source "drivers/sensor/lis2du12/Kconfig"
source "drivers/sensor/lis2dw12/Kconfig"
source "drivers/sensor/lis2mdl/Kconfig"
source "drivers/sensor/lis3mdl/Kconfig"
source "drivers/sensor/lm35/Kconfig"
source "drivers/sensor/lm75/Kconfig"
source "drivers/sensor/lm77/Kconfig"
source "drivers/sensor/lps2xdf/Kconfig"

View file

@ -0,0 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(lm35.c)

View file

@ -0,0 +1,12 @@
# LM35 temperature sensor config
# Copyright (c) 2024 Renato Soma <renatoys08@gmail.com>
# SPDX-License-Identifier: Apache-2.0
config LM35
bool "LM35 Temperature Sensor"
default y
depends on DT_HAS_LM35_ENABLED
select ADC
help
Enable the driver for the LM35 digital temperature Sensor

109
drivers/sensor/lm35/lm35.c Normal file
View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2024 Renato Soma <renatoys08@gmail.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT lm35
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#define LM35_GAIN ADC_GAIN_1
#define LM35_REF ADC_REF_INTERNAL
LOG_MODULE_REGISTER(LM35, CONFIG_SENSOR_LOG_LEVEL);
struct lm35_data {
uint16_t raw;
};
struct lm35_config {
const struct device *adc;
uint8_t adc_channel;
struct adc_sequence adc_seq;
struct adc_channel_cfg ch_cfg;
};
static int lm35_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) {
return -ENOTSUP;
}
const struct lm35_config *cfg = dev->config;
return adc_read(cfg->adc, &cfg->adc_seq);
}
static int lm35_channel_get(const struct device *dev, enum sensor_channel chan,
struct sensor_value *val)
{
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) {
return -ENOTSUP;
}
int err;
struct lm35_data *data = dev->data;
const struct lm35_config *cfg = dev->config;
int32_t mv = data->raw;
err = adc_raw_to_millivolts(adc_ref_internal(cfg->adc), cfg->ch_cfg.gain,
cfg->adc_seq.resolution, &mv);
if (err) {
return err;
}
/* LM35 computes linearly 10mV per 1 degree C */
val->val1 = mv / 10;
val->val2 = (mv % 10) * 100000;
return 0;
}
static const struct sensor_driver_api lm35_driver_api = {
.sample_fetch = lm35_sample_fetch,
.channel_get = lm35_channel_get,
};
static int lm35_init(const struct device *dev)
{
const struct lm35_config *cfg = dev->config;
if (!device_is_ready(cfg->adc)) {
LOG_ERR("ADC device is not ready.");
return -EINVAL;
}
adc_channel_setup(cfg->adc, &cfg->ch_cfg);
return 0;
}
#define LM35_INST(inst) \
static struct lm35_data lm35_data_##inst; \
\
static const struct lm35_config lm35_cfg_##inst = { \
.adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(inst)), \
.adc_channel = DT_INST_IO_CHANNELS_INPUT(inst), \
.adc_seq = \
{ \
.channels = BIT(DT_INST_IO_CHANNELS_INPUT(inst)), \
.buffer = &lm35_data_##inst.raw, \
.buffer_size = sizeof(lm35_data_##inst.raw), \
.resolution = DT_INST_PROP(inst, resolution), \
}, \
.ch_cfg = { \
.gain = LM35_GAIN, \
.reference = LM35_REF, \
.acquisition_time = ADC_ACQ_TIME_DEFAULT, \
.channel_id = DT_INST_IO_CHANNELS_INPUT(inst), \
}}; \
\
SENSOR_DEVICE_DT_INST_DEFINE(inst, lm35_init, NULL, &lm35_data_##inst, &lm35_cfg_##inst, \
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &lm35_driver_api);
DT_INST_FOREACH_STATUS_OKAY(LM35_INST)

View file

@ -0,0 +1,20 @@
# SPDX-License-Identifier: Apache-2.0
description: LM35 Digital Temperature Sensor
compatible: "lm35"
include: sensor-device.yaml
properties:
io-channels:
required: true
description: |
ADC channel that will perform measurement
resolution:
type: int
default: 12
description: |
ADC resolution to be used for the channel. Defaults to 12 bits
as it's the most common for adc based drivers.