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