1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 #include "plat_addr_map.h"
16 #include "plat_types.h"
17 #include "string.h"
18 #include "hal_iomux.h"
19 #include "hal_timer.h"
20 #include "hwtimer_list.h"
21 #include "hal_sleep.h"
22 #include "hal_trace.h"
23 #include "hal_chipid.h"
24 #include "hal_key.h"
25 #include "cmsis_nvic.h"
26 #include "pmu.h"
27 #include "tgt_hardware.h"
28
29 #ifdef KEY_DEBUG
30 #define HAL_KEY_TRACE(n, s, ...) TRACE(n, "[%u]" s, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__)
31 #else
32 #define HAL_KEY_TRACE(n, s, ...) TRACE_DUMMY(n, s, ##__VA_ARGS__)
33 #endif
34
35 // Warning on permanent press
36 #define KEY_PERMPRESS_WARNING
37
38 #ifdef CHIP_BEST2000
39 #define GPIO_MAP_64BIT
40 #endif
41
42 #ifdef GPIO_MAP_64BIT
43 typedef uint64_t GPIO_MAP_T;
44 #else
45 typedef uint32_t GPIO_MAP_T;
46 #endif
47
48 #ifndef APP_TEST_MODE
49 #define CHECK_PWRKEY_AT_BOOT
50 #endif
51 #ifdef NO_PWRKEY
52 #undef CHECK_PWRKEY_AT_BOOT
53 #endif
54 #ifdef NO_GPIOKEY
55 #undef CFG_HW_GPIOKEY_NUM
56 #define CFG_HW_GPIOKEY_NUM 0
57 #endif
58 #ifdef NO_ADCKEY
59 #undef CFG_HW_ADCKEY_NUMBER
60 #define CFG_HW_ADCKEY_NUMBER 0
61 #endif
62
63 #ifndef CFG_SW_KEY_LLPRESS_THRESH_MS
64 #define CFG_SW_KEY_LLPRESS_THRESH_MS 5000
65 #endif
66 #ifndef CFG_SW_KEY_LPRESS_THRESH_MS
67 #define CFG_SW_KEY_LPRESS_THRESH_MS 1500
68 #endif
69 #ifndef CFG_SW_KEY_REPEAT_THRESH_MS
70 #define CFG_SW_KEY_REPEAT_THRESH_MS 500
71 #endif
72 #ifndef CFG_SW_KEY_DBLCLICK_THRESH_MS
73 #define CFG_SW_KEY_DBLCLICK_THRESH_MS 400
74 #endif
75 #ifndef CFG_SW_KEY_INIT_DOWN_THRESH_MS
76 #define CFG_SW_KEY_INIT_DOWN_THRESH_MS 200
77 #endif
78 #ifndef CFG_SW_KEY_INIT_LPRESS_THRESH_MS
79 #define CFG_SW_KEY_INIT_LPRESS_THRESH_MS 3000
80 #endif
81 #ifndef CFG_SW_KEY_INIT_LLPRESS_THRESH_MS
82 #define CFG_SW_KEY_INIT_LLPRESS_THRESH_MS 10000
83 #endif
84 #ifndef CFG_SW_KEY_CHECK_INTERVAL_MS
85 #define CFG_SW_KEY_CHECK_INTERVAL_MS 40
86 #endif
87
88 //common key define
89 #define KEY_PERMPRESS_THRESHOLD MS_TO_TICKS(30000)
90 #define KEY_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LLPRESS_THRESH_MS)
91 #define KEY_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LPRESS_THRESH_MS)
92 #define KEY_DOUBLECLICK_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_DBLCLICK_THRESH_MS)
93 #define KEY_LONGPRESS_REPEAT_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_REPEAT_THRESH_MS)
94
95 #define KEY_INIT_DOWN_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_DOWN_THRESH_MS)
96 #define KEY_INIT_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LPRESS_THRESH_MS)
97 #define KEY_INIT_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LLPRESS_THRESH_MS)
98
99 #define KEY_CHECKER_INTERVAL MS_TO_TICKS(CFG_SW_KEY_CHECK_INTERVAL_MS)
100
101 #define KEY_DEBOUNCE_INTERVAL (KEY_CHECKER_INTERVAL * 2)
102 #define KEY_DITHER_INTERVAL (KEY_CHECKER_INTERVAL * 1)
103
104 #define MAX_KEY_CLICK_COUNT (HAL_KEY_EVENT_RAMPAGECLICK - HAL_KEY_EVENT_CLICK)
105
106 struct HAL_KEY_ADCKEY_T {
107 bool debounce;
108 bool dither;
109 enum HAL_KEY_CODE_T code_debounce;
110 enum HAL_KEY_CODE_T code_down;
111 uint32_t time;
112 };
113
114 struct HAL_KEY_GPIOKEY_T {
115 GPIO_MAP_T pin_debounce;
116 GPIO_MAP_T pin_dither;
117 GPIO_MAP_T pin_down;
118 uint32_t time_debounce;
119 uint32_t time_dither;
120 };
121
122 struct HAL_KEY_PWRKEY_T {
123 bool debounce;
124 bool dither;
125 bool pressed;
126 uint32_t time;
127 };
128
129 struct HAL_KEY_STATUS_T {
130 enum HAL_KEY_CODE_T code_down;
131 enum HAL_KEY_CODE_T code_ready;
132 enum HAL_KEY_CODE_T code_click;
133 enum HAL_KEY_EVENT_T event;
134 uint32_t time_updown;
135 uint32_t time_click;
136 uint8_t cnt_repeat;
137 uint8_t cnt_click;
138 };
139
140 static int (*key_detected_callback)(uint32_t, uint8_t) = NULL;
141 static HWTIMER_ID debounce_timer = NULL;
142 static bool timer_active = false;
143 static struct HAL_KEY_STATUS_T key_status;
144
145 #ifdef KEY_PERMPRESS_WARNING
146 static bool debounce_started = false;
147 static uint32_t time_first_debounce;
148 #endif
149
150 static void hal_key_disable_allint(void);
151 static void hal_key_enable_allint(void);
152 static uint32_t adc_key_status;
send_key_event(enum HAL_KEY_CODE_T code,enum HAL_KEY_EVENT_T event)153 static int send_key_event(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event)
154 {
155 for(int i = 0; i < CFG_HW_ADCKEY_NUMBER; i++) {
156 if(CFG_HW_ADCKEY_MAP_TABLE[i] == code) {
157 if (event == HAL_KEY_EVENT_DOWN)
158 adc_key_status |= CFG_HW_ADCKEY_MAP_TABLE[i];
159 else if (event == HAL_KEY_EVENT_UP)
160 adc_key_status &= ~CFG_HW_ADCKEY_MAP_TABLE[i];
161 }
162 }
163 if (key_detected_callback) {
164 return key_detected_callback(code, event);
165 }
166 return 0;
167 }
168
hal_key_debounce_timer_restart(void)169 static void hal_key_debounce_timer_restart(void)
170 {
171 uint32_t lock;
172 bool set = false;
173
174 lock = int_lock();
175 if (!timer_active) {
176 timer_active = true;
177 set = true;
178 }
179 int_unlock(lock);
180
181 if (set) {
182 hwtimer_stop(debounce_timer);
183 hwtimer_start(debounce_timer, KEY_CHECKER_INTERVAL);
184 //hal_sys_wake_lock(HAL_SYS_WAKE_LOCK_USER_KEY);
185 }
186 }
187
188 #if (CFG_HW_ADCKEY_NUMBER > 0)
189 static uint16_t adckey_volt_table[CFG_HW_ADCKEY_NUMBER];
190 struct HAL_KEY_ADCKEY_T adc_key;
191
hal_adckey_enable_press_int(void)192 static inline POSSIBLY_UNUSED void hal_adckey_enable_press_int(void)
193 {
194 hal_adckey_set_irq(HAL_ADCKEY_IRQ_PRESSED);
195 }
196
hal_adckey_enable_release_int(void)197 static inline POSSIBLY_UNUSED void hal_adckey_enable_release_int(void)
198 {
199 hal_adckey_set_irq(HAL_ADCKEY_IRQ_RELEASED);
200 }
201
hal_adckey_enable_adc_int(void)202 static inline POSSIBLY_UNUSED void hal_adckey_enable_adc_int(void)
203 {
204 hal_gpadc_open(HAL_GPADC_CHAN_ADCKEY, HAL_GPADC_ATP_NULL, NULL);
205 }
206
hal_adckey_disable_adc_int(void)207 static inline POSSIBLY_UNUSED void hal_adckey_disable_adc_int(void)
208 {
209 hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY);
210 }
211
hal_adckey_disable_allint(void)212 static inline POSSIBLY_UNUSED void hal_adckey_disable_allint(void)
213 {
214 hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY);
215 hal_adckey_set_irq(HAL_ADCKEY_IRQ_NONE);
216 }
217
hal_adckey_reset(void)218 static inline POSSIBLY_UNUSED void hal_adckey_reset(void)
219 {
220 memset(&adc_key, 0, sizeof(adc_key));
221 }
222
hal_adckey_findkey(uint16_t volt)223 static enum HAL_KEY_CODE_T hal_adckey_findkey(uint16_t volt)
224 {
225 int index = 0;
226
227 #if 0
228 if (volt == HAL_GPADC_BAD_VALUE) {
229 return HAL_KEY_CODE_NONE;
230 }
231 #endif
232 #if defined(NUTTX_BUILD)
233 if (volt == 0) volt++;
234 #endif
235 if (CFG_HW_ADCKEY_ADC_KEYVOLT_BASE <= volt && volt < CFG_HW_ADCKEY_ADC_MAXVOLT) {
236 for (index = 0; index < CFG_HW_ADCKEY_NUMBER; index++) {
237 if (volt <= adckey_volt_table[index]) {
238 return CFG_HW_ADCKEY_MAP_TABLE[index];
239 }
240 }
241 }
242
243 return HAL_KEY_CODE_NONE;
244 }
245
hal_adckey_irqhandler(enum HAL_ADCKEY_IRQ_STATUS_T irq_status,HAL_GPADC_MV_T val)246 static void hal_adckey_irqhandler(enum HAL_ADCKEY_IRQ_STATUS_T irq_status, HAL_GPADC_MV_T val)
247 {
248 enum HAL_KEY_CODE_T code;
249
250 #ifdef NO_GROUPKEY
251 hal_key_disable_allint();
252 #else
253 hal_adckey_disable_allint();
254 #endif
255
256 if (irq_status & (HAL_ADCKEY_ERR0 | HAL_ADCKEY_ERR1)) {
257 HAL_KEY_TRACE(1,"irq,adckey err 0x%04X", irq_status);
258 adc_key.debounce = true;
259 adc_key.code_debounce = HAL_KEY_CODE_NONE;
260 goto _debounce;
261 }
262 if (irq_status & HAL_ADCKEY_PRESSED) {
263 HAL_KEY_TRACE(0,"irq,adckey press");
264 adc_key.debounce = true;
265 adc_key.code_debounce = HAL_KEY_CODE_NONE;
266 adc_key.time = hal_sys_timer_get();
267 hal_adckey_enable_adc_int();
268 goto _exit;
269 }
270 if (irq_status & HAL_ADCKEY_RELEASED) {
271 HAL_KEY_TRACE(0,"irq,adckey release");
272 adc_key.code_debounce = HAL_KEY_CODE_NONE;
273 goto _debounce;
274 }
275 if(irq_status & HAL_ADCKEY_ADC_VALID) {
276 code = hal_adckey_findkey(val);
277 HAL_KEY_TRACE(3,"irq,adckey cur:0x%X pre:0x%X volt:%d", code, adc_key.code_debounce, val);
278
279 if (adc_key.code_debounce == HAL_KEY_CODE_NONE) {
280 adc_key.code_debounce = code;
281 } else if (adc_key.code_debounce != code) {
282 adc_key.code_debounce = HAL_KEY_CODE_NONE;
283 }
284 }
285
286 _debounce:
287 hal_key_debounce_timer_restart();
288 _exit:
289 return;
290 }
291
hal_adckey_open(void)292 static void hal_adckey_open(void)
293 {
294 uint16_t i;
295
296 hal_adckey_reset();
297 /*
298 uint32_t basevolt;
299 basevolt = (CFG_HW_ADCKEY_ADC_MAXVOLT - CFG_HW_ADCKEY_ADC_MINVOLT) / (CFG_HW_ADCKEY_NUMBER + 2);
300
301 adckey_volt_table[0] = CFG_HW_ADCKEY_ADC_KEYVOLT_BASE + basevolt;
302
303 for(i = 1; i < CFG_HW_ADCKEY_NUMBER-1; i++) {
304 adckey_volt_table[i] = adckey_volt_table[i - 1] + basevolt;
305 }
306 adckey_volt_table[CFG_HW_ADCKEY_NUMBER - 1] = CFG_HW_ADCKEY_ADC_MAXVOLT;
307 */
308 for(i=0; i< CFG_HW_ADCKEY_NUMBER; ++i)
309 adckey_volt_table[i] = CFG_HW_ADCKEY_VOL_TABLE[i];
310 hal_adckey_set_irq_handler(hal_adckey_irqhandler);
311 }
312
hal_adckey_close(void)313 static void hal_adckey_close(void)
314 {
315 HAL_KEY_TRACE(1,"%s\n", __func__);
316
317 hal_adckey_reset();
318
319 hal_adckey_disable_allint();
320 }
321 #endif // (CFG_HW_ADCKEY_NUMBER > 0)
322
323 #ifndef NO_PWRKEY
324 struct HAL_KEY_PWRKEY_T pwr_key;
325
hal_pwrkey_enable_riseedge_int(void)326 static inline POSSIBLY_UNUSED void hal_pwrkey_enable_riseedge_int(void)
327 {
328 hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_RISING_EDGE);
329 }
330
hal_pwrkey_enable_falledge_int(void)331 static inline POSSIBLY_UNUSED void hal_pwrkey_enable_falledge_int(void)
332 {
333 hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_FALLING_EDGE);
334 }
335
hal_pwrkey_enable_bothedge_int(void)336 static inline POSSIBLY_UNUSED void hal_pwrkey_enable_bothedge_int(void)
337 {
338 hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_BOTH_EDGE);
339 }
340
hal_pwrkey_enable_int(void)341 static inline void hal_pwrkey_enable_int(void)
342 {
343 #ifdef __POWERKEY_CTRL_ONOFF_ONLY__
344 hal_pwrkey_enable_riseedge_int();
345 #else
346 hal_pwrkey_enable_falledge_int();
347 #endif
348 }
349
hal_pwrkey_disable_int(void)350 static inline void hal_pwrkey_disable_int(void)
351 {
352 hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_NONE);
353 }
354
hal_pwrkey_reset(void)355 static inline void hal_pwrkey_reset(void)
356 {
357 memset(&pwr_key, 0, sizeof(pwr_key));
358 }
359
hal_pwrkey_get_status(void)360 static inline bool hal_pwrkey_get_status(void)
361 {
362 #ifdef CHIP_BEST1000
363 if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
364 return pwr_key.pressed;
365 } else
366 #endif
367 {
368 return hal_pwrkey_pressed();
369 }
370 }
371
hal_pwrkey_handle_irq_state(enum HAL_PWRKEY_IRQ_T state)372 static void hal_pwrkey_handle_irq_state(enum HAL_PWRKEY_IRQ_T state)
373 {
374 uint32_t time = hal_sys_timer_get();
375
376 #ifdef NO_GROUPKEY
377 hal_key_disable_allint();
378 #else
379 hal_pwrkey_disable_int();
380 #endif
381
382 #ifdef __POWERKEY_CTRL_ONOFF_ONLY__
383
384 if (state & HAL_PWRKEY_IRQ_RISING_EDGE) {
385 HAL_KEY_TRACE(0,"pwr_key irq up");
386 pwr_key.debounce = true;
387 }
388
389 #else // !__POWERKEY_CTRL_ONOFF_ONLY__
390
391 if (state & HAL_PWRKEY_IRQ_FALLING_EDGE) {
392 HAL_KEY_TRACE(0,"pwr_key irq down");
393 #ifdef CHIP_BEST1000
394 if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
395 pwr_key.debounce = true;
396 pwr_key.pressed = true;
397 hal_pwrkey_enable_riseedge_int();
398 } else
399 #endif
400 {
401 pwr_key.pressed = hal_pwrkey_pressed();
402 if (pwr_key.pressed) {
403 pwr_key.debounce = true;
404 } else {
405 pwr_key.dither = true;
406 }
407 }
408 pwr_key.time = time;
409 }
410
411 #ifdef CHIP_BEST1000
412 if (state & HAL_PWRKEY_IRQ_RISING_EDGE) {
413 if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
414 HAL_KEY_TRACE(0,"pwr_key irq up");
415 pwr_key.pressed = false;
416 hal_pwrkey_enable_falledge_int();
417 }
418 }
419 #endif
420
421 #endif // !__POWERKEY_CTRL_ONOFF_ONLY__
422
423 hal_key_debounce_timer_restart();
424 }
425
426 #ifdef CHIP_HAS_EXT_PMU
427 #define PWRKEY_IRQ_HDLR_PARAM uint16_t irq_status
428 #else
429 #define PWRKEY_IRQ_HDLR_PARAM void
430 #endif
hal_pwrkey_irqhandler(PWRKEY_IRQ_HDLR_PARAM)431 static void hal_pwrkey_irqhandler(PWRKEY_IRQ_HDLR_PARAM)
432 {
433 enum HAL_PWRKEY_IRQ_T state;
434
435 #ifdef CHIP_HAS_EXT_PMU
436 state = pmu_pwrkey_irq_value_to_state(irq_status);
437 #else
438 state = hal_pwrkey_get_irq_state();
439 #endif
440
441 HAL_KEY_TRACE(2,"%s: %08x", __func__, state);
442
443 hal_pwrkey_handle_irq_state(state);
444 }
445
hal_pwrkey_open(void)446 static void hal_pwrkey_open(void)
447 {
448 hal_pwrkey_reset();
449
450 #ifdef CHIP_HAS_EXT_PMU
451 pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, hal_pwrkey_irqhandler);
452 #else
453 NVIC_SetVector(PWRKEY_IRQn, (uint32_t)hal_pwrkey_irqhandler);
454 NVIC_SetPriority(PWRKEY_IRQn, IRQ_PRIORITY_NORMAL);
455 NVIC_ClearPendingIRQ(PWRKEY_IRQn);
456 NVIC_EnableIRQ(PWRKEY_IRQn);
457 #endif
458 }
459
hal_pwrkey_close(void)460 static void hal_pwrkey_close(void)
461 {
462 hal_pwrkey_reset();
463
464 hal_pwrkey_disable_int();
465
466 #ifdef CHIP_HAS_EXT_PMU
467 pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, NULL);
468 #else
469 NVIC_SetVector(PWRKEY_IRQn, (uint32_t)NULL);
470 NVIC_DisableIRQ(PWRKEY_IRQn);
471 #endif
472 }
473 #endif // !NO_PWRKEY
474
475 #if (CFG_HW_GPIOKEY_NUM > 0)
476 struct HAL_KEY_GPIOKEY_T gpio_key;
477
478 static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin);
479
hal_gpiokey_reset(void)480 static inline void hal_gpiokey_reset(void)
481 {
482 memset(&gpio_key, 0, sizeof(gpio_key));
483 }
484
hal_gpiokey_find_index(enum HAL_GPIO_PIN_T pin)485 static int hal_gpiokey_find_index(enum HAL_GPIO_PIN_T pin)
486 {
487 int i;
488
489 for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
490 if (cfg_hw_gpio_key_cfg[i].key_config.pin == (enum HAL_IOMUX_PIN_T)pin) {
491 return i;
492 }
493 }
494
495 ASSERT(i < CFG_HW_GPIOKEY_NUM, "GPIOKEY IRQ: Invalid pin=%d", pin);
496 return i;
497 }
498
hal_gpiokey_pressed(enum HAL_GPIO_PIN_T pin)499 static bool hal_gpiokey_pressed(enum HAL_GPIO_PIN_T pin)
500 {
501 int i = hal_gpiokey_find_index(pin);
502 return (hal_gpio_pin_get_val(pin) == cfg_hw_gpio_key_cfg[i].key_down);
503 }
504
hal_gpiokey_irqhandler(enum HAL_GPIO_PIN_T pin)505 static void hal_gpiokey_irqhandler(enum HAL_GPIO_PIN_T pin)
506 {
507 bool pressed;
508 uint32_t lock;
509 uint32_t time;
510
511 #ifdef NO_GROUPKEY
512 hal_key_disable_allint();
513 #else
514 hal_gpiokey_disable_irq(pin);
515 #endif
516
517 pressed = hal_gpiokey_pressed(pin);
518 HAL_KEY_TRACE(2,"gpio_key trig=%d pressed=%d", pin, pressed);
519
520 time = hal_sys_timer_get();
521
522 lock = int_lock();
523 if (pressed) {
524 gpio_key.pin_debounce |= ((GPIO_MAP_T)1 << pin);
525 gpio_key.time_debounce = time;
526 } else {
527 gpio_key.pin_dither |= ((GPIO_MAP_T)1 << pin);
528 gpio_key.time_dither = time;
529 }
530 int_unlock(lock);
531
532 hal_key_debounce_timer_restart();
533 }
534
hal_gpiokey_enable_irq(enum HAL_GPIO_PIN_T pin,enum HAL_GPIO_IRQ_POLARITY_T polarity)535 static void hal_gpiokey_enable_irq(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_IRQ_POLARITY_T polarity)
536 {
537 struct HAL_GPIO_IRQ_CFG_T gpiocfg;
538
539 hal_gpio_pin_set_dir(pin, HAL_GPIO_DIR_IN, 0);
540
541 gpiocfg.irq_enable = true;
542 gpiocfg.irq_debounce = true;
543 gpiocfg.irq_polarity = polarity;
544 gpiocfg.irq_handler = hal_gpiokey_irqhandler;
545 gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE;
546
547 hal_gpio_setup_irq(pin, &gpiocfg);
548 }
549
hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin)550 static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin)
551 {
552 static const struct HAL_GPIO_IRQ_CFG_T gpiocfg = {
553 .irq_enable = false,
554 .irq_debounce = false,
555 .irq_polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING,
556 .irq_handler = NULL,
557 .irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE,
558 };
559
560 hal_gpio_setup_irq(pin, &gpiocfg);
561 }
562
hal_gpiokey_enable_allint(void)563 static inline void hal_gpiokey_enable_allint(void)
564 {
565 uint8_t i;
566 enum HAL_GPIO_IRQ_POLARITY_T polarity;
567
568 for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++){
569 if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
570 continue;
571 }
572
573 if (cfg_hw_gpio_key_cfg[i].key_down == HAL_KEY_GPIOKEY_VAL_LOW) {
574 polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING;
575 } else {
576 polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING;
577 }
578 hal_gpiokey_enable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin, polarity);
579 }
580 }
581
hal_gpiokey_disable_allint(void)582 static inline void hal_gpiokey_disable_allint(void)
583 {
584 uint8_t i;
585
586 for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
587 if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
588 continue;
589 }
590
591 hal_gpiokey_disable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin);
592 }
593 }
594
hal_gpiokey_open(void)595 static void hal_gpiokey_open(void)
596 {
597 uint8_t i;
598 HAL_KEY_TRACE(1,"%s\n", __func__);
599
600 hal_gpiokey_reset();
601
602 for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
603 if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
604 continue;
605 }
606
607 hal_iomux_init(&cfg_hw_gpio_key_cfg[i].key_config, 1);
608 }
609 }
610
hal_gpiokey_close(void)611 static void hal_gpiokey_close(void)
612 {
613 HAL_KEY_TRACE(1,"%s\n", __func__);
614
615 hal_gpiokey_reset();
616
617 hal_gpiokey_disable_allint();
618 }
619 #endif // (CFG_HW_GPIOKEY_NUM > 0)
620
hal_key_read_status(enum HAL_KEY_CODE_T code)621 enum HAL_KEY_EVENT_T hal_key_read_status(enum HAL_KEY_CODE_T code)
622 {
623 uint8_t gpio_val;
624 int i;
625
626 if (code == HAL_KEY_CODE_PWR){
627 if (hal_pwrkey_pressed())
628 return HAL_KEY_EVENT_DOWN;
629 else
630 return HAL_KEY_EVENT_UP;
631 }else{
632 for(i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
633 if(cfg_hw_gpio_key_cfg[i].key_code == code) {
634 gpio_val = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin);
635 if (gpio_val == cfg_hw_gpio_key_cfg[i].key_down) {
636 return HAL_KEY_EVENT_DOWN;
637 } else {
638 return HAL_KEY_EVENT_UP;
639 }
640 }
641 }
642 for(i = 0; i < CFG_HW_ADCKEY_NUMBER; i++) {
643 if(CFG_HW_ADCKEY_MAP_TABLE[i] == code) {
644 if (adc_key_status & CFG_HW_ADCKEY_MAP_TABLE[i]) {
645 return HAL_KEY_EVENT_DOWN;
646 } else {
647 return HAL_KEY_EVENT_UP;
648 }
649 }
650 }
651 }
652 return HAL_KEY_EVENT_NONE;
653 }
654
hal_key_disable_allint(void)655 static void hal_key_disable_allint(void)
656 {
657 #ifndef NO_PWRKEY
658 hal_pwrkey_disable_int();
659 #endif
660
661 #if (CFG_HW_ADCKEY_NUMBER > 0)
662 hal_adckey_disable_allint();
663 #endif
664
665 #if (CFG_HW_GPIOKEY_NUM > 0)
666 hal_gpiokey_disable_allint();
667 #endif
668 }
669
hal_key_enable_allint(void)670 static void hal_key_enable_allint(void)
671 {
672 #ifndef NO_PWRKEY
673 hal_pwrkey_enable_int();
674 #endif
675
676 #if (CFG_HW_ADCKEY_NUMBER > 0)
677 hal_adckey_enable_press_int();
678 #endif
679
680 #if (CFG_HW_GPIOKEY_NUM > 0)
681 hal_gpiokey_enable_allint();
682 #endif
683 }
684
hal_key_debounce_handler(void * param)685 static void hal_key_debounce_handler(void *param)
686 {
687 uint32_t time;
688 enum HAL_KEY_CODE_T code_down = HAL_KEY_CODE_NONE;
689 int index;
690 bool need_timer = false;
691
692 timer_active = false;
693
694 time = hal_sys_timer_get();
695
696 #ifndef NO_PWRKEY
697 #ifdef __POWERKEY_CTRL_ONOFF_ONLY__
698 if (pwr_key.debounce) {
699 pwr_key.debounce = false;
700 code_down |= HAL_KEY_CODE_PWR;
701 #ifdef NO_GROUPKEY
702 hal_key_enable_allint();
703 #else
704 hal_pwrkey_enable_int();
705 #endif
706 }
707 #else
708 if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
709 bool pressed = hal_pwrkey_get_status();
710
711 //HAL_KEY_TRACE(4,"keyDbnPwr: dbn=%d dither=%d pressed=%d/%d", pwr_key.debounce, pwr_key.dither, pwr_key.pressed, pressed);
712
713 if (pwr_key.debounce) {
714 pwr_key.pressed = pressed;
715 if (pressed) {
716 pwr_key.dither = false;
717 if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) {
718 pwr_key.debounce = false;
719 pwr_key.dither = false;
720 code_down |= HAL_KEY_CODE_PWR;
721 }
722 } else {
723 pwr_key.debounce = false;
724 pwr_key.dither = true;
725 pwr_key.time = time;
726 }
727 } else if (pwr_key.dither) {
728 if (time - pwr_key.time >= KEY_DITHER_INTERVAL) {
729 pwr_key.dither = false;
730 pwr_key.pressed = false;
731 #ifdef NO_GROUPKEY
732 hal_key_enable_allint();
733 #else
734 hal_pwrkey_enable_int();
735 #endif
736 }
737 } else if (pwr_key.pressed) {
738 if (pressed) {
739 code_down |= HAL_KEY_CODE_PWR;
740 } else {
741 pwr_key.pressed = false;
742 #ifdef NO_GROUPKEY
743 hal_key_enable_allint();
744 #else
745 hal_pwrkey_enable_int();
746 #endif
747 }
748 }
749 }
750 if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
751 need_timer = true;
752 }
753 #endif
754 #endif
755
756 #if (CFG_HW_ADCKEY_NUMBER > 0)
757 if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) {
758 bool skip_check = false;
759
760 //HAL_KEY_TRACE(4,"keyDbnAdc: dbn=%d dither=%d code_dbn=0x%X code_down=0x%X", adc_key.debounce, adc_key.dither, adc_key.code_debounce, adc_key.code_down);
761
762 if (adc_key.debounce) {
763 if (adc_key.code_debounce == HAL_KEY_CODE_NONE) {
764 adc_key.debounce = false;
765 adc_key.dither = true;
766 adc_key.time = time;
767 } else {
768 if (time - adc_key.time >= KEY_DEBOUNCE_INTERVAL) {
769 adc_key.debounce = false;
770 adc_key.dither = false;
771 adc_key.code_down = adc_key.code_debounce;
772 adc_key.code_debounce = HAL_KEY_CODE_NONE;
773 code_down |= adc_key.code_down;
774 }
775 }
776 } else if (adc_key.dither) {
777 if (time - adc_key.time >= KEY_DITHER_INTERVAL) {
778 adc_key.dither = false;
779 adc_key.code_debounce = HAL_KEY_CODE_NONE;
780 adc_key.code_down = HAL_KEY_CODE_NONE;
781 #ifdef NO_GROUPKEY
782 hal_key_enable_allint();
783 #else
784 hal_adckey_enable_press_int();
785 #endif
786 }
787 skip_check = true;
788 } else if (adc_key.code_down != HAL_KEY_CODE_NONE) {
789 if (adc_key.code_debounce == adc_key.code_down) {
790 code_down |= adc_key.code_down;
791 } else {
792 adc_key.code_down = HAL_KEY_CODE_NONE;
793 #ifdef NO_GROUPKEY
794 hal_key_enable_allint();
795 #else
796 hal_adckey_enable_press_int();
797 #endif
798 skip_check = true;
799 }
800 }
801
802 if (!skip_check) {
803 hal_adckey_enable_adc_int();
804 }
805 }
806 if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) {
807 need_timer = true;
808 }
809 #endif
810
811 #if (CFG_HW_GPIOKEY_NUM > 0)
812 enum HAL_GPIO_PIN_T gpio;
813 GPIO_MAP_T pin;
814 uint32_t lock;
815
816 #ifdef GPIO_MAP_64BIT
817 ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
818 (gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
819 (gpio_key.pin_debounce & gpio_key.pin_dither) == 0,
820 "Bad gpio_key pin map: dbn=0x%X-%X dither=0x%X-%X down=0x%X-%X",
821 (uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce),
822 (uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither),
823 (uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down));
824 #if 0
825 HAL_KEY_TRACE(6,"keyDbnGpio: pin_dbn=0x%X-%X pin_dither=0x%X-%X pin_down=0x%X-%X",
826 (uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce),
827 (uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither),
828 (uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down));
829 #endif
830 #else // !GPIO_MAP_64BIT
831 ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
832 (gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
833 (gpio_key.pin_debounce & gpio_key.pin_dither) == 0,
834 "Bad gpio_key pin map: dbn=0x%X dither=0x%X down=0x%X",
835 (uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down);
836 #if 0
837 HAL_KEY_TRACE(3,"keyDbnGpio: pin_dbn=0x%X pin_dither=0x%X pin_down=0x%X",
838 (uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down);
839 #endif
840 #endif // !GPIO_MAP_64BIT
841
842 if (gpio_key.pin_dither) {
843 if (time - gpio_key.time_dither >= KEY_DITHER_INTERVAL) {
844 pin = gpio_key.pin_dither;
845
846 lock = int_lock();
847 gpio_key.pin_dither &= ~pin;
848 int_unlock(lock);
849
850 #ifdef NO_GROUPKEY
851 hal_key_enable_allint();
852 #else
853 gpio = HAL_GPIO_PIN_P0_0;
854 while (pin) {
855 if (pin & ((GPIO_MAP_T)1 << gpio)) {
856 pin &= ~((GPIO_MAP_T)1 << gpio);
857 index = hal_gpiokey_find_index(gpio);
858 hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ?
859 HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING);
860 }
861 gpio++;
862 }
863 #endif
864 }
865 }
866 if (gpio_key.pin_down) {
867 pin = gpio_key.pin_down;
868
869 gpio = HAL_GPIO_PIN_P0_0;
870 while (pin) {
871 if (pin & ((GPIO_MAP_T)1 << gpio)) {
872 pin &= ~((GPIO_MAP_T)1 << gpio);
873 index = hal_gpiokey_find_index(gpio);
874 if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) {
875 code_down |= cfg_hw_gpio_key_cfg[index].key_code;
876 } else {
877 gpio_key.pin_down &= ~((GPIO_MAP_T)1 << gpio);
878 #ifdef NO_GROUPKEY
879 hal_key_enable_allint();
880 #else
881 hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ?
882 HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING);
883 #endif
884 }
885 }
886 gpio++;
887 }
888 }
889 if (gpio_key.pin_debounce) {
890 GPIO_MAP_T down_added = 0;
891 GPIO_MAP_T dither_added = 0;
892
893 pin = gpio_key.pin_debounce;
894
895 gpio = HAL_GPIO_PIN_P0_0;
896 while (pin) {
897 if (pin & ((GPIO_MAP_T)1 << gpio)) {
898 pin &= ~((GPIO_MAP_T)1 << gpio);
899 index = hal_gpiokey_find_index(gpio);
900 if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) {
901 if (time - gpio_key.time_debounce >= KEY_DEBOUNCE_INTERVAL) {
902 down_added |= ((GPIO_MAP_T)1 << gpio);
903 code_down |= cfg_hw_gpio_key_cfg[index].key_code;
904 gpio_key.pin_down |= ((GPIO_MAP_T)1 << gpio);
905 }
906 } else {
907 dither_added |= ((GPIO_MAP_T)1 << gpio);
908 }
909 }
910 gpio++;
911 }
912
913 lock = int_lock();
914 gpio_key.pin_debounce &= ~(down_added | dither_added);
915 gpio_key.pin_dither |= dither_added;
916 int_unlock(lock);
917 }
918 if (gpio_key.pin_dither || gpio_key.pin_down || gpio_key.pin_debounce) {
919 need_timer = true;
920 }
921 #endif
922
923 enum HAL_KEY_CODE_T down_new;
924 enum HAL_KEY_CODE_T up_new;
925 enum HAL_KEY_CODE_T map;
926
927 down_new = code_down & ~key_status.code_down;
928 up_new = ~code_down & key_status.code_down;
929
930 //HAL_KEY_TRACE(5,"keyDbn: code_down=0x%X/0x%X down_new=0x%X up_new=0x%X event=%d", key_status.code_down, code_down, down_new, up_new, key_status.event);
931
932 // Check newly up keys
933 map = up_new;
934 index = 0;
935 while (map) {
936 if (map & (1 << index)) {
937 map &= ~(1 << index);
938 send_key_event((1 << index), HAL_KEY_EVENT_UP);
939 if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
940 send_key_event((1 << index), HAL_KEY_EVENT_UP_AFTER_LONGPRESS);
941 }
942 key_status.time_updown = time;
943 }
944 index++;
945 }
946
947 if (up_new) {
948 if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
949 // LongPress is finished when all of the LongPress keys are released
950 if ((code_down & key_status.code_ready) == 0) {
951 key_status.event = HAL_KEY_EVENT_NONE;
952 }
953 } else if (key_status.event == HAL_KEY_EVENT_DOWN) {
954 // Enter click handling if not in LongPress
955 key_status.event = HAL_KEY_EVENT_UP;
956 }
957 }
958
959 if (key_status.event == HAL_KEY_EVENT_UP) {
960 //ASSERT(key_status.code_ready != HAL_KEY_CODE_NONE, "Bad code_ready");
961
962 if (key_status.code_click == HAL_KEY_CODE_NONE || key_status.code_click != key_status.code_ready) {
963 if (key_status.code_click != HAL_KEY_CODE_NONE) {
964 send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click);
965 }
966 key_status.code_click = key_status.code_ready;
967 key_status.cnt_click = 0;
968 key_status.time_click = time;
969 } else if (up_new && (up_new | key_status.code_down) == key_status.code_click) {
970 key_status.cnt_click++;
971 key_status.time_click = time;
972 }
973 if (time - key_status.time_click >= KEY_DOUBLECLICK_THRESHOLD || key_status.cnt_click >= MAX_KEY_CLICK_COUNT) {
974 send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click);
975 key_status.code_click = HAL_KEY_CODE_NONE;
976 key_status.cnt_click = 0;
977 key_status.event = HAL_KEY_EVENT_NONE;
978 }
979 }
980
981 // Update key_status.code_down
982 key_status.code_down = code_down;
983
984 // Check newly down keys and update key_status.code_ready
985 map = down_new;
986 index = 0;
987 while (map) {
988 if (map & (1 << index)) {
989 map &= ~(1 << index);
990 send_key_event((1 << index), HAL_KEY_EVENT_DOWN);
991 if (key_status.event == HAL_KEY_EVENT_NONE) {
992 send_key_event((1 << index), HAL_KEY_EVENT_FIRST_DOWN);
993 } else {
994 send_key_event((1 << index), HAL_KEY_EVENT_CONTINUED_DOWN);
995 }
996 if (key_status.event == HAL_KEY_EVENT_NONE ||
997 key_status.event == HAL_KEY_EVENT_DOWN ||
998 key_status.event == HAL_KEY_EVENT_UP) {
999 key_status.code_ready = code_down;
1000 }
1001 key_status.time_updown = time;
1002 }
1003 index++;
1004 }
1005
1006 if (down_new) {
1007 if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_UP) {
1008 key_status.event = HAL_KEY_EVENT_DOWN;
1009 }
1010 }
1011
1012 // LongPress should be stopped if any key is released
1013 if ((code_down & key_status.code_ready) == key_status.code_ready) {
1014 if (key_status.event == HAL_KEY_EVENT_DOWN) {
1015 if (time - key_status.time_updown >= KEY_LONGPRESS_THRESHOLD) {
1016 key_status.cnt_repeat = 0;
1017 key_status.event = HAL_KEY_EVENT_LONGPRESS;
1018 send_key_event(key_status.code_ready, key_status.event);
1019 }
1020 } else if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
1021 key_status.cnt_repeat++;
1022 if (key_status.cnt_repeat == KEY_LONGPRESS_REPEAT_THRESHOLD / KEY_CHECKER_INTERVAL) {
1023 key_status.cnt_repeat = 0;
1024 send_key_event(key_status.code_ready, HAL_KEY_EVENT_REPEAT);
1025 }
1026 if (key_status.event == HAL_KEY_EVENT_LONGPRESS) {
1027 if (time - key_status.time_updown >= KEY_LONGLONGPRESS_THRESHOLD) {
1028 key_status.event = HAL_KEY_EVENT_LONGLONGPRESS;
1029 send_key_event(key_status.code_ready, key_status.event);
1030 }
1031 }
1032 }
1033 }
1034
1035 if (key_status.event != HAL_KEY_EVENT_NONE) {
1036 need_timer = true;
1037
1038 #ifdef KEY_PERMPRESS_WARNING
1039 if (debounce_started) {
1040 if (time - time_first_debounce >= KEY_PERMPRESS_THRESHOLD) {
1041 time_first_debounce = time;
1042 #if (CFG_HW_GPIOKEY_NUM > 0)
1043 #ifdef GPIO_MAP_64BIT
1044 #define GPIO_DOWN_STR " gpio_down=0x%X-%X"
1045 #define GPIO_DOWN_VAL , (uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down)
1046 #else
1047 #define GPIO_DOWN_STR " gpio_down=0x%X"
1048 #define GPIO_DOWN_VAL , (uint32_t)(gpio_key.pin_down)
1049 #endif
1050 #else
1051 #define GPIO_DOWN_STR
1052 #define GPIO_DOWN_VAL
1053 #endif
1054 TR_WARN(0, "*** WARNING:keyDbn: Permanent key press? code_down=0x%X" GPIO_DOWN_STR, code_down GPIO_DOWN_VAL);
1055 }
1056 } else {
1057 debounce_started = true;
1058 time_first_debounce = time;
1059 }
1060 #endif
1061 }
1062
1063 if (need_timer) {
1064 hal_key_debounce_timer_restart();
1065 } else {
1066 //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
1067 #ifdef KEY_PERMPRESS_WARNING
1068 debounce_started = false;
1069 #endif
1070 }
1071 }
1072
1073 #ifdef CHECK_PWRKEY_AT_BOOT
hal_key_boot_handler(void * param)1074 static void hal_key_boot_handler(void *param)
1075 {
1076 #ifndef NO_PWRKEY
1077 uint32_t time;
1078
1079 timer_active = false;
1080
1081 time = hal_sys_timer_get();
1082
1083 if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
1084 bool pressed = hal_pwrkey_get_status();
1085
1086 //HAL_KEY_TRACE(5,"keyBoot: dbn=%d dither=%d pressed=%d/%d event=%d", pwr_key.debounce, pwr_key.dither, pwr_key.pressed, pressed, key_status.event);
1087
1088 if (pwr_key.debounce) {
1089 pwr_key.pressed = pressed;
1090 if (pressed) {
1091 pwr_key.dither = false;
1092 if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) {
1093 pwr_key.debounce = false;
1094 key_status.time_updown = time;
1095 }
1096 } else {
1097 pwr_key.debounce = false;
1098 pwr_key.dither = true;
1099 pwr_key.time = time;
1100 }
1101 } else if (pwr_key.dither) {
1102 if (time - pwr_key.time >= KEY_DITHER_INTERVAL) {
1103 pwr_key.dither = false;
1104 pwr_key.pressed = false;
1105 }
1106 } else if (pwr_key.pressed) {
1107 if (!pressed) {
1108 pwr_key.pressed = false;
1109 }
1110 }
1111 }
1112 if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
1113 if (pwr_key.pressed) {
1114 if (key_status.event == HAL_KEY_EVENT_NONE) {
1115 if (time - key_status.time_updown >= KEY_INIT_DOWN_THRESHOLD) {
1116 key_status.event = HAL_KEY_EVENT_INITDOWN;
1117 send_key_event(HAL_KEY_CODE_PWR, key_status.event);
1118 }
1119 } else if (key_status.event == HAL_KEY_EVENT_INITDOWN) {
1120 if (time - key_status.time_updown >= KEY_INIT_LONGPRESS_THRESHOLD) {
1121 key_status.cnt_repeat = 0;
1122 key_status.event = HAL_KEY_EVENT_INITLONGPRESS;
1123 send_key_event(HAL_KEY_CODE_PWR, key_status.event);
1124 }
1125 } else if (key_status.event == HAL_KEY_EVENT_INITLONGPRESS) {
1126 if (time - key_status.time_updown >= KEY_INIT_LONGLONGPRESS_THRESHOLD) {
1127 key_status.event = HAL_KEY_EVENT_INITLONGLONGPRESS;
1128 send_key_event(HAL_KEY_CODE_PWR, key_status.event);
1129 }
1130 }
1131 }
1132 hal_key_debounce_timer_restart();
1133 } else {
1134 if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_INITDOWN) {
1135 send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITUP);
1136 }
1137 send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITFINISHED);
1138
1139 hwtimer_update(debounce_timer, hal_key_debounce_handler, NULL);
1140 //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
1141
1142 memset(&key_status, 0, sizeof(key_status));
1143 hal_pwrkey_reset();
1144 hal_key_enable_allint();
1145 }
1146 #endif
1147 }
1148 #endif //CHECK_PWRKEY_AT_BOOT
1149
hal_key_open(int checkPwrKey,int (* cb)(uint32_t,uint8_t))1150 int hal_key_open(int checkPwrKey, int (* cb)(uint32_t, uint8_t))
1151 {
1152 int nRet = 0;
1153 uint32_t lock;
1154
1155 key_detected_callback = cb;
1156
1157 memset(&key_status, 0, sizeof(key_status));
1158
1159 lock = int_lock();
1160
1161 #ifdef CHECK_PWRKEY_AT_BOOT
1162 if (checkPwrKey) {
1163 int cnt;
1164 int i = 0;
1165
1166 cnt = 10;
1167 do {
1168 hal_sys_timer_delay(MS_TO_TICKS(20));
1169 if (!hal_pwrkey_startup_pressed()) {
1170 HAL_KEY_TRACE(0,"pwr_key init DITHERING");
1171 nRet = -1;
1172 goto _exit;
1173 }
1174 } while (++i < cnt);
1175 }
1176 #endif
1177
1178 #ifndef NO_PWRKEY
1179 hal_pwrkey_open();
1180 #endif
1181 #if (CFG_HW_ADCKEY_NUMBER > 0)
1182 hal_adckey_open();
1183 #endif
1184 #if (CFG_HW_GPIOKEY_NUM > 0)
1185 hal_gpiokey_open();
1186 #endif
1187
1188 #ifdef CHECK_PWRKEY_AT_BOOT
1189 #ifndef __POWERKEY_CTRL_ONOFF_ONLY__
1190 if (checkPwrKey) {
1191 debounce_timer = hwtimer_alloc(hal_key_boot_handler, NULL);
1192 hal_pwrkey_handle_irq_state(HAL_PWRKEY_IRQ_FALLING_EDGE);
1193 } else
1194 #endif
1195 #endif
1196 {
1197 debounce_timer = hwtimer_alloc(hal_key_debounce_handler, NULL);
1198 hal_key_enable_allint();
1199 }
1200
1201 ASSERT(debounce_timer, "Failed to alloc key debounce timer");
1202
1203 goto _exit; // Avoid compiler warnings
1204
1205 _exit:
1206 int_unlock(lock);
1207
1208 return nRet;
1209 }
1210
hal_key_close(void)1211 int hal_key_close(void)
1212 {
1213 hal_key_disable_allint();
1214
1215 #ifndef NO_PWRKEY
1216 hal_pwrkey_close();
1217 #endif
1218 #if (CFG_HW_ADCKEY_NUMBER > 0)
1219 hal_adckey_close();
1220 #endif
1221 #if (CFG_HW_GPIOKEY_NUM > 0)
1222 hal_gpiokey_close();
1223 #endif
1224
1225 if (debounce_timer) {
1226 hwtimer_stop(debounce_timer);
1227 hwtimer_free(debounce_timer);
1228 debounce_timer = NULL;
1229 }
1230 timer_active = false;
1231 key_detected_callback = NULL;
1232
1233 //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
1234
1235 return 0;
1236 }
1237
1238