1184 lines
34 KiB
C
1184 lines
34 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
****************************************************************************/
|
|
#include "plat_addr_map.h"
|
|
#include "plat_types.h"
|
|
#include "string.h"
|
|
#include "hal_iomux.h"
|
|
#include "hal_timer.h"
|
|
#include "hwtimer_list.h"
|
|
#include "hal_sleep.h"
|
|
#include "hal_trace.h"
|
|
#include "hal_chipid.h"
|
|
#include "hal_key.h"
|
|
#include "cmsis_nvic.h"
|
|
#include "pmu.h"
|
|
#include "tgt_hardware.h"
|
|
|
|
#ifdef KEY_DEBUG
|
|
#define HAL_KEY_TRACE(n, s, ...) TRACE(n, "[%u]" s, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__)
|
|
#else
|
|
#define HAL_KEY_TRACE(n, s, ...) TRACE_DUMMY(n, s, ##__VA_ARGS__)
|
|
#endif
|
|
|
|
#ifdef CHIP_BEST2000
|
|
#define GPIO_MAP_64BIT
|
|
#endif
|
|
|
|
#ifdef GPIO_MAP_64BIT
|
|
typedef uint64_t GPIO_MAP_T;
|
|
#else
|
|
typedef uint32_t GPIO_MAP_T;
|
|
#endif
|
|
|
|
#ifndef APP_TEST_MODE
|
|
#define CHECK_PWRKEY_AT_BOOT
|
|
#endif
|
|
#ifdef NO_PWRKEY
|
|
#undef CHECK_PWRKEY_AT_BOOT
|
|
#endif
|
|
#ifdef NO_GPIOKEY
|
|
#undef CFG_HW_GPIOKEY_NUM
|
|
#define CFG_HW_GPIOKEY_NUM 0
|
|
#endif
|
|
#ifdef NO_ADCKEY
|
|
#undef CFG_HW_ADCKEY_NUMBER
|
|
#define CFG_HW_ADCKEY_NUMBER 0
|
|
#endif
|
|
|
|
#ifndef CFG_SW_KEY_LLPRESS_THRESH_MS
|
|
#define CFG_SW_KEY_LLPRESS_THRESH_MS 5000
|
|
#endif
|
|
#ifndef CFG_SW_KEY_LPRESS_THRESH_MS
|
|
#define CFG_SW_KEY_LPRESS_THRESH_MS 1500
|
|
#endif
|
|
#ifndef CFG_SW_KEY_REPEAT_THRESH_MS
|
|
#define CFG_SW_KEY_REPEAT_THRESH_MS 500
|
|
#endif
|
|
#ifndef CFG_SW_KEY_DBLCLICK_THRESH_MS
|
|
#define CFG_SW_KEY_DBLCLICK_THRESH_MS 400
|
|
#endif
|
|
#ifndef CFG_SW_KEY_INIT_DOWN_THRESH_MS
|
|
#define CFG_SW_KEY_INIT_DOWN_THRESH_MS 200
|
|
#endif
|
|
#ifndef CFG_SW_KEY_INIT_LPRESS_THRESH_MS
|
|
#define CFG_SW_KEY_INIT_LPRESS_THRESH_MS 3000
|
|
#endif
|
|
#ifndef CFG_SW_KEY_INIT_LLPRESS_THRESH_MS
|
|
#define CFG_SW_KEY_INIT_LLPRESS_THRESH_MS 10000
|
|
#endif
|
|
#ifndef CFG_SW_KEY_CHECK_INTERVAL_MS
|
|
#define CFG_SW_KEY_CHECK_INTERVAL_MS 40
|
|
#endif
|
|
|
|
//common key define
|
|
#define KEY_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LLPRESS_THRESH_MS)
|
|
#define KEY_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LPRESS_THRESH_MS)
|
|
#define KEY_DOUBLECLICK_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_DBLCLICK_THRESH_MS)
|
|
#define KEY_LONGPRESS_REPEAT_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_REPEAT_THRESH_MS)
|
|
|
|
#define KEY_INIT_DOWN_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_DOWN_THRESH_MS)
|
|
#define KEY_INIT_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LPRESS_THRESH_MS)
|
|
#define KEY_INIT_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LLPRESS_THRESH_MS)
|
|
|
|
#define KEY_CHECKER_INTERVAL MS_TO_TICKS(CFG_SW_KEY_CHECK_INTERVAL_MS)
|
|
|
|
#define KEY_DEBOUNCE_INTERVAL (KEY_CHECKER_INTERVAL * 2)
|
|
#define KEY_DITHER_INTERVAL (KEY_CHECKER_INTERVAL * 1)
|
|
|
|
#define MAX_KEY_CLICK_COUNT (HAL_KEY_EVENT_RAMPAGECLICK - HAL_KEY_EVENT_CLICK)
|
|
|
|
struct HAL_KEY_ADCKEY_T {
|
|
bool debounce;
|
|
bool dither;
|
|
enum HAL_KEY_CODE_T code_debounce;
|
|
enum HAL_KEY_CODE_T code_down;
|
|
uint32_t time;
|
|
};
|
|
|
|
struct HAL_KEY_GPIOKEY_T {
|
|
GPIO_MAP_T pin_debounce;
|
|
GPIO_MAP_T pin_dither;
|
|
GPIO_MAP_T pin_down;
|
|
uint32_t time_debounce;
|
|
uint32_t time_dither;
|
|
};
|
|
|
|
struct HAL_KEY_PWRKEY_T {
|
|
bool debounce;
|
|
bool dither;
|
|
bool pressed;
|
|
uint32_t time;
|
|
};
|
|
|
|
struct HAL_KEY_STATUS_T {
|
|
enum HAL_KEY_CODE_T code_down;
|
|
enum HAL_KEY_CODE_T code_ready;
|
|
enum HAL_KEY_CODE_T code_click;
|
|
enum HAL_KEY_EVENT_T event;
|
|
uint32_t time_updown;
|
|
uint32_t time_click;
|
|
uint8_t cnt_repeat;
|
|
uint8_t cnt_click;
|
|
};
|
|
|
|
static int (*key_detected_callback)(uint32_t, uint8_t) = NULL;
|
|
static HWTIMER_ID debounce_timer = NULL;
|
|
static bool timer_active = false;
|
|
static struct HAL_KEY_STATUS_T key_status;
|
|
|
|
static void hal_key_disable_allint(void);
|
|
static void hal_key_enable_allint(void);
|
|
|
|
static int send_key_event(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event)
|
|
{
|
|
if (key_detected_callback) {
|
|
return key_detected_callback(code, event);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void hal_key_debounce_timer_restart(void)
|
|
{
|
|
uint32_t lock;
|
|
bool set = false;
|
|
|
|
lock = int_lock();
|
|
if (!timer_active) {
|
|
timer_active = true;
|
|
set = true;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (set) {
|
|
hwtimer_stop(debounce_timer);
|
|
hwtimer_start(debounce_timer, KEY_CHECKER_INTERVAL);
|
|
//hal_sys_wake_lock(HAL_SYS_WAKE_LOCK_USER_KEY);
|
|
}
|
|
}
|
|
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
static uint16_t adckey_volt_table[CFG_HW_ADCKEY_NUMBER];
|
|
struct HAL_KEY_ADCKEY_T adc_key;
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_enable_press_int(void)
|
|
{
|
|
hal_adckey_set_irq(HAL_ADCKEY_IRQ_PRESSED);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_enable_release_int(void)
|
|
{
|
|
hal_adckey_set_irq(HAL_ADCKEY_IRQ_RELEASED);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_enable_adc_int(void)
|
|
{
|
|
hal_gpadc_open(HAL_GPADC_CHAN_ADCKEY, HAL_GPADC_ATP_NULL, NULL);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_disable_adc_int(void)
|
|
{
|
|
hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_disable_allint(void)
|
|
{
|
|
hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY);
|
|
hal_adckey_set_irq(HAL_ADCKEY_IRQ_NONE);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_adckey_reset(void)
|
|
{
|
|
memset(&adc_key, 0, sizeof(adc_key));
|
|
}
|
|
|
|
static enum HAL_KEY_CODE_T hal_adckey_findkey(uint16_t volt)
|
|
{
|
|
int index = 0;
|
|
|
|
#if 0
|
|
if (volt == HAL_GPADC_BAD_VALUE) {
|
|
return HAL_KEY_CODE_NONE;
|
|
}
|
|
#endif
|
|
|
|
if (CFG_HW_ADCKEY_ADC_KEYVOLT_BASE < volt && volt < CFG_HW_ADCKEY_ADC_MAXVOLT) {
|
|
for (index = 0; index < CFG_HW_ADCKEY_NUMBER; index++) {
|
|
if (volt <= adckey_volt_table[index]) {
|
|
return CFG_HW_ADCKEY_MAP_TABLE[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
return HAL_KEY_CODE_NONE;
|
|
}
|
|
|
|
static void hal_adckey_irqhandler(enum HAL_ADCKEY_IRQ_STATUS_T irq_status, HAL_GPADC_MV_T val)
|
|
{
|
|
enum HAL_KEY_CODE_T code;
|
|
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_disable_allint();
|
|
#else
|
|
hal_adckey_disable_allint();
|
|
#endif
|
|
|
|
if (irq_status & (HAL_ADCKEY_ERR0 | HAL_ADCKEY_ERR1)) {
|
|
HAL_KEY_TRACE(1,"irq,adckey err 0x%04X", irq_status);
|
|
adc_key.debounce = true;
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
goto _debounce;
|
|
}
|
|
if (irq_status & HAL_ADCKEY_PRESSED) {
|
|
HAL_KEY_TRACE(0,"irq,adckey press");
|
|
adc_key.debounce = true;
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
adc_key.time = hal_sys_timer_get();
|
|
hal_adckey_enable_adc_int();
|
|
goto _exit;
|
|
}
|
|
if (irq_status & HAL_ADCKEY_RELEASED) {
|
|
HAL_KEY_TRACE(0,"irq,adckey release");
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
goto _debounce;
|
|
}
|
|
if(irq_status & HAL_ADCKEY_ADC_VALID) {
|
|
code = hal_adckey_findkey(val);
|
|
HAL_KEY_TRACE(3,"irq,adckey cur:0x%X pre:0x%X volt:%d", code, adc_key.code_debounce, val);
|
|
|
|
if (adc_key.code_debounce == HAL_KEY_CODE_NONE) {
|
|
adc_key.code_debounce = code;
|
|
} else if (adc_key.code_debounce != code) {
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
}
|
|
}
|
|
|
|
_debounce:
|
|
hal_key_debounce_timer_restart();
|
|
_exit:
|
|
return;
|
|
}
|
|
|
|
static void hal_adckey_open(void)
|
|
{
|
|
uint16_t i;
|
|
uint32_t basevolt;
|
|
|
|
HAL_KEY_TRACE(1,"%s\n", __func__);
|
|
|
|
hal_adckey_reset();
|
|
|
|
basevolt = (CFG_HW_ADCKEY_ADC_MAXVOLT - CFG_HW_ADCKEY_ADC_MINVOLT) / (CFG_HW_ADCKEY_NUMBER + 2);
|
|
|
|
adckey_volt_table[0] = CFG_HW_ADCKEY_ADC_KEYVOLT_BASE + basevolt;
|
|
|
|
for(i = 1; i < CFG_HW_ADCKEY_NUMBER-1; i++) {
|
|
adckey_volt_table[i] = adckey_volt_table[i - 1] + basevolt;
|
|
}
|
|
adckey_volt_table[CFG_HW_ADCKEY_NUMBER - 1] = CFG_HW_ADCKEY_ADC_MAXVOLT;
|
|
|
|
hal_adckey_set_irq_handler(hal_adckey_irqhandler);
|
|
}
|
|
|
|
static void hal_adckey_close(void)
|
|
{
|
|
HAL_KEY_TRACE(1,"%s\n", __func__);
|
|
|
|
hal_adckey_reset();
|
|
|
|
hal_adckey_disable_allint();
|
|
}
|
|
#endif // (CFG_HW_ADCKEY_NUMBER > 0)
|
|
|
|
#ifndef NO_PWRKEY
|
|
struct HAL_KEY_PWRKEY_T pwr_key;
|
|
|
|
static inline POSSIBLY_UNUSED void hal_pwrkey_enable_riseedge_int(void)
|
|
{
|
|
hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_RISING_EDGE);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_pwrkey_enable_falledge_int(void)
|
|
{
|
|
hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_FALLING_EDGE);
|
|
}
|
|
|
|
static inline POSSIBLY_UNUSED void hal_pwrkey_enable_bothedge_int(void)
|
|
{
|
|
hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_BOTH_EDGE);
|
|
}
|
|
|
|
static inline void hal_pwrkey_enable_int(void)
|
|
{
|
|
#ifdef __POWERKEY_CTRL_ONOFF_ONLY__
|
|
hal_pwrkey_enable_riseedge_int();
|
|
#else
|
|
hal_pwrkey_enable_falledge_int();
|
|
#endif
|
|
}
|
|
|
|
static inline void hal_pwrkey_disable_int(void)
|
|
{
|
|
hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_NONE);
|
|
}
|
|
|
|
static inline void hal_pwrkey_reset(void)
|
|
{
|
|
memset(&pwr_key, 0, sizeof(pwr_key));
|
|
}
|
|
|
|
static inline bool hal_pwrkey_get_status(void)
|
|
{
|
|
#ifdef CHIP_BEST1000
|
|
if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
|
|
return pwr_key.pressed;
|
|
} else
|
|
#endif
|
|
{
|
|
return hal_pwrkey_pressed();
|
|
}
|
|
}
|
|
|
|
static void hal_pwrkey_handle_irq_state(enum HAL_PWRKEY_IRQ_T state)
|
|
{
|
|
// uint32_t time = hal_sys_timer_get();
|
|
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_disable_allint();
|
|
#else
|
|
hal_pwrkey_disable_int();
|
|
#endif
|
|
|
|
#ifdef __POWERKEY_CTRL_ONOFF_ONLY__
|
|
|
|
if (state & HAL_PWRKEY_IRQ_RISING_EDGE) {
|
|
HAL_KEY_TRACE(0,"pwr_key irq up");
|
|
pwr_key.debounce = true;
|
|
}
|
|
|
|
#else // !__POWERKEY_CTRL_ONOFF_ONLY__
|
|
|
|
if (state & HAL_PWRKEY_IRQ_FALLING_EDGE) {
|
|
HAL_KEY_TRACE(0,"pwr_key irq down");
|
|
#ifdef CHIP_BEST1000
|
|
if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
|
|
pwr_key.debounce = true;
|
|
pwr_key.pressed = true;
|
|
hal_pwrkey_enable_riseedge_int();
|
|
} else
|
|
#endif
|
|
{
|
|
pwr_key.pressed = hal_pwrkey_pressed();
|
|
if (pwr_key.pressed) {
|
|
pwr_key.debounce = true;
|
|
} else {
|
|
pwr_key.dither = true;
|
|
}
|
|
}
|
|
// pwr_key.time = time;
|
|
}
|
|
|
|
#ifdef CHIP_BEST1000
|
|
if (state & HAL_PWRKEY_IRQ_RISING_EDGE) {
|
|
if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) {
|
|
HAL_KEY_TRACE(0,"pwr_key irq up");
|
|
pwr_key.pressed = false;
|
|
hal_pwrkey_enable_falledge_int();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endif // !__POWERKEY_CTRL_ONOFF_ONLY__
|
|
|
|
hal_key_debounce_timer_restart();
|
|
}
|
|
|
|
#ifdef CHIP_HAS_EXT_PMU
|
|
#define PWRKEY_IRQ_HDLR_PARAM uint16_t irq_status
|
|
#else
|
|
#define PWRKEY_IRQ_HDLR_PARAM void
|
|
#endif
|
|
static void hal_pwrkey_irqhandler(PWRKEY_IRQ_HDLR_PARAM)
|
|
{
|
|
enum HAL_PWRKEY_IRQ_T state;
|
|
|
|
#ifdef CHIP_HAS_EXT_PMU
|
|
state = pmu_pwrkey_irq_value_to_state(irq_status);
|
|
#else
|
|
state = hal_pwrkey_get_irq_state();
|
|
#endif
|
|
|
|
HAL_KEY_TRACE(2,"%s: %08x", __func__, state);
|
|
|
|
hal_pwrkey_handle_irq_state(state);
|
|
}
|
|
|
|
static void hal_pwrkey_open(void)
|
|
{
|
|
hal_pwrkey_reset();
|
|
|
|
#ifdef CHIP_HAS_EXT_PMU
|
|
pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, hal_pwrkey_irqhandler);
|
|
#else
|
|
NVIC_SetVector(PWRKEY_IRQn, (uint32_t)hal_pwrkey_irqhandler);
|
|
NVIC_SetPriority(PWRKEY_IRQn, IRQ_PRIORITY_NORMAL);
|
|
NVIC_ClearPendingIRQ(PWRKEY_IRQn);
|
|
NVIC_EnableIRQ(PWRKEY_IRQn);
|
|
#endif
|
|
}
|
|
|
|
static void hal_pwrkey_close(void)
|
|
{
|
|
hal_pwrkey_reset();
|
|
|
|
hal_pwrkey_disable_int();
|
|
|
|
#ifdef CHIP_HAS_EXT_PMU
|
|
pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, NULL);
|
|
#else
|
|
NVIC_SetVector(PWRKEY_IRQn, (uint32_t)NULL);
|
|
NVIC_DisableIRQ(PWRKEY_IRQn);
|
|
#endif
|
|
}
|
|
#endif // !NO_PWRKEY
|
|
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
struct HAL_KEY_GPIOKEY_T gpio_key;
|
|
|
|
static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin);
|
|
|
|
static inline void hal_gpiokey_reset(void)
|
|
{
|
|
memset(&gpio_key, 0, sizeof(gpio_key));
|
|
}
|
|
|
|
static int hal_gpiokey_find_index(enum HAL_GPIO_PIN_T pin)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
|
|
if (cfg_hw_gpio_key_cfg[i].key_config.pin == (enum HAL_IOMUX_PIN_T)pin) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
ASSERT(i < CFG_HW_GPIOKEY_NUM, "GPIOKEY IRQ: Invalid pin=%d", pin);
|
|
return i;
|
|
}
|
|
|
|
static bool hal_gpiokey_pressed(enum HAL_GPIO_PIN_T pin)
|
|
{
|
|
int i = hal_gpiokey_find_index(pin);
|
|
return (hal_gpio_pin_get_val(pin) == cfg_hw_gpio_key_cfg[i].key_down);
|
|
}
|
|
|
|
static void hal_gpiokey_irqhandler(enum HAL_GPIO_PIN_T pin)
|
|
{
|
|
bool pressed;
|
|
uint32_t lock;
|
|
uint32_t time;
|
|
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_disable_allint();
|
|
#else
|
|
hal_gpiokey_disable_irq(pin);
|
|
#endif
|
|
|
|
pressed = hal_gpiokey_pressed(pin);
|
|
HAL_KEY_TRACE(2,"gpio_key trig=%d pressed=%d", pin, pressed);
|
|
|
|
time = hal_sys_timer_get();
|
|
|
|
lock = int_lock();
|
|
if (pressed) {
|
|
gpio_key.pin_debounce |= ((GPIO_MAP_T)1 << pin);
|
|
gpio_key.time_debounce = time;
|
|
} else {
|
|
gpio_key.pin_dither |= ((GPIO_MAP_T)1 << pin);
|
|
gpio_key.time_dither = time;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
hal_key_debounce_timer_restart();
|
|
}
|
|
|
|
static void hal_gpiokey_enable_irq(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_IRQ_POLARITY_T polarity)
|
|
{
|
|
struct HAL_GPIO_IRQ_CFG_T gpiocfg;
|
|
|
|
hal_gpio_pin_set_dir(pin, HAL_GPIO_DIR_IN, 0);
|
|
|
|
gpiocfg.irq_enable = true;
|
|
gpiocfg.irq_debounce = true;
|
|
gpiocfg.irq_polarity = polarity;
|
|
gpiocfg.irq_handler = hal_gpiokey_irqhandler;
|
|
gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE;
|
|
|
|
hal_gpio_setup_irq(pin, &gpiocfg);
|
|
}
|
|
|
|
static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin)
|
|
{
|
|
static const struct HAL_GPIO_IRQ_CFG_T gpiocfg = {
|
|
.irq_enable = false,
|
|
.irq_debounce = false,
|
|
.irq_polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING,
|
|
.irq_handler = NULL,
|
|
.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE,
|
|
};
|
|
|
|
hal_gpio_setup_irq(pin, &gpiocfg);
|
|
}
|
|
|
|
static inline void hal_gpiokey_enable_allint(void)
|
|
{
|
|
uint8_t i;
|
|
enum HAL_GPIO_IRQ_POLARITY_T polarity;
|
|
|
|
for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++){
|
|
if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
|
|
continue;
|
|
}
|
|
|
|
if (cfg_hw_gpio_key_cfg[i].key_down == HAL_KEY_GPIOKEY_VAL_LOW) {
|
|
polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING;
|
|
} else {
|
|
polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING;
|
|
}
|
|
hal_gpiokey_enable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin, polarity);
|
|
}
|
|
}
|
|
|
|
static inline void hal_gpiokey_disable_allint(void)
|
|
{
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
|
|
if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
|
|
continue;
|
|
}
|
|
|
|
hal_gpiokey_disable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin);
|
|
}
|
|
}
|
|
|
|
static void hal_gpiokey_open(void)
|
|
{
|
|
uint8_t i;
|
|
HAL_KEY_TRACE(1,"%s\n", __func__);
|
|
|
|
hal_gpiokey_reset();
|
|
|
|
for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
|
|
if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) {
|
|
continue;
|
|
}
|
|
|
|
hal_iomux_init(&cfg_hw_gpio_key_cfg[i].key_config, 1);
|
|
}
|
|
}
|
|
|
|
static void hal_gpiokey_close(void)
|
|
{
|
|
HAL_KEY_TRACE(1,"%s\n", __func__);
|
|
|
|
hal_gpiokey_reset();
|
|
|
|
hal_gpiokey_disable_allint();
|
|
}
|
|
#endif // (CFG_HW_GPIOKEY_NUM > 0)
|
|
|
|
enum HAL_KEY_EVENT_T hal_key_read_status(enum HAL_KEY_CODE_T code)
|
|
{
|
|
uint8_t gpio_val;
|
|
int i;
|
|
|
|
if (code == HAL_KEY_CODE_PWR){
|
|
if (hal_pwrkey_pressed())
|
|
return HAL_KEY_EVENT_DOWN;
|
|
else
|
|
return HAL_KEY_EVENT_UP;
|
|
}else{
|
|
for(i = 0; i < CFG_HW_GPIOKEY_NUM; i++) {
|
|
if(cfg_hw_gpio_key_cfg[i].key_code == code) {
|
|
gpio_val = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin);
|
|
if (gpio_val == cfg_hw_gpio_key_cfg[i].key_down) {
|
|
return HAL_KEY_EVENT_DOWN;
|
|
} else {
|
|
return HAL_KEY_EVENT_UP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return HAL_KEY_EVENT_NONE;
|
|
}
|
|
|
|
static void hal_key_disable_allint(void)
|
|
{
|
|
#ifndef NO_PWRKEY
|
|
hal_pwrkey_disable_int();
|
|
#endif
|
|
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
hal_adckey_disable_allint();
|
|
#endif
|
|
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
hal_gpiokey_disable_allint();
|
|
#endif
|
|
}
|
|
|
|
static void hal_key_enable_allint(void)
|
|
{
|
|
#ifndef NO_PWRKEY
|
|
hal_pwrkey_enable_int();
|
|
#endif
|
|
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
hal_adckey_enable_press_int();
|
|
#endif
|
|
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
hal_gpiokey_enable_allint();
|
|
#endif
|
|
}
|
|
|
|
static void hal_key_debounce_handler(void *param)
|
|
{
|
|
uint32_t time;
|
|
enum HAL_KEY_CODE_T code_down = HAL_KEY_CODE_NONE;
|
|
int index;
|
|
bool need_timer = false;
|
|
|
|
timer_active = false;
|
|
|
|
time = hal_sys_timer_get();
|
|
|
|
#ifndef NO_PWRKEY
|
|
#ifdef __POWERKEY_CTRL_ONOFF_ONLY__
|
|
if (pwr_key.debounce) {
|
|
pwr_key.debounce = false;
|
|
code_down |= HAL_KEY_CODE_PWR;
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_pwrkey_enable_int();
|
|
#endif
|
|
}
|
|
#else
|
|
if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
|
|
bool pressed = hal_pwrkey_get_status();
|
|
|
|
//HAL_KEY_TRACE(4,"keyDbnPwr: dbn=%d dither=%d pressed=%d/%d", pwr_key.debounce, pwr_key.dither, pwr_key.pressed, pressed);
|
|
|
|
if (pwr_key.debounce) {
|
|
pwr_key.pressed = pressed;
|
|
if (pressed) {
|
|
pwr_key.dither = false;
|
|
if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) {
|
|
pwr_key.debounce = false;
|
|
pwr_key.dither = false;
|
|
code_down |= HAL_KEY_CODE_PWR;
|
|
}
|
|
} else {
|
|
pwr_key.debounce = false;
|
|
pwr_key.dither = true;
|
|
pwr_key.time = time;
|
|
}
|
|
} else if (pwr_key.dither) {
|
|
if (time - pwr_key.time >= KEY_DITHER_INTERVAL) {
|
|
pwr_key.dither = false;
|
|
pwr_key.pressed = false;
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_pwrkey_enable_int();
|
|
#endif
|
|
}
|
|
} else if (pwr_key.pressed) {
|
|
if (pressed) {
|
|
code_down |= HAL_KEY_CODE_PWR;
|
|
} else {
|
|
pwr_key.pressed = false;
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_pwrkey_enable_int();
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
|
|
need_timer = true;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) {
|
|
bool skip_check = false;
|
|
|
|
//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);
|
|
|
|
if (adc_key.debounce) {
|
|
if (adc_key.code_debounce == HAL_KEY_CODE_NONE) {
|
|
adc_key.debounce = false;
|
|
adc_key.dither = true;
|
|
adc_key.time = time;
|
|
} else {
|
|
if (time - adc_key.time >= KEY_DEBOUNCE_INTERVAL) {
|
|
adc_key.debounce = false;
|
|
adc_key.dither = false;
|
|
adc_key.code_down = adc_key.code_debounce;
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
code_down |= adc_key.code_down;
|
|
}
|
|
}
|
|
} else if (adc_key.dither) {
|
|
if (time - adc_key.time >= KEY_DITHER_INTERVAL) {
|
|
adc_key.dither = false;
|
|
adc_key.code_debounce = HAL_KEY_CODE_NONE;
|
|
adc_key.code_down = HAL_KEY_CODE_NONE;
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_adckey_enable_press_int();
|
|
#endif
|
|
}
|
|
skip_check = true;
|
|
} else if (adc_key.code_down != HAL_KEY_CODE_NONE) {
|
|
if (adc_key.code_debounce == adc_key.code_down) {
|
|
code_down |= adc_key.code_down;
|
|
} else {
|
|
adc_key.code_down = HAL_KEY_CODE_NONE;
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_adckey_enable_press_int();
|
|
#endif
|
|
skip_check = true;
|
|
}
|
|
}
|
|
|
|
if (!skip_check) {
|
|
hal_adckey_enable_adc_int();
|
|
}
|
|
}
|
|
if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) {
|
|
need_timer = true;
|
|
}
|
|
#endif
|
|
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
enum HAL_GPIO_PIN_T gpio;
|
|
GPIO_MAP_T pin;
|
|
uint32_t lock;
|
|
|
|
#ifdef GPIO_MAP_64BIT
|
|
ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
|
|
(gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
|
|
(gpio_key.pin_debounce & gpio_key.pin_dither) == 0,
|
|
"Bad gpio_key pin map: dbn=0x%X-%X dither=0x%X-%X down=0x%X-%X",
|
|
(uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce),
|
|
(uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither),
|
|
(uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down));
|
|
#if 0
|
|
HAL_KEY_TRACE(6,"keyDbnGpio: pin_dbn=0x%X-%X pin_dither=0x%X-%X pin_down=0x%X-%X",
|
|
(uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce),
|
|
(uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither),
|
|
(uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down));
|
|
#endif
|
|
#else // !GPIO_MAP_64BIT
|
|
ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
|
|
(gpio_key.pin_debounce & gpio_key.pin_dither) == 0 &&
|
|
(gpio_key.pin_debounce & gpio_key.pin_dither) == 0,
|
|
"Bad gpio_key pin map: dbn=0x%X dither=0x%X down=0x%X",
|
|
(uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down);
|
|
#if 0
|
|
HAL_KEY_TRACE(3,"keyDbnGpio: pin_dbn=0x%X pin_dither=0x%X pin_down=0x%X",
|
|
(uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down);
|
|
#endif
|
|
#endif // !GPIO_MAP_64BIT
|
|
|
|
if (gpio_key.pin_dither) {
|
|
if (time - gpio_key.time_dither >= KEY_DITHER_INTERVAL) {
|
|
pin = gpio_key.pin_dither;
|
|
|
|
lock = int_lock();
|
|
gpio_key.pin_dither &= ~pin;
|
|
int_unlock(lock);
|
|
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
gpio = HAL_GPIO_PIN_P0_0;
|
|
while (pin) {
|
|
if (pin & ((GPIO_MAP_T)1 << gpio)) {
|
|
pin &= ~((GPIO_MAP_T)1 << gpio);
|
|
index = hal_gpiokey_find_index(gpio);
|
|
hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ?
|
|
HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING);
|
|
}
|
|
gpio++;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
if (gpio_key.pin_down) {
|
|
pin = gpio_key.pin_down;
|
|
|
|
gpio = HAL_GPIO_PIN_P0_0;
|
|
while (pin) {
|
|
if (pin & ((GPIO_MAP_T)1 << gpio)) {
|
|
pin &= ~((GPIO_MAP_T)1 << gpio);
|
|
index = hal_gpiokey_find_index(gpio);
|
|
if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) {
|
|
code_down |= cfg_hw_gpio_key_cfg[index].key_code;
|
|
} else {
|
|
gpio_key.pin_down &= ~((GPIO_MAP_T)1 << gpio);
|
|
#ifdef NO_GROUPKEY
|
|
hal_key_enable_allint();
|
|
#else
|
|
hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ?
|
|
HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING);
|
|
#endif
|
|
}
|
|
}
|
|
gpio++;
|
|
}
|
|
}
|
|
if (gpio_key.pin_debounce) {
|
|
GPIO_MAP_T down_added = 0;
|
|
GPIO_MAP_T dither_added = 0;
|
|
|
|
pin = gpio_key.pin_debounce;
|
|
|
|
gpio = HAL_GPIO_PIN_P0_0;
|
|
while (pin) {
|
|
if (pin & ((GPIO_MAP_T)1 << gpio)) {
|
|
pin &= ~((GPIO_MAP_T)1 << gpio);
|
|
index = hal_gpiokey_find_index(gpio);
|
|
if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) {
|
|
if (time - gpio_key.time_debounce >= KEY_DEBOUNCE_INTERVAL) {
|
|
down_added |= ((GPIO_MAP_T)1 << gpio);
|
|
code_down |= cfg_hw_gpio_key_cfg[index].key_code;
|
|
gpio_key.pin_down |= ((GPIO_MAP_T)1 << gpio);
|
|
}
|
|
} else {
|
|
dither_added |= ((GPIO_MAP_T)1 << gpio);
|
|
}
|
|
}
|
|
gpio++;
|
|
}
|
|
|
|
lock = int_lock();
|
|
gpio_key.pin_debounce &= ~(down_added | dither_added);
|
|
gpio_key.pin_dither |= dither_added;
|
|
int_unlock(lock);
|
|
}
|
|
if (gpio_key.pin_dither || gpio_key.pin_down || gpio_key.pin_debounce) {
|
|
need_timer = true;
|
|
}
|
|
#endif
|
|
|
|
enum HAL_KEY_CODE_T down_new;
|
|
enum HAL_KEY_CODE_T up_new;
|
|
enum HAL_KEY_CODE_T map;
|
|
|
|
down_new = code_down & ~key_status.code_down;
|
|
up_new = ~code_down & key_status.code_down;
|
|
|
|
//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);
|
|
|
|
// Check newly up keys
|
|
map = up_new;
|
|
index = 0;
|
|
while (map) {
|
|
if (map & (1 << index)) {
|
|
map &= ~(1 << index);
|
|
send_key_event((1 << index), HAL_KEY_EVENT_UP);
|
|
if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
|
|
send_key_event((1 << index), HAL_KEY_EVENT_UP_AFTER_LONGPRESS);
|
|
}
|
|
key_status.time_updown = time;
|
|
}
|
|
index++;
|
|
}
|
|
|
|
if (up_new) {
|
|
if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
|
|
// LongPress is finished when all of the LongPress keys are released
|
|
if ((code_down & key_status.code_ready) == 0) {
|
|
key_status.event = HAL_KEY_EVENT_NONE;
|
|
}
|
|
} else if (key_status.event == HAL_KEY_EVENT_DOWN) {
|
|
// Enter click handling if not in LongPress
|
|
key_status.event = HAL_KEY_EVENT_UP;
|
|
}
|
|
}
|
|
|
|
if (key_status.event == HAL_KEY_EVENT_UP) {
|
|
//ASSERT(key_status.code_ready != HAL_KEY_CODE_NONE, "Bad code_ready");
|
|
|
|
if (key_status.code_click == HAL_KEY_CODE_NONE || key_status.code_click != key_status.code_ready) {
|
|
if (key_status.code_click != HAL_KEY_CODE_NONE) {
|
|
send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click);
|
|
}
|
|
key_status.code_click = key_status.code_ready;
|
|
key_status.cnt_click = 0;
|
|
key_status.time_click = time;
|
|
} else if (up_new && (up_new | key_status.code_down) == key_status.code_click) {
|
|
key_status.cnt_click++;
|
|
key_status.time_click = time;
|
|
}
|
|
if (time - key_status.time_click >= KEY_DOUBLECLICK_THRESHOLD || key_status.cnt_click >= MAX_KEY_CLICK_COUNT) {
|
|
send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click);
|
|
key_status.code_click = HAL_KEY_CODE_NONE;
|
|
key_status.cnt_click = 0;
|
|
key_status.event = HAL_KEY_EVENT_NONE;
|
|
}
|
|
}
|
|
|
|
// Update key_status.code_down
|
|
key_status.code_down = code_down;
|
|
|
|
// Check newly down keys and update key_status.code_ready
|
|
map = down_new;
|
|
index = 0;
|
|
while (map) {
|
|
if (map & (1 << index)) {
|
|
map &= ~(1 << index);
|
|
send_key_event((1 << index), HAL_KEY_EVENT_DOWN);
|
|
if (key_status.event == HAL_KEY_EVENT_NONE) {
|
|
send_key_event((1 << index), HAL_KEY_EVENT_FIRST_DOWN);
|
|
} else {
|
|
send_key_event((1 << index), HAL_KEY_EVENT_CONTINUED_DOWN);
|
|
}
|
|
if (key_status.event == HAL_KEY_EVENT_NONE ||
|
|
key_status.event == HAL_KEY_EVENT_DOWN ||
|
|
key_status.event == HAL_KEY_EVENT_UP) {
|
|
key_status.code_ready = code_down;
|
|
}
|
|
key_status.time_updown = time;
|
|
}
|
|
index++;
|
|
}
|
|
|
|
if (down_new) {
|
|
if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_UP) {
|
|
key_status.event = HAL_KEY_EVENT_DOWN;
|
|
}
|
|
}
|
|
|
|
// LongPress should be stopped if any key is released
|
|
if ((code_down & key_status.code_ready) == key_status.code_ready) {
|
|
if (key_status.event == HAL_KEY_EVENT_DOWN) {
|
|
if (time - key_status.time_updown >= KEY_LONGPRESS_THRESHOLD) {
|
|
key_status.cnt_repeat = 0;
|
|
key_status.event = HAL_KEY_EVENT_LONGPRESS;
|
|
send_key_event(key_status.code_ready, key_status.event);
|
|
}
|
|
} else if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
|
|
key_status.cnt_repeat++;
|
|
if (key_status.cnt_repeat == KEY_LONGPRESS_REPEAT_THRESHOLD / KEY_CHECKER_INTERVAL) {
|
|
key_status.cnt_repeat = 0;
|
|
send_key_event(key_status.code_ready, HAL_KEY_EVENT_REPEAT);
|
|
}
|
|
if (key_status.event == HAL_KEY_EVENT_LONGPRESS) {
|
|
if (time - key_status.time_updown >= KEY_LONGLONGPRESS_THRESHOLD) {
|
|
key_status.event = HAL_KEY_EVENT_LONGLONGPRESS;
|
|
send_key_event(key_status.code_ready, key_status.event);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (key_status.event != HAL_KEY_EVENT_NONE) {
|
|
need_timer = true;
|
|
}
|
|
|
|
if (need_timer) {
|
|
hal_key_debounce_timer_restart();
|
|
} else {
|
|
//hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
|
|
}
|
|
}
|
|
|
|
#if 0//def CHECK_PWRKEY_AT_BOOT
|
|
static void hal_key_boot_handler(void *param)
|
|
{
|
|
#ifndef NO_PWRKEY
|
|
uint32_t time;
|
|
|
|
timer_active = false;
|
|
|
|
time = hal_sys_timer_get();
|
|
|
|
if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
|
|
bool pressed = hal_pwrkey_get_status();
|
|
|
|
//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);
|
|
|
|
if (pwr_key.debounce) {
|
|
pwr_key.pressed = pressed;
|
|
if (pressed) {
|
|
pwr_key.dither = false;
|
|
if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) {
|
|
pwr_key.debounce = false;
|
|
key_status.time_updown = time;
|
|
}
|
|
} else {
|
|
pwr_key.debounce = false;
|
|
pwr_key.dither = true;
|
|
pwr_key.time = time;
|
|
}
|
|
} else if (pwr_key.dither) {
|
|
if (time - pwr_key.time >= KEY_DITHER_INTERVAL) {
|
|
pwr_key.dither = false;
|
|
pwr_key.pressed = false;
|
|
}
|
|
} else if (pwr_key.pressed) {
|
|
if (!pressed) {
|
|
pwr_key.pressed = false;
|
|
}
|
|
}
|
|
}
|
|
if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) {
|
|
if (pwr_key.pressed) {
|
|
if (key_status.event == HAL_KEY_EVENT_NONE) {
|
|
if (time - key_status.time_updown >= KEY_INIT_DOWN_THRESHOLD) {
|
|
key_status.event = HAL_KEY_EVENT_INITDOWN;
|
|
send_key_event(HAL_KEY_CODE_PWR, key_status.event);
|
|
}
|
|
} else if (key_status.event == HAL_KEY_EVENT_INITDOWN) {
|
|
if (time - key_status.time_updown >= KEY_INIT_LONGPRESS_THRESHOLD) {
|
|
key_status.cnt_repeat = 0;
|
|
key_status.event = HAL_KEY_EVENT_INITLONGPRESS;
|
|
send_key_event(HAL_KEY_CODE_PWR, key_status.event);
|
|
}
|
|
} else if (key_status.event == HAL_KEY_EVENT_INITLONGPRESS) {
|
|
if (time - key_status.time_updown >= KEY_INIT_LONGLONGPRESS_THRESHOLD) {
|
|
key_status.event = HAL_KEY_EVENT_INITLONGLONGPRESS;
|
|
send_key_event(HAL_KEY_CODE_PWR, key_status.event);
|
|
}
|
|
}
|
|
}
|
|
hal_key_debounce_timer_restart();
|
|
} else {
|
|
if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_INITDOWN) {
|
|
send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITUP);
|
|
}
|
|
send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITFINISHED);
|
|
|
|
hwtimer_update(debounce_timer, hal_key_debounce_handler, NULL);
|
|
//hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
|
|
|
|
memset(&key_status, 0, sizeof(key_status));
|
|
hal_pwrkey_reset();
|
|
hal_key_enable_allint();
|
|
}
|
|
#endif
|
|
}
|
|
#endif //CHECK_PWRKEY_AT_BOOT
|
|
|
|
int hal_key_open(int checkPwrKey, int (* cb)(uint32_t, uint8_t))
|
|
{
|
|
int nRet = 0;
|
|
uint32_t lock;
|
|
|
|
key_detected_callback = cb;
|
|
|
|
memset(&key_status, 0, sizeof(key_status));
|
|
|
|
lock = int_lock();
|
|
|
|
#ifdef CHECK_PWRKEY_AT_BOOT
|
|
if (checkPwrKey) {
|
|
int cnt;
|
|
int i = 0;
|
|
|
|
cnt = 10;
|
|
do {
|
|
hal_sys_timer_delay(MS_TO_TICKS(150));
|
|
if (!hal_pwrkey_startup_pressed()) {
|
|
HAL_KEY_TRACE(0,"pwr_key init DITHERING");
|
|
nRet = -1;
|
|
goto _exit;
|
|
}
|
|
} while (++i < cnt);
|
|
}
|
|
#endif
|
|
|
|
#ifndef NO_PWRKEY
|
|
hal_pwrkey_open();
|
|
#endif
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
hal_adckey_open();
|
|
#endif
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
hal_gpiokey_open();
|
|
#endif
|
|
|
|
#ifdef CHECK_PWRKEY_AT_BOOT
|
|
#ifndef __POWERKEY_CTRL_ONOFF_ONLY__
|
|
if (checkPwrKey) {
|
|
debounce_timer = hwtimer_alloc(hal_key_boot_handler, NULL);
|
|
hal_pwrkey_handle_irq_state(HAL_PWRKEY_IRQ_FALLING_EDGE);
|
|
} else
|
|
#endif
|
|
#endif
|
|
{
|
|
debounce_timer = hwtimer_alloc(hal_key_debounce_handler, NULL);
|
|
hal_key_enable_allint();
|
|
}
|
|
|
|
ASSERT(debounce_timer, "Failed to alloc key debounce timer");
|
|
|
|
goto _exit; // Avoid compiler warnings
|
|
|
|
_exit:
|
|
int_unlock(lock);
|
|
|
|
return nRet;
|
|
}
|
|
|
|
int hal_key_close(void)
|
|
{
|
|
hal_key_disable_allint();
|
|
|
|
#ifndef NO_PWRKEY
|
|
hal_pwrkey_close();
|
|
#endif
|
|
#if (CFG_HW_ADCKEY_NUMBER > 0)
|
|
hal_adckey_close();
|
|
#endif
|
|
#if (CFG_HW_GPIOKEY_NUM > 0)
|
|
hal_gpiokey_close();
|
|
#endif
|
|
|
|
if (debounce_timer) {
|
|
hwtimer_stop(debounce_timer);
|
|
hwtimer_free(debounce_timer);
|
|
debounce_timer = NULL;
|
|
}
|
|
timer_active = false;
|
|
key_detected_callback = NULL;
|
|
|
|
//hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY);
|
|
|
|
return 0;
|
|
}
|
|
|