1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 <hi_mux.h>
17 #include <hi_time.h>
18 #include <string.h>
19 #include "ohos_init.h"
20 #include "cmsis_os2.h"
21 #include "app_demo_multi_sample.h"
22 #include "iot_errno.h"
23 #include "iot_i2c.h"
24 #include "app_demo_aht20.h"
25
26 #define AHT_REG_ARRAY_LEN (6)
27 #define AHT_OC_ARRAY_LEN (6)
28 #define AHT_SNED_CMD_LEN (3)
29 #define AHT20_DEMO_TASK_STAK_SIZE (1024*4)
30 #define AHT20_DEMO_TASK_PRIORITY (25)
31 #define AHT_REG_ARRAY_INIT_LEN (1)
32 #define AHT_CALCULATION (1048576)
33
34 #define AHT_WRITE_COMMAND ((unsigned char)0x00)
35 #define AHT_READ_COMMAND ((unsigned char)0x01)
36
37 #define IOT_BIT_1 (1)
38 #define IOT_BIT_4 (4)
39 #define IOT_BIT_8 (8)
40 #define IOT_BIT_12 (12)
41 #define IOT_BIT_16 (16)
42
43 #define BUFF_BIT_1 (1)
44 #define BUFF_BIT_2 (2)
45 #define BUFF_BIT_3 (3)
46 #define BUFF_BIT_4 (4)
47 #define BUFF_BIT_5 (5)
48
49 #define CONSTER_50 (50)
50 #define CONSTER_100 (100)
51 #define CONSTER_200 (200)
52
53 #define LOW_4_BIT ((unsigned char)0x0f)
54 #define HIGH_4_BIT ((unsigned char)0xf0)
55
56 AhtSersonValue sensorV = {0};
57
GetAhtSensorValue(AhtSersonType type)58 float GetAhtSensorValue(AhtSersonType type)
59 {
60 float value = 0;
61
62 switch (type) {
63 case AHT_TEMPERATURE:
64 value = sensorV.g_ahtTemper;
65 break;
66 case AHT_HUMIDITY:
67 value = sensorV.g_ahtHumi;
68 break;
69 default:
70 break;
71 }
72 return value;
73 }
74
75 /*
76 * Check whether the bit3 of the temperature and humidity sensor is initialized successfully,
77 * otherwise send the setting of 0xbe to set the sensor initialization
78 */
Ath20CheckAndInit(unsigned char initCmd,unsigned char initHighByte,unsigned char initLowByte)79 static unsigned int Ath20CheckAndInit(unsigned char initCmd,
80 unsigned char initHighByte, unsigned char initLowByte)
81 {
82 unsigned int status = 0;
83
84 IotI2cData aht20I2cWriteCmdAddrInit = {0};
85 IotI2cData aht20I2cData = { 0 };
86 unsigned char recvDataInit[AHT_REG_ARRAY_INIT_LEN] = { 0 };
87 unsigned char initSendUserCmd[AHT_SNED_CMD_LEN] = {initCmd, initHighByte, initLowByte};
88
89 (void)memset_s(&recvDataInit, sizeof(recvDataInit), 0x0, sizeof(recvDataInit));
90 (void)memset_s(&aht20I2cData, sizeof(IotI2cData), 0x0, sizeof(IotI2cData));
91
92 aht20I2cData.receiveBuf = recvDataInit;
93 aht20I2cData.receiveLen = AHT_REG_ARRAY_INIT_LEN;
94 aht20I2cWriteCmdAddrInit.sendBuf = initSendUserCmd;
95 aht20I2cWriteCmdAddrInit.sendLen = AHT_SNED_CMD_LEN;
96
97 status = IoTI2cRead(IOT_I2C_IDX_0, (AHT_DEVICE_ADDR << IOT_BIT_1) | AHT_READ_COMMAND,
98 aht20I2cData.receiveBuf, aht20I2cData.receiveLen);
99 if (((recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR) && (recvDataInit[0] != AHT_DEVICE_CALIBRATION_ERR_R)) ||
100 (recvDataInit[0] == AHT_DEVICE_CALIBRATION)) {
101 status = IoTI2cWrite(IOT_I2C_IDX_0, (AHT_DEVICE_ADDR << IOT_BIT_1) | AHT_WRITE_COMMAND,
102 aht20I2cWriteCmdAddrInit.sendBuf, aht20I2cWriteCmdAddrInit.sendLen);
103 TaskMsleep(AHT_SLEEP_1S);
104 return IOT_FAILURE;
105 }
106
107 return IOT_SUCCESS;
108 }
109
110 /* 发送触犯测量命令 */
Aht20Write(unsigned char triggerCmd,unsigned char highByteCmd,unsigned char lowByteCmd)111 unsigned int Aht20Write(unsigned char triggerCmd, unsigned char highByteCmd, unsigned char lowByteCmd)
112 {
113 unsigned int status = 0;
114
115 IotI2cData aht20I2cWriteCmdAddr = {0};
116 unsigned char sendUserCmd[AHT_SNED_CMD_LEN] = {triggerCmd, highByteCmd, lowByteCmd};
117
118 aht20I2cWriteCmdAddr.sendBuf = sendUserCmd;
119 aht20I2cWriteCmdAddr.sendLen = AHT_SNED_CMD_LEN;
120
121 status = IoTI2cWrite(IOT_I2C_IDX_0, (AHT_DEVICE_ADDR << IOT_BIT_1) | AHT_WRITE_COMMAND,
122 aht20I2cWriteCmdAddr.sendBuf, aht20I2cWriteCmdAddr.sendLen);
123
124 return IOT_SUCCESS;
125 }
126
127 /* 读取 aht20 serson 数据 */
Aht20Read(unsigned int recvLen,unsigned char type)128 unsigned int Aht20Read(unsigned int recvLen, unsigned char type)
129 {
130 unsigned int status = 0;
131
132 unsigned char recvData[AHT_REG_ARRAY_LEN] = { 0 };
133 IotI2cData aht20I2cData = { 0 };
134 float temper = 0;
135 float temperT = 0;
136 float humi = 0;
137 float humiH = 0;
138 /* Request memory space */
139 (void)memset_s(&recvData, sizeof(recvData), 0x0, sizeof(recvData));
140 (void)memset_s(&aht20I2cData, sizeof(IotI2cData), 0x0, sizeof(IotI2cData));
141 aht20I2cData.receiveBuf = recvData;
142 aht20I2cData.receiveLen = recvLen;
143
144 status = IoTI2cRead(IOT_I2C_IDX_0, (AHT_DEVICE_ADDR << IOT_BIT_1) | AHT_READ_COMMAND,
145 aht20I2cData.receiveBuf, aht20I2cData.receiveLen);
146 if (type == AHT_TEMPERATURE) {
147 temper = (float)(((recvData[BUFF_BIT_3] & LOW_4_BIT) << IOT_BIT_16) |
148 (recvData[BUFF_BIT_4] << IOT_BIT_8) |
149 recvData[BUFF_BIT_5]); // 温度拼接
150 temperT = (temper / AHT_CALCULATION) * CONSTER_200 - CONSTER_50; // T = (S_t/2^20)*200-50
151 sensorV.g_ahtTemper = temperT;
152 return IOT_SUCCESS;
153 }
154 if (type == AHT_HUMIDITY) {
155 humi = (float)((recvData[BUFF_BIT_1] << IOT_BIT_12 | recvData[BUFF_BIT_2] << IOT_BIT_4) |
156 ((recvData[BUFF_BIT_3] & HIGH_4_BIT) >> IOT_BIT_4)); // 湿度拼接
157 humiH = humi / AHT_CALCULATION * CONSTER_100;
158 sensorV.g_ahtHumi = humiH;
159 return IOT_SUCCESS;
160 }
161 }
162
AppDemoAht20(char * param)163 void *AppDemoAht20(char *param)
164 {
165 unsigned int status = 0;
166 unsigned int ret = 0;
167
168 /* init oled i2c */
169 IoTGpioInit(HI_GPIO_13); /* GPIO13 */
170 IoSetFunc(HI_GPIO_13, HI_I2C_SDA_SCL); /* GPIO13, SDA */
171 IoTGpioInit(HI_GPIO_14); /* GPIO 14 */
172 IoSetFunc(HI_GPIO_14, HI_I2C_SDA_SCL); /* GPIO14 SCL */
173
174 IoTI2cInit(IOT_I2C_IDX_0, BAUDRATE_INIT); /* baudrate: 400000 */
175 /* 上电等待40ms */
176 hi_udelay(AHT_DELAY_40MS); // 40ms
177 while (1) {
178 if (ret == IOT_SUCCESS) {
179 /* check whethe the sensor calibration */
180 while (IOT_SUCCESS != Ath20CheckAndInit(AHT_DEVICE_INIT_CMD,
181 AHT_DEVICE_PARAM_INIT_HIGH, AHT_DEVICE_PARAM_LOW_BYTE)) {
182 printf("aht20 sensor check init failed!\r\n");
183 TaskMsleep(AHT_SLEEP_50MS);
184 }
185 /* on hold master mode */
186 status = Aht20Write(AHT_DEVICE_TEST_CMD, AHT_DEVICE_PARAM_HIGH_BYTE,
187 AHT_DEVICE_PARAM_LOW_BYTE); // tempwerature
188 if (status != IOT_SUCCESS) {
189 printf("get tempwerature data error!\r\n");
190 }
191 hi_udelay(AHT_DELAY_100MS); // 100ms等待测量完成
192 status = Aht20Read(AHT_REG_ARRAY_LEN, AHT_TEMPERATURE);
193 if (status != IOT_SUCCESS) {
194 printf("get tempwerature data error!\r\n");
195 }
196 status = Aht20Read(AHT_REG_ARRAY_LEN, AHT_HUMIDITY);
197 if (status != IOT_SUCCESS) {
198 printf("get humidity data error!\r\n");
199 }
200 }
201 TaskMsleep(AHT_TASK_SLEEP_TIME); // 20ms
202 }
203 }
204
205 /* get aht20 sensor data */
GetAht20SensorData(void)206 void GetAht20SensorData(void)
207 {
208 unsigned int status = 0;
209
210 /* on hold master mode */
211 status = Aht20Write(AHT_DEVICE_TEST_CMD, AHT_DEVICE_PARAM_HIGH_BYTE,
212 AHT_DEVICE_PARAM_LOW_BYTE); // tempwerature
213 hi_udelay(AHT_DELAY_100MS); // 100ms等待测量完成
214 status = Aht20Read(AHT_REG_ARRAY_LEN, AHT_TEMPERATURE);
215 status = Aht20Read(AHT_REG_ARRAY_LEN, AHT_HUMIDITY);
216 }
217
StartAht20Task(void)218 static void StartAht20Task(void)
219 {
220 osThreadAttr_t attr = {0};
221
222 attr.stack_size = AHT20_DEMO_TASK_STAK_SIZE;
223 attr.priority = AHT20_DEMO_TASK_PRIORITY;
224 attr.name = (hi_char*)"app_demo_aht20_task";
225
226 if (osThreadNew((osThreadFunc_t)AppDemoAht20, NULL, &attr) == NULL) {
227 printf("[LedExample] Failed to create app_demo_aht20!\n");
228 }
229 }
230
231 SYS_RUN(StartAht20Task);