/**********************************************************************
|
* Copyright: (C)2023 LingYun IoT System Studio
|
* Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292
|
* Description: ISKBoard SHT20 R&H sensor Hardware Abstract Layer driver
|
*
|
* ChangeLog:
|
* Version Date Author Description
|
* V1.0.0 2023.04.3 GuoWenxue Release initial version
|
***********************************************************************/
|
|
#include <sht20.h>
|
#include <stdio.h>
|
#include <string.h>
|
|
#define delay_ms(x) HAL_Delay(x)
|
|
enum
|
{
|
TRIG_T_MEASUREMENT_HM = 0xE3, // command trig. temp meas. hold master
|
TRIG_RH_MEASUREMENT_HM = 0xE5, // command trig. humidity meas. hold master
|
TRIG_T_MEASUREMENT_POLL = 0xF3, // command trig. temp meas. no hold master
|
TRIG_RH_MEASUREMENT_POLL = 0xF5, // command trig. humidity meas. no hold master
|
USER_REG_W = 0xE6, // command writing user register
|
USER_REG_R = 0xE7, // command reading user register
|
SOFT_RESET = 0xFE // command soft reset
|
};
|
|
|
//#define CONFIG_SHT2X_DEBUG
|
|
#ifdef CONFIG_SHT2X_DEBUG
|
static inline void dump_buf(uint8_t *buf, uint32_t size)
|
{
|
int i;
|
|
if(!buf)
|
return ;
|
|
for(i=0; i<size; i++)
|
printf("%02x ", buf[i]);
|
|
printf("\r\n");
|
}
|
#endif
|
|
#ifdef CONFIG_SHT2X_DEBUG
|
#define sht2x_print(format,args...) printf(format, ##args)
|
#else
|
#define sht2x_print(format,args...) do{} while(0);
|
#endif
|
|
|
static int sht2x_measure_value(uint8_t command, uint16_t *val);
|
static int sht2x_softreset(void);
|
|
|
uint32_t sht20_sample_TrH(uint32_t *temperature, uint32_t *humdity)
|
{
|
uint16_t sT;
|
uint16_t sRH;
|
uint32_t T;
|
uint32_t RH;
|
uint32_t TRH=TRH_FAIL_VAL;
|
|
i2c_term(SHT2X_I2CBUS);
|
|
if( i2c_init(SHT2X_I2CBUS, SHT2X_CHIPADDR) )
|
{
|
sht2x_print("SHT20 initial I2C bus failed.\r\n");
|
return TRH;
|
}
|
|
if( sht2x_softreset() )
|
{
|
sht2x_print("SHT20 soft reset failed.\r\n");
|
goto OUT;
|
}
|
|
sht2x_print("Start to measurement temperature...\r\n");
|
if( sht2x_measure_value(TRIG_T_MEASUREMENT_POLL, &sT) < 0 )
|
{
|
sht2x_print("I2C measurement failed\r\n");
|
goto OUT;
|
}
|
|
T=(uint32_t)(100*(float)((175.72*sT)/65536-46.85));
|
sht2x_print("Measure temperature: %lu.%lu\r\n", T/100, T%100);
|
if( temperature )
|
*temperature=T;
|
|
TRH = ((T/100)<<8|(T%100))<<16 | 0xFFFF;
|
|
sht2x_print("Start to measurement relative humidity...\r\n");
|
if( sht2x_measure_value(TRIG_RH_MEASUREMENT_POLL, &sRH) < 0 )
|
{
|
goto OUT;
|
}
|
|
RH=(uint32_t)(100*(float)((125*sRH)/65535-6.0));
|
sht2x_print("Measure relative humidity: %lu.%lu%%\r\n", RH/100, RH%100);
|
if( humdity )
|
*humdity=RH;
|
|
TRH &= 0xFFFF0000 | ((uint16_t)RH/100)<<8 | ((uint16_t)RH%100) ;
|
|
OUT:
|
i2c_term(SHT2X_I2CBUS);
|
return TRH;
|
}
|
|
int sht2x_softreset(void)
|
{
|
uint8_t command = SOFT_RESET;
|
int rv = 0;
|
|
sht2x_print("Start soft reset sht2x\r\n");
|
rv=i2c_write(SHT2X_I2CBUS, &command, 1);
|
|
if( rv )
|
{
|
sht2x_print("SHT2X send soft reset command 0x%0x failure: rv=0x%02x\r\n", command, rv);
|
return -rv;
|
}
|
|
delay_ms(15);
|
return 0;
|
}
|
|
static int sht2x_checkcrc(uint8_t *data, uint8_t bytes, uint8_t checksum)
|
{
|
uint8_t crc = 0;
|
uint8_t i;
|
uint8_t bit;
|
|
//calculates 8-Bit checksum with given polynomial
|
for (i=0; i<bytes; ++i)
|
{
|
crc ^= (data[i]);
|
for (bit=8; bit>0; --bit)
|
{
|
if (crc & 0x80)
|
crc = (crc << 1) ^ 0x0131; //POLYNOMIAL;
|
else
|
crc = (crc << 1);
|
}
|
}
|
|
if (crc != checksum)
|
{
|
return -1;
|
}
|
else
|
{
|
return 0;
|
}
|
}
|
|
static int sht2x_measure_value(uint8_t command, uint16_t *val)
|
{
|
uint8_t buf[3]; /* I2C������buffer */
|
int count=4; /* �ܹ����Ĵ��� */
|
|
if( !val )
|
{
|
sht2x_print("SHT2X invalid input arguments\r\n");
|
return -1;
|
}
|
|
if(TRIG_T_MEASUREMENT_POLL!=command && TRIG_RH_MEASUREMENT_POLL !=command )
|
{
|
sht2x_print("SHT2X unsupport command: 0x%0x\r\n", command);
|
return -2;
|
}
|
|
if( NO_ERROR != i2c_write(SHT2X_I2CBUS, &command, 1) )
|
{
|
sht2x_print("SHT2X send measure command 0x%0x failure\r\n", command);
|
return -3;
|
}
|
|
if(TRIG_T_MEASUREMENT_POLL == command)
|
delay_ms(85);
|
else
|
delay_ms(29);
|
|
while(count--)
|
{
|
memset(buf, 0, 3);
|
|
if( !i2c_read(SHT2X_I2CBUS, buf, 3) )
|
{
|
break;
|
}
|
delay_ms(5);
|
}
|
|
if( sht2x_checkcrc(buf, 2, buf[2])< 0 )
|
{
|
#ifdef CONFIG_SHT2X_DEBUG
|
sht2x_print("Measurement data checksum failure:\r\n");
|
dump_buf(buf, 3);
|
#endif
|
return -4;
|
}
|
|
if(TRIG_T_MEASUREMENT_POLL == command)
|
*val = buf[0]<<8|(buf[1]&0xFC); //14bits(1111 1100)
|
else
|
*val = buf[0]<<8|(buf[1]&0xFF); //12bits(1100 0000)
|
|
sht2x_print("Measurement temperature value: 0x%04x\r\n", *val);
|
|
return 0;
|
}
|