diff --git a/general/include/hdc2021debr.h b/general/include/hdc2021debr.h new file mode 100644 index 00000000..5b5b3fea --- /dev/null +++ b/general/include/hdc2021debr.h @@ -0,0 +1,61 @@ +#ifndef hdc2021debr_h +#define hdc2021debr_h +#include +#include +/** + * https://www.ti.com/lit/ds/symlink/hdc2021.pdf + * --Datasheet + * + */ + +#define HDC2021_I2C_ADDR \ + 0x40 /* If ADDR is connected to VDD, 0x41 This is shifted left as it is required to be read as a dev address.*/ + +typedef enum { + REG_TEMP_LOW = 0x00, + REG_TEMP_HIGH = 0x01, + REG_HUMID_LOW = 0x02, + REG_HUMID_HIGH = 0x03, + REG_STATUS = 0x04, + REG_DEVICE_CONFIG = 0x0E, + REG_MEASURE_CONFIG = 0x0F +} HDC2021_REG_ADDR_t; + +/** Function Pointers */ +typedef int (*Write_ptr)(uint8_t *data, uint8_t dev_address, uint8_t length); +typedef int (*Read_ptr)(uint8_t *data, uint8_t reg, uint8_t dev_address, + uint8_t length); + +typedef struct { + Write_ptr write_reg; + Read_ptr read_reg; + float temp; + float humidity; + bool is_heater_enabled; + uint8_t dev_address; +} hdc2021debr_t; + +/** + * @brief Initializes an HDC2021 Driver + * + * @param hdc2021 - hdc2021debr driver + * @return int - Status code + */ +int hdc2021_init(hdc2021debr_t *hdc2021, Write_ptr write_reg, Read_ptr read_reg, + uint8_t dev_address); +/** + * @brief Toggles the status of the internal heater + * + * @param hdc2021 - hdc2021debr driver + * @param enable - true to enable, false to disable + * @return int - Status code + */ +int hdc2021_toggle_heater(hdc2021debr_t *hdc2021, bool enable); +/** + * @brief Retrieves the temperature and humidity + * @note Call hdc2021_trigger_oneshot() and wait a couple ms before calling this + * @param hdc2021 - hdc2021debr driver + * @return int - Status code + */ +int hdc2021_get_temp_humid(hdc2021debr_t *hdc2021); +#endif \ No newline at end of file diff --git a/general/src/hdc2021debr.c b/general/src/hdc2021debr.c new file mode 100644 index 00000000..d3f33fee --- /dev/null +++ b/general/src/hdc2021debr.c @@ -0,0 +1,99 @@ +#include "hdc2021debr.h" +#include +#include + +static int hdc2021_write_reg(hdc2021debr_t *hdc2021, uint8_t reg, uint8_t data) +{ + uint8_t buffer[2] = {reg, data}; + return hdc2021->write_reg(buffer, hdc2021->dev_address, sizeof(buffer)); +} + +static int hdc2021_read_reg(hdc2021debr_t *hdc2021, uint8_t reg, uint8_t *data, + uint8_t length) +{ + return hdc2021->read_reg(data, reg, hdc2021->dev_address, length); +} + +int hdc2021_init(hdc2021debr_t *hdc2021, Write_ptr write_reg, Read_ptr read_reg, + uint8_t dev_address) +{ + hdc2021->write_reg = write_reg; + hdc2021->read_reg = read_reg; + hdc2021->dev_address = dev_address << 1u; + + return 0; +} + +int hdc2021_toggle_heater(hdc2021debr_t *hdc2021, bool enable) +{ + uint8_t device_config; + + if (hdc2021_read_reg(hdc2021, REG_DEVICE_CONFIG, &device_config, + sizeof(device_config))) + { + return 1; + }; + + // the 3rd bit toggles the heater + if (enable) { + device_config |= (1 << 3); + } else { + device_config &= ~(1 << 3); + }; + + if (hdc2021_write_reg(hdc2021, REG_DEVICE_CONFIG, device_config)) + { + return 1; + }; + + return 0; + +} +/** + * @brief triggers oneshot measurement + * + * @param hdc2021 - hdc2021debr driver + * @return int - Status code + */ +int hdc2021_trigger_oneshot(hdc2021debr_t *hdc2021) +{ + uint8_t config; + + if (hdc2021_read_reg(hdc2021, REG_MEASURE_CONFIG, &config, 1)) { + return 1; + } + + config |= 0x01; + + if (hdc2021_write_reg(hdc2021, REG_MEASURE_CONFIG, config)) { + return 1; + } + + return 0; +} + +int hdc2021_get_temp_humid(hdc2021debr_t *hdc2021) +{ + uint8_t buffer[4]; + + if (hdc2021_trigger_oneshot(hdc2021)) { + return 1; + } + + + if (hdc2021_read_reg(hdc2021, REG_TEMP_LOW, buffer, 4)) + { + return 1; + }; + + uint16_t temp_bytes = (buffer[1] << 8) | buffer[0]; + uint16_t humid_bytes = (buffer[3] << 8) | buffer[2]; + + float tempVal = (((float)temp_bytes/65536.0f) * 165.0f) - 40.0f; + hdc2021->temp = tempVal; + + float humidVal = ((float)humid_bytes/65536.0f) * 100.0f; + hdc2021->humidity = humidVal; + + return 0; +} \ No newline at end of file