2. 低时延模式

Note

在标准的BLE协议中,通常最小连接间隔是7.5ms(回报率最大为133),这种连接频率对普通数据传输已经足够,但对于游戏鼠标等对速度有极高要求的设备来说,延迟较高。而低于1ms的连接间隔则能够极大地提升鼠标的数据传输速度和响应表现。尤其在电竞鼠标领域,能够达到低于1ms的连接间隔对于减少延迟和提升响应速度至关重要。

Note

AW31支持私有的ble低时延数据传输模式,目前支持最高单连接500us连接间隔。demo应用中也有1k回报率鼠标例子应用。

2.1. 低延迟从机配置

默认使用CONFIG_APP_MOUSE_DUAL这个鼠标应用进行低延迟模拟测试

  • 选择 hid 工程选择CONFIG_APP_MOUSE_DUAL应用

apps/demo/hid/include/app_config.h

#define CONFIG_APP_KEYBOARD                 0//hid按键 ,default case
#define CONFIG_APP_KEYFOB                   0//自拍器,
#define CONFIG_APP_MOUSE_SINGLE             0//单模鼠标(ble) 需搭配CONFIG_BOARD_AW313A_MOUSE_SINGLE板级
#define CONFIG_APP_MOUSE_DUAL               1//三模鼠标(ble&2.4g&usb) 需搭配CONFIG_BOARD_AW313A_MOUSE板级
#define CONFIG_APP_KEYPAGE                  0//翻页器
#define CONFIG_APP_REMOTE_CONTROL           0//遥控器,需搭配CONFIG_BOARD_AW31A_RC板级
#define CONFIG_APP_IDLE                     0//IDLE

  • 选择对应板级

apps/demo/hid/board/bd47/board_config.h

// #define CONFIG_BOARD_AW31N_DEMO
// #define CONFIG_BOARD_AW31A_RC
// #define CONFIG_BOARD_AW313A_MOUSE_SINGLE
#define CONFIG_BOARD_AW313A_MOUSE
  • 打开低时延测试模式

apps/demo/hid/board/bd47/board_aw313a_mouse_cfg.h

#define LOW_CONNECT_INTERVAL_TEST      1
  • 打开模拟发数使能

apps/demo/hid/examples/mouse dual/app_mouse_dual.h

// 模拟sensor发数使能
#define TEST_MOUSE_SIMULATION_ENABLE        1
  • 如果是测试1ms双连接和500us单连接需要关闭加密功能

#define CONFIG_BT_SM_SUPPORT_ENABLE         0 //配置是否支持加密

2.2. 低时延主机配置

默认使用transfer工程的dongle应用(CONFIG_APP_DONGLE)进行低时延测试

  • 选择 hid 工程选择CONFIG_APP_DONGLE应用

apps/demo/transfer/include/app_config.h

//apps example 选择,只能选1个,要配置对应的board_config.h
#define CONFIG_APP_LE_TRANS               0 // LE's slave
#define CONFIG_APP_MULTI                  0 //BLE多机应用,支持2.4g code,支持4主,3主1从,2主2从...
#define CONFIG_APP_NONCONN_24G            0 //2.4G 非连接收发
#define CONFIG_APP_DONGLE                 1 //usb + 蓝牙(ble 主机),PC hid设备, 使用需要配置板级board_aw31n_dongle.h
#define CONFIG_APP_AT_CHAR_COM            0 //AT com 字符串格式命令
#define CONFIG_APP_IDLE                   0 // 空闲任务
  • 开启高回报率模式

#elif CONFIG_APP_DONGLE
#define CONFIG_BLE_CONNECT_SLOT            1 //BLE高回报率设置, 支持私有协议,所有周期单位为us,适配1k回报率鼠标需要开此宏
#define CONFIG_BT_GATT_CLIENT_NUM          1 // range(1~2)
#define CONFIG_BT_GATT_SERVER_NUM          0
#define CONFIG_BT_GATT_CONNECTION_NUM      (CONFIG_BT_GATT_SERVER_NUM + CONFIG_BT_GATT_CLIENT_NUM)
#define CONFIG_BT_EXT_CONNECT_LINK_SIZE   (CONFIG_BT_GATT_CONNECTION_NUM) * 0x76C
  • 如果是测试1ms双连接和500us单连接需要关闭加密功能

#define CONFIG_BT_SM_SUPPORT_ENABLE        0 //配置是否支持加密

2.3. 测试现象

完成连接后从机会自动发数,dongle收到后通过USB发数划正方形,可以使用Mouse Test软件测试低时延的鼠标回报率

image-20241109161557212

Note

正常1ms和500us都会达到980+的回报率,并且500us的连接发数会更快,由于USB限制,500us回报率未能突破1k(ble通信为2k),可以使用分析仪查看连接间隔是否为500us

2.4. 接口说明

Note

目前低时延只适配了上述两个应用,如果开发者需要自行开发低时延应用,可以熟悉以下接口

CONFIG_BLE_CONNECT_SLOT:低时延高回报率宏需要打开

  • 从机端(以下两个接口为弱函数,需要自行在应用层覆盖写发数逻辑)

/* --------------------------------------------------------------------------*/
/**
 * @brief  库函数,蓝牙事件中断后会被调用一次
 *
 * @param  [in] priv_hw
 * @param  [in] link
 * @param  [in] hw_state
 * @param  [in] flag 能否压包标志
 * @return 0: 发送成功; 非0:发送失败
 * @note   用法参考app_mouse_dual.c
 */
/* ----------------------------------------------------------------------------*/
void ble_event_irq_hook(void *priv_hw, void *link, uint8_t hw_state, u8 flag);

/* --------------------------------------------------------------------------*/
/**
 * @brief  私有协议调用快速发数
 *
 * @param  [in] packet
 * @param  [in] len
 * @param  [in] tx_octets 发送申请的buffer
 * @return 0: 发送成功; 非0:发送失败
 * @note   用法参考app_mouse_dual.c
 */
/* ----------------------------------------------------------------------------*/
int hw_send_packet_fast(u16 att_handle, void *priv_hw, const u8 *packet, int len, int tx_octets, uint8_t hw_state);

连接前调用以下接口

/*************************************************************************************************/
/*!
 *  \brief      us 为单位连接  set 配置1开启 0关闭   如果要用这个功能 必须要统一配置
 */
/*************************************************************************************************/
#define ble_op_conn_us_unit(set)     \
	ble_user_cmd_prepare(BLE_CMD_US_UNIT, 1, set)

/*************************************************************************************************/
/*!
 *  \brief     获取是否配置了us为单位连接
 */
/*************************************************************************************************/
#define ble_op_is_us_unit(ptr)     \
	ble_user_cmd_prepare(BLE_CMD_GET_IS_US_UNIT, 1, ptr)

// 设置高回报率模式
ble_op_conn_us_unit(1);
ble_op_conn_init_2Mphy(1);
// 关闭more data
set_config_vendor_le_bb(VENDOR_BB_MD_CLOSE);

  • 主机端(下面两个接口为弱函数,需要自行在应用层覆盖写逻辑)

/* --------------------------------------------------------------------------*/
/**
 * @brief  库函数,使用私有协议连接后调用捕获蓝牙接收数据
 *
 * @param  [in] data
 * @param  [in] len
 * @return true释放rx buffer,false走原本协议栈流程
 * @note   用法参考ble_dg_central.c
 */
/* ----------------------------------------------------------------------------*/
bool ll_conn_rx_acl_hook_get(const uint8_t *const data, size_t len);

/*************************************************************************************************/
/*!
 *  \brief      1. 用于做低时延数据发送(适用于500us,1ms双连接流程),不开sm加密功能优先级高于ll_conn_rx_acl_hook_get,
                   return false则走ll_conn_rx_acl_hook_get流程
                2. 底层有事件触发后回调直接来上层拿数据发送,函数名不可修改,无需调用;
                3. 不可做耗时操作(需要在us级);
 *
 *  \param
 *
 *  \return
 *
 *  \note
 */
/*************************************************************************************************/
bool bb_le_rx_data_pdu_hook_get(void *priv, const u8 *data, u8 len)

连接前调用以下接口:

// 设置高回报率模式
ble_op_conn_us_unit(1);
ble_op_conn_init_2Mphy(1);
/*************************************************************************************************/
/*!
 *  \brief      us 为单位连接  set 配置1开启 0关闭   如果要用这个功能 必须要统一配置
 */
/*************************************************************************************************/
#define ble_op_conn_us_unit(set)     \
	ble_user_cmd_prepare(BLE_CMD_US_UNIT, 1, set)

/*************************************************************************************************/
/*!
 *  \brief     获取是否配置了us为单位连接
 */
/*************************************************************************************************/
#define ble_op_is_us_unit(ptr)     \
	ble_user_cmd_prepare(BLE_CMD_GET_IS_US_UNIT, 1, ptr)
  • 值得注意的是,低时延模式时主机端需要发起的连接间隔需要为1000(1k回报率)或500(2k回报率)

//连接周期
#if CONFIG_BLE_CONNECT_SLOT
#define BASE_INTERVAL_MIN   (500) // 最小的interval
#define SET_CONN_INTERVAL   (BASE_INTERVAL_MIN) //(unit:us)
#else
#define BASE_INTERVAL_MIN   (6)//最小的interval
#define SET_CONN_INTERVAL   (BASE_INTERVAL_MIN*3) //(unit:1.25ms)
#endif