BES key讲解

  下面来讲解下BES的按键,按键的定义、时间、多击灵敏度等都是在 hal_key.c 里面去修改的。如下代码:

 

1、添加多击事件

  ...
#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)
// 设置多击的个是。有多少击就将 HAL_KEY_EVENT_NINECLICK 改掉。相应的也要在hal_key.h中添加相应的 多击
#define MAX_KEY_CLICK_COUNT                 (HAL_KEY_EVENT_NINECLICK - HAL_KEY_EVENT_CLICK)

hal_key.h

enum HAL_KEY_EVENT_T {
    ...
    // 下面这些就是添加的相应多击
    HAL_KEY_EVENT_CLICK,
    HAL_KEY_EVENT_DOUBLECLICK,
    HAL_KEY_EVENT_TRIPLECLICK,
    HAL_KEY_EVENT_ULTRACLICK,
    HAL_KEY_EVENT_RAMPAGECLICK,
    HAL_KEY_EVENT_SIXCLICK,
    HAL_KEY_EVENT_SEVENCLICK,
    HAL_KEY_EVENT_EIGHTCLICK,
    HAL_KEY_EVENT_NINECLICK,
    HAL_KEY_EVENT_REPEAT,
...
    HAL_KEY_EVENT_NUM,
};

app_key.h 中也要去添加相应的。方便应用层去调用。代码如下:

enum APP_KEY_EVENT_T {
...
    APP_KEY_EVENT_LONGLONGPRESS      = HAL_KEY_EVENT_LONGLONGPRESS,
    APP_KEY_EVENT_CLICK              = HAL_KEY_EVENT_CLICK,  // 单击
    APP_KEY_EVENT_DOUBLECLICK        = HAL_KEY_EVENT_DOUBLECLICK,  // 双击
    APP_KEY_EVENT_TRIPLECLICK        = HAL_KEY_EVENT_TRIPLECLICK,  // 三击 10
    APP_KEY_EVENT_ULTRACLICK         = HAL_KEY_EVENT_ULTRACLICK,  // 四击
    APP_KEY_EVENT_RAMPAGECLICK       = HAL_KEY_EVENT_RAMPAGECLICK,  // 五击
    APP_KEY_EVENT_SIXCLICK           = HAL_KEY_EVENT_SIXCLICK,      // 六击 13
    APP_KEY_EVENT_SEVENCLICK         = HAL_KEY_EVENT_SEVENCLICK,
    APP_KEY_EVENT_EIGHTCLICK         = HAL_KEY_EVENT_EIGHTCLICK,
    APP_KEY_EVENT_NINECLICK          = HAL_KEY_EVENT_NINECLICK,     
    APP_KEY_EVENT_REPEAT             = HAL_KEY_EVENT_REPEAT,
...
    APP_KEY_EVENT_NUM = HAL_KEY_EVENT_NUM,
};

 

2、添加长按事件

hal_key.c

#ifndef CFG_SW_KEY_LLLPRESS_THRESH_MS
#define CFG_SW_KEY_LLLPRESS_THRESH_MS       10000
#endif
// 添加自己定义的长按事件
#ifndef CFG_SW_KEY_LLPRESS_PH6_MS
#define CFG_SW_KEY_LLPRESS_PH6_MS           6000
#endif
#define KEY_LONGLONGLONGPRESS_THRESHOLD         MS_TO_TICKS(CFG_SW_KEY_LLLPRESS_THRESH_MS)
// 自定义
#define KEY_LONGLONGPH6PRESS_THRESHOLD         MS_TO_TICKS(CFG_SW_KEY_LLPRESS_PH6_MS)

