下面来讲解下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相关的已经讲解完了。