/**
* @file AHT20_ATY.c
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2023 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief Familiar functions of AHT20 for all embedded device
*
* @version
* - 1_01_220804 > ATY
* -# Preliminary version, first Release
* - 1_02_220901 > ATY
* -# Init tmp to zero, test AHT20_Init()
********************************************************************************
*/
#ifndef __AHT20_ATY_C
#define __AHT20_ATY_C
#include "AHT20_ATY.h"
/******************************* For user *************************************/
/******************************************************************************/
/**
* @brief AHT20 soft reset
*/
void AHT20_SoftReset(void)
{
uint8_t temp_uint8 = 0;
I2C_WriteReg(ATH20_ADDRESS, AHT20_SOFT_RST, &temp_uint8, 0);
}
/**
* @brief read AHT20 status reg
* @return reg data
*/
uint8_t AHT20_ReadStatusCmd(void)
{
uint8_t temp_uint8 = 0;
I2C_ReadReg(ATH20_ADDRESS, AHT20_STATUS, &temp_uint8, 1);
return temp_uint8;
}
/**
* @brief AHT20 chip initialization
*/
void AHT20_IcInitCmd(void)
{
const uint8_t temp_uint8[2] = {0x08, 0x00};
// temp_uint8[0] = 0x00;
// temp_uint8[1] = 0x00;
// I2C_WriteReg(ATH20_ADDRESS, AHT20_NOR_MODE, temp_uint8, 2);
// temp_uint8[0] = 0x08;
// temp_uint8[1] = 0x00;
I2C_WriteReg(ATH20_ADDRESS, AHT20_INIT, temp_uint8, 2);
// I2C_WriteReg(ATH20_ADDRESS, 0xE1, temp_uint8, 2);
}
/**
* @brief get AHT20 busy flag
* @return busy flag: 1 - busy, 0 - leisure
*/
uint8_t AHT20_ReadBusyCmd(void)
{
uint8_t temp_uint8 = 0;
temp_uint8 = AHT20_ReadStatusCmd();
return (temp_uint8 >> 7) & 0x01;
}
/**
* @brief read AHT20 calibration enable
* @return calibration state: 1 - calibrate done, 0 - not calibrated
*/
uint8_t AHT20_ReadCalEnableCmd(void)
{
uint8_t temp_uint8 = 0;
temp_uint8 = AHT20_ReadStatusCmd();
return (temp_uint8 >> 3) & 0x01;
}
/**
* @brief AHT20 measure command
*/
void AHT20_TrigMeasure(void)
{
const uint8_t temp_uint8[2] = {0x33, 0x00};
// temp_uint8[0] = 0x33;
// temp_uint8[1] = 0x00;
I2C_WriteReg(ATH20_ADDRESS, AHT20_TRIG_MEASURE, temp_uint8, 2);
}
/**
* @brief AHT20 measure command
* @param data_t group to save origin reg data
*/
void AHT20_ReadData(uint8_t* data_t)
{
I2C_Start();
I2C_WriteRegByte(ATH20_ADDRESS << 1 | 1);
I2C_WaitAck(I2C_WAIT_ACK_TIME);
data_t[0] = I2C_ReadByte(1);
data_t[1] = I2C_ReadByte(1);
data_t[2] = I2C_ReadByte(1);
data_t[3] = I2C_ReadByte(1);
data_t[4] = I2C_ReadByte(1);
data_t[5] = I2C_ReadByte(0);
I2C_Stop();
}
/**
* @brief reset AHT20 reg setting
* @param addr reg address
* @note generally not needed
*/
void AHT20_RegReset(uint8_t addr)
{
uint8_t temp_uint8[3] = {0};
temp_uint8[0] = 0x00;
temp_uint8[1] = 0x00;
temp_uint8[2] = 0x00;
I2C_WriteReg(ATH20_ADDRESS, addr, temp_uint8, 2);
DelayMs(5);
I2C_ReadReg(ATH20_ADDRESS, AHT20_STATUS, temp_uint8, 3);
DelayMs(10);
I2C_WriteReg(ATH20_ADDRESS, 0xB0 | addr, temp_uint8 + 1, 2);
}
/**
* @brief reset AHT20 reg setting
* @note generally not needed
*/
void AHT20_RegInit(void)
{
AHT20_RegReset(0x1B);
AHT20_RegReset(0x1C);
AHT20_RegReset(0x1D);
}
/**
* @brief AHT20 all initialize
* @return errCode, 0: success, !0: error
*/
uint8_t AHT20_Init(void)
{
uint8_t errCount = 5;
while(errCount--)
{
DelayMs(40); // wait time after power on
if((AHT20_ReadStatusCmd() & 0x18) != 0x18)
{
AHT20_SoftReset();
AHT20_IcInitCmd();
AHT20_RegInit();
DelayMs(10);
continue;
}
else
break;
}
if(errCount == 0)
return 1;
errCount = 5;
while(errCount--)
{
// check if calibrate over
if(AHT20_ReadCalEnableCmd() == 0)
{
DelayMs(10);
// if not calibrated, reset to retry
AHT20_IcInitCmd();
// AHT20_SoftReset();
DelayMs(200); // time not sure
}
else
break;
}
if(errCount == 0)
return 2;
return 0;
}
/*
0x1C 93 61 76 05 42
TEM:25.2HUM:57.5
*/
/**
* @brief read and split data to origin hum & tem
* @param ht group to save hum & tem data
* @return errCode, 0: success, !0: error
*/
uint8_t AHT20_ReadHT(uint32_t* ht)
{
uint8_t errCount = 5;
uint8_t temp_uint8[6] = {0};
uint32_t RetuData = 0;
AHT20_TrigMeasure();
while(errCount--)
{
// wait 75ms for measure finished, busy flag Bit7 set to 0
DelayMs(80);
AHT20_ReadData(temp_uint8);
if((temp_uint8[0] & 0x68) == 0x08)
{
// origin hum data
RetuData = temp_uint8[1];
RetuData = (RetuData << 8) | temp_uint8[2];
RetuData = (RetuData << 8) | temp_uint8[3];
RetuData = RetuData >> 4;
ht[0] = RetuData;
// origin tem data
RetuData = temp_uint8[3] & 0x0F;
RetuData = (RetuData << 8) | temp_uint8[4];
RetuData = (RetuData << 8) | temp_uint8[5];
ht[1] = RetuData;
return 0;
}
}
return 1;
}
/**
* @brief calculate result from 20bit origin data, RH=%, T=C
* @param ht input origin data, always bigger than 0
* @param aht float data after calculate
* @return errCode, 0: success, 1: out of range
*/
uint8_t AHT20_CalcResult(uint32_t* ht, float* aht)
{
aht[0] = (double)ht[0] * 100 / 1024 / 1024; // hum
aht[1] = (double)ht[1] * 200 / 1024 / 1024; // tem
// limit data range, RH = 0~100%, Temperature = -40~85C(+50)
if((aht[0] >= 0) && (aht[0] <= 100) && (aht[1] >= 10) && (aht[1] <= 135))
return 0;
else
return 1;
}
/**
* @brief calculate result from 20bit origin data, RH=%, T=C
* @param ht data group to save th value
* @return errCode, 0: success, !0: error
*/
uint8_t AHT20_InitFlag = 0;
uint8_t AHT20_TemHumGet(uint16_t* ht)
{
if(AHT20_InitFlag == 0)
{
if(AHT20_Init() == 1)
{
AHT20_InitFlag = 2; // init fail
}
else
{
AHT20_InitFlag = 1;
}
}
if(AHT20_InitFlag == 2)
{
#ifdef __DEBUG_AHT20_ATY
printf("\r\n0xFF");
#endif /* __DEBUG_AHT20_ATY */
return 0xFF;
}
else if(AHT20_InitFlag == 1)
{
// Init success
uint32_t tempHT_uint32[2] = {0};
float tempHT_f[2] = {0};
if(AHT20_ReadHT(tempHT_uint32) == 0)
{
if((tempHT_uint32[0] && tempHT_uint32[1]) != 0)
{
AHT20_CalcResult(tempHT_uint32, tempHT_f);
ht[0] = ((tempHT_f[0] * 1000) + 5) / 10;
ht[1] = ((tempHT_f[1] * 1000) + 5) / 10;
#ifdef __DEBUG_AHT20_ATY
printf("\r\nHum: %.2f - Tem: %.2f", tempHT_f[0], tempHT_f[1] - 50);
#endif /* __DEBUG_AHT20_ATY */
}
else
{
#ifdef __DEBUG_AHT20_ATY
printf("\r\n0xFD");
#endif /* __DEBUG_AHT20_ATY */
return 0xFD;
}
}
else
{
#ifdef __DEBUG_AHT20_ATY
printf("\r\n0xFE");
#endif /* __DEBUG_AHT20_ATY */
return 0xFE;
}
}
return 0;
}
#endif /* __AHT20_ATY_C */
/******************************** End Of File *********************************/