• 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_aht20.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 Aht20DrvData *g_aht20DrvData = NULL;
20 
Aht20GetDrvData(void)21 static struct Aht20DrvData *Aht20GetDrvData(void)
22 {
23     return g_aht20DrvData;
24 }
25 
ReadAht20RawData(struct SensorCfgData * data,struct TemperatureData * rawData,uint64_t * timestamp)26 static int32_t ReadAht20RawData(struct SensorCfgData *data, struct TemperatureData *rawData, uint64_t *timestamp)
27 {
28     OsalTimespec time;
29     int32_t count;
30     int32_t ret = HDF_SUCCESS;
31     uint8_t value[AHT20_TEMP_DATA_BUF_LEN];
32     uint64_t tempValue;
33     uint8_t measureCmdValue[] = {AHT20_TEMP_MEASURE_ADDR, AHT20_TEMP_MEASURE_ARG0, AHT20_TEMP_MEASURE_ARG1};
34 
35     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
36 
37     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
38 
39     if (OsalGetTime(&time) != HDF_SUCCESS) {
40         HDF_LOGE("%s: Get time failed", __func__);
41         return HDF_FAILURE;
42     }
43 
44     *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
45 
46     ret = WriteSensor(&data->busCfg, measureCmdValue, sizeof(measureCmdValue));
47     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
48 
49     OsalMDelay(AHT20_TEMP_DELAY_MS);
50 
51     ret = ReadSensor(&data->busCfg, AHT20_TEMP_STATUS_ADDR, value, sizeof(value));
52     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
53 
54     for (count = 0; AHT20_TEMP_IS_BUSY(value[AHT20_TEMP_VALUE_IDX_ZERO]) && (count < AHT20_TEMP_RETRY_TIMES); count++) {
55         OsalMDelay(AHT20_TEMP_DELAY_MS);
56         ret = ReadSensor(&data->busCfg, AHT20_TEMP_STATUS_ADDR, value, sizeof(value));
57         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
58     }
59 
60     if (count >= AHT20_TEMP_RETRY_TIMES) {
61         HDF_LOGE("%s:line %d aht20 device status busy!", __func__, __LINE__);
62         return HDF_FAILURE;
63     }
64 
65     tempValue = value[AHT20_TEMP_VALUE_IDX_THREE] & AHT20_TEMP_MASK;
66     tempValue = (tempValue << AHT20_TEMP_SHFIT_BITS) | value[AHT20_TEMP_VALUE_IDX_FOUR];
67     tempValue = (tempValue << AHT20_TEMP_SHFIT_BITS) | value[AHT20_TEMP_VALUE_IDX_FIVE];
68 
69     rawData->temperature = ((tempValue * AHT20_TEMP_SLOPE) / AHT20_TEMP_RESOLUTION) - AHT20_TEMP_CONSATNT;
70 
71     return HDF_SUCCESS;
72 }
73 
ReadAht20Data(struct SensorCfgData * data)74 static int32_t ReadAht20Data(struct SensorCfgData *data)
75 {
76     int32_t ret;
77     static int32_t temperature;
78     struct TemperatureData rawData = { 0 };
79     OsalTimespec time;
80     struct SensorReportEvent event;
81 
82     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
83     (void)memset_s(&event, sizeof(event), 0, sizeof(event));
84 
85     if (OsalGetTime(&time) != HDF_SUCCESS) {
86         HDF_LOGE("%s: Get time failed", __func__);
87         return HDF_FAILURE;
88     }
89 
90     event.timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT;
91 
92     ret = ReadAht20RawData(data, &rawData, &event.timestamp);
93     if (ret != HDF_SUCCESS) {
94         HDF_LOGE("%s: AHT20 read raw data failed", __func__);
95         return HDF_FAILURE;
96     }
97 
98     temperature = rawData.temperature;
99 
100     event.sensorId = SENSOR_TAG_TEMPERATURE;
101     event.mode = SENSOR_WORK_MODE_REALTIME;
102     event.dataLen = sizeof(temperature);
103     event.data = (uint8_t *)&temperature;
104     ret = ReportSensorEvent(&event);
105     if (ret != HDF_SUCCESS) {
106         HDF_LOGE("%s: report data failed", __func__);
107     }
108 
109     return ret;
110 }
111 
InitAht20(struct SensorCfgData * data)112 static int32_t InitAht20(struct SensorCfgData *data)
113 {
114     int32_t ret;
115     uint8_t value[AHT20_TEMP_DATA_BUF_LEN];
116     uint8_t resetCmd = AHT20_TEMP_RESET_ADDR;
117     uint8_t calibrationCmd[] = {AHT20_TEMP_CALIBRATION_ADDR, AHT20_TEMP_CALIBRATION_ARG0, AHT20_TEMP_CALIBRATION_ARG1};
118 
119     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
120     ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
121     if (ret != HDF_SUCCESS) {
122         HDF_LOGE("%s: sensor init config failed", __func__);
123         return HDF_FAILURE;
124     }
125 
126     ret = ReadSensor(&data->busCfg, AHT20_TEMP_STATUS_ADDR, value, sizeof(value));
127     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
128 
129     if (AHT20_TEMP_IS_BUSY(value[AHT20_TEMP_VALUE_IDX_ZERO]) || !AHT20_TEMP_IS_CALI(value[AHT20_TEMP_VALUE_IDX_ZERO])) {
130         ret = WriteSensor(&data->busCfg, &resetCmd, sizeof(resetCmd));
131         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
132 
133         OsalMDelay(AHT20_TEMP_STARTUP_MS);
134 
135         ret = WriteSensor(&data->busCfg, calibrationCmd, sizeof(calibrationCmd));
136         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
137 
138         OsalMDelay(AHT20_TEMP_CALIBRATION_MS);
139     }
140 
141     return HDF_SUCCESS;
142 }
143 
DispatchAht20(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)144 static int32_t DispatchAht20(struct HdfDeviceIoClient *client,
145     int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
146 {
147     (void)client;
148     (void)cmd;
149     (void)data;
150     (void)reply;
151 
152     return HDF_SUCCESS;
153 }
154 
Aht20BindDriver(struct HdfDeviceObject * device)155 static int32_t Aht20BindDriver(struct HdfDeviceObject *device)
156 {
157     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
158 
159     struct Aht20DrvData *drvData = (struct Aht20DrvData *)OsalMemCalloc(sizeof(*drvData));
160     if (drvData == NULL) {
161         HDF_LOGE("%s: malloc drv data fail", __func__);
162         return HDF_ERR_MALLOC_FAIL;
163     }
164 
165     drvData->ioService.Dispatch = DispatchAht20;
166     drvData->device = device;
167     device->service = &drvData->ioService;
168     g_aht20DrvData = drvData;
169 
170     return HDF_SUCCESS;
171 }
172 
Aht20InitDriver(struct HdfDeviceObject * device)173 static int32_t Aht20InitDriver(struct HdfDeviceObject *device)
174 {
175     int32_t ret;
176     struct TemperatureOpsCall ops;
177 
178     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
179     struct Aht20DrvData *drvData = (struct Aht20DrvData *)device->service;
180     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
181 
182     drvData->sensorCfg = TemperatureCreateCfgData(device->property);
183     if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
184         HDF_LOGE("%s: Creating temperature cfg failed because detection failed", __func__);
185         return HDF_ERR_NOT_SUPPORT;
186     }
187 
188     ops.Init = NULL;
189     ops.ReadData = ReadAht20Data;
190     ret = TemperatureRegisterChipOps(&ops);
191     if (ret != HDF_SUCCESS) {
192         HDF_LOGE("%s: Register temperature failed", __func__);
193         return HDF_FAILURE;
194     }
195 
196     ret = InitAht20(drvData->sensorCfg);
197     if (ret != HDF_SUCCESS) {
198         HDF_LOGE("%s: Init AHT20 temperature sensor failed", __func__);
199         return HDF_FAILURE;
200     }
201 
202     return HDF_SUCCESS;
203 }
204 
Aht20ReleaseDriver(struct HdfDeviceObject * device)205 static void Aht20ReleaseDriver(struct HdfDeviceObject *device)
206 {
207     CHECK_NULL_PTR_RETURN(device);
208 
209     struct Aht20DrvData *drvData = (struct Aht20DrvData *)device->service;
210     CHECK_NULL_PTR_RETURN(drvData);
211 
212     if (drvData->sensorCfg != NULL) {
213         TemperatureReleaseCfgData(drvData->sensorCfg);
214         drvData->sensorCfg = NULL;
215     }
216     OsalMemFree(drvData);
217 }
218 
219 struct HdfDriverEntry g_temperatureAht20DevEntry = {
220     .moduleVersion = 1,
221     .moduleName = "HDF_SENSOR_TEMPERATURE_AHT20",
222     .Bind = Aht20BindDriver,
223     .Init = Aht20InitDriver,
224     .Release = Aht20ReleaseDriver,
225 };
226 
227 HDF_INIT(g_temperatureAht20DevEntry);
228