1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "drv_temp_humi_si_si7006.h"
6 #include "aos/kernel.h"
7 #include "ulog/ulog.h"
8 #include <math.h>
9 #include <stdlib.h>
10 
11 /*========================================================================*/
12 /*                           PUBLIC FUNCTIONS                             */
13 /*========================================================================*/
14 #define SI7006_I2C_PORT 1
15 
si7006_i2c_master_send(const uint8_t * data,uint16_t size,uint32_t timeout)16 int32_t si7006_i2c_master_send(const uint8_t *data, uint16_t size, uint32_t timeout)
17 {
18     return sensor_i2c_master_send(SI7006_I2C_PORT, SI7006_ADDRESS, data, size, timeout);
19 }
20 
si7006_i2c_master_recv(uint8_t * data,uint16_t size,uint32_t timeout)21 int32_t si7006_i2c_master_recv(uint8_t *data, uint16_t size, uint32_t timeout)
22 {
23     return sensor_i2c_master_recv(SI7006_I2C_PORT, SI7006_ADDRESS, data, size, timeout);
24 }
25 
si7006_init(void)26 void si7006_init(void)
27 {
28     int32_t ret = sensor_i2c_open(SI7006_I2C_PORT, SI7006_ADDRESS, I2C_BUS_BIT_RATES_400K, 0);
29     if (ret) {
30         printf("sensor i2c open failed, ret:%d\n", ret);
31         return;
32     }
33 }
34 
si7006_getVer(void)35 uint8_t si7006_getVer(void)
36 {
37     uint8_t reg[2]  = {SI7006_READ_Firmware_Revision_0,
38                        SI7006_READ_Firmware_Revision_1
39                       };
40     uint8_t version = 0;
41 
42     si7006_i2c_master_send(reg, 2, 1000);
43     aos_msleep(30);
44     si7006_i2c_master_recv(&version, 1, 1000);
45     // LOGI("SENSOR","ver:0x%2x\n",version);
46     return version;
47 }
48 
si7006_getID(uint8_t * id_buf)49 void si7006_getID(uint8_t *id_buf)
50 {
51     uint8_t reg[4] = {SI7006_READ_ID_LOW_0, SI7006_READ_ID_LOW_1,
52                       SI7006_READ_ID_HIGH_0, SI7006_READ_ID_HIGH_1
53                      };
54 
55     si7006_i2c_master_send(reg, 2, 1000);
56     aos_msleep(30);
57     si7006_i2c_master_recv(id_buf, 4, 1000);
58 
59     si7006_i2c_master_send(&reg[2], 2, 1000);
60     aos_msleep(30);
61     si7006_i2c_master_recv(&id_buf[4], 4, 1000);
62 
63     return;
64 }
65 
si7006_getTemperature(float * temperature)66 bool si7006_getTemperature(float *temperature)
67 {
68     uint8_t      reg          = SI7006_MEAS_TEMP_NO_MASTER_MODE;
69     uint8_t      read_data[2] = {0};
70     unsigned int value;
71 
72     si7006_i2c_master_send(&reg, 1, 1000);
73     aos_msleep(30);
74     si7006_i2c_master_recv(read_data, 2, 1000);
75     value = (read_data[0] << 8) | read_data[1];
76     LOGI("SENSOR", "%0x -- %0x -->0x%x\n", read_data[0], read_data[1], value);
77     // A temperature measurement will always return XXXXXX00 in the LSB field.
78     if (value & 0xFFFC) {
79         *temperature = (175.72f * (float)value) / 65536.0f - 46.85f;
80         LOGI("SENDOR", "temperature: %2f\n", *temperature);
81     } else {
82         LOGE("SENDOR", "Error on temp\n");
83         return 1;
84     }
85     return 0;
86 }
87 
88 /*
89 i2c – the i2c device
90 dev_addr – device address
91 mem_addr – mem address
92 mem_addr_size – mem address
93 data – i2c master send data
94 size – i2c master send data size
95 */
si7006_getHumidity(float * humidity)96 bool si7006_getHumidity(float *humidity)
97 {
98     uint8_t      reg          = SI7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE;
99     uint8_t      read_data[3] = {0};
100     unsigned int value;
101 
102     si7006_i2c_master_send(&reg, 1, 1000);
103 
104     aos_msleep(30);
105 
106     si7006_i2c_master_recv(read_data, 2, 1000);
107     value = (read_data[0] << 8) | read_data[1];
108     LOGI("SENSOR", "%0x -- %0x -->0x%x\n", read_data[0], read_data[1], value);
109     if (value & 0xFFFE) {
110         *humidity = ((125.0f * (float)value) / 65535.0f) - 6.0f;
111         LOGI("SENDOR", "humidity: %f\n", *humidity);
112     } else {
113         LOGE("SENDOR", "Error on humidity\n");
114         return 1;
115     }
116     return 0;
117 }
118 
119 // get temp and humidity
si7006_getTempHumidity(float * humidity,float * temperature)120 void si7006_getTempHumidity(float *humidity, float *temperature)
121 {
122     si7006_getTemperature(temperature);
123     si7006_getHumidity(humidity);
124 }
125 
126 
si7006_deinit(void)127 void si7006_deinit(void)
128 {
129     int32_t ret = sensor_i2c_close(SI7006_I2C_PORT);
130     if (ret) {
131         LOGE("SENSOR", "sensor i2c close failed, ret:%d\n", ret);
132     }
133 
134     return;
135 }
136