#include /* Private header */ #include "dht_aht10.h" #define AHT10_STATUS_CALIBRATED_MASK (1U << 3U) #define AHT10_STATUS_BUSY_MASK (1U << 7U) #define AHT10_ERROR_CHECK(x) \ if (x != IMS_SUCCESS) return IMS_FAIL typedef struct { uint8_t status; uint32_t temperature; uint32_t humidity; } ims_aht10_raw_t; static ims_ret_t aht10_software_reset(ims_aht10_t *aht) { /* Reset and initialize device */ uint8_t tx_data[3] = {0xBA}; ims_i2c_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 1U, .rx_data = NULL, .rx_size = 0U, }; AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer)); AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 20)); tx_data[0] = 0xE1; tx_data[1] = 0x08; tx_data[2] = 0x00; xfer.tx_size = 3U; AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer)); return IMS_SUCCESS; } static ims_ret_t aht10_start_measurement(ims_aht10_t *aht) { /* Start measurement */ uint8_t tx_data[3] = {0xAC, 0x33, 0x00}; ims_i2c_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 3U, .rx_data = NULL, .rx_size = 0U, }; AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer)); return IMS_SUCCESS; } static ims_ret_t aht10_read_result(ims_aht10_t *aht, ims_aht10_raw_t *raw) { /* Read conversion result */ uint8_t tx_data[] = {0x71}; uint8_t rx_data[6]; ims_i2c_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 1U, .rx_data = rx_data, .rx_size = 6U, }; AHT10_ERROR_CHECK(aht->cb.i2c_xfer(aht->pdev, &xfer)); 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]; return IMS_SUCCESS; } ims_ret_t aht10_init(ims_aht10_t *aht) { /* Check if we need initialization */ /* Delay 40ms after POR */ AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 40)); ims_aht10_raw_t raw; /* 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)); } return IMS_SUCCESS; } ims_ret_t aht10_measure(ims_aht10_t *aht, ims_aht10_result_t *result) { /* Start a measurement and read back result... */ AHT10_ERROR_CHECK(aht10_start_measurement(aht)); AHT10_ERROR_CHECK(aht->cb.delay(aht->pdev, 80)); ims_aht10_raw_t raw; uint8_t max_retries = 5U; do { AHT10_ERROR_CHECK(aht10_read_result(aht, &raw)); max_retries--; if (max_retries == 0) { return IMS_FAIL; } } #ifdef IMS_CFG_DHT_AHT10_BUSY_CHECK 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; return IMS_SUCCESS; }