• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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