QCC512x QCC302x Earbud 工程增加三击事件
Earbud 工程支持的按键事件比 Sink 少。默认支持的按键事件有下面5种
- ENTER
- RELEASE
- HELD
- HELD_RELEASE
- DOUBLE
- TRIPLE (此文后面新增)
修改方法
由于项目需求,需要在 Earbud 上使用到三击事件,因此需要手动增加对三击事件的处理。
在此用最简单的方法,来实现,利用现成的双击事件,嵌套多一层判断与超时。
- 原效果是双击后立刻上报双击事件。
- 现效果是双击后等待超时,若没有三击则超时后上报双击事件,若有三击立刻上报三击事件。实际测试,超时时间选择400ms左右比较理想。
实现代码
1、《input_event_manager.c》
(1)包含头文件。
由于 input_event_manager 是在库文件里面的,我们稍后会用到 1_button.h 定义的三击事件,因此需要包含一下这个头文件,由于库中不能直接的调用app层的头文件,因此需要在包含的时候,增加一下路径。
#include "../../applications/earbud/qcc512x_qcc302x/QCC3020-AA_DEV-BRD-R2-AA/depend_debug_qcc512x_qcc302x/1_button.h"
(2)修改 doubleAction() 函数
双击的处理函数在 doubleAction() 中,直接将这个函数用下面代码替换掉。
static void doubleAction(InputEventState_t *state,
const InputActionMessage_t *input_action,
input_event_bits_t input_event_bits)
{
/* if the Pio has changed to On... */
if (input_action->bits == (input_event_bits & input_action->mask))
{
/* fitst tap */
if ((state->double_tap != input_action) && (state->triple_tap != input_action) )
{
state->TapCount = 1;
MessageSendLater(&state->task, IEM_INTERNAL_DOUBLE_TIMER,
NULL, input_action->timeout);
state->double_tap = input_action;
}
/* double tap */
else if (state->double_tap == input_action )
{
state->TapCount = 2;
MessageCancelAll(&state->task, IEM_INTERNAL_DOUBLE_TIMER);
MessageSendLater(&state->task, IEM_INTERNAL_DOUBLE_TIMER,
NULL, input_action->timeout);
state->double_tap = 0;
state->triple_tap = input_action;
}
/* triple tap */
else
{
state->TapCount = 3;
MessageCancelAll(&state->task, IEM_INTERNAL_DOUBLE_TIMER);
MessageSend(&state->task, IEM_INTERNAL_DOUBLE_TIMER, NULL);
state->triple_tap = 0;
}
}
}
(3)修改 inputEventsChanged() 函数
在 DOUBLE 下,增加一个 case TRIPLE,即不管双击,还是三击,都用原有函数来处理。
case DOUBLE:
case TRIPLE:
doubleAction(state, input_action, input_event_bits);
break;
(4)修改 pioHandler() 函数
该函数用来处理超时消息,找到 case IEM_INTERNAL_DOUBLE_TIMER
,需要将原有流程替换一下,替换成能够判断双击和三击。用下面代码替换原代码。
case IEM_INTERNAL_DOUBLE_TIMER:
/* Clear the stored input_action */
if(state->TapCount == 2)
{
MessageSend(state->client, APP_MFB_BUTTON_DOUBLE, 0);
}
else if(state->TapCount == 3)
{
MessageSend(state->client, APP_MFB_BUTTON_TRIPLE, 0);
}
state->double_tap = 0;
state->triple_tap = 0;
state->TapCount = 0;
break;
2、《input_event_manager.h》
该文件需要增加 TRIPLE 的动作
在 InputEventAction_t 枚举体中增加。
typedef enum
{
ENTER,
RELEASE,
HELD,
HELD_RELEASE,
DOUBLE,
TRIPLE
} InputEventAction_t;
3、《input_event_manager_private.h》
该文件需要增加 在三击过程中引入的变量
在 InputEventState_t 结构体中,增加下面两个变量,
const InputActionMessage_t *triple_tap;
unsigned TapCount:8; /* multiple press counter */
4、《1_button.buttonxml》
这个文件是用来定义按键事件的,用于绑定按键、触发事件,触发动作、超时时间。
在此文件定义的内容,将会用于生成 x_button,c 与 x_button.h 这两个文件。因此在上述包含的 1_button.h是在这里生成的。如果改变了这个xml文件名,应该将上面第一步包含的头文件也同步修改,否则将会出错。
实现双击、三击、长按的例子
<message>
<messageName>APP_MFB_BUTTON_DOUBLE</messageName>
<buttonEvent>DOUBLE</buttonEvent>
<activePinFriendlyName>MFB_BUTTON</activePinFriendlyName>
<timeout_ms>400</timeout_ms>
</message>
<message>
<messageName>APP_MFB_BUTTON_TRIPLE</messageName>
<buttonEvent>TRIPLE</buttonEvent>
<activePinFriendlyName>MFB_BUTTON</activePinFriendlyName>
<timeout_ms>400</timeout_ms>
</message>
<message>
<messageName>APP_MFB_BUTTON_HELD</messageName>
<buttonEvent>HELD</buttonEvent>
<activePinFriendlyName>MFB_BUTTON</activePinFriendlyName>
<timeout_ms>1500</timeout_ms>
<repeat_ms>600</repeat_ms>
</message>
5、《av_headset_ui.c》
最后,需要对按键的事件进行处理,处理的函数在该文件中
找到 appUiHandleMessage() 函数,添加case。
case APP_MFB_BUTTON_DOUBLE:
{
DEBUG_LOG("**** DOUBLE ****");
/* TODO: */
}
break;
case APP_MFB_BUTTON_TRIPLE:
{
DEBUG_LOG("**** TRIPLE ****");
/* TODO: */
}
break;
case APP_MFB_BUTTON_HELD:
{
DEBUG_LOG("**** HELD ****");
}
break;
注意: .buttonxml 定义的 messageName , 会在 1_button.h 中去 #define,因此如果修改过xml,在av_headset_ui.c 中处理的时候,也要相应的修改相关的 case,不要出现宏定义与 case 不匹配的情况。