drivers: sensor: Add MH-Z19B CO2 sensor driver
Add MH-Z19B CO2 sensor driver. Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com> Co-Authored-By: Azamlukman <azamlukmanabdullah@gmail.com>
This commit is contained in:
parent
b037054f21
commit
26f7b9c1ea
|
@ -64,6 +64,7 @@ add_subdirectory_ifdef(CONFIG_MAX30101 max30101)
|
|||
add_subdirectory_ifdef(CONFIG_MAX44009 max44009)
|
||||
add_subdirectory_ifdef(CONFIG_MAX6675 max6675)
|
||||
add_subdirectory_ifdef(CONFIG_MCP9808 mcp9808)
|
||||
add_subdirectory_ifdef(CONFIG_MHZ19B mhz19b)
|
||||
add_subdirectory_ifdef(CONFIG_MPR mpr)
|
||||
add_subdirectory_ifdef(CONFIG_MPU6050 mpu6050)
|
||||
add_subdirectory_ifdef(CONFIG_MS5607 ms5607)
|
||||
|
|
|
@ -168,6 +168,8 @@ source "drivers/sensor/mchp_tach_xec/Kconfig"
|
|||
|
||||
source "drivers/sensor/mcp9808/Kconfig"
|
||||
|
||||
source "drivers/sensor/mhz19b/Kconfig"
|
||||
|
||||
source "drivers/sensor/mpr/Kconfig"
|
||||
|
||||
source "drivers/sensor/mpu6050/Kconfig"
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(mhz19b.c)
|
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2021 G-Technologies Sdn. Bhd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config MHZ19B
|
||||
bool "Winsen CO2 sensor"
|
||||
depends on UART_INTERRUPT_DRIVEN
|
||||
help
|
||||
Enable driver for the MHZ19B CO2 Sensor.
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* Copyright (c) 2021 G-Technologies Sdn. Bhd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Datasheet:
|
||||
* https://www.winsen-sensor.com/sensors/co2-sensor/mh-z19b.html
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT winsen_mhz19b
|
||||
|
||||
#include <logging/log.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <drivers/sensor.h>
|
||||
|
||||
#include <drivers/sensor/mhz19b.h>
|
||||
#include "mhz19b.h"
|
||||
|
||||
LOG_MODULE_REGISTER(mhz19b, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
/* Table of supported MH-Z19B commands with precomputed checksum */
|
||||
static const uint8_t mhz19b_cmds[MHZ19B_CMD_IDX_MAX][MHZ19B_BUF_LEN] = {
|
||||
[MHZ19B_CMD_IDX_GET_CO2] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_GET_CO2, MHZ19B_NULL_COUNT(5), 0x79
|
||||
},
|
||||
[MHZ19B_CMD_IDX_GET_RANGE] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_GET_RANGE, MHZ19B_NULL_COUNT(5), 0x64
|
||||
},
|
||||
[MHZ19B_CMD_IDX_GET_ABC] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_GET_ABC, MHZ19B_NULL_COUNT(5), 0x82
|
||||
},
|
||||
[MHZ19B_CMD_IDX_SET_ABC_ON] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_SET_ABC, MHZ19B_ABC_ON,
|
||||
MHZ19B_NULL_COUNT(4), 0xE6
|
||||
},
|
||||
[MHZ19B_CMD_IDX_SET_ABC_OFF] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_SET_ABC, MHZ19B_ABC_OFF,
|
||||
MHZ19B_NULL_COUNT(4), 0x86
|
||||
},
|
||||
[MHZ19B_CMD_IDX_SET_RANGE_2000] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_SET_RANGE, MHZ19B_NULL_COUNT(3),
|
||||
MHZ19B_RANGE_2000, 0x8F
|
||||
},
|
||||
[MHZ19B_CMD_IDX_SET_RANGE_5000] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_SET_RANGE, MHZ19B_NULL_COUNT(3),
|
||||
MHZ19B_RANGE_5000, 0xCB
|
||||
},
|
||||
[MHZ19B_CMD_IDX_SET_RANGE_10000] = {
|
||||
MHZ19B_HEADER, MHZ19B_RESERVED, MHZ19B_CMD_SET_RANGE, MHZ19B_NULL_COUNT(3),
|
||||
MHZ19B_RANGE_10000, 0x2F
|
||||
},
|
||||
};
|
||||
|
||||
static void mhz19b_uart_flush(const struct device *uart_dev)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
while (uart_fifo_read(uart_dev, &c, 1) > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t mhz19b_checksum(const uint8_t *data)
|
||||
{
|
||||
uint8_t cs = 0;
|
||||
|
||||
for (uint8_t i = 1; i < MHZ19B_BUF_LEN - 1; i++) {
|
||||
cs += data[i];
|
||||
}
|
||||
|
||||
return 0xff - cs + 1;
|
||||
}
|
||||
|
||||
static int mhz19b_send_cmd(const struct device *dev, enum mhz19b_cmd_idx cmd_idx, bool has_rsp)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
const struct mhz19b_cfg *cfg = dev->config;
|
||||
int ret;
|
||||
|
||||
/* Make sure last command has been transferred */
|
||||
ret = k_sem_take(&data->tx_sem, MHZ19B_WAIT);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->cmd_idx = cmd_idx;
|
||||
data->has_rsp = has_rsp;
|
||||
k_sem_reset(&data->rx_sem);
|
||||
|
||||
uart_irq_tx_enable(cfg->uart_dev);
|
||||
|
||||
if (has_rsp) {
|
||||
uart_irq_rx_enable(cfg->uart_dev);
|
||||
ret = k_sem_take(&data->rx_sem, MHZ19B_WAIT);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int mhz19b_send_config(const struct device *dev, enum mhz19b_cmd_idx cmd_idx)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
ret = mhz19b_send_cmd(dev, cmd_idx, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (data->rd_data[MHZ19B_RX_CMD_IDX] != mhz19b_cmds[data->cmd_idx][MHZ19B_TX_CMD_IDX]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mhz19b_poll_data(const struct device *dev, enum mhz19b_cmd_idx cmd_idx)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
uint8_t checksum;
|
||||
int ret;
|
||||
|
||||
ret = mhz19b_send_cmd(dev, cmd_idx, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
checksum = mhz19b_checksum(data->rd_data);
|
||||
if (checksum != data->rd_data[MHZ19B_CHECKSUM_IDX]) {
|
||||
LOG_DBG("Checksum mismatch: 0x%x != 0x%x", checksum,
|
||||
data->rd_data[MHZ19B_CHECKSUM_IDX]);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
switch (cmd_idx) {
|
||||
case MHZ19B_CMD_IDX_GET_CO2:
|
||||
data->data = sys_get_be16(&data->rd_data[2]);
|
||||
break;
|
||||
case MHZ19B_CMD_IDX_GET_RANGE:
|
||||
data->data = sys_get_be16(&data->rd_data[4]);
|
||||
break;
|
||||
case MHZ19B_CMD_IDX_GET_ABC:
|
||||
data->data = data->rd_data[7];
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mhz19b_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
|
||||
if (chan != SENSOR_CHAN_CO2) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
val->val1 = (int32_t)data->data;
|
||||
val->val2 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mhz19b_attr_full_scale_cfg(const struct device *dev, int range)
|
||||
{
|
||||
switch (range) {
|
||||
case 2000:
|
||||
LOG_DBG("Configure range to %d", range);
|
||||
return mhz19b_send_config(dev, MHZ19B_CMD_IDX_SET_RANGE_2000);
|
||||
case 5000:
|
||||
LOG_DBG("Configure range to %d", range);
|
||||
return mhz19b_send_config(dev, MHZ19B_CMD_IDX_SET_RANGE_5000);
|
||||
case 10000:
|
||||
LOG_DBG("Configure range to %d", range);
|
||||
return mhz19b_send_config(dev, MHZ19B_CMD_IDX_SET_RANGE_10000);
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
static int mhz19b_attr_abc_cfg(const struct device *dev, bool on)
|
||||
{
|
||||
if (on) {
|
||||
LOG_DBG("%s ABC", "Enable");
|
||||
return mhz19b_send_config(dev, MHZ19B_CMD_IDX_SET_ABC_ON);
|
||||
}
|
||||
|
||||
LOG_DBG("%s ABC", "Disable");
|
||||
return mhz19b_send_config(dev, MHZ19B_CMD_IDX_SET_ABC_OFF);
|
||||
}
|
||||
|
||||
static int mhz19b_attr_set(const struct device *dev, enum sensor_channel chan,
|
||||
enum sensor_attribute attr, const struct sensor_value *val)
|
||||
{
|
||||
if (chan != SENSOR_CHAN_CO2) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_FULL_SCALE:
|
||||
return mhz19b_attr_full_scale_cfg(dev, val->val1);
|
||||
|
||||
case SENSOR_ATTR_MHZ19B_ABC:
|
||||
return mhz19b_attr_abc_cfg(dev, val->val1);
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
static int mhz19b_attr_get(const struct device *dev, enum sensor_channel chan,
|
||||
enum sensor_attribute attr, struct sensor_value *val)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
if (chan != SENSOR_CHAN_CO2) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_FULL_SCALE:
|
||||
ret = mhz19b_poll_data(dev, MHZ19B_CMD_IDX_GET_RANGE);
|
||||
break;
|
||||
case SENSOR_ATTR_MHZ19B_ABC:
|
||||
ret = mhz19b_poll_data(dev, MHZ19B_CMD_IDX_GET_ABC);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
val->val1 = (int32_t)data->data;
|
||||
val->val2 = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mhz19b_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
if (chan != SENSOR_CHAN_CO2) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return mhz19b_poll_data(dev, MHZ19B_CMD_IDX_GET_CO2);
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api mhz19b_api_funcs = {
|
||||
.attr_set = mhz19b_attr_set,
|
||||
.attr_get = mhz19b_attr_get,
|
||||
.sample_fetch = mhz19b_sample_fetch,
|
||||
.channel_get = mhz19b_channel_get,
|
||||
};
|
||||
|
||||
static void mhz19b_uart_isr(const struct device *uart_dev, void *user_data)
|
||||
{
|
||||
const struct device *dev = user_data;
|
||||
struct mhz19b_data *data = dev->data;
|
||||
|
||||
ARG_UNUSED(user_data);
|
||||
|
||||
if (uart_dev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uart_irq_update(uart_dev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uart_irq_rx_ready(uart_dev)) {
|
||||
data->xfer_bytes += uart_fifo_read(uart_dev, &data->rd_data[data->xfer_bytes],
|
||||
MHZ19B_BUF_LEN - data->xfer_bytes);
|
||||
|
||||
if (data->xfer_bytes == MHZ19B_BUF_LEN) {
|
||||
data->xfer_bytes = 0;
|
||||
uart_irq_rx_disable(uart_dev);
|
||||
k_sem_give(&data->rx_sem);
|
||||
if (data->has_rsp) {
|
||||
k_sem_give(&data->tx_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uart_irq_tx_ready(uart_dev)) {
|
||||
data->xfer_bytes +=
|
||||
uart_fifo_fill(uart_dev, &mhz19b_cmds[data->cmd_idx][data->xfer_bytes],
|
||||
MHZ19B_BUF_LEN - data->xfer_bytes);
|
||||
|
||||
if (data->xfer_bytes == MHZ19B_BUF_LEN) {
|
||||
data->xfer_bytes = 0;
|
||||
uart_irq_tx_disable(uart_dev);
|
||||
if (!data->has_rsp) {
|
||||
k_sem_give(&data->tx_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int mhz19b_init(const struct device *dev)
|
||||
{
|
||||
struct mhz19b_data *data = dev->data;
|
||||
const struct mhz19b_cfg *cfg = dev->config;
|
||||
int ret;
|
||||
|
||||
uart_irq_rx_disable(cfg->uart_dev);
|
||||
uart_irq_tx_disable(cfg->uart_dev);
|
||||
|
||||
mhz19b_uart_flush(cfg->uart_dev);
|
||||
|
||||
uart_irq_callback_user_data_set(cfg->uart_dev, cfg->cb, (void *)dev);
|
||||
|
||||
k_sem_init(&data->rx_sem, 0, 1);
|
||||
k_sem_init(&data->tx_sem, 1, 1);
|
||||
|
||||
/* Configure default detection range */
|
||||
ret = mhz19b_attr_full_scale_cfg(dev, cfg->range);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Error setting default range %d", cfg->range);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure ABC logic */
|
||||
ret = mhz19b_attr_abc_cfg(dev, cfg->abc_on);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Error setting default ABC %s", cfg->abc_on ? "on" : "off");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MHZ19B_INIT(inst) \
|
||||
\
|
||||
static struct mhz19b_data mhz19b_data_##inst; \
|
||||
\
|
||||
static const struct mhz19b_cfg mhz19b_cfg_##inst = { \
|
||||
.uart_dev = DEVICE_DT_GET(DT_INST_BUS(inst)), \
|
||||
.range = DT_INST_PROP(inst, maximum_range), \
|
||||
.abc_on = DT_INST_PROP(inst, abc_on), \
|
||||
.cb = mhz19b_uart_isr, \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, mhz19b_init, NULL, &mhz19b_data_##inst, &mhz19b_cfg_##inst, \
|
||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &mhz19b_api_funcs);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MHZ19B_INIT)
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2021 G-Technologies Sdn. Bhd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B
|
||||
#define ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B
|
||||
|
||||
#include <kernel.h>
|
||||
#include <device.h>
|
||||
#include <drivers/uart.h>
|
||||
|
||||
#define MHZ19B_BUF_LEN 9
|
||||
|
||||
#define MHZ19B_TX_CMD_IDX 2
|
||||
#define MHZ19B_RX_CMD_IDX 1
|
||||
#define MHZ19B_CHECKSUM_IDX 8
|
||||
|
||||
/* Arbitrary max duration to wait for the response */
|
||||
#define MHZ19B_WAIT K_SECONDS(1)
|
||||
|
||||
enum mhz19b_cmd_idx {
|
||||
/* Command to poll for CO2 */
|
||||
MHZ19B_CMD_IDX_GET_CO2,
|
||||
/* Read range */
|
||||
MHZ19B_CMD_IDX_GET_RANGE,
|
||||
/* Get ABC status */
|
||||
MHZ19B_CMD_IDX_GET_ABC,
|
||||
/* Enable ABC */
|
||||
MHZ19B_CMD_IDX_SET_ABC_ON,
|
||||
/* Disable ABC */
|
||||
MHZ19B_CMD_IDX_SET_ABC_OFF,
|
||||
/* Set detection range to 2000 ppm */
|
||||
MHZ19B_CMD_IDX_SET_RANGE_2000,
|
||||
/* Set detection range to 5000 ppm */
|
||||
MHZ19B_CMD_IDX_SET_RANGE_5000,
|
||||
/* Set detection range to 10000 ppm */
|
||||
MHZ19B_CMD_IDX_SET_RANGE_10000,
|
||||
/* Number of supported commands */
|
||||
MHZ19B_CMD_IDX_MAX,
|
||||
};
|
||||
|
||||
struct mhz19b_data {
|
||||
/* Max data length is 16 bits */
|
||||
uint16_t data;
|
||||
/* Command buf length is 9 */
|
||||
uint8_t xfer_bytes;
|
||||
bool has_rsp;
|
||||
|
||||
uint8_t rd_data[MHZ19B_BUF_LEN];
|
||||
|
||||
struct k_sem tx_sem;
|
||||
struct k_sem rx_sem;
|
||||
|
||||
enum mhz19b_cmd_idx cmd_idx;
|
||||
};
|
||||
|
||||
struct mhz19b_cfg {
|
||||
const struct device *uart_dev;
|
||||
uint16_t range;
|
||||
bool abc_on;
|
||||
uart_irq_callback_user_data_t cb;
|
||||
};
|
||||
|
||||
#define MHZ19B_HEADER 0xff
|
||||
#define MHZ19B_RESERVED 0x01
|
||||
#define MHZ19B_NULL 0x00
|
||||
#define MHZ19B_NULL_1 MHZ19B_NULL
|
||||
#define MHZ19B_NULL_2 MHZ19B_NULL, MHZ19B_NULL_1
|
||||
#define MHZ19B_NULL_3 MHZ19B_NULL, MHZ19B_NULL_2
|
||||
#define MHZ19B_NULL_4 MHZ19B_NULL, MHZ19B_NULL_3
|
||||
#define MHZ19B_NULL_5 MHZ19B_NULL, MHZ19B_NULL_4
|
||||
#define MHZ19B_NULL_COUNT(c) MHZ19B_NULL_##c
|
||||
|
||||
#define MHZ19B_ABC_ON 0xA0
|
||||
#define MHZ19B_ABC_OFF 0x00
|
||||
#define MHZ19B_RANGE_2000 0x07, 0xD0
|
||||
#define MHZ19B_RANGE_5000 0x13, 0x88
|
||||
#define MHZ19B_RANGE_10000 0x27, 0x10
|
||||
|
||||
enum mhz19b_cmd {
|
||||
MHZ19B_CMD_SET_ABC = 0x79,
|
||||
MHZ19B_CMD_GET_ABC = 0x7D,
|
||||
MHZ19B_CMD_GET_CO2 = 0x86,
|
||||
MHZ19B_CMD_SET_RANGE = 0x99,
|
||||
MHZ19B_CMD_GET_RANGE = 0x9B,
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B */
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2021 G-Technologies Sdn. Bhd.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Winsen MHZ-19B CO2 Sensor
|
||||
|
||||
compatible: "winsen,mhz19b"
|
||||
|
||||
include: uart-device.yaml
|
||||
|
||||
properties:
|
||||
maximum-range:
|
||||
type: int
|
||||
required: true
|
||||
description: CO2 detection range.
|
||||
enum:
|
||||
- 2000
|
||||
- 5000
|
||||
- 10000
|
||||
|
||||
abc-on:
|
||||
type: boolean
|
||||
required: false
|
||||
description: |
|
||||
Enable ABC self-calibration function
|
|
@ -650,6 +650,7 @@ wexler Wexler
|
|||
whwave Shenzhen whwave Electronics, Inc.
|
||||
wi2wi Wi2Wi, Inc.
|
||||
winbond Winbond Electronics corp.
|
||||
winsen Zhengzhou Winsen Electronics Technology Co., Ltd.
|
||||
winstar Winstar Display Corp.
|
||||
wits Shenzhen Merrii Technology Co., Ltd. (WITS)
|
||||
wiznet WIZnet Co., Ltd.
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2021 G-Technologies Sdn. Bhd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Extended public API for MH-Z19B CO2 Sensor
|
||||
*
|
||||
* Some capabilities and operational requirements for this sensor
|
||||
* cannot be expressed within the sensor driver abstraction.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_MHZ19B_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_MHZ19B_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <drivers/sensor.h>
|
||||
|
||||
enum sensor_attribute_mhz19b {
|
||||
/** Automatic Baseline Correction Self Calibration Function. */
|
||||
SENSOR_ATTR_MHZ19B_ABC = SENSOR_ATTR_PRIV_START,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_MHZ19B_H_ */
|
Loading…
Reference in New Issue