QCC512x QCC302x Earbud 工程增加三击事件

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 不匹配的情况。

发布了12 篇原创文章 · 获赞 16 · 访问量 8125

猜你喜欢

转载自blog.csdn.net/qq_29225913/article/details/103504044