drivers: sensor: ENS210: add single shot mode
Add possibility to change the measurement modes of the temperature and humidity measurements to continuous or single-shot mode or switch them off. Signed-off-by: Christian Hirsch <christian.hirsch@tuwien.ac.at>
This commit is contained in:
parent
57c28c0d44
commit
d85b672368
3 changed files with 166 additions and 34 deletions
|
@ -10,6 +10,32 @@ menuconfig ENS210
|
|||
Enable driver for ENS210 Digital Temperature and Humidity sensor.
|
||||
if ENS210
|
||||
|
||||
choice
|
||||
prompt "Temperature measurement mode"
|
||||
default ENS210_TEMPERATURE_CONTINUOUS
|
||||
help
|
||||
Enable/disable temperature measurements and set measurement mode.
|
||||
config ENS210_TEMPERATURE_OFF
|
||||
bool "Disable temperature measurements"
|
||||
config ENS210_TEMPERATURE_SINGLE
|
||||
bool "Enable temperature measurements in single shot mode"
|
||||
config ENS210_TEMPERATURE_CONTINUOUS
|
||||
bool "Enable temperature measurements in continuous mode"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Humidity measurement mode"
|
||||
default ENS210_HUMIDITY_CONTINUOUS
|
||||
help
|
||||
Enable/disable relative humidity measurements and set measurement mode.
|
||||
config ENS210_HUMIDITY_OFF
|
||||
bool "Disable relative humidity measurements"
|
||||
config ENS210_HUMIDITY_SINGLE
|
||||
bool "Enable relative humidity measurements in single shot mode"
|
||||
config ENS210_HUMIDITY_CONTINUOUS
|
||||
bool "Enable relative humidity measurements in continuous mode"
|
||||
endchoice
|
||||
|
||||
config ENS210_CRC_CHECK
|
||||
bool "Enable CRC Check"
|
||||
default y
|
||||
|
|
|
@ -36,6 +36,46 @@ static u32_t ens210_crc7(u32_t bitstream)
|
|||
}
|
||||
#endif /* CONFIG_ENS210_CRC_CHECK */
|
||||
|
||||
#if defined(CONFIG_ENS210_TEMPERATURE_SINGLE) \
|
||||
|| defined(CONFIG_ENS210_HUMIDITY_SINGLE)
|
||||
static int ens210_measure(struct device *i2c_dev, enum sensor_channel chan)
|
||||
{
|
||||
u8_t buf;
|
||||
int ret;
|
||||
const struct ens210_sens_start sense_start = {
|
||||
.t_start = ENS210_T_START && (chan == SENSOR_CHAN_ALL
|
||||
|| chan == SENSOR_CHAN_AMBIENT_TEMP),
|
||||
.h_start = ENS210_H_START && (chan == SENSOR_CHAN_ALL
|
||||
|| chan == SENSOR_CHAN_HUMIDITY)
|
||||
};
|
||||
|
||||
/* Start measuring */
|
||||
ret = i2c_reg_write_byte(i2c_dev,
|
||||
DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
ENS210_REG_SENS_START, *(u8_t *)&sense_start);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to set SENS_START to 0x%x",
|
||||
*(u8_t *)&sense_start);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Wait for measurement to be completed */
|
||||
do {
|
||||
k_sleep(K_MSEC(2));
|
||||
ret = i2c_reg_read_byte(i2c_dev,
|
||||
DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
ENS210_REG_SENS_START, &buf);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to read SENS_STAT");
|
||||
}
|
||||
} while (buf & *(u8_t *)&sense_start);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* Single shot mode */
|
||||
|
||||
static int ens210_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct ens210_data *drv_data = dev->driver_data;
|
||||
|
@ -46,7 +86,18 @@ static int ens210_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|||
u32_t temp_valid, humidity_valid;
|
||||
#endif /* CONFIG_ENS210_CRC_CHECK */
|
||||
|
||||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL
|
||||
|| chan == SENSOR_CHAN_AMBIENT_TEMP
|
||||
|| chan == SENSOR_CHAN_HUMIDITY);
|
||||
|
||||
#if defined(CONFIG_ENS210_TEMPERATURE_SINGLE) \
|
||||
|| defined(CONFIG_ENS210_HUMIDITY_SINGLE)
|
||||
ret = ens210_measure(drv_data->i2c, chan);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to measure");
|
||||
return ret;
|
||||
}
|
||||
#endif /* Single shot mode */
|
||||
|
||||
for (cnt = 0; cnt <= CONFIG_ENS210_MAX_READ_RETRIES; cnt++) {
|
||||
ret = i2c_burst_read(drv_data->i2c, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
|
@ -56,35 +107,47 @@ static int ens210_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Get temperature value */
|
||||
if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
|
||||
if (!data[0].valid) {
|
||||
LOG_WRN("Temperature not valid");
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ENS210_CRC_CHECK
|
||||
temp_valid = data[0].val |
|
||||
(data[0].valid << (sizeof(data[0].val) * 8));
|
||||
|
||||
if (ens210_crc7(temp_valid) != data[0].crc7) {
|
||||
LOG_WRN("Temperature CRC error");
|
||||
continue;
|
||||
}
|
||||
#endif /* CONFIG_ENS210_CRC_CHECK */
|
||||
|
||||
drv_data->temp = data[0];
|
||||
}
|
||||
|
||||
/* Get humidity value */
|
||||
if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_HUMIDITY) {
|
||||
|
||||
if (!data[1].valid) {
|
||||
LOG_WRN("Humidity not valid");
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ENS210_CRC_CHECK
|
||||
temp_valid = data[0].val |
|
||||
(data[0].valid << (sizeof(data[0].val) * 8));
|
||||
humidity_valid = data[1].val |
|
||||
(data[1].valid << (sizeof(data[1].val) * 8));
|
||||
|
||||
if (ens210_crc7(temp_valid) != data[0].crc7) {
|
||||
LOG_WRN("Temperature CRC error");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ens210_crc7(humidity_valid) != data[1].crc7) {
|
||||
LOG_WRN("Humidity CRC error");
|
||||
continue;
|
||||
}
|
||||
#endif /* CONFIG_ENS210_CRC_CHECK */
|
||||
|
||||
drv_data->temp = data[0];
|
||||
drv_data->humidity = data[1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -125,7 +188,10 @@ static int ens210_channel_get(struct device *dev,
|
|||
|
||||
static int ens210_sys_reset(struct device *i2c_dev)
|
||||
{
|
||||
const struct ens210_sys_ctrl sys_ctrl = {.low_power = 0, .reset = 1};
|
||||
const struct ens210_sys_ctrl sys_ctrl = {
|
||||
.low_power = 0,
|
||||
.reset = 1
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = i2c_reg_write_byte(i2c_dev, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
|
@ -136,9 +202,12 @@ static int ens210_sys_reset(struct device *i2c_dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ens210_sys_enable(struct device *i2c_dev)
|
||||
static int ens210_sys_enable(struct device *i2c_dev, u8_t low_power)
|
||||
{
|
||||
const struct ens210_sys_ctrl sys_ctrl = {.low_power = 0, .reset = 0};
|
||||
const struct ens210_sys_ctrl sys_ctrl = {
|
||||
.low_power = low_power,
|
||||
.reset = 0
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = i2c_reg_write_byte(i2c_dev, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
|
@ -173,7 +242,7 @@ static int ens210_wait_boot(struct device *i2c_dev)
|
|||
ens210_sys_reset(i2c_dev);
|
||||
}
|
||||
|
||||
ens210_sys_enable(i2c_dev);
|
||||
ens210_sys_enable(i2c_dev, 0);
|
||||
|
||||
k_sleep(K_MSEC(2));
|
||||
}
|
||||
|
@ -196,13 +265,18 @@ static int ens210_init(struct device *dev)
|
|||
{
|
||||
struct ens210_data *drv_data = dev->driver_data;
|
||||
const struct ens210_sens_run sense_run = {
|
||||
.t_run = 1,
|
||||
.h_run = 1
|
||||
.t_run = ENS210_T_RUN,
|
||||
.h_run = ENS210_H_RUN
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ENS210_TEMPERATURE_CONTINUOUS) \
|
||||
|| defined(CONFIG_ENS210_HUMIDITY_CONTINUOUS)
|
||||
const struct ens210_sens_start sense_start = {
|
||||
.t_start = 1,
|
||||
.h_start = 1
|
||||
.t_start = ENS210_T_RUN,
|
||||
.h_start = ENS210_H_RUN
|
||||
};
|
||||
#endif
|
||||
|
||||
int ret;
|
||||
u16_t part_id;
|
||||
|
||||
|
@ -219,7 +293,9 @@ static int ens210_init(struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
/* Check Hardware ID. This is only possible after device is ready */
|
||||
/* Check Hardware ID. This is only possible after device is ready
|
||||
* and active
|
||||
*/
|
||||
ret = i2c_burst_read(drv_data->i2c, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
ENS210_REG_PART_ID, (u8_t *)&part_id,
|
||||
sizeof(part_id));
|
||||
|
@ -234,7 +310,12 @@ static int ens210_init(struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
/* Set continuous measurement */
|
||||
/* Enable low power mode */
|
||||
if ((ENS210_T_RUN | ENS210_H_RUN) == 0) {
|
||||
ens210_sys_enable(drv_data->i2c, 1);
|
||||
}
|
||||
|
||||
/* Set measurement mode*/
|
||||
ret = i2c_reg_write_byte(drv_data->i2c, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
ENS210_REG_SENS_RUN, *(u8_t *)&sense_run);
|
||||
if (ret < 0) {
|
||||
|
@ -243,6 +324,8 @@ static int ens210_init(struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ENS210_TEMPERATURE_CONTINUOUS) \
|
||||
|| defined(CONFIG_ENS210_HUMIDITY_CONTINUOUS)
|
||||
/* Start measuring */
|
||||
ret = i2c_reg_write_byte(drv_data->i2c, DT_INST_0_AMS_ENS210_BASE_ADDRESS,
|
||||
ENS210_REG_SENS_START, *(u8_t *)&sense_start);
|
||||
|
@ -251,6 +334,7 @@ static int ens210_init(struct device *dev)
|
|||
*(u8_t *)&sense_start);
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,28 @@
|
|||
|
||||
#define ENS210_PART_ID 0x0210
|
||||
|
||||
#if defined CONFIG_ENS210_TEMPERATURE_OFF
|
||||
#define ENS210_T_RUN 0
|
||||
#define ENS210_T_START 0
|
||||
#elif defined CONFIG_ENS210_TEMPERATURE_SINGLE
|
||||
#define ENS210_T_RUN 0
|
||||
#define ENS210_T_START 1
|
||||
#elif defined CONFIG_ENS210_TEMPERATURE_CONTINUOUS
|
||||
#define ENS210_T_RUN 1
|
||||
#define ENS210_T_START 1
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_ENS210_HUMIDITY_OFF
|
||||
#define ENS210_H_RUN 0
|
||||
#define ENS210_H_START 0
|
||||
#elif defined CONFIG_ENS210_HUMIDITY_SINGLE
|
||||
#define ENS210_H_RUN 0
|
||||
#define ENS210_H_START 1
|
||||
#elif defined CONFIG_ENS210_HUMIDITY_CONTINUOUS
|
||||
#define ENS210_H_RUN 1
|
||||
#define ENS210_H_START 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Polynomial
|
||||
* 0b 1000 1001 ~ x^7+x^3+x^0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue