1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 
6 
7 #include "ulog/ulog.h"
8 #include "aos/hal/i2c.h"
9 #include <math.h>
10 #include <stdbool.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include "aos/kernel.h"
15 #include "sensor_drv_api.h"
16 #include "sensor_hal.h"
17 
18 #define SI7006_I2C_ADDRESS 0x40
19 #define SI7006_I2C_ADDR_TRANS(n) ((n) << 1)
20 #define SI7006_TAG     0x06
21 
22 #define SI7006_MEAS_REL_HUMIDITY_MASTER_MODE    0xE5
23 #define SI7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE 0xF5
24 #define SI7006_MEAS_TEMP_MASTER_MODE            0xE3
25 #define SI7006_MEAS_TEMP_NO_MASTER_MODE         0xF3
26 #define SI7006_READ_OLD_TEMP                    0xE0
27 #define SI7006_RESET                            0xFE
28 #define SI7006_READ_ID_LOW_0                    0xFA
29 #define SI7006_READ_ID_LOW_1                    0x0F
30 #define SI7006_READ_ID_HIGH_0                   0xFC
31 #define SI7006_READ_ID_HIGH_1                   0xC9
32 #define SI7006_READ_Firmware_Revision_0         0x84
33 #define SI7006_READ_Firmware_Revision_1         0xB8
34 
35 
36 i2c_dev_t SI7006_ctx = {
37     .port                 = 1,
38     .config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT,
39     .config.freq          = I2C_BUS_BIT_RATES_100K,
40     .config.mode          = I2C_MODE_MASTER,
41     .config.dev_addr      = SI7006_I2C_ADDRESS,
42 };
43 
44 
drv_temp_si_si7006_write(const void * buf,size_t len)45 static int drv_temp_si_si7006_write(const void *buf, size_t len)
46 {
47     return 0;
48 }
49 
drv_temp_si_si7006_read(void * buf,size_t len)50 static int drv_temp_si_si7006_read(void *buf, size_t len)
51 {
52     int          ret = 0;
53     size_t       size;
54     float      temp;
55     uint8_t      read_data[2] = {0};
56     unsigned int value;
57     temperature_data_t *pdata = (temperature_data_t *)buf;
58 
59     // printf("\n enter %s : %d\n", __func__, __LINE__);
60 
61     if (buf == NULL) {
62         return -1;
63     }
64     //printf("\n enter %s : %d\n", __func__, __LINE__);
65 
66     size = sizeof(temperature_data_t);
67     if (len < size) {
68         return -1;
69     }
70     //printf("\n enter %s : %d\n", __func__, __LINE__);
71     uint8_t  reg = SI7006_MEAS_TEMP_NO_MASTER_MODE;
72 
73     // hal_i2c_master_send(&SI7006_ctx, SI7006_ctx.config.dev_addr, &reg, 1, 1000);
74     ret = sensor_drv_i2c_master_send(&SI7006_ctx, &reg, 1, 1000);
75     if (ret < 0) {
76         LOG("%s Error on i2c master send\n", SENSOR_STR);
77         return -1;
78     }
79 
80     aos_msleep(30);
81     // hal_i2c_master_recv(&SI7006_ctx, SI7006_ctx.config.dev_addr, read_data, 2, 1000);
82     ret = sensor_drv_i2c_master_recv(&SI7006_ctx, read_data, 2, 1000);
83     if (ret < 0) {
84         LOG("%s Error on i2c master recv\n", SENSOR_STR);
85         return -1;
86     }
87     value = (read_data[0] << 8) | read_data[1];
88     //LOGI("APP", "%0x -- %0x -->0x%x\n", read_data[0], read_data[1], value);
89     //LOG("%s %0x -- %0x -->0x%x\n", SENSOR_STR, read_data[0], read_data[1], value);
90     // A temperature measurement will always return XXXXXX00 in the LSB field.
91     if (value & 0xFFFC) {
92         temp = (175.72f * (float)value) / 65536.0f - 46.85f;
93         //LOGI("APP", "temperature: %2f\n", temp);
94         LOG("%s temperature: %2f\n", SENSOR_STR, temp);
95         pdata->t = (int)(temp * 10);
96         pdata->timestamp = aos_now_ms();
97     } else {
98         LOG("%s Error on temp\n", SENSOR_STR);
99         return -1;
100     }
101     return (int)size;
102 }
103 
drv_temp_si_si7006_ioctl(int cmd,unsigned long arg)104 static int drv_temp_si_si7006_ioctl(int cmd, unsigned long arg)
105 {
106 
107 }
108 
drv_temp_si_si7006_irq_handle(void)109 static void drv_temp_si_si7006_irq_handle(void)
110 {
111     /* no handle so far */
112 }
113 
drv_temp_si_si7006_close(void)114 static int drv_temp_si_si7006_close(void)
115 {
116 #if 0
117     int ret = 0;
118     ret     = drv_temp_si_si7006_set_power_mode(&SI7006_ctx, DEV_POWER_OFF);
119     if (unlikely(ret)) {
120         return -1;
121     }
122 #endif
123     LOG("%s %s successfully \n", SENSOR_STR, __func__);
124     return 0;
125 }
126 
drv_temp_si_si7006_open(void)127 static int drv_temp_si_si7006_open(void)
128 {
129 #if 0
130     int ret = 0;
131     ret     = drv_temp_si_si7006_set_power_mode(&SI7006_ctx, DEV_POWER_ON);
132     if (unlikely(ret)) {
133         return -1;
134     }
135 #endif
136     LOG("%s %s successfully \n", SENSOR_STR, __func__);
137     return 0;
138 }
139 
drv_temp_si_si7006_init(void)140 int drv_temp_si_si7006_init(void)
141 {
142     int          ret = 0;
143     sensor_obj_t sensor;
144 
145     memset(&sensor, 0, sizeof(sensor));
146 
147     /* fill the sensor obj parameters here */
148     sensor.tag        = TAG_DEV_TEMP;
149     sensor.path       = dev_temp_path;
150     sensor.io_port    = I2C_PORT;
151     sensor.open       = drv_temp_si_si7006_open;
152     sensor.close      = drv_temp_si_si7006_close;
153     sensor.read       = drv_temp_si_si7006_read;
154     sensor.write      = drv_temp_si_si7006_write;
155     sensor.ioctl      = drv_temp_si_si7006_ioctl;
156     sensor.irq_handle = drv_temp_si_si7006_irq_handle;
157 
158     ret = sensor_create_obj(&sensor);
159     if (unlikely(ret)) {
160         return -1;
161     }
162 
163     /* update the phy sensor info to sensor hal */
164     LOG("%s %s successfully \n", SENSOR_STR, __func__);
165     return 0;
166 }
167 
168 
drv_humi_si_si7006_write(const void * buf,size_t len)169 static int drv_humi_si_si7006_write(const void *buf, size_t len)
170 {
171     return 0;
172 }
173 
drv_humi_si_si7006_read(void * buf,size_t len)174 static int drv_humi_si_si7006_read(void *buf, size_t len)
175 {
176     int          ret = 0;
177     size_t       size;
178     uint8_t      read_data[3] = {0};
179     unsigned int value;
180     float          humi;
181     uint8_t  reg  = SI7006_MEAS_REL_HUMIDITY_NO_MASTER_MODE;
182 
183     humidity_data_t *pdata = (humidity_data_t *)buf;
184 
185     //printf("\n enter %s : %d\n", __func__, __LINE__);
186 
187     if (buf == NULL) {
188         return -1;
189     }
190     //printf("\n enter %s : %d\n", __func__, __LINE__);
191 
192     size = sizeof(humidity_data_t);
193     if (len < size) {
194         return -1;
195     }
196     //printf("\n enter %s : %d\n", __func__, __LINE__);
197 
198     // hal_i2c_master_send(&SI7006_ctx, SI7006_ctx.config.dev_addr, &reg, 1, 1000);
199     ret = sensor_drv_i2c_master_send(&SI7006_ctx, &reg, 1, 1000);
200     if (ret < 0) {
201         LOG("%s Error on i2c master send\n", SENSOR_STR);
202         return -1;
203     }
204     aos_msleep(30);
205 
206     // hal_i2c_master_recv(&SI7006_ctx, SI7006_ctx.config.dev_addr, read_data, 2, 1000);
207     ret = sensor_drv_i2c_master_recv(&SI7006_ctx, read_data, 2, 1000);
208     if (ret < 0) {
209         LOG("%s Error on i2c master recv\n", SENSOR_STR);
210         return -1;
211     }
212     value = (read_data[0] << 8) | read_data[1];
213     //LOGI("APP", "%0x -- %0x -->0x%x\n", read_data[0], read_data[1], value);
214     if (value & 0xFFFE) {
215         humi = ((125.0f * (float)value) / 65535.0f) - 6.0f;
216         LOG("%s humidity: %2f\n", SENSOR_STR, humi);
217         pdata->h = (int)(humi * 10);
218         pdata->timestamp = aos_now_ms();
219 
220     } else {
221         LOG("%s Error on humidity\n", SENSOR_STR);
222         return 1;
223     }
224     return (int)size;
225 }
226 
drv_humi_si_si7006_ioctl(int cmd,unsigned long arg)227 static int drv_humi_si_si7006_ioctl(int cmd, unsigned long arg)
228 {
229 
230 }
231 
drv_humi_si_si7006_irq_handle(void)232 static void drv_humi_si_si7006_irq_handle(void)
233 {
234     /* no handle so far */
235 }
236 
drv_humi_si_si7006_close(void)237 static int drv_humi_si_si7006_close(void)
238 {
239 #if 0
240     int ret = 0;
241     ret     = drv_temp_si_si7006_set_power_mode(&SI7006_ctx, DEV_POWER_OFF);
242     if (unlikely(ret)) {
243         return -1;
244     }
245 #endif
246     LOG("%s %s successfully \n", SENSOR_STR, __func__);
247     return 0;
248 }
249 
drv_humi_si_si7006_open(void)250 static int drv_humi_si_si7006_open(void)
251 {
252 #if 0
253     int ret = 0;
254     ret     = drv_temp_si_si7006_set_power_mode(&SI7006_ctx, DEV_POWER_ON);
255     if (unlikely(ret)) {
256         return -1;
257     }
258 #endif
259     LOG("%s %s successfully \n", SENSOR_STR, __func__);
260     return 0;
261 }
262 
drv_humi_si_si7006_init(void)263 int drv_humi_si_si7006_init(void)
264 {
265 
266     int          ret = 0;
267     sensor_obj_t sensor;
268 
269     memset(&sensor, 0, sizeof(sensor));
270     /* fill the sensor obj parameters here */
271     sensor.tag        = TAG_DEV_HUMI;
272     sensor.path       = dev_humi_path;
273     sensor.io_port    = I2C_PORT;
274     sensor.open       = drv_humi_si_si7006_open;
275     sensor.close      = drv_humi_si_si7006_close;
276     sensor.read       = drv_humi_si_si7006_read;
277     sensor.write      = drv_humi_si_si7006_write;
278     sensor.ioctl      = drv_humi_si_si7006_ioctl;
279     sensor.irq_handle = drv_humi_si_si7006_irq_handle;
280 
281     ret = sensor_create_obj(&sensor);
282     if (unlikely(ret)) {
283         return -1;
284     }
285 
286     LOG("%s %s successfully \n", SENSOR_STR, __func__);
287 
288     return 0;
289 }
290 
291 SENSOR_DRV_ADD(drv_temp_si_si7006_init);
292 SENSOR_DRV_ADD(drv_humi_si_si7006_init);
293 
294