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