Funpack3-1---基于XG24-EK2703A的蓝牙鼠标+键盘复合设备
该项目使用了XG24-EK2703A,实现了蓝牙鼠标+键盘复合设备的设计,它的主要功能为:两个按键短按模拟滚轮上下翻页一行,两个同时按下2s后时依次发送字符EETREE.CN。
标签
蓝牙鼠标
蓝牙键盘
FunPack3-1
XG24-EK2703A
冷月烟
更新2024-03-05
191

项目介绍

对蓝牙功能进行开发,实现一个蓝牙鼠标+键盘复合设备。板子上有两个按键,分别短按后模拟滚轮上下翻页一行,两个同时按下2s后时依次发送字符EETREE.CN。


设计思路

Silicon Labs提供了许多例程,其中在SDK4.2.1里面有一个bluetooth_hid_keyboard例程,主要实现了蓝牙键盘的功能,我们这次就在这个代码的基础上进行修改。

本项目可以分解为以下几个部分:

  1. 蓝牙鼠标+键盘复合设备描述:这部分就在已有程序的基础上,增加鼠标的描述符,利用REPORT_ID进行区分。
  2. 短按后模拟滚轮上下翻页一行:没啥好说的,在按键回调函数里面进行编写就行。
  3. 两个同时按下2s后时依次发送字符:这里难点主要是判断2s,这里我偷了个懒,在一个空闲任务里面不断计数,通过计数得到当前大概的时间。


硬件介绍

XG24-EK2703A是一款基于EFR32MG24片上系统的开发套件,具备超低成本、低功耗和小巧的特点。该套件支持2.4GHz无线通信,兼容蓝牙LE、蓝牙mesh、Zigbee、Thread和Matter协议,为无线物联网产品的开发和原型制作提供了极大的便利。

整个评估套件最核心部分是EFR32MG24B210F1536IM48无线SoC芯片,是使用蓝牙低功耗和蓝牙网状网络实现物联网无线连接的理想选择,适用于智能家居、照明和便携式医疗设备产品。该芯片是EFR32MG24无线SoC芯片家族系列中的中高端型号,以ARM Cortex-M3为核心、主频为78MHz且支持2.4GHz无线通信,带有1536KB闪存和256KBRAM,并且还搭载了AI/ML硬件加速功能,能够满足在嵌入式系统中部署轻量级AI应用。

该板卡套件所有的例程和相应的板卡资料都集成在了SDK开发包中,辅以配套的Simplicity Studio Version 5工具,只需要将SDK下载进Simplicity Studio Version 5中就可以进行例程的演示,操作方便简单。

套件特性:

  • 一个USB接口
  • 一个板载SEGGER J-Link 调试器,支持SWD
  • 两个LED和两个按钮
  • 虚拟COM端口
  • 数据包跟踪接口(PTI)
  • 一个支持外部硬件连接的mikroBus插座和一个Qwiic连接器
  • 32 位 ARM Cortex-M33,78 MHz最高工作频率
  • 1536 kB 闪存和 256 kB RAM


软件流程图


主要代码片段及说明

HID报文描述符

