#include /* Private header */ #include "aht10.h" #define AHT10_STATUS_CALIBRATED_MASK (1U << 3U) #define AHT10_STATUS_BUSY_MASK (1U << 7U) #define AHT10_ERROR_CHECK(x) \ if (x != AHT10_OK) return AHT10_FAIL typedef struct { uint8_t status; uint32_t temperature; uint32_t humidity; } aht10_raw_t; static aht10_ret_t aht10_software_reset(aht10_t *aht) { /* Reset and initialize device */ uint8_t tx_data[3] = {0xBA}; aht10_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 1U, .rx_data = NULL, .rx_size = 0U, }; AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer)); AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 20)); tx_data[0] = 0xE1; tx_data[1] = 0x08; tx_data[2] = 0x00; xfer.tx_size = 3U; AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer)); return AHT10_OK; } static aht10_ret_t aht10_start_measurement(aht10_t *aht) { /* Start measurement */ uint8_t tx_data[3] = {0xAC, 0x33, 0x00}; aht10_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 3U, .rx_data = NULL, .rx_size = 0U, }; AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer)); return AHT10_OK; } static aht10_ret_t aht10_read_result(aht10_t *aht, aht10_raw_t *raw) { /* Read conversion result */ uint8_t tx_data[] = {0x71}; uint8_t rx_data[6]; aht10_xfer_desc_t xfer = { .tx_data = tx_data, .tx_size = 1U, .rx_data = rx_data, .rx_size = 6U, }; AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &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 AHT10_OK; } aht10_ret_t aht10_init(aht10_t *aht) { /* Check if we need initialization */ /* Delay 40ms after POR */ AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 40)); 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 AHT10_OK; } aht10_ret_t aht10_measure(aht10_t *aht, 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->user_data, 80)); 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 AHT10_FAIL; } #ifndef AHT10_SKIP_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 AHT10_OK; }