forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: sensor: Aosong AGS10 TVOC sensor
Added support for Aosong AGS10 TVOC sensor Signed-off-by: Balthazar Deliers <[email protected]>
- Loading branch information
1 parent
3cdce5b
commit bea34c5
Showing
8 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
|
||
zephyr_library() | ||
zephyr_library_sources(ags10.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright (c) 2023 Balthazar Deliers | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
# AOSONG AGS10 TVOC sensor driver options. | ||
|
||
config AGS10 | ||
bool "AOSONG AGS10 TVOC sensor" | ||
default y | ||
depends on DT_HAS_AOSONG_AGS10_ENABLED | ||
select I2C | ||
help | ||
Enable AOSONG AGS10 TVOC sensor driver. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* Copyright (c) 2023 Balthazar Deliers | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#define DT_DRV_COMPAT aosong_ags10 | ||
|
||
#include <zephyr/drivers/sensor.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/logging/log.h> | ||
#include <zephyr/sys/byteorder.h> | ||
#include <zephyr/sys/crc.h> | ||
|
||
#include "ags10.h" | ||
|
||
LOG_MODULE_REGISTER(AGS10, CONFIG_SENSOR_LOG_LEVEL); | ||
|
||
#define AGS10_MAX_PAYLOAD_SIZE 5U /* Payload will be max 4 bytes + CRC (datasheet 3.1) */ | ||
|
||
static int ags10_read(const struct device *dev, uint8_t cmd, uint8_t *data, uint8_t rx_bytes) | ||
{ | ||
if (rx_bytes > AGS10_MAX_PAYLOAD_SIZE) { | ||
return -EINVAL; | ||
} | ||
|
||
const struct ags10_config *conf = dev->config; | ||
|
||
uint8_t recv_buf[AGS10_MAX_PAYLOAD_SIZE] = {0}; | ||
int ret = i2c_write_read_dt(&conf->bus, &cmd, sizeof(cmd), &recv_buf, rx_bytes); | ||
|
||
if (ret < 0) { | ||
return ret; | ||
} | ||
|
||
memcpy(data, recv_buf, rx_bytes); | ||
|
||
return 0; | ||
} | ||
|
||
static int ags10_sample_fetch(const struct device *dev, enum sensor_channel chan) | ||
{ | ||
if (chan != SENSOR_CHAN_VOC && chan != SENSOR_CHAN_ALL) { | ||
return -ENOTSUP; | ||
} | ||
|
||
struct ags10_data *data = dev->data; | ||
int ret = -ENOTSUP; | ||
uint8_t recv_buf[5] = {0}; | ||
|
||
ret = ags10_read(dev, AGS10_CMD_DATA_ACQUISITION, recv_buf, 5); | ||
|
||
if (ret == 0) { | ||
/* If CRC is valid and data is valid too */ | ||
if (crc8(&recv_buf[0], 4, 0x31, 0xFF, false) == recv_buf[4] && | ||
((recv_buf[0] & AGS10_MSK_STATUS) == AGS10_REG_STATUS_NRDY_READY)) { | ||
data->status = recv_buf[0] & AGS10_MSK_STATUS; | ||
data->tvoc_ppb = sys_get_be24(&recv_buf[1]); | ||
return 0; | ||
} | ||
|
||
LOG_WRN("Bad CRC or data not ready"); | ||
ret = -EIO; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static int ags10_channel_get(const struct device *dev, enum sensor_channel chan, | ||
struct sensor_value *val) | ||
{ | ||
struct ags10_data *data = dev->data; | ||
|
||
if (chan == SENSOR_CHAN_VOC) { | ||
val->val1 = data->tvoc_ppb; | ||
} else { | ||
return -ENOTSUP; | ||
} | ||
|
||
val->val2 = 0; | ||
|
||
return 0; | ||
} | ||
|
||
static int ags10_init(const struct device *dev) | ||
{ | ||
const struct ags10_config *conf = dev->config; | ||
struct ags10_data *data = dev->data; | ||
int ret; | ||
|
||
if (!i2c_is_ready_dt(&conf->bus)) { | ||
LOG_ERR("Device not ready"); | ||
return -ENODEV; | ||
} | ||
|
||
/* Set initial data values */ | ||
data->tvoc_ppb = 0; | ||
data->status = 0xFF; | ||
data->version = 0; | ||
|
||
/* Read firmware version and check CRC */ | ||
uint8_t recv_buf[5] = {0}; | ||
|
||
ret = ags10_read(dev, AGS10_CMD_READ_VERSION, recv_buf, 5); | ||
|
||
/* Bytes 0 to 2 are reserved, byte 3 is version, byte 4 is CRC */ | ||
if (ret == 0 && crc8(&recv_buf[0], 4, 0x31, 0xFF, false) == recv_buf[4]) { | ||
data->version = recv_buf[3]; | ||
LOG_DBG("Sensor detected"); | ||
} else if (ret != 0) { | ||
LOG_ERR("No reply from sensor"); | ||
ret = -ENODEV; | ||
} else { | ||
LOG_WRN("Bad CRC"); | ||
ret = -EIO; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static const struct sensor_driver_api ags10_api = {.sample_fetch = ags10_sample_fetch, | ||
.channel_get = ags10_channel_get}; | ||
|
||
#define AGS10_INIT(n) \ | ||
static struct ags10_data ags10_data_##n; \ | ||
\ | ||
static const struct ags10_config ags10_config_##n = { \ | ||
.bus = I2C_DT_SPEC_INST_GET(n), \ | ||
}; \ | ||
\ | ||
SENSOR_DEVICE_DT_INST_DEFINE(n, ags10_init, NULL, &ags10_data_##n, &ags10_config_##n, \ | ||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &ags10_api); | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(AGS10_INIT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright (c) 2023 Balthazar Deliers | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_AGS10_H_ | ||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_AGS10_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <zephyr/device.h> | ||
#include <zephyr/drivers/i2c.h> | ||
|
||
#define AGS10_CMD_DATA_ACQUISITION 0x00 | ||
#define AGS10_CMD_ZERO_POINT_CALIBRATION 0x01 | ||
#define AGS10_CMD_READ_VERSION 0x11 | ||
#define AGS10_CMD_READ_RESISTANCE 0x20 | ||
#define AGS10_CMD_MODIFY_SLAVE_ADDRESS 0x21 | ||
|
||
#define AGS10_REG_ZERO_POINT_CALIBRATION_RESET 0xFFFF /* Reset to the factory value */ | ||
#define AGS10_REG_ZERO_POINT_CALIBRATION_SET 0x0000 /* Set sensor resistance to zero-point */ | ||
#define AGS10_REG_STATUS_NRDY_READY 0x00 /* Device is ready */ | ||
#define AGS10_REG_STATUS_CH_PPB 0x00 /* Unit is PPB */ | ||
|
||
#define AGS10_MSK_STATUS 0x0F | ||
#define AGS10_MSK_STATUS_NRDY 0x01 | ||
#define AGS10_MSK_STATUS_CH 0x0E | ||
|
||
struct ags10_config { | ||
struct i2c_dt_spec bus; | ||
}; | ||
|
||
struct ags10_data { | ||
uint32_t tvoc_ppb; | ||
uint8_t status; | ||
uint32_t version; | ||
}; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_AGS10_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Copyright (c) 2023 Balthazar Deliers | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
description: | | ||
AOSONG AGS10 a high-performance TVOC Sensor With I2C Interface. | ||
See: http://www.aosong.com/en/products-86.html | ||
compatible: "aosong,ags10" | ||
|
||
include: [sensor-device.yaml, i2c-device.yaml] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters