780|1

10

帖子

0

资源

一粒金砂(中级)

【沁恒RISC-V内核 CH582】蓝牙HID键盘代码解读 [复制链接]

CH582这款MCU的特点在蓝牙上面,所以我准备做一个有线键盘转蓝牙键盘的小东西,看到官方给的例程里面也有蓝牙HID键盘的例程,所以就研读一下。

官方的有main函数的代码如下:


/******************************************************************************/
/* 头文件包含 */
#include "CONFIG.h"
#include "HAL.h"
#include "hiddev.h"
#include "hidkbd.h"

/*********************************************************************
 * GLOBAL TYPEDEFS
 */
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];

#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
#endif

/*********************************************************************
 * @fn      Main_Circulation
 *
 * @brief 主循环
 *
 * @return none
 */
__HIGH_CODE
void Main_Circulation()
{
    while(1)
    {
        TMOS_SystemProcess();
    }
}

/*********************************************************************
 * @fn      main
 *
 * @brief   主函数
 *
 * @return  none
 */
int main(void)
{
#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
    PWR_DCDCCfg(ENABLE);
#endif
    SetSysClock(CLK_SOURCE_PLL_60MHz);
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
    GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
    GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
#endif
#ifdef DEBUG
    GPIOA_SetBits(bTXD1);
    GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
#endif
    PRINT("%s\n", VER_LIB);
    CH58X_BLEInit();
    HAL_Init();
    GAPRole_PeripheralInit();
    HidDev_Init();
    HidEmu_Init();
    Main_Circulation();
}

看到了主循环的这段代码:

/*********************************************************************
 * @fn      Main_Circulation
 *
 * @brief   主循环
 *
 * @return  none
 */
__HIGH_CODE
void Main_Circulation()
{
    while(1)
    {
        TMOS_SystemProcess();
    }
}

这段代码应该是一个用软件定时器实现的简单任务的轮询调度,跳转进来看到这段代码:

/**
 * @brief   tmos system timer initialization
 *
 * @note    must initialization before call tmos task
 *
 * @param   fnGetClock - 0:system clock select RTC timer
 *                   valid:system clock select extend input
 *
 * @return  Command Status.
 */
extern bStatus_t TMOS_TimerInit( pfnGetSysClock fnGetClock );

/**
 * @brief   Process system
 *
 * @param   None.
 *
 * @return  None.
 */
extern void TMOS_SystemProcess( void );

这个.h对应的.c文件是.a文件的形式,所以应该是闭源的,注释可以看出来的确是一个软件定时器,需要一个外部输入时钟做os的时钟源。所以具体的蓝牙键值上传代码应该是通过注册callback的方式实现的,然后找到hidkbd.c中的代码:

/*********************************************************************
 * @fn      HidEmu_ProcessEvent
 *
 * @brief   HidEmuKbd Application Task event processor.  This function
 *          is called to process all events for the task.  Events
 *          include timers, messages and any other user defined events.
 *
 * @param   task_id  - The TMOS assigned task ID.
 * @param   events - events to process.  This is a bit map and can
 *                   contain more than one event.
 *
 * @return  events not processed
 */
uint16_t HidEmu_ProcessEvent(uint8_t task_id, uint16_t events)
{
    static uint8_t send_char = 4;

    if(events & SYS_EVENT_MSG)
    {
        uint8_t *pMsg;

        if((pMsg = tmos_msg_receive(hidEmuTaskId)) != NULL)
        {
            hidEmu_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);

            // Release the TMOS message
            tmos_msg_deallocate(pMsg);
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if(events & START_DEVICE_EVT)
    {
        return (events ^ START_DEVICE_EVT);
    }

    if(events & START_PARAM_UPDATE_EVT)
    {
        // Send connect param update request
        GAPRole_PeripheralConnParamUpdateReq(hidEmuConnHandle,
                                             DEFAULT_DESIRED_MIN_CONN_INTERVAL,
                                             DEFAULT_DESIRED_MAX_CONN_INTERVAL,
                                             DEFAULT_DESIRED_SLAVE_LATENCY,
                                             DEFAULT_DESIRED_CONN_TIMEOUT,
                                             hidEmuTaskId);

        return (events ^ START_PARAM_UPDATE_EVT);
    }

    if(events & START_PHY_UPDATE_EVT)
    {
        // start phy update
        PRINT("Send Phy Update %x...n", GAPRole_UpdatePHY(hidEmuConnHandle, 0, GAP_PHY_BIT_LE_2M,
                                                           GAP_PHY_BIT_LE_2M, 0));

        return (events ^ START_PHY_UPDATE_EVT);
    }

    if(events & START_REPORT_EVT)
    {
        hidEmuSendKbdReport(send_char);
        send_char++;
        if(send_char >= 29)
            send_char = 4;
        hidEmuSendKbdReport(0x00);
        tmos_start_task(hidEmuTaskId, START_REPORT_EVT, 2000);
        return (events ^ START_REPORT_EVT);
    }
    return 0;
}

可以很明显的看到每隔2000ms会上传一次键值,然后看一下hid设备的键码表,可以知道键值是从a到z循环输入。

key.png 而且没有功能按键,只有字母的输入:

/*********************************************************************
 * @fn      hidEmuSendKbdReport
 *
 * @brief   Build and send a HID keyboard report.
 *
 * @param   keycode - HID keycode.
 *
 * @return  none
 */
static void hidEmuSendKbdReport(uint8_t keycode)
{
    uint8_t buf[HID_KEYBOARD_IN_RPT_LEN];

    buf[0] = 0;       // Modifier keys
    buf[1] = 0;       // Reserved
    buf[2] = keycode; // Keycode 1
    buf[3] = 0;       // Keycode 2
    buf[4] = 0;       // Keycode 3
    buf[5] = 0;       // Keycode 4
    buf[6] = 0;       // Keycode 5
    buf[7] = 0;       // Keycode 6

    HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT,
                  HID_KEYBOARD_IN_RPT_LEN, buf);
}

烧录程序到开发板

2022.03.30_14.03.08.png

打开设置蓝牙配对连接

2022.03.30_13.43.20.jpg

打开串口终端查看,connected连接成功

2022.03.30_14.05.33.jpg

可以看到依次输入26个字母,这里是l、m、n,前面的是录屏之前输入的。

1648618822594.gif

 


回复

1422

帖子

3

资源

版主

蓝牙4.0跟蓝牙5.0的接收器都兼容接收吗?还有无线键盘,原来是有线的,供电考虑怎么解决呢?

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

最新文章 更多>>
    推荐帖子
    获奖名单:学习TI E2E 工业设计资料抢楼有礼

    活动详情:学习TI E2E 工业设计资料抢楼有礼 领奖方式:请获奖网友确认论坛个人资料中的相关信息>>点击查看自己个人信息,并 ...

    MSP430FR2355 LaunchPad™ 开发套件

    481376 MSP-EXP430FR2355 LaunchPad™ 开发套件是基于 MSP430FR2355 超值系列微控制器 (MCU) 的易于使用的评估模块 (EVM ...

    【HC32F460开发板测评】05.矩阵按键的识别与处理

    HC32F460芯片搭载一个键盘控制模块(KEYSCAN),支持矩阵键盘的行和列扫描;列是由独立的输出KEYOUTm(m=0~7)驱动,而行KEYINn(n= ...

    颁奖:泰克MSO6B情报站—电源纹波测量指北

    【活动详情】泰克MSO6B情报站—电源纹波测量指北 请获奖者务必在2021年12月8日23:59前,按照下方领奖确认流程完成领 ...

    【平头哥Sipeed LicheeRV 86 Panel测评】八、lvgl库初体验

    1、入坑lvgl库 本人对Tina-SDK的源码检索中,在packages目录下发现了一个“gui”文件夹,里面包含了不少GUI库。打 ...

    和Vicor工程师一起聊聊高效供电

    半导体制造商正在对自动测试设备(ATE)公司提出更高的要求,要求他们能够快速可靠地设计出满足不断增长的 IC 需求的测试系统, ...

    关闭
    站长推荐上一条 1/7 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表