0x05, 0x01,      # USAGE_PAGE (Generic Desktop)
0x09, 0x06, # USAGE (Keyboard)
0xa1, 0x01, # COLLECTION (Application)
0x85, 0x01, # REPORT_ID (1)
0x75, 0x01, # Report Size (1)
0x95, 0x08, # Report Count (8)
0x05, 0x07, # Usage Page (Key Codes)
0x19, 0xE0, # Usage Minimum (224)
0x29, 0xE7, # Usage Maximum (231)
0x15, 0x00, # Logical Minimum (0)
0x25, 0x01, # Logical Maximum (1)
0x81, 0x02, # Input (Data, Variable, Absolute); Modifier byte
0x95, 0x01, # Report Count (1)
0x75, 0x08, # Report Size (8)
0x81, 0x01, # Input (Constant); Reserved byte
0x95, 0x05, # Report Count (5)
0x75, 0x01, # Report Size (1)
0x05, 0x08, # Usage Page (LEDs)
0x19, 0x01, # Usage Minimum (1)
0x29, 0x05, # Usage Maximum (5)
0x91, 0x02, # Output (Data, Variable, Absolute); LED report
0x95, 0x01, # Report Count (1)
0x75, 0x03, # Report Size (3)
0x91, 0x01, # Output (Constant); LED report padding
0x95, 0x06, # Report Count (6)
0x75, 0x08, # Report Size (8)
0x15, 0x00, # Logical Minimum (0)
0x25, 0x65, # Logical Maximum (101)
0x05, 0x07, # Usage Page (Key Codes)
0x19, 0x00, # Usage Minimum (0)
0x29, 0x65, # Usage Maximum (101)
0x81, 0x00, # Input (Data, Array); Key array (6 bytes)
0xc0 # END_COLLECTION
0x05, 0x01, # USAGE_PAGE (Generic Desktop)
0x09, 0x02, # USAGE (Mouse)
0xa1, 0x01, # COLLECTION (Application)
0x85, 0x02, # REPORT_ID (2)
0x09, 0x01, # USAGE (Pointer)
0xa1, 0x00, # COLLECTION (Physical)
0x05, 0x09, # Usage Page (Buttons)
0x19, 0x01, # Usage Minimum (1)
0x29, 0x03, # Usage Maximum (3)
0x15, 0x00, # Logical Minimum (0)
0x25, 0x01, # Logical Maximum (1)
0x95, 0x03, # Report Count (3)
0x75, 0x01, # Report Size (1)
0x81, 0x02, # Input(Data, Variable, Absolute); 3 button bits
0x95, 0x01, # Report Count(1)
0x75, 0x05, # Report Size(5)
0x81, 0x03, # Input(Constant); 5 bit padding
0x05, 0x01, # Usage Page (Generic Desktop)
0x09, 0x30, # Usage (X)
0x09, 0x31, # Usage (Y)
0x09, 0x38, # Usage (Wheel)
0x15, 0x81, # Logical Minimum (-127)
0x25, 0x7F, # Logical Maximum (127)
0x75, 0x08, # Report Size (8)
0x95, 0x03, # Report Count (3)
0x81, 0x06, # Input(Data, Variable, Relative); 3 position bytes (X,Y,Wheel)
0xc0, # END_COLLECTION
0xc0 # END_COLLECTION

这里写法主要是方便观看理解,由于Simplicity Studio v5提供了一套图形化配置软件,使用上面一段代码的配置为下图:

05010906a101850175019508050719E029E715002501810295017508810195057501050819012905910295017503910195067508150025650507190029658100c005010902a10185020901a1000509190129031500250195037501810295017505810305010930093109381581257F750895038106c0c0

不得不吐槽,这种写法是真抽象。


按键初始化

配置IO

配置驱动


蓝牙数据发送代码

if (notification_enabled == 1) {
      memset(input_report_data, 0, sizeof(input_report_data));
      if(actual_mose != 0)
      {
            input_report_data[0] = 2;
            input_report_data[1] = 0;
            input_report_data[2] = 0;
            input_report_data[3] = 0;
            input_report_data[4] = actual_mose;
            sc = sl_bt_gatt_server_notify_all(gattdb_report,
                                                5,
                                                input_report_data);
            actual_mose = 0;
      }
      else
      {
            input_report_data[0] = 1;
            input_report_data[1] = 0;
            input_report_data[2] = 0;
            input_report_data[3] = actual_key;
            input_report_data[4] = 0;

            sc = sl_bt_gatt_server_notify_all(gattdb_report,
                                                9,
                                                input_report_data);

            actual_key = 0;
      }
      app_assert_status(sc);
}


按键中断代码

void sl_button_on_change(const sl_button_t *handle)
{
if (&sl_button_btn0 == handle)
{
if (sl_button_get_state(handle) == SL_SIMPLE_BUTTON_PRESSED)
{
key_mode += 1;
actual_mose = -1;
app_log("Button pushed - callback %d \r\n",time_count);
}
else
{
key_mode -= 1;
actual_key = 0;
app_log("Button released - callback %d\r\n",time_count);
}
}

if (&sl_button_btn1 == handle)
{
if (sl_button_get_state(handle) == SL_SIMPLE_BUTTON_PRESSED)
{
key_mode += 1;
actual_mose = 1;
app_log("Button pushed - callback\r\n");
}
else
{
key_mode -= 1;
app_log("Button released - callback \r\n");
}
}

if(key_mode == 2)
{
time_count_p = time_count;
}

if(key_mode_p == 2 && time_count-time_count_p > 500)
{
actual_mose = 0;
actual_key = reduced_key_array[counter];
if (9 == counter)
{
counter = 0;
}
else
{
counter++;
}
}

key_mode_p = key_mode;
sl_bt_external_signal(1);
}


功能展示及说明

见视频


对本活动的心得体会

很高兴能参加硬禾Funpack3-1活动,这次活动让我完整体验了一把独立探索一款新芯片,并进行开发的流程,未来,我计划深入研究更多的硬件技术,不断提升自己的设计能力。同时,我也希望能够与更多的同行交流学习,共同进步。这次在硬禾学堂的体验让我更加坚信,只要我们敢于挑战、勇于创新,就一定能够创造出更加出色的作品。

 

附件下载
bluetooth_hid_keyboard_mouse.zip
代码
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号