2022-07-22 01:29:28 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
/* Private header */
|
2023-07-02 15:09:29 +00:00
|
|
|
#include "dht_aht10.h"
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
#define AHT10_STATUS_CALIBRATED_MASK (1U << 3U)
|
|
|
|
#define AHT10_STATUS_BUSY_MASK (1U << 7U)
|
|
|
|
|
|
|
|
#define AHT10_ERROR_CHECK(x) \
|
2023-07-02 15:09:29 +00:00
|
|
|
if (x != IMS_SUCCESS) return IMS_FAIL
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t status;
|
|
|
|
uint32_t temperature;
|
|
|
|
uint32_t humidity;
|
2023-07-02 15:09:29 +00:00
|
|
|
} ims_aht10_raw_t;
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
static ims_ret_t aht10_software_reset(ims_aht10_t *aht) {
|
2022-07-22 01:29:28 +00:00
|
|
|
/* Reset and initialize device */
|
|
|
|
|
|
|
|
uint8_t tx_data[3] = {0xBA};
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_i2c_xfer_desc_t xfer = {
|
2022-07-22 01:29:28 +00:00
|
|
|
.tx_data = tx_data,
|
|
|
|
.tx_size = 1U,
|
|
|
|
.rx_data = NULL,
|
|
|
|
.rx_size = 0U,
|
|
|
|
};
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 20));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
tx_data[0] = 0xE1;
|
|
|
|
tx_data[1] = 0x08;
|
|
|
|
tx_data[2] = 0x00;
|
|
|
|
|
|
|
|
xfer.tx_size = 3U;
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_SUCCESS;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
static ims_ret_t aht10_start_measurement(ims_aht10_t *aht) {
|
2022-07-22 01:29:28 +00:00
|
|
|
/* Start measurement */
|
|
|
|
|
|
|
|
uint8_t tx_data[3] = {0xAC, 0x33, 0x00};
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_i2c_xfer_desc_t xfer = {
|
2022-07-22 01:29:28 +00:00
|
|
|
.tx_data = tx_data,
|
|
|
|
.tx_size = 3U,
|
|
|
|
.rx_data = NULL,
|
|
|
|
.rx_size = 0U,
|
|
|
|
};
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_SUCCESS;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
static ims_ret_t aht10_read_result(ims_aht10_t *aht, ims_aht10_raw_t *raw) {
|
2022-07-22 01:29:28 +00:00
|
|
|
/* Read conversion result */
|
|
|
|
|
|
|
|
uint8_t tx_data[] = {0x71};
|
|
|
|
uint8_t rx_data[6];
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_i2c_xfer_desc_t xfer = {
|
2022-07-22 01:29:28 +00:00
|
|
|
.tx_data = tx_data,
|
|
|
|
.tx_size = 1U,
|
|
|
|
.rx_data = rx_data,
|
|
|
|
.rx_size = 6U,
|
|
|
|
};
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
raw->humidity = rx_data[1] << 12U;
|
|
|
|
raw->humidity |= rx_data[2] << 4U;
|
|
|
|
raw->humidity |= rx_data[3] >> 4U;
|
|
|
|
|
|
|
|
raw->temperature = (rx_data[3] & 0x0FU) << 16U;
|
|
|
|
raw->temperature |= rx_data[4] << 8U;
|
|
|
|
raw->temperature |= rx_data[5];
|
|
|
|
|
|
|
|
raw->status = rx_data[0];
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_SUCCESS;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_ret_t aht10_init(ims_aht10_t *aht) {
|
2022-07-22 01:29:28 +00:00
|
|
|
/* Check if we need initialization */
|
|
|
|
|
|
|
|
/* Delay 40ms after POR */
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 40));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_aht10_raw_t raw;
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
/* Check 0x71 status byte, if uncalibrated then reset and calibrate it. */
|
|
|
|
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
|
|
|
|
if ((raw.status & AHT10_STATUS_CALIBRATED_MASK) == 0) {
|
|
|
|
AHT10_ERROR_CHECK(aht10_software_reset(aht));
|
|
|
|
}
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_SUCCESS;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_ret_t aht10_measure(ims_aht10_t *aht, ims_aht10_result_t *result) {
|
2022-07-22 01:29:28 +00:00
|
|
|
/* Start a measurement and read back result... */
|
|
|
|
|
|
|
|
AHT10_ERROR_CHECK(aht10_start_measurement(aht));
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 80));
|
2022-07-22 01:29:28 +00:00
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
ims_aht10_raw_t raw;
|
2022-07-22 01:29:28 +00:00
|
|
|
|
|
|
|
uint8_t max_retries = 5U;
|
|
|
|
|
|
|
|
do {
|
|
|
|
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
|
|
|
|
max_retries--;
|
|
|
|
if (max_retries == 0) {
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_FAIL;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-07-02 15:09:29 +00:00
|
|
|
#ifdef IMS_CFG_DHT_AHT10_BUSY_CHECK
|
2022-07-22 01:29:28 +00:00
|
|
|
while (raw.status & AHT10_STATUS_BUSY_MASK);
|
|
|
|
#else
|
|
|
|
while (0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
result->temperature = ((double)raw.temperature * 200.0 / 1048576.0) - 50.0;
|
|
|
|
result->humidity = (double)raw.humidity * 100.0 / 1048576.0;
|
|
|
|
|
2023-07-02 15:09:29 +00:00
|
|
|
return IMS_SUCCESS;
|
2022-07-22 01:29:28 +00:00
|
|
|
}
|