You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.6 KiB

/*
"THE BEER/MATE-WARE LICENSE":
<xil@xil.se> wrote this file. As long as you retain this notice you
can do whatever you want with this stuff. If we meet some day, and you think
this stuff is worth it, you can buy us a ( > 0 ) beer/mate in return - The Xil TEAM
*/
#include <stdint.h>
#include <stdbool.h>
#include "drivers/i2c.h"
#include "drivers/htu21.h"
#include "drivers/drivers.h"
#define I2C_ADDRESS 0x40
#define HTU21_TRIGGER_TEMP 0xF3
#define HTU21_TRIGGER_HUMIDITY 0xF5
// Temperature measurement seems to take ~45ms
// Humidity measurement seems to take ~15ms
#define HTU21_I2C_RETRIES 100 // 1ms per retry
static uint16_t ICACHE_FLASH_ATTR byteswap16(uint16_t u16)
{
uint8_t* u8;
u8 = (uint8_t*)&u16;
return (u8[0] << 8) | (u8[1] << 0);
}
static int16_t ICACHE_FLASH_ATTR htu21_read_temp(htu21_t* htu21)
{
float temp;
int res;
int retries;
uint8_t buffer[3];
if (!htu21->initilized) {
return 0;
}
buffer[0] = HTU21_TRIGGER_TEMP;
retries = HTU21_I2C_RETRIES;
do {
res = i2c_transmit(htu21->i2c, I2C_ADDRESS, buffer, 1);
retries--;
I2C_DELAY_US(1000);
} while (res != 0 && retries > 0);
if (res != 0)
{
return 0;
}
retries = HTU21_I2C_RETRIES;
do {
I2C_DELAY_US(1000);
res = i2c_receive(htu21->i2c, I2C_ADDRESS, buffer, 3);
retries--;
} while (res != 0 && retries > 0);
if (res != 0)
{
return 0;
}
temp = byteswap16(*(uint16_t*)buffer);
temp = -46.85 + 175.72 * temp/(1<<16);
// return value in 0.1C
return temp * 10;
}
static int16_t ICACHE_FLASH_ATTR htu21_read_humidity(htu21_t* htu21)
{
float humidity;
int res;
int retries;
uint8_t buffer[3];
if (!htu21->initilized) {
return 0;
}
buffer[0] = HTU21_TRIGGER_HUMIDITY;
retries = HTU21_I2C_RETRIES;
do {
res = i2c_transmit(htu21->i2c, I2C_ADDRESS, buffer, 1);
retries--;
I2C_DELAY_US(1000);
} while (res != 0 && retries > 0);
if (res != 0)
{
return 0;
}
retries = HTU21_I2C_RETRIES;
do {
I2C_DELAY_US(1000);
res = i2c_receive(htu21->i2c, I2C_ADDRESS, buffer, 3);
retries--;
} while (res != 0 && retries > 0);
if (res != 0)
{
return 0;
}
humidity = byteswap16(*(uint16_t*)buffer);
humidity = -6 + 125 * humidity/(1<<16);
// return value in 0.1%
return humidity * 10;
}
bool ICACHE_FLASH_ATTR htu21_read(driver_params_t* params)
{
htu21_t* htu21 = &params->htu21;
htu21->temperature = htu21_read_temp(htu21);
htu21->humidity = htu21_read_humidity(htu21);
return true;
}
bool ICACHE_FLASH_ATTR htu21_print(driver_params_t* params, driver_print_data_t* print)
{
htu21_t* htu21 = &params->htu21;
print->print_string(print->data, print->index, print->i, "driver", "htu21");
print->print_value(print->data, print->index, print->i, "temp", &htu21->temperature, sizeof(htu21->temperature));
print->print_value(print->data, print->index, print->i, "humidity", &htu21->humidity, sizeof(htu21->humidity));
return true;
}
bool ICACHE_FLASH_ATTR htu21_init(driver_params_t* params, driver_bus_t* bus)
{
htu21_t* htu21 = &params->htu21;
i2c_t* i2c = &bus->params.i2c;
htu21->i2c = i2c;
htu21->initilized = true;
return true;
}
// Global variable with function pointers
const driver_sensor_t sensor_htu21 = {
.init = htu21_init,
.read = htu21_read,
.print = htu21_print,
};