• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "temperature_sht30.h"
10 #include <securec.h>
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "sensor_config_controller.h"
14 #include "sensor_device_manager.h"
15 #include "sensor_temperature_driver.h"
16 
17 #define HDF_LOG_TAG    hdf_sensor_temperature_driver
18 
19 static struct Sht30DrvData *g_sht30DrvData = NULL;
20 
Sht30GetDrvData(void)21 static struct Sht30DrvData *Sht30GetDrvData(void)
22 {
23     return g_sht30DrvData;
24 }
25 
Sht30CalcCrc8(const uint8_t * data,uint32_t dataLen)26 static uint8_t Sht30CalcCrc8(const uint8_t *data, uint32_t dataLen)
27 {
28     uint8_t value = SHT30_TEMP_CRC8_BASE;
29 
30     for (uint32_t i = dataLen; i; --i) {
31         value ^= *data++;
32         for (uint32_t j = SENSOR_DATA_WIDTH_8_BIT; j; --j) {
33             value = (value & SHT30_TEMP_CRC8_MASK) ? \
34                 ((value << SHT30_TEMP_SHFIT_1_BIT) ^ SHT30_TEMP_CRC8_POLYNOMIAL) : (value << SHT30_TEMP_SHFIT_1_BIT);
35         }
36     }
37 
38     return value;
39 }
40 
ReadSht30RawData(struct SensorCfgData * data,struct TemperatureData * rawData,uint64_t * timestamp)41 static int32_t ReadSht30RawData(struct SensorCfgData *data, struct TemperatureData *rawData, uint64_t *timestamp)
42 {
43     OsalTimespec time;
44     uint8_t value[SHT30_TEMP_DATA_BUF_LEN];
45     uint16_t tempValue;
46 
47     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
48 
49     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
50 
51     if (OsalGetTime(&time) != HDF_SUCCESS) {
52         HDF_LOGE("%s: Get time failed", __func__);
53         return HDF_FAILURE;
54     }
55 
56     *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
57 
58     int32_t ret = ReadSensor(&data->busCfg, SHT30_TEMP_DATA_ADDR, value, sizeof(value));
59     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
60 
61     tempValue = value[SHT30_TEMP_VALUE_IDX_ZERO];
62     tempValue <<= SENSOR_DATA_WIDTH_8_BIT;
63     tempValue |= value[SHT30_TEMP_VALUE_IDX_ONE];
64 
65     rawData->temperature = (SHT30_TEMP_CONSATNT + ((SHT30_TEMP_SLOPE *  tempValue) / 0xFFFF));
66 
67     if (value[SHT30_TEMP_VALUE_IDX_TWO] != Sht30CalcCrc8(value, SHT30_TEMP_CRC8_LEN)) {
68         HDF_LOGE("%s: Calc temperature crc8 failed!", __func__);
69         return HDF_FAILURE;
70     }
71 
72     return HDF_SUCCESS;
73 }
74 
ReadSht30Data(struct SensorCfgData * data)75 static int32_t ReadSht30Data(struct SensorCfgData *data)
76 {
77     int32_t ret;
78     static int32_t temperature;
79     struct TemperatureData rawData = { 0 };
80     OsalTimespec time;
81     struct SensorReportEvent event;
82 
83     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
84     (void)memset_s(&event, sizeof(event), 0, sizeof(event));
85 
86     if (OsalGetTime(&time) != HDF_SUCCESS) {
87         HDF_LOGE("%s: Get time failed", __func__);
88         return HDF_FAILURE;
89     }
90 
91     event.timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT;
92 
93     ret = ReadSht30RawData(data, &rawData, &event.timestamp);
94     if (ret != HDF_SUCCESS) {
95         HDF_LOGE("%s: SHT30 read raw data failed", __func__);
96         return HDF_FAILURE;
97     }
98 
99     temperature = rawData.temperature;
100 
101     event.sensorId = SENSOR_TAG_TEMPERATURE;
102     event.mode = SENSOR_WORK_MODE_REALTIME;
103     event.dataLen = sizeof(temperature);
104     event.data = (uint8_t *)&temperature;
105     ret = ReportSensorEvent(&event);
106     if (ret != HDF_SUCCESS) {
107         HDF_LOGE("%s: report data failed", __func__);
108     }
109 
110     return ret;
111 }
112 
InitSht30(struct SensorCfgData * data)113 static int32_t InitSht30(struct SensorCfgData *data)
114 {
115     int32_t ret;
116 
117     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
118     ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
119     if (ret != HDF_SUCCESS) {
120         HDF_LOGE("%s: sensor init config failed", __func__);
121         return HDF_FAILURE;
122     }
123 
124     return HDF_SUCCESS;
125 }
126 
DispatchSht30(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)127 static int32_t DispatchSht30(struct HdfDeviceIoClient *client,
128     int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
129 {
130     (void)client;
131     (void)cmd;
132     (void)data;
133     (void)reply;
134 
135     return HDF_SUCCESS;
136 }
137 
Sht30BindDriver(struct HdfDeviceObject * device)138 static int32_t Sht30BindDriver(struct HdfDeviceObject *device)
139 {
140     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
141 
142     struct Sht30DrvData *drvData = (struct Sht30DrvData *)OsalMemCalloc(sizeof(*drvData));
143     if (drvData == NULL) {
144         HDF_LOGE("%s: malloc drv data fail", __func__);
145         return HDF_ERR_MALLOC_FAIL;
146     }
147 
148     drvData->ioService.Dispatch = DispatchSht30;
149     drvData->device = device;
150     device->service = &drvData->ioService;
151     g_sht30DrvData = drvData;
152 
153     return HDF_SUCCESS;
154 }
155 
Sht30InitDriver(struct HdfDeviceObject * device)156 static int32_t Sht30InitDriver(struct HdfDeviceObject *device)
157 {
158     int32_t ret;
159     struct TemperatureOpsCall ops;
160 
161     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
162     struct Sht30DrvData *drvData = (struct Sht30DrvData *)device->service;
163     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
164 
165     drvData->sensorCfg = TemperatureCreateCfgData(device->property);
166     if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
167         HDF_LOGE("%s: Creating temperature cfg failed because detection failed", __func__);
168         return HDF_ERR_NOT_SUPPORT;
169     }
170 
171     ops.Init = NULL;
172     ops.ReadData = ReadSht30Data;
173     ret = TemperatureRegisterChipOps(&ops);
174     if (ret != HDF_SUCCESS) {
175         HDF_LOGE("%s: Register temperature failed", __func__);
176         return HDF_FAILURE;
177     }
178 
179     ret = InitSht30(drvData->sensorCfg);
180     if (ret != HDF_SUCCESS) {
181         HDF_LOGE("%s: Init SHT30 temperature sensor failed", __func__);
182         return HDF_FAILURE;
183     }
184 
185     return HDF_SUCCESS;
186 }
187 
Sht30ReleaseDriver(struct HdfDeviceObject * device)188 static void Sht30ReleaseDriver(struct HdfDeviceObject *device)
189 {
190     CHECK_NULL_PTR_RETURN(device);
191 
192     struct Sht30DrvData *drvData = (struct Sht30DrvData *)device->service;
193     CHECK_NULL_PTR_RETURN(drvData);
194 
195     if (drvData->sensorCfg != NULL) {
196         TemperatureReleaseCfgData(drvData->sensorCfg);
197         drvData->sensorCfg = NULL;
198     }
199     OsalMemFree(drvData);
200 }
201 
202 struct HdfDriverEntry g_temperatureSht30DevEntry = {
203     .moduleVersion = 1,
204     .moduleName = "HDF_SENSOR_TEMPERATURE_SHT30",
205     .Bind = Sht30BindDriver,
206     .Init = Sht30InitDriver,
207     .Release = Sht30ReleaseDriver,
208 };
209 
210 HDF_INIT(g_temperatureSht30DevEntry);
211