• 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 "humidity_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_humidity_driver.h"
16 
17 #define HDF_LOG_TAG    hdf_sensor_humidity_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 HumidityData * rawData,uint64_t * timestamp)26 static int32_t ReadAht20RawData(struct SensorCfgData *data, struct HumidityData *rawData, uint64_t *timestamp)
27 {
28     OsalTimespec time;
29     int32_t cnt;
30     uint64_t humidityValue;
31     int32_t ret = HDF_SUCCESS;
32     uint8_t value[AHT20_HUM_DATA_BUF_LEN] = {0};
33     uint8_t measureCmdValue[] = {AHT20_HUM_MEASURE_ADDR, AHT20_HUM_MEASURE_ARG0, AHT20_HUM_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_HUM_DELAY_MS);
50 
51     ret = ReadSensor(&data->busCfg, AHT20_HUM_STATUS_ADDR, value, sizeof(value));
52     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
53 
54     for (cnt = 0; AHT20_HUM_IS_BUSY(value[AHT20_HUM_VALUE_IDX_ZERO]) && (cnt < AHT20_HUM_RETRY_TIMES); cnt++) {
55         OsalMDelay(AHT20_HUM_DELAY_MS);
56         ret = ReadSensor(&data->busCfg, AHT20_HUM_STATUS_ADDR, value, sizeof(value));
57         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
58     }
59 
60     if (cnt >= AHT20_HUM_RETRY_TIMES) {
61         HDF_LOGE("%s:line %d aht20 device status busy!", __func__, __LINE__);
62         return HDF_FAILURE;
63     }
64 
65     humidityValue = value[AHT20_HUM_VALUE_IDX_ONE];
66     humidityValue = (humidityValue << AHT20_HUM_SHFIT_EIGHT_BITS) | value[AHT20_HUM_VALUE_IDX_TWO];
67     humidityValue = (humidityValue << AHT20_HUM_SHFIT_FOUR_BITS) | \
68         ((value[AHT20_HUM_VALUE_IDX_THREE] & AHT20_HUM_MASK) >> AHT20_HUM_SHFIT_FOUR_BITS);
69 
70     rawData->humidity = ((humidityValue * AHT20_HUM_SLOPE) / AHT20_HUM_RESOLUTION);
71 
72     return HDF_SUCCESS;
73 }
74 
ReadAht20Data(struct SensorCfgData * data)75 static int32_t ReadAht20Data(struct SensorCfgData *data)
76 {
77     int32_t ret;
78     static int32_t humidity;
79     struct HumidityData 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 = ReadAht20RawData(data, &rawData, &event.timestamp);
94     if (ret != HDF_SUCCESS) {
95         HDF_LOGE("%s: AHT20 read raw data failed", __func__);
96         return HDF_FAILURE;
97     }
98 
99     humidity = rawData.humidity;
100 
101     event.sensorId = SENSOR_TAG_HUMIDITY;
102     event.mode = SENSOR_WORK_MODE_REALTIME;
103     event.dataLen = sizeof(humidity);
104     event.data = (uint8_t *)&humidity;
105     ret = ReportSensorEvent(&event);
106     if (ret != HDF_SUCCESS) {
107         HDF_LOGE("%s: report data failed", __func__);
108     }
109 
110     return ret;
111 }
112 
InitAht20(struct SensorCfgData * data)113 static int32_t InitAht20(struct SensorCfgData *data)
114 {
115     int32_t ret;
116     uint8_t value[AHT20_HUM_DATA_BUF_LEN];
117     uint8_t resetCmd = AHT20_HUM_RESET_ADDR;
118     uint8_t calibrationCmd[] = {AHT20_HUM_CALIBRATION_ADDR, AHT20_HUM_CALIBRATION_ARG0, AHT20_HUM_CALIBRATION_ARG1};
119 
120     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
121     ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
122     if (ret != HDF_SUCCESS) {
123         HDF_LOGE("%s: sensor init config failed", __func__);
124         return HDF_FAILURE;
125     }
126 
127     ret = ReadSensor(&data->busCfg, AHT20_HUM_STATUS_ADDR, value, sizeof(value));
128     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
129 
130     if (AHT20_HUM_IS_BUSY(value[AHT20_HUM_VALUE_IDX_ZERO]) || !AHT20_HUM_IS_CALI(value[AHT20_HUM_VALUE_IDX_ZERO])) {
131         ret = WriteSensor(&data->busCfg, &resetCmd, sizeof(resetCmd));
132         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
133 
134         OsalMDelay(AHT20_HUM_STARTUP_MS);
135 
136         ret = WriteSensor(&data->busCfg, calibrationCmd, sizeof(calibrationCmd));
137         CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
138 
139         OsalMDelay(AHT20_HUM_CALIBRATION_MS);
140     }
141 
142     return HDF_SUCCESS;
143 }
144 
DispatchAht20(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)145 static int32_t DispatchAht20(struct HdfDeviceIoClient *client,
146     int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
147 {
148     (void)client;
149     (void)cmd;
150     (void)data;
151     (void)reply;
152 
153     return HDF_SUCCESS;
154 }
155 
Aht20BindDriver(struct HdfDeviceObject * device)156 static int32_t Aht20BindDriver(struct HdfDeviceObject *device)
157 {
158     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
159 
160     struct Aht20DrvData *drvData = (struct Aht20DrvData *)OsalMemCalloc(sizeof(*drvData));
161     if (drvData == NULL) {
162         HDF_LOGE("%s: malloc drv data fail", __func__);
163         return HDF_ERR_MALLOC_FAIL;
164     }
165 
166     drvData->ioService.Dispatch = DispatchAht20;
167     drvData->device = device;
168     device->service = &drvData->ioService;
169     g_aht20DrvData = drvData;
170 
171     return HDF_SUCCESS;
172 }
173 
Aht20InitDriver(struct HdfDeviceObject * device)174 static int32_t Aht20InitDriver(struct HdfDeviceObject *device)
175 {
176     int32_t ret;
177     struct HumidityOpsCall ops;
178 
179     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
180     struct Aht20DrvData *drvData = (struct Aht20DrvData *)device->service;
181     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
182 
183     drvData->sensorCfg = HumidityCreateCfgData(device->property);
184     if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
185         HDF_LOGE("%s: Creating humidity cfg failed because detection failed", __func__);
186         return HDF_ERR_NOT_SUPPORT;
187     }
188 
189     ops.Init = NULL;
190     ops.ReadData = ReadAht20Data;
191     ret = HumidityRegisterChipOps(&ops);
192     if (ret != HDF_SUCCESS) {
193         HDF_LOGE("%s: Register humidity failed", __func__);
194         return HDF_FAILURE;
195     }
196 
197     ret = InitAht20(drvData->sensorCfg);
198     if (ret != HDF_SUCCESS) {
199         HDF_LOGE("%s: Init AHT20 humidity sensor failed", __func__);
200         return HDF_FAILURE;
201     }
202 
203     return HDF_SUCCESS;
204 }
205 
Aht20ReleaseDriver(struct HdfDeviceObject * device)206 static void Aht20ReleaseDriver(struct HdfDeviceObject *device)
207 {
208     CHECK_NULL_PTR_RETURN(device);
209 
210     struct Aht20DrvData *drvData = (struct Aht20DrvData *)device->service;
211     CHECK_NULL_PTR_RETURN(drvData);
212 
213     if (drvData->sensorCfg != NULL) {
214         HumidityReleaseCfgData(drvData->sensorCfg);
215         drvData->sensorCfg = NULL;
216     }
217     OsalMemFree(drvData);
218 }
219 
220 struct HdfDriverEntry g_humidityAht20DevEntry = {
221     .moduleVersion = 1,
222     .moduleName = "HDF_SENSOR_HUMIDITY_AHT20",
223     .Bind = Aht20BindDriver,
224     .Init = Aht20InitDriver,
225     .Release = Aht20ReleaseDriver,
226 };
227 
228 HDF_INIT(g_humidityAht20DevEntry);
229