1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <aos/kernel.h>
7
8 #include "ulog/ulog.h"
9 #include "flower_app.h"
10 #include "k_api.h"
11 #if AOS_COMP_CLI
12 #include "aos/cli.h"
13 #endif
14 #include <sys/ioctl.h>
15 #include <vfsdev/gpio_dev.h>
16 #include <drivers/char/u_device.h>
17 #include <drivers/u_ld.h>
18 #include "aos/vfs.h"
19
20 #include "aos/hal/gpio.h"
21 #include "hal_iomux_haas1000.h"
22
23
24 extern uint32_t hal_fast_sys_timer_get();
25 extern uint32_t hal_cmu_get_crystal_freq();
26
27 #define CONFIG_FAST_SYSTICK_HZ (hal_cmu_get_crystal_freq() / 4)
28 #define FAST_TICKS_TO_US(tick) ((uint32_t)(tick) * 10 / (CONFIG_FAST_SYSTICK_HZ / 1000 / 100))
29
30
31 #define DHT11_PIN HAL_IOMUX_PIN_P0_1
32
33 static int fd = 0;
34 static uint8_t last_temp = 0,last_hum = 0;
35 extern uint8_t mqtt_status;
36
37
38 #if (RHINO_CONFIG_HW_COUNT > 0)
_udelay(unsigned long x)39 void _udelay(unsigned long x) {
40 unsigned long now,t;
41
42 t = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
43 now = t;
44 while ((now - t) < x) {
45 now = FAST_TICKS_TO_US(hal_fast_sys_timer_get());
46 }
47 }
48
_msdelay(unsigned long x)49 void _msdelay(unsigned long x) {
50 _udelay(x * 1000);
51 }
52 #else
53 #error "RHINO_CONFIG_HW_COUNT should be configured to get us level delay"
54 #endif
55
56 // temp && humidity gpio set
DHT11_GPIO_Set(unsigned char leve)57 static void DHT11_GPIO_Set(unsigned char leve)
58 {
59 struct gpio_io_config config;
60
61 config.id = DHT11_PIN;
62 config.config = GPIO_IO_OUTPUT | GPIO_IO_OUTPUT_ODPU;
63 if(leve == 1){
64 config.data = 1;
65 }
66 else if(leve == 0){
67 config.data = 0;
68 }
69 ioctl(fd, IOC_GPIO_SET, (unsigned long)&config);
70 }
71
DHT11_GPIO_Get(void)72 static uint32_t DHT11_GPIO_Get(void)
73 {
74 struct gpio_io_config config;
75 int ret = 0xff;
76
77 config.id = DHT11_PIN;
78 config.config = GPIO_IO_INPUT | GPIO_IO_INPUT_PU;
79 config.data = 0;
80 ret = ioctl(fd, IOC_GPIO_GET, (unsigned long)&config);
81 return ret;
82 }
83
84 //复位DHT11
DHT11_Reset(void)85 void DHT11_Reset(void)
86 {
87 DHT11_GPIO_Set(0);
88 _msdelay(20);
89 DHT11_GPIO_Set(1);
90 _udelay(30);
91 }
92
DHT11_IsOnline(void)93 uint8_t DHT11_IsOnline(void)
94 {
95 uint8_t retry = 0;
96 //DHT11会拉低40~80us
97 while (DHT11_GPIO_Get() && retry < 100){
98 retry ++;
99 _udelay(1);
100 }
101 if(retry >= 100){
102 LOGE("APP", "DHT Pin High!\n");
103 return 1;
104 }
105 else{
106 retry = 0;
107 }
108 //DHT11拉低后会再次拉高40~80us
109 while (!DHT11_GPIO_Get() && retry < 100){
110 retry ++;
111 _udelay(1);
112 }
113 if(retry >= 100){
114 LOGE("APP", "DHT Pin Low!\n");
115 return 1;
116 }
117 return 0;
118 }
119
DHT11_ReadBit(void)120 uint8_t DHT11_ReadBit(void)
121 {
122 uint8_t retry = 0;
123 while(DHT11_GPIO_Get() && retry < 100){
124 retry ++;
125 _udelay(1);
126 }
127 retry = 0;
128 while(!DHT11_GPIO_Get() && retry < 100){
129 retry ++;
130 _udelay(1);
131 }
132 _udelay(40);//等待40us
133 if(DHT11_GPIO_Get()){
134 return 1;
135 }
136 else {
137 return 0;
138 }
139 }
140
DHT11_ReadByte(void)141 uint8_t DHT11_ReadByte(void)
142 {
143 uint8_t i,dat;
144 dat = 0;
145 for (i = 0; i < 8; i ++) {
146 dat <<= 1;
147 dat |= DHT11_ReadBit();
148 }
149 return dat;
150 }
151
DHT11_Read_Data(uint8_t * temp,uint8_t * humi)152 uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi)
153 {
154 uint8_t buf[5];
155 uint8_t i;
156
157 DHT11_Reset();
158 if(DHT11_IsOnline() == 0){
159 //读取40位数据
160 for(i = 0; i < 5; i ++){
161 buf[i] = DHT11_ReadByte();
162 }
163 if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]){
164 *humi = buf[0];
165 *temp = buf[2];
166 }
167 }
168 else {
169 LOGE("APP", "DHT is not online!\n");
170 return 1;
171 }
172 return 0;
173 }
174
report_2_cloud(void * dm_handle)175 void report_2_cloud(void *dm_handle)
176 {
177 uint8_t temp =0,humidity=0,d_flag = 0;
178 char property_payload[30] = {0};
179
180 if(mqtt_status == 0){
181 printf("mqtt status :%d %p\r\n",mqtt_status,dm_handle);
182 return;
183 }
184
185 d_flag = DHT11_Read_Data(&temp,&humidity);
186
187 printf("temp ->%d humidity->%d --%d\n",temp,humidity,d_flag);
188 if((last_temp != temp)&&(!d_flag)){
189 snprintf(property_payload, sizeof(property_payload), "{\"Temperature\": %d}", temp);
190 printf("report:%s\r\n",property_payload);
191 demo_send_property_post(dm_handle, property_payload);
192 last_temp = temp;
193 }
194 if((last_hum != humidity)&&(!d_flag)){
195 snprintf(property_payload, sizeof(property_payload), "{\"Humidity\": %d}", humidity);
196 printf("report:%s\r\n",property_payload);
197 demo_send_property_post(dm_handle, property_payload);
198 last_hum = humidity;
199 }
200 }
201
handle_temp_cmd(char * pwbuf,int blen,int argc,char ** argv)202 static void handle_temp_cmd(char *pwbuf, int blen, int argc, char **argv)
203 {
204 uint8_t temp =0,humidity=0;
205
206 if(0 == strcmp(argv[1],"0")){
207 DHT11_GPIO_Set(0);
208 }
209 else if(0 == strcmp(argv[1],"1")){
210 DHT11_GPIO_Set(1);
211 }
212 else if(0 == strcmp(argv[1],"2")){
213 DHT11_Reset();
214 }
215 else if(0 == strcmp(argv[1],"3")){
216 DHT11_Read_Data(&temp,&humidity);
217 LOGI("APP", "temp ->%d humidity->%d\n",temp,humidity);
218 }
219 }
220
221 #if AOS_COMP_CLI
222 static struct cli_command temp_cmd = {
223 .name = "temp",
224 .help = "temp [read]",
225 .function = handle_temp_cmd
226 };
227 #endif /* AOS_COMP_CLI */
228
flower_gpio_init(void)229 int flower_gpio_init(void)
230 {
231 gpio_dev_t temp_gpio;
232
233 temp_gpio.port = DHT11_PIN;
234 temp_gpio.config = OUTPUT_OPEN_DRAIN_PULL_UP;
235 hal_gpio_init(&temp_gpio);
236
237 fd = open("/dev/gpio", 0);
238 printf("open gpio %s, fd:%d\r\n", fd >= 0 ? "success" : "fail", fd);
239
240 DHT11_GPIO_Set(1);
241 DHT11_Reset();
242 #if AOS_COMP_CLI
243 aos_cli_register_command(&temp_cmd);
244 #endif /* AOS_COMP_CLI */
245 return 0;
246 }
247