static void hal_key_debounce_handler(void *param)
{
    ...
    // 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.event == HAL_KEY_EVENT_LONGLONGPH6PRESS ||\
           key_status.event == HAL_KEY_EVENT_LONGLONGPH7PRESS || key_status.event == HAL_KEY_EVENT_LONGLONGLONGPRESS) 
        {
            ...
            else if (key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) {
                if (time - key_status.time_updown >= KEY_LONGLONGPH6PRESS_THRESHOLD) {
                    key_status.event = HAL_KEY_EVENT_LONGLONGPH6PRESS;
                    send_key_event(key_status.code_ready, key_status.event);
                }
            }
            else if (key_status.event == HAL_KEY_EVENT_LONGLONGPH6PRESS) {
                if (time - key_status.time_updown >= KEY_LONGLONGPH7PRESS_THRESHOLD) {
                    key_status.event = HAL_KEY_EVENT_LONGLONGPH7PRESS;
                    send_key_event(key_status.code_ready, key_status.event);
                }
            }
            else if (key_status.event == HAL_KEY_EVENT_LONGLONGPH7PRESS) {
                if (time - key_status.time_updown >= KEY_LONGLONGLONGPRESS_THRESHOLD) {
                    key_status.event = HAL_KEY_EVENT_LONGLONGLONGPRESS;
                    send_key_event(key_status.code_ready, key_status.event);
                    }
                }
        }
    }
    if (key_status.event != HAL_KEY_EVENT_NONE) {
        need_timer = true;
    }
    ...
}

以上的代码是要对自己定义的长按在code中进行处理的。如果这里不加,那么就不会有自己定义的长按事件出现

hal_key.h

 

enum HAL_KEY_EVENT_T {
    ...
    HAL_KEY_EVENT_LONGLONGPRESS,  // 4s
    HAL_KEY_EVENT_LONGLONGPH6PRESS,  // 6s
    HAL_KEY_EVENT_LONGLONGPH7PRESS,
    HAL_KEY_EVENT_LONGLONGLONGPRESS,  // 10s
    ...
    HAL_KEY_EVENT_NUM,
};

app_key.h ( 以下定义的是方便应用层调用)

enum APP_KEY_EVENT_T {
    ...
    APP_KEY_EVENT_UP_AFTER_LONGPRESS = HAL_KEY_EVENT_UP_AFTER_LONGPRESS,  // 5
    APP_KEY_EVENT_LONGPRESS          = HAL_KEY_EVENT_LONGPRESS,
    APP_KEY_EVENT_LONGLONGPRESS      = HAL_KEY_EVENT_LONGLONGPRESS,
    APP_KEY_EVENT_LONGLONGPH6GPRESS  = HAL_KEY_EVENT_LONGLONGPH6PRESS,
    APP_KEY_EVENT_LONGLONGPH7GPRESS  = HAL_KEY_EVENT_LONGLONGPH7PRESS,
    APP_KEY_EVENT_LONGLONGLONGPRESS  = HAL_KEY_EVENT_LONGLONGLONGPRESS,
    ...
    APP_KEY_EVENT_NUM = HAL_KEY_EVENT_NUM,
};

 

3、app_key_init() 函数 对按键进行注册。

4、进入DUT模式之后,是使用 app_factorymode_key_init() 函数进行注册的。

所以有效的按键就看函数中注册了多少功能函数。

5、开机的时候会根据按键按压的时间来修改 g_pwron_case 的状态。代码如下:

const  APP_KEY_HANDLE  pwron_key_handle_cfg[] = {
    {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITUP},           "power on: normal"     , app_poweron_normal, NULL},
    {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITLONGPRESS},    "power on: both scan"  , app_poweron_scan  , NULL},
    {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITFINISHED},     "power on: finished"   , app_poweron_finished  , NULL},
};

6、默认的长按开机改为短按开机。代码如下:

int hal_key_open(int checkPwrKey, int (* cb)(uint32_t, uint8_t))
{
...
// 将下面宏里面的一段注释掉就变成单击开机
#ifdef CHECK_PWRKEY_AT_BOOT
    if (checkPwrKey) {
        int cnt;
        int i = 0;

        if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_3) {
            cnt = 1;
        } else {
            cnt = 10;
        }
        cnt = 18;

        do {
            hal_sys_timer_delay(MS_TO_TICKS(20));
            if (!hal_pwrkey_startup_pressed()) {
                HAL_KEY_TRACE("pwr_key init DITHERING");
                nRet = -1;
                goto _exit;
            }
        } while (++i < cnt);
    }
#endif
...
}

7、拨动开关进行开关机。代码如下:

hal_key.c

static inline void hal_pwrkey_enable_int(void)
{
    // 修改进入中断函数为上升和下降
    hal_pwrkey_enable_bothedge_int();
}
// 下面的函数是耳机开机一直长按会在这个中断函数中不会自己调出来。所以手动添加个跳出函数的判断
bool pwr_key_up;
static void hal_pwrkey_handle_irq_state(enum HAL_PWRKEY_IRQ_T state)
{
    pwr_key_up = false;
 ...
        {
            pwr_key.pressed = hal_pwrkey_pressed();
            if (pwr_key.pressed) {
                pwr_key.debounce = true;
            } else {
                pwr_key.dither = true;
            }
        }
        pwr_key.time = time;
    }
    else {
        TRACE("==> pwr key irq up !!!");
        //app_shutdown();
        pwr_key_up = true;
        }
 ...
}

static void hal_key_debounce_handler(void *param)
{
    ...
    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;
    // Check newly up keys
    if (pwr_key_up == true) {
        up_new = pwr_key_up;
    }
    map = up_new;
    index = 0;
    while (map) {
    ...
            key_status.time_updown = time;
        }
        index++;
    }
    if (pwr_key_up)
    {
        key_status.code_click = HAL_KEY_CODE_NONE;
        key_status.cnt_click = 0;
        key_status.event = HAL_KEY_EVENT_NONE;
        pwr_key_up = false;
    }
    if (up_new) {
        if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS || \
            key_status.event == HAL_KEY_EVENT_LONGLONGPH5PRESS || key_status.event == HAL_KEY_EVENT_LONGLONGLONGPRESS) {
            // 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;
            }
     ...
}
static void hal_key_boot_handler(void *param)
{
    ...
        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);
                }
            }
        }
        if ((time - key_status.time_updown) > MS_TO_TICKS(2000))
            goto exit;
        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);
        }
exit:
        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();
    }      
}

apps.c

const  APP_KEY_HANDLE  pwron_key_handle_cfg[] = {
    {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITUP},           "power on: normal"     , app_poweron_normal, NULL},
};

8、同时长按触发。代码如下:(PS:还需要优化,思路是这样的)

apps.c

// 功能函数 同时长按进DUT
void app_bt_groupkey(APP_KEY_STATUS *status, void* param)
{
    uint16_t i = 0;
    uint8_t j = 0;
    //bool groupkey_detected = false;
    //APP_KEY_HANDLE key_none_handle_cfg = {{APP_KEY_CODE_NONE,APP_KEY_EVENT_NONE},"none function key",app_bt_nonekey,NULL};
    TRACE("==> %s event|code = %d|%d", __func__, status->event, status->code);
    if (status->event != APP_KEY_EVENT_DOWN || connect_mobile_flag/*|| app_status_indication_get() == APP_STATUS_INDICATION_BOTHSCAN*/)
    	return;
	
    switch (status->code) {
    	case APP_KEY_CODE_PWR:
    		do {
                TRACE("===> i = %d", i);
    			if (app_bt_key_read(APP_KEY_CODE_FN3) == APP_KEY_EVENT_DOWN) {
                    TRACE("#### input DUT ########");
                    j++;
                    if (j == 200) {
                    app_factorymode_enter();
    				break;
                    }
    			}
                if (i > 40 && j == 0)
                    break;
    			osDelay(30);
    		} while(i++<250);
    		break;
        default:
            TRACE("==> %s unregister down key event", __func__);
            break;
    }
}
// 在按键初始化的时候,注册的功能按键
const APP_KEY_HANDLE  app_key_handle_cfg[] = {
    {{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOWN},"bt function key",app_bt_groupkey, NULL},
    {{HAL_KEY_CODE_FN3,APP_KEY_EVENT_DOWN},"bt function key",app_bt_groupkey, NULL},
}

 

key相关的已经讲解完了。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值