Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | /*
* Copyright (c) 2019 Electronut Labs
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT silabs_si7006
#include <drivers/sensor.h>
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <string.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <logging/log.h>
#include <drivers/i2c.h>
#include <logging/log.h>
#include <stdio.h>
#include <stdlib.h>
#include "si7006.h"
LOG_MODULE_REGISTER(si7006, CONFIG_SENSOR_LOG_LEVEL);
struct si7006_data {
const struct device *i2c_dev;
uint16_t temperature;
uint16_t humidity;
};
/**
* @brief function to get relative humidity
*
* @return int 0 on success
*/
static int si7006_get_humidity(const struct device *i2c_dev,
struct si7006_data *si_data)
{
int retval;
uint8_t hum[2];
retval = i2c_burst_read(i2c_dev, DT_INST_REG_ADDR(0),
SI7006_MEAS_REL_HUMIDITY_MASTER_MODE, hum, sizeof(hum));
if (retval == 0) {
si_data->humidity = (hum[0] << 8) | hum[1];
} else {
LOG_ERR("read register err");
}
return retval;
}
/**
* @brief function to get temperature
*
* Note that si7006_get_humidity must be called before calling
* si7006_get_old_temperature.
*
* @return int 0 on success
*/
static int si7006_get_old_temperature(const struct device *i2c_dev,
struct si7006_data *si_data)
{
uint8_t temp[2];
int retval;
retval = i2c_burst_read(i2c_dev, DT_INST_REG_ADDR(0),
SI7006_READ_OLD_TEMP, temp, sizeof(temp));
if (retval == 0) {
si_data->temperature = (temp[0] << 8) | temp[1];
} else {
LOG_ERR("read register err");
}
return retval;
}
/**
* @brief fetch a sample from the sensor
*
* @return 0
*/
static int si7006_sample_fetch(const struct device *dev,
enum sensor_channel chan)
{
int retval;
struct si7006_data *si_data = dev->data;
retval = si7006_get_humidity(si_data->i2c_dev, si_data);
if (retval == 0) {
retval = si7006_get_old_temperature(si_data->i2c_dev, si_data);
}
return retval;
}
/**
* @brief sensor value get
*
* @return -ENOTSUP for unsupported channels
*/
static int si7006_channel_get(const struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct si7006_data *si_data = dev->data;
if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
int32_t temp_ucelcius = (((17572 * (int32_t)si_data->temperature)
/ 65536) - 4685) * 10000;
val->val1 = temp_ucelcius / 1000000;
val->val2 = temp_ucelcius % 1000000;
LOG_DBG("temperature = val1:%d, val2:%d", val->val1, val->val2);
return 0;
} else if (chan == SENSOR_CHAN_HUMIDITY) {
int32_t relative_humidity = (((125 * (int32_t)si_data->humidity)
/ 65536) - 6) * 1000000;
val->val1 = relative_humidity / 1000000;
val->val2 = relative_humidity % 1000000;
LOG_DBG("humidity = val1:%d, val2:%d", val->val1, val->val2);
return 0;
} else {
return -ENOTSUP;
}
}
static const struct sensor_driver_api si7006_api = {
.sample_fetch = &si7006_sample_fetch,
.channel_get = &si7006_channel_get,
};
/**
* @brief initiasize the sensor
*
* @return 0 for success
*/
static int si7006_init(const struct device *dev)
{
struct si7006_data *drv_data = dev->data;
drv_data->i2c_dev = device_get_binding(
DT_INST_BUS_LABEL(0));
if (!drv_data->i2c_dev) {
LOG_ERR("i2c master not found.");
return -EINVAL;
}
LOG_DBG("si7006 init ok");
return 0;
}
static struct si7006_data si_data;
DEVICE_DT_INST_DEFINE(0, si7006_init, NULL,
&si_data, NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &si7006_api);
|