/**
* @brief HTS221 Calibration procedure * @retval HUM_TEMP_OK in case of success, an error code otherwise
*/
static HUM_TEMP_StatusTypeDef HTS221_Calibration(void)
{
/* Temperature Calibration */
/* Temperature in degree for calibration ( "/8" to obtain float) */
uint16_t T0_degC_x8_L, T0_degC_x8_H, T1_degC_x8_L, T1_degC_x8_H;
uint8_t H0_rh_x2, H1_rh_x2;
uint8_t tempReg[2] = {0, 0};
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, HTS221_T0_degC_X8_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T0_degC_x8_L = (uint16_t)tempReg[0];
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, HTS221_T1_T0_MSB_X8_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T0_degC_x8_H = (uint16_t) (tempReg[0] & 0x03);
T0_degC = ((float)((T0_degC_x8_H << 8) | (T0_degC_x8_L))) / 8;
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, HTS221_T1_degC_X8_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T1_degC_x8_L = (uint16_t)tempReg[0];
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, HTS221_T1_T0_MSB_X8_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T1_degC_x8_H = (uint16_t) (tempReg[0] & 0x0C);
T1_degC_x8_H = T1_degC_x8_H >> 2;
T1_degC = ((float)((T1_degC_x8_H << 8) | (T1_degC_x8_L))) / 8;
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, (HTS221_T0_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD), 2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T0_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
if(HTS221_IO_Read(tempReg, HTS221_ADDRESS, (HTS221_T1_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD), 2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T1_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
/* Humidity Calibration */
/* Humidity in degree for calibration ( "/2" to obtain float) */
if(HTS221_IO_Read(&H0_rh_x2, HTS221_ADDRESS, HTS221_H0_RH_X2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
if(HTS221_IO_Read(&H1_rh_x2, HTS221_ADDRESS, HTS221_H1_RH_X2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
if(HTS221_IO_Read(&tempReg[0], HTS221_ADDRESS, (HTS221_H0_T0_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD),
2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
H0_T0_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
if(HTS221_IO_Read(&tempReg[0], HTS221_ADDRESS, (HTS221_H1_T0_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD),
2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
H1_T0_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
H0_rh = ((float)H0_rh_x2) / 2;
H1_rh = ((float)H1_rh_x2) / 2;
return HUM_TEMP_OK;
}
/**
* @brief Read HTS221 output register, and calculate the humidity
* @param pfData the pointer to data output
* @retval HUM_TEMP_OK in case of success, an error code otherwise
*/
static HUM_TEMP_StatusTypeDef HTS221_GetHumidity(float* pfData)
{
int16_t H_T_out, humidity_t;
uint8_t tempReg[2] = {0, 0};
uint8_t tmp = 0x00;
float H_rh;
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
/* Output Data Rate selection */
tmp &= (HTS221_ODR_MASK);
if(tmp == 0x00)
{
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
/* Serial Interface Mode selection */
tmp &= ~(HTS221_ONE_SHOT_MASK);
tmp |= HTS221_ONE_SHOT_START;
if(HTS221_IO_Write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
do
{
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_STATUS_REG_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
}
while(!(tmp && 0x02));
}
if(HTS221_IO_Read(&tempReg[0], HTS221_ADDRESS, (HTS221_HUMIDITY_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD),
2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
H_T_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
H_rh = ( float )(((( H_T_out - H0_T0_out ) * ( H1_rh - H0_rh )) / ( H1_T0_out - H0_T0_out )) + H0_rh );
// Truncate to specific number of decimal digits 先乘后除为的是 保留有效的小数值可理解为四舍五入
humidity_t = (uint16_t)(H_rh * pow(10, HUM_DECIMAL_DIGITS)); /* 10^HUM_DECIMAL_DIGITS */
*pfData = ((float)humidity_t) / pow(10, HUM_DECIMAL_DIGITS);
// Prevent data going below 0% and above 100% due to linear interpolation
if ( *pfData < 0.0f ) *pfData = 0.0f;
if ( *pfData > 100.0f ) *pfData = 100.0f;
return HUM_TEMP_OK;
}
/**
* @brief Read HTS221 output register, and calculate the temperature
* @param pfData the pointer to data output
* @retval HUM_TEMP_OK in case of success, an error code otherwise
*/
static HUM_TEMP_StatusTypeDef HTS221_GetTemperature(float* pfData)
{
int16_t T_out, temperature_t;
uint8_t tempReg[2] = {0, 0};
uint8_t tmp = 0x00;
float T_degC;
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG1_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
/* Output Data Rate selection */
tmp &= (HTS221_ODR_MASK);
if(tmp == 0x00)
{
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
/* Serial Interface Mode selection */
tmp &= ~(HTS221_ONE_SHOT_MASK);
tmp |= HTS221_ONE_SHOT_START;
if(HTS221_IO_Write(&tmp, HTS221_ADDRESS, HTS221_CTRL_REG2_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
do
{
if(HTS221_IO_Read(&tmp, HTS221_ADDRESS, HTS221_STATUS_REG_ADDR, 1) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
}
while(!(tmp && 0x01)); /* 等待数据转换结束 */
}
if(HTS221_IO_Read(&tempReg[0], HTS221_ADDRESS, (HTS221_TEMP_OUT_L_ADDR | HTS221_I2C_MULTIPLEBYTE_CMD),
2) != HUM_TEMP_OK)
{
return HUM_TEMP_ERROR;
}
T_out = ((((int16_t)tempReg[1]) << 8) + (int16_t)tempReg[0]);
T_degC = ((float)(T_out - T0_out)) / (T1_out - T0_out) * (T1_degC - T0_degC) + T0_degC;
temperature_t = (int16_t)(T_degC * pow(10, TEMP_DECIMAL_DIGITS));
*pfData = ((float)temperature_t) / pow(10, TEMP_DECIMAL_DIGITS);
return HUM_TEMP_OK;
}