Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions general/include/hdc2021debr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef hdc2021debr_h
#define hdc2021debr_h
#include <stdbool.h>
#include <stdint.h>
/**
* 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
99 changes: 99 additions & 0 deletions general/src/hdc2021debr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "hdc2021debr.h"
#include <stdbool.h>
#include <stdio.h>

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;
}
Loading