guowenxue
2021-08-29 77ddd4a0943e2f9935bec2e00fffacec370cc1aa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * sht30.c
 *
 *  Created on: Aug 9, 2021
 *      Author: Think
 */
 
#include <stdio.h>
#include "stm32l4xx_hal.h"
#include "sht30.h"
 
//#define CONFIG_GPIO_I2C
 
#ifdef CONFIG_GPIO_I2C
#include "gpio_i2c_sht30.h"
#else
#include "i2c.h"
#endif
 
//#define CONFIG_SHT30_DEBUG
 
#ifdef CONFIG_SHT30_DEBUG
#define sht30_print(format,args...) printf(format, ##args)
#else
#define sht30_print(format,args...) do{} while(0)
#endif
 
static int sht30_send_cmd(SHT30_CMD cmd)
{
    uint8_t buf[2];
 
    buf[0] = cmd >> 8;
    buf[1] = cmd;
 
#ifdef CONFIG_GPIO_I2C
    return I2C_Master_Transmit(SHT30_ADDR_WR, (uint8_t*)buf, 2);
#else
    return HAL_I2C_Master_Transmit(&hi2c2, SHT30_ADDR_WR, (uint8_t*)buf, 2, 0xFFFF);
#endif
}
 
 
static void sht30_soft_reset(void)
{
     sht30_send_cmd(SOFT_RESET_CMD);
 
     HAL_Delay(1);
}
 
 
static int sht30_single_shot_measurement(uint8_t *buf, uint8_t buf_size)
{
    uint16_t      cmd = HIGH_ENABLED_CMD;  /* High with clock stretching */
    uint8_t       rv;
 
    if( !buf || buf_size<SHT30_DATA_SIZE )
    {
        sht30_print("%s(): Invalid input arguments\n", __func__);
        return -1;
    }
 
    rv = sht30_send_cmd(cmd);
    if( rv )
    {
        sht30_print("ERROR: SHT30 send measurement command failure, rv=%d\n", rv);
        sht30_soft_reset();
        return -2;
    }
 
#ifdef CONFIG_GPIO_I2C
    rv = I2C_Master_Receive(SHT30_ADDR_RD, buf, SHT30_DATA_SIZE);
#else
    rv = HAL_I2C_Master_Receive(&hi2c2, SHT30_ADDR_RD, buf, SHT30_DATA_SIZE, 0xFFFF);
#endif
    if(rv)
    {
        sht30_print("ERROR: SHT30 read measurement result failure, rv=%d\n", rv);
        return -3;
    }
 
    return 0;
}
 
 
static uint8_t sht30_crc8(const uint8_t *data, int len)
{
     const uint8_t     POLYNOMIAL = 0x31;   /* SHT30 CRC8 Polynomial:  0x31=x8 + x5 + x4 + 1  */
     uint8_t           crc = 0xFF;          /* SHT30 CRC8 Initialization: 0xFF */
     int               i, j;
 
     for (i=0; i<len; ++i)
     {
         crc ^= *data++;
 
         for (j=0; j<8; ++j)
        {
            crc = ( crc & 0x80 )? (crc << 1) ^ POLYNOMIAL: (crc << 1);
           }
       }
 
     return crc;
}
 
 
int SHT30_SampleData(float *temperature, float *humidity)
{
    uint8_t             buf[SHT30_DATA_SIZE];
    int                 rv;
 
    uint16_t            temp;
    uint16_t            humd;
    uint8_t             crc;
 
    if(!temperature || !humidity)
    {
        sht30_print("%s(): Invalid input arguments\n", __func__);
        return -1;
    }
 
    sht30_print("SHT30 start single short measurement\n");
    rv = sht30_single_shot_measurement(buf, SHT30_DATA_SIZE);
    if( rv )
    {
        sht30_print("SHT30 Single Short measurement failure, rv=%d\n", rv);
        return -2;
    }
 
#ifdef CONFIG_SHT30_DEBUG
    {
        int          i;
 
        sht30_print("SHT30 get %d bytes sample data: \n", SHT30_DATA_SIZE);
        for(i=0; i<SHT30_DATA_SIZE; i++)
        {
            sht30_print("0x%02x ", buf[i]);
        }
        sht30_print("\n");
    }
#endif
 
    /* byte[0-1] is temperature value, and byte[2] is temperature CRC */
    crc = sht30_crc8(buf, 2);
    sht30_print("SHT30 temperature Cal_CRC: [%02x] EXP_CRC: [%02x]\n", crc, buf[2]);
    if( crc != buf[2])
    {
        sht30_print("SHT30 measurement temperature got CRC error\n");
        return -3;
    }
 
    /* byte[3-4] is humidity value, and byte[5] is humidity CRC */
    crc = sht30_crc8(&buf[3], 2);
    sht30_print("SHT30 humidity Cal_CRC: [%02x] EXP_CRC: [%02x]\n", crc, buf[5]);
    if( crc != buf[5])
    {
        sht30_print("SHT30 measurement temperature got CRC error\n");
        return -4;
    }
 
    temp = (buf[0]<<8) | buf[1];
    humd = (buf[3]<<8) | buf[4];
 
    *temperature = -45 + 175*((float)temp/65535);
    *humidity = 100 * ((float)humd / 65535);
 
    return 0;
}