1 #include "key.h"
2 #include "aos/hal/gpio.h"
3 #include "hal_iomux_haas1000.h"
4 #include "ulog/ulog.h"
5 #include <aos/kernel.h>
6 #include <stdio.h>
7 #include <vfsdev/gpio_dev.h>
8 
9 #define TAG "key_poll"
10 
11 #define EDK_BOARD_KEY1 HAL_IOMUX_PIN_P2_7
12 #define EDK_BOARD_KEY2 HAL_IOMUX_PIN_P2_4
13 #define EDK_BOARD_KEY3 HAL_IOMUX_PIN_P2_5
14 #define EDK_BOARD_KEY4 HAL_IOMUX_PIN_P3_2
15 
16 #define KEY_NUM              4
17 #define TIMER_CHECK_INTERVAL 30
18 #define DI_STABLE_COUNT      4
19 
20 #define USING_VFS_GPIO
21 
22 static key_code_cb notify_key_code_cb = NULL;
23 
24 static aos_timer_t key_poll_timer = {0};
25 static int32_t g_gpio_fd = -1;
26 
27 typedef struct {
28     uint8_t key_code;
29     uint8_t check_count;
30 } key_value_t;
31 
32 static key_value_t key_value;
33 
34 typedef struct {
35     uint8_t    installed;
36     uint8_t    monitor_flag;
37     uint8_t    check_count;
38     gpio_dev_t gpio_dev;
39 } key_dev_input_t;
40 
41 /*digital input gpio dev list , the default value is high*/
42 static key_dev_input_t key_dev_input[KEY_NUM] = {
43     {0, 0, 0, {EDK_BOARD_KEY1, IRQ_MODE, NULL} },
44     {0, 0, 0, {EDK_BOARD_KEY2, IRQ_MODE, NULL} },
45     {0, 0, 0, {EDK_BOARD_KEY3, IRQ_MODE, NULL} },
46     {0, 0, 0, {EDK_BOARD_KEY4, IRQ_MODE, NULL} },
47 };
48 
49 static void key_rising_edge_handle(gpio_dev_t *gpio);
50 static void key_falling_edge_handle(gpio_dev_t *gpio);
51 
find_key_index(gpio_dev_t * gpio)52 int find_key_index(gpio_dev_t *gpio)
53 {
54     int         index    = -1;
55     gpio_dev_t *key_gpio = gpio;
56     if (key_gpio == NULL) {
57         return index;
58     }
59 
60     switch (key_gpio->port) {
61         case EDK_BOARD_KEY1:
62             index = 0;
63             break;
64         case EDK_BOARD_KEY2:
65             index = 1;
66             break;
67         case EDK_BOARD_KEY3:
68             index = 2;
69             break;
70         case EDK_BOARD_KEY4:
71             index = 3;
72             break;
73     }
74     //printf("%s, index : %d\n", __func__, index);
75     return index;
76 }
77 
key_poll(void * timer,void * arg)78 static void key_poll(void *timer, void *arg)
79 {
80     uint32_t i;
81     int32_t  ret        = 0;
82     uint32_t gpio_value = 0;
83     uint8_t  key_code   = 0;
84 
85     for (i = 0; i < KEY_NUM; i++) {
86         if (key_dev_input[i].installed == 0 ||
87             key_dev_input[i].monitor_flag == 0) {
88             continue;
89         }
90 #ifdef USING_VFS_GPIO
91         int ret = 0;
92         gpio_io_config_t config;
93         config.id = key_dev_input[i].gpio_dev.port;
94         config.config = GPIO_IO_INPUT | GPIO_IO_INPUT_PU;
95         config.data = 0;
96 
97         ret = ioctl(g_gpio_fd, IOC_GPIO_GET, &config);
98         if (ret) {
99             LOGE(TAG, "get gpio:%d failed, ret %d", config.id, ret);
100             return;
101         }
102 #else
103         ret = hal_gpio_input_get(&key_dev_input[i].gpio_dev, &gpio_value);
104         if (ret) {
105             LOGE(TAG, "Fail to get di %d port %d value at %s %d", i,
106                  key_dev_input[i].gpio_dev.port, __FILE__, __LINE__);
107             continue;
108         }
109 #endif
110         if (gpio_value == GPIO_PinState_Reset) {
111             //printf(" %d key is pressing\n", i);
112             key_code = key_code | (0x01 << i);
113         }
114     }
115 
116     if ((key_value.key_code == key_code) && (key_value.key_code != 0)) {
117         key_value.check_count++;
118     } else {
119         key_value.key_code    = key_code;
120         key_value.check_count = 0;
121     }
122 
123     if (key_value.check_count >= DI_STABLE_COUNT) {
124         key_value.check_count = 0;
125         LOGI(TAG, "notify %d in key_poll\n", key_value.key_code);
126         if (key_value.key_code) {
127             notify_key_code_cb(key_value.key_code);
128         }
129     }
130 }
131 
key_rising_edge_handle(gpio_dev_t * gpio)132 static void key_rising_edge_handle(gpio_dev_t *gpio)
133 {
134     int         index    = -1;
135     gpio_dev_t *key_gpio = gpio;
136 
137     index = find_key_index(key_gpio);
138     if (index < 0 || index >= KEY_NUM) {
139         printf("err in %s:%d\n", __func__, __LINE__);
140         return;
141     }
142 
143     //printf(" %d key release\n", index);
144     key_dev_input[index].check_count  = 0;
145     key_dev_input[index].monitor_flag = 0;
146 
147 
148 #ifdef USING_VFS_GPIO
149     int ret = 0;
150     gpio_irq_config_t irq_config;
151     irq_config.id = key_gpio->port;
152     irq_config.config = GPIO_IRQ_CLEAR;
153 
154     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
155     if (ret) {
156         LOGE(TAG, "clear gpio irq:%d failed, ret %d", key_gpio->port, ret);
157         return;
158     }
159     irq_config.config = GPIO_IRQ_DISABLE;
160     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
161     if (ret) {
162         LOGE(TAG, "clear gpio irq:%d failed, ret %d", key_gpio->port, ret);
163         return;
164     }
165 
166     irq_config.id = key_gpio->port;
167     irq_config.config = GPIO_IRQ_ENABLE | GPIO_IRQ_EDGE_FALLING;
168     irq_config.cb = key_falling_edge_handle;
169     irq_config.arg = key_gpio;
170 
171     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
172     if (ret) {
173         LOGE(TAG, "enable gpio irq:%d failed, ret %d", ret);
174         return -1;
175     }
176 #else
177 
178     hal_gpio_clear_irq(key_gpio);
179     hal_gpio_disable_irq(key_gpio);
180 
181     hal_gpio_enable_irq(key_gpio, IRQ_TRIGGER_FALLING_EDGE,
182                         key_falling_edge_handle, key_gpio);
183 #endif
184 }
185 
key_falling_edge_handle(gpio_dev_t * gpio)186 static void key_falling_edge_handle(gpio_dev_t *gpio)
187 {
188     int         index    = -1;
189     gpio_dev_t *key_gpio = gpio;
190 
191     index = find_key_index(key_gpio);
192     if (index < 0 || index >= KEY_NUM) {
193         printf("err in %s:%d\n", __func__, __LINE__);
194         return;
195     }
196 
197     //printf(" %d key press\n", index);
198 #ifdef USING_VFS_GPIO
199     int ret = -1;
200     gpio_irq_config_t irq_config;
201     irq_config.id = key_gpio->port;
202     irq_config.config = GPIO_IRQ_CLEAR;
203 
204     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
205     if (ret) {
206         LOGE(TAG, "clear gpio irq:%d failed, ret %d", key_gpio->port, ret);
207         return;
208     }
209     irq_config.config = GPIO_IRQ_DISABLE;
210     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
211     if (ret) {
212         LOGE(TAG, "clear gpio irq:%d failed, ret %d", key_gpio->port, ret);
213         return;
214     }
215     key_dev_input[index].check_count  = 0;
216     key_dev_input[index].monitor_flag = 1;
217 
218     irq_config.id = key_gpio->port;
219     irq_config.config = GPIO_IRQ_ENABLE | GPIO_IRQ_EDGE_RISING;
220     irq_config.cb = key_rising_edge_handle;
221     irq_config.arg = key_gpio;
222 
223     ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
224     if (ret) {
225         LOGE(TAG, "enable gpio irq:%d failed, ret %d", ret);
226         return -1;
227     }
228 #else
229     hal_gpio_clear_irq(key_gpio);
230     hal_gpio_disable_irq(key_gpio);
231 
232     key_dev_input[index].check_count  = 0;
233     key_dev_input[index].monitor_flag = 1;
234 
235     hal_gpio_enable_irq(key_gpio, IRQ_TRIGGER_RISING_EDGE,
236                         key_rising_edge_handle, key_gpio);
237 #endif
238 }
239 
key_init(key_code_cb key_func)240 int key_init(key_code_cb key_func)
241 {
242     int32_t  ret = 0;
243     uint32_t i   = 0;
244     printf("enter %s:%d\n", __func__, __LINE__);
245 
246     if (key_func) {
247         notify_key_code_cb = key_func;
248     } else {
249         return -1;
250     }
251 #ifdef USING_VFS_GPIO
252     gpio_irq_config_t irq_config;
253     g_gpio_fd = open("/dev/gpio", 0);
254     if (g_gpio_fd < 0) {
255         printf("open /dev/gpio failed\n");
256         return -1;
257     }
258 #endif
259 
260     for (i = 0; i < KEY_NUM; i++) {
261 #ifdef USING_VFS_GPIO
262         irq_config.id = key_dev_input[i].gpio_dev.port;
263         irq_config.config = GPIO_IRQ_ENABLE | GPIO_IRQ_EDGE_FALLING;
264         irq_config.cb = key_falling_edge_handle;
265         irq_config.arg = &key_dev_input[i].gpio_dev;
266 
267         ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
268         if (ret) {
269             LOGE(TAG, "di %d pin %d fail enable irq ret %d", i,
270                  key_dev_input[i].gpio_dev.port, ret);
271             return -1;
272         }
273 #else
274         ret = hal_gpio_init(&key_dev_input[i].gpio_dev);
275         if (ret) {
276             LOGE(TAG, "di %d pin %d init fail ret", i,
277                  key_dev_input[i].gpio_dev.port, ret);
278             return -1;
279         }
280 
281         ret = hal_gpio_enable_irq(
282             &key_dev_input[i].gpio_dev, IRQ_TRIGGER_FALLING_EDGE,
283             key_falling_edge_handle, &key_dev_input[i].gpio_dev);
284         if (ret) {
285             LOGE(TAG, "di %d pin %d fail enable irq ret %d", i,
286                  key_dev_input[i].gpio_dev.port, ret);
287             return -1;
288         }
289 #endif
290         key_dev_input[i].installed = 1;
291     }
292 
293     /*init the gpio check timer, check gpio value every 30ms */
294     ret = aos_timer_new_ext(&key_poll_timer, key_poll, NULL,
295                             TIMER_CHECK_INTERVAL, 1, 1);
296     if (ret) {
297         LOGE(TAG, "Fail to new gpio value check timer ret 0x%x", ret);
298         for (i = 0; i < KEY_NUM; i++) {
299 #ifdef USING_VFS_GPIO
300         irq_config.id = key_dev_input[i].gpio_dev.port;
301         irq_config.config = GPIO_IRQ_DISABLE;
302         irq_config.cb = key_falling_edge_handle;
303         irq_config.arg = &key_dev_input[i].gpio_dev;
304 
305         ret = ioctl(g_gpio_fd, IOC_GPIO_SET_IRQ, &irq_config);
306         if (ret) {
307             LOGE(TAG, "di %d pin %d fail enable irq ret %d", i,
308                  key_dev_input[i].gpio_dev.port, ret);
309             return -1;
310         }
311 #else
312             hal_gpio_disable_irq(&key_dev_input[i].gpio_dev);
313             hal_gpio_finalize(&key_dev_input[i].gpio_dev);
314 #endif
315             key_dev_input[i].installed = 0;
316         }
317 #ifdef USING_VFS_GPIO
318         if (g_gpio_fd >= 0) {
319             close(g_gpio_fd);
320             g_gpio_fd = -1;
321         }
322 #endif
323         return -1;
324     }
325 
326     return 0;
327 }
328