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:
parent
f3c93e0302
commit
da7b65735e
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
4
drivers/sensor/lm35/CMakeLists.txt
Normal file
4
drivers/sensor/lm35/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_sources(lm35.c)
|
12
drivers/sensor/lm35/Kconfig
Normal file
12
drivers/sensor/lm35/Kconfig
Normal 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
109
drivers/sensor/lm35/lm35.c
Normal 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)
|
20
dts/bindings/sensor/lm35.yaml
Normal file
20
dts/bindings/sensor/lm35.yaml
Normal 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.
|
Loading…
Reference in a new issue