• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Unionman Technology Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <sys/ioctl.h>
22 
23 #include <linux/i2c.h>
24 #include <linux/i2c-dev.h>
25 
26 #include "securec.h"
27 #include "hilog/log.h"
28 
29 #include "i2cinterface.h"
30 
31 /* 函数返回值说明 return 0 代表正常运行     return -1 代表驱动无法打开
32                  return -2 代表分配缓存失败 return -3 代表读取/写入失败
33                  return -4 代表CRC校验失败  return -5 代表保存数据失败  */
34 
35 // 转换温湿度并保存在结构体中
ConvertTempAndHum(sRHAndTemp_t * tempRH,uint8_t * rawTemp,uint8_t * rawHum)36 void ConvertTempAndHum(sRHAndTemp_t *tempRH, uint8_t *rawTemp, uint8_t *rawHum)
37 {
38     tempRH->TemperatureC = ConvertTemperature(rawTemp);
39     tempRH->Humidity = ConvertHumidity(rawHum);
40     tempRH->TemperatureF = 1.8f * tempRH->TemperatureC + 32L;
41 }
42 
43 // 温度转换函数
ConvertTemperature(uint8_t * rawTemp)44 float ConvertTemperature(uint8_t *rawTemp)
45 {
46     uint16_t rawValue = 0;
47     rawValue = rawTemp[0];
48     rawValue = (rawValue << 8L) | rawTemp[1];
49     return 175.0f * (float)rawValue / 65535.0f - 45.0f;
50 }
51 
52 // 湿度转换函数
ConvertHumidity(uint8_t * rawHum)53 float ConvertHumidity(uint8_t *rawHum)
54 {
55     uint16_t rawValue = 0;
56     rawValue = rawHum[0];
57     rawValue = (rawValue << 8L) | rawHum[1];
58     return 100.0f * (float)rawValue / 65535.0f;
59 }
60 
61 // CRC校验
CheckCrc(uint8_t * data)62 uint8_t CheckCrc(uint8_t *data)
63 {
64     uint8_t bit = 0;
65     uint8_t crc = 0xFF;
66 
67     for (uint8_t dataCounter = 0; dataCounter < 2L; dataCounter++) {
68         crc ^= (data[dataCounter]);
69         for (bit = 8L; bit > 0; --bit) {
70             if (crc & 0x80) {
71                 crc = (crc << 1) ^ 0x31;
72             } else {
73                 crc = (crc << 1);
74             }
75         }
76     }
77     return crc;
78 }
79 
SoftReset(char * devName,char addr)80 int SoftReset(char *devName, char addr)
81 {
82     int fd = -1;
83     int ret = -1;
84     uint8_t _pBuf[2L] = {0};
85 
86     struct i2c_rdwr_ioctl_data i2c_data;
87 
88     // 关闭周期测量
89     SendCommand(devName, addr, SHT3X_CMD_STOP_PERIODIC_ACQUISITION_MODE);
90     usleep(50L * 1000L); // 等待发送控制命令完成
91 
92     fd = open(devName, O_RDWR);
93     if (fd < 0) {
94         HILOG_ERROR(LOG_CORE, "Can not have dev %s \n", devName);
95         return -1;
96     }
97 
98     i2c_data.nmsgs = 1;
99     i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg));
100     if (i2c_data.msgs == NULL) {
101         HILOG_ERROR(LOG_CORE, "malloc error \n");
102         close(fd);
103         return -2L;
104     }
105 
106     ioctl(fd, I2C_TIMEOUT, 1);
107     ioctl(fd, I2C_RETRIES, 2L);
108 
109     _pBuf[0] = SHT3X_CMD_SOFT_RESET >> 8L;
110     _pBuf[1] = SHT3X_CMD_SOFT_RESET & 0xFF;
111 
112     // 写寄存器
113     i2c_data.msgs[0].len = 2L;
114     i2c_data.msgs[0].addr = addr;
115     i2c_data.msgs[0].flags = 0; // 写:0 读:1
116     i2c_data.msgs[0].buf = _pBuf;
117 
118     ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
119     if (ret < 0) {
120         HILOG_ERROR(LOG_CORE, "SoftReset %c error \n", addr);
121         close(fd);
122         free(i2c_data.msgs);
123         return -3L;
124     }
125     free(i2c_data.msgs);
126     close(fd);
127 
128     return 0;
129 }
130 
SendCommand(char * devName,char addr,uint16_t modeCommand)131 int SendCommand(char *devName, char addr, uint16_t modeCommand)
132 {
133     int fd = -1;
134     int ret = -1;
135     uint8_t _pBuf[2L] = {0};
136 
137     struct i2c_rdwr_ioctl_data i2c_data;
138 
139     fd = open(devName, O_RDWR);
140     if (fd < 0) {
141         HILOG_ERROR(LOG_CORE, "can not have dev %s \n", devName);
142         return -1;
143     }
144 
145     i2c_data.nmsgs = 1;
146     i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg));
147     if (i2c_data.msgs == NULL) {
148         HILOG_ERROR(LOG_CORE, "malloc error \n");
149         close(fd);
150         return -2L;
151     }
152 
153     ioctl(fd, I2C_TIMEOUT, 1);
154     ioctl(fd, I2C_RETRIES, 2L);
155 
156     _pBuf[0] = modeCommand >> 8L;
157     _pBuf[1] = modeCommand & 0xFF;
158     // 写寄存器
159     i2c_data.msgs[0].len = 2L;
160     i2c_data.msgs[0].addr = addr;
161     i2c_data.msgs[0].flags = 0; // 写:0 读:1
162     i2c_data.msgs[0].buf = _pBuf;
163 
164     ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
165     if (ret < 0) {
166         HILOG_ERROR(LOG_CORE, "SendCommand %c error \n", addr);
167         close(fd);
168         free(i2c_data.msgs);
169         return -3L;
170     }
171     free(i2c_data.msgs);
172     close(fd);
173 
174     return 0;
175 }
176 
177 // 读状态寄存器
ReadStatusReg(char * devName,char addr,sStatusReg_t * regRaw)178 int ReadStatusReg(char *devName, char addr, sStatusReg_t *regRaw)
179 {
180     uint8_t register1[3L] = {0};
181     uint16_t data = 0;
182 
183     int fd = -1;
184     int ret = -1;
185 
186     uint8_t _pBuf[2L] = {0};
187 
188     struct i2c_rdwr_ioctl_data i2c_data;
189 
190     fd = open(devName, O_RDWR);
191     if (fd < 0) {
192         HILOG_ERROR(LOG_CORE, "can not have dev %s \n", devName);
193         return -1;
194     }
195 
196     i2c_data.nmsgs = 2L;
197     i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg));
198     if (i2c_data.msgs == NULL) {
199         HILOG_ERROR(LOG_CORE, "malloc error \n");
200         close(fd);
201         return -2L;
202     }
203 
204     ioctl(fd, I2C_TIMEOUT, 1);
205     ioctl(fd, I2C_RETRIES, 2L);
206 
207     _pBuf[0] = SHT3X_CMD_READ_STATUS_REG >> 8L;
208     _pBuf[1] = SHT3X_CMD_READ_STATUS_REG & 0xFF;
209     // 写寄存器
210     i2c_data.msgs[0].len = 2L;
211     i2c_data.msgs[0].addr = addr;
212     i2c_data.msgs[0].flags = 0; // 写:0 读:1
213     i2c_data.msgs[0].buf = _pBuf;
214     // 读取数据
215     i2c_data.msgs[1].len = 3L;
216     i2c_data.msgs[1].addr = addr;
217     i2c_data.msgs[1].flags = 1; // 写:0 读:1
218     i2c_data.msgs[1].buf = register1;
219 
220     ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
221     if (ret < 0) {
222         HILOG_ERROR(LOG_CORE, "ReadStatusRegister read data %c  error \n", addr);
223         close(fd);
224         free(i2c_data.msgs);
225         return -3L;
226     }
227     free(i2c_data.msgs);
228     close(fd);
229 
230     if (CheckCrc(register1) != register1[2L]) {
231         HILOG_ERROR(LOG_CORE, "ReadStatusRegister data checkCrc fail \n");
232         return -4L;
233     }
234 
235     data = (register1[0] << 8L) | register1[1];
236     ret = memcpy_s(regRaw, sizeof(sStatusReg_t), &data, 2L);
237     if (ret != 0) {
238         HILOG_ERROR(LOG_CORE, "ReadStatusRegister memcpy_s fail! \n");
239         return -5L;
240     }
241 
242     return 0;
243 }
244 
245 // 读温湿度
ReadTempAndHum(char * devName,char addr,sRHAndTemp_t * tempRH)246 int ReadTempAndHum(char *devName, char addr, sRHAndTemp_t *tempRH)
247 {
248     int fd = -1;
249     int ret = -1;
250 
251     uint8_t rawData[6L] = {0};
252     uint8_t rawTemp[3L] = {0};
253     uint8_t rawHum[3L] = {0};
254 
255     struct i2c_rdwr_ioctl_data i2c_data;
256 
257     fd = open(devName, O_RDWR);
258     if (fd < 0) {
259         HILOG_ERROR(LOG_CORE, "can not have dev %s \n", devName);
260         return -1;
261     }
262 
263     i2c_data.nmsgs = 1;
264     i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg));
265     if (i2c_data.msgs == NULL) {
266         HILOG_ERROR(LOG_CORE, "malloc error \n");
267         close(fd);
268         return -2L;
269     }
270 
271     ioctl(fd, I2C_TIMEOUT, 1);
272     ioctl(fd, I2C_RETRIES, 2L);
273 
274     // 读取数据
275     i2c_data.msgs[0].len = 6L;
276     i2c_data.msgs[0].addr = addr;
277     i2c_data.msgs[0].flags = 1; // 写:0 读:1
278     i2c_data.msgs[0].buf = rawData;
279 
280     ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
281     if (ret < 0) {
282         HILOG_ERROR(LOG_CORE, "ReadTempAndHum read data 0x%c  error \n", addr);
283         close(fd);
284         free(i2c_data.msgs);
285         return -3L;
286     }
287     free(i2c_data.msgs);
288     close(fd);
289 
290     ret = memcpy_s(rawTemp, sizeof(rawTemp), rawData, 3L);
291     if (ret != 0) {
292         HILOG_ERROR(LOG_CORE, "ReadTempAndHum memcpy_s fail! \n");
293         return -5L;
294     }
295 
296     ret = memcpy_s(rawHum, sizeof(rawHum), rawData + 3L, 3L);
297     if (ret != 0) {
298         HILOG_ERROR(LOG_CORE, "ReadTempAndHum memcpy_s fail! \n");
299         return -5L;
300     }
301 
302     if ((CheckCrc(rawTemp) != rawTemp[2L]) || (CheckCrc(rawHum) != rawHum[2L])) {
303         HILOG_ERROR(LOG_CORE, "ReadTempAndHum data checkCrc fail \n");
304         return -4L;
305     }
306 
307     ConvertTempAndHum(tempRH, rawTemp, rawHum);
308 
309     return 0;
310 }
311 
312 // 设置mps与刷新率
ModeSet(char * devName,char addr,uint8_t mps,uint8_t repeatability)313 int ModeSet(char *devName, char addr, uint8_t mps, uint8_t repeatability)
314 {
315     int ret;
316     if (mps == 0) {
317         ret = MpsHalfHz(devName, addr, repeatability);
318     } else if (mps == 1) {
319         ret = Mps1Hz(devName, addr, repeatability);
320     } else if (mps == 2L) {
321         ret = Mps2Hz(devName, addr, repeatability);
322     } else if (mps == 3L) {
323         ret = Mps4Hz(devName, addr, repeatability);
324     } else if (mps == 4L) {
325         ret = Mps10Hz(devName, addr, repeatability);
326     } else {
327         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
328         ret = -3L;
329     }
330     return ret;
331 }
332 
333 // mps为0.5hz时候选择刷新率
MpsHalfHz(char * devName,char addr,uint8_t repeatability)334 int MpsHalfHz(char *devName, char addr, uint8_t repeatability)
335 {
336     int ret;
337     if (repeatability == 0) {
338         SendCommand(devName, addr, SHT3X_CMD_SETMODE_L_FREQUENCY_HALF_HZ);
339         ret = 0;
340     } else if (repeatability == 1) {
341         SendCommand(devName, addr, SHT3X_CMD_SETMODE_M_FREQUENCY_HALF_HZ);
342         ret = 0;
343     } else if (repeatability == 2L) {
344         SendCommand(devName, addr, SHT3X_CMD_SETMODE_H_FREQUENCY_HALF_HZ);
345         ret = 0;
346     } else {
347         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
348         ret = -3L;
349     }
350     return ret;
351 }
352 
353 // mps为1hz时候选择刷新率
Mps1Hz(char * devName,char addr,uint8_t repeatability)354 int Mps1Hz(char *devName, char addr, uint8_t repeatability)
355 {
356     int ret;
357     if (repeatability == 0) {
358         SendCommand(devName, addr, SHT3X_CMD_SETMODE_L_FREQUENCY_1_HZ);
359         ret = 0;
360     } else if (repeatability == 1) {
361         SendCommand(devName, addr, SHT3X_CMD_SETMODE_M_FREQUENCY_1_HZ);
362         ret = 0;
363     } else if (repeatability == 2L) {
364         SendCommand(devName, addr, SHT3X_CMD_SETMODE_H_FREQUENCY_1_HZ);
365         ret = 0;
366     } else {
367         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
368         ret = -3L;
369     }
370     return ret;
371 }
372 
373 // mps为2hz时候选择刷新率
Mps2Hz(char * devName,char addr,uint8_t repeatability)374 int Mps2Hz(char *devName, char addr, uint8_t repeatability)
375 {
376     int ret;
377     if (repeatability == 0) {
378         SendCommand(devName, addr, SHT3X_CMD_SETMODE_L_FREQUENCY_2_HZ);
379         ret = 0;
380     } else if (repeatability == 1) {
381         SendCommand(devName, addr, SHT3X_CMD_SETMODE_M_FREQUENCY_2_HZ);
382         ret = 0;
383     } else if (repeatability == 2L) {
384         SendCommand(devName, addr, SHT3X_CMD_SETMODE_H_FREQUENCY_2_HZ);
385         ret = 0;
386     } else {
387         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
388         ret = -3L;
389     }
390     return ret;
391 }
392 
393 // mps为4hz时候选择刷新率
Mps4Hz(char * devName,char addr,uint8_t repeatability)394 int Mps4Hz(char *devName, char addr, uint8_t repeatability)
395 {
396     int ret;
397     if (repeatability == 0) {
398         SendCommand(devName, addr, SHT3X_CMD_SETMODE_L_FREQUENCY_4_HZ);
399         ret = 0;
400     } else if (repeatability == 1) {
401         SendCommand(devName, addr, SHT3X_CMD_SETMODE_M_FREQUENCY_4_HZ);
402         ret = 0;
403     } else if (repeatability == 2L) {
404         SendCommand(devName, addr, SHT3X_CMD_SETMODE_H_FREQUENCY_4_HZ);
405         ret = 0;
406     } else {
407         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
408         ret = -3L;
409     }
410     return ret;
411 }
412 
413 // mps为10hz时候选择刷新率
Mps10Hz(char * devName,char addr,uint8_t repeatability)414 int Mps10Hz(char *devName, char addr, uint8_t repeatability)
415 {
416     int ret;
417     if (repeatability == 0) {
418         SendCommand(devName, addr, SHT3X_CMD_SETMODE_L_FREQUENCY_10_HZ);
419         ret = 0;
420     } else if (repeatability == 1) {
421         SendCommand(devName, addr, SHT3X_CMD_SETMODE_M_FREQUENCY_10_HZ);
422         ret = 0;
423     } else if (repeatability == 2L) {
424         SendCommand(devName, addr, SHT3X_CMD_SETMODE_H_FREQUENCY_10_HZ);
425         ret = 0;
426     } else {
427         HILOG_ERROR(LOG_CORE, " mps int for range[0,4]\n repeatability int for range[0,2] \n");
428         ret = -3L;
429     }
430     return ret;
431 }