Skip to content

Commit d22d400

Browse files
committed
samples: bluetooth: classic: add HID Device mouse sample
Add a Bluetooth Classic HID Device sample that demonstrates a mouse peripheral. The sample registers an SDP HID service record with a standard two-button mouse report descriptor (buttons + X/Y + wheel, no Report ID), waits for an incoming HID Host connection, and turns board button events into mouse input reports on the interrupt channel. Features demonstrated: - HID Device callback registration and SDP service setup - Boot Protocol and Report Protocol mode support - Get_Report, Set_Report and Set_Protocol request handling - Event-driven input reports mapped from board buttons via the input subsystem (left/right click and relative X/Y motion) - Suspend/Exit-Suspend and Virtual Cable Unplug handling On native_sim the button GPIOs can be driven from an SDL window with the gpio-emul-sdl backend. Verified end-to-end with a real USB HCI dongle as the controller and a second dongle running a Bluetooth HID Host: connect/pair/encrypt, HID control + interrupt channels, a Get_Report round-trip, and each of the four button/axis events producing the expected input report on the host. Signed-off-by: Kai Cheng <chengkai@xiaomi.com> Assisted-by: Claude Opus 4.8 (1M context)
1 parent ebc49dc commit d22d400

6 files changed

Lines changed: 737 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.28.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(hid_device)
6+
7+
target_sources(app PRIVATE src/main.c)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
.. zephyr:code-sample:: bluetooth_hid_device
2+
:name: Bluetooth: HID Device (Mouse)
3+
:relevant-api: bt_hid_device
4+
5+
Demonstrate a Bluetooth Classic HID Device acting as a mouse.
6+
7+
Overview
8+
********
9+
10+
This sample implements a Bluetooth Classic HID Device (mouse) that
11+
advertises itself via SDP and waits for an incoming HID Host connection.
12+
Once connected, it sends mouse input reports in response to board button
13+
presses, using the Zephyr :ref:`input <input>` subsystem.
14+
15+
The sample demonstrates:
16+
17+
- Registering HID Device callbacks and the HID SDP service record
18+
- Handling Get_Report, Set_Report and Set_Protocol requests
19+
- Sending input reports on the interrupt channel from button events
20+
- Boot Protocol and Report Protocol mode support
21+
- Suspend/Exit-Suspend and Virtual Cable Unplug handling
22+
23+
Get_Protocol is answered by the host stack and needs no application
24+
callback.
25+
26+
The board buttons are mapped to mouse actions as follows:
27+
28+
=========== ================
29+
Button Action
30+
=========== ================
31+
``sw0`` Left button
32+
``sw1`` Right button
33+
``sw2`` Move cursor +X
34+
``sw3`` Move cursor +Y
35+
=========== ================
36+
37+
Requirements
38+
************
39+
40+
- A board with Bluetooth BR/EDR support and at least four buttons exposed
41+
through the input subsystem as ``sw0`` .. ``sw3``. When built for
42+
:ref:`native_sim <native_sim>` the bundled overlay defines these buttons
43+
on the emulated GPIO controller.
44+
- A Bluetooth HID Host (e.g., a PC or phone) to connect to the device
45+
46+
Building and Running
47+
********************
48+
49+
.. zephyr-app-commands::
50+
:zephyr-app: samples/bluetooth/classic/hid_device
51+
:board: <board>
52+
:goals: build flash
53+
:compact:
54+
55+
After flashing, the device will initialize Bluetooth, register the HID
56+
service, and become discoverable. Pair with it from a HID Host, then press
57+
the board buttons to generate mouse clicks and cursor movement on the host.
58+
59+
On :ref:`native_sim <native_sim>`, where there are no physical buttons, the
60+
button GPIOs can be driven from an SDL window by adding a
61+
``zephyr,gpio-emul-sdl`` child to the emulated GPIO controller (see
62+
:zephyr_file:`samples/subsys/display/lvgl/boards/native_sim.overlay` for the
63+
pattern) and enabling ``CONFIG_GPIO_EMUL_SDL``. Combined with a USB HCI dongle
64+
as the controller and a second dongle running a Bluetooth HID Host, this drives
65+
the full send path end to end.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2026 Xiaomi Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/dt-bindings/input/input-event-codes.h>
8+
9+
/ {
10+
aliases {
11+
sw0 = &button0;
12+
sw1 = &button1;
13+
sw2 = &button2;
14+
sw3 = &button3;
15+
};
16+
17+
gpio_keys {
18+
compatible = "gpio-keys";
19+
20+
button0: button_0 {
21+
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
22+
zephyr,code = <INPUT_KEY_0>;
23+
};
24+
25+
button1: button_1 {
26+
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
27+
zephyr,code = <INPUT_KEY_1>;
28+
};
29+
30+
button2: button_2 {
31+
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
32+
zephyr,code = <INPUT_KEY_2>;
33+
};
34+
35+
button3: button_3 {
36+
gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
37+
zephyr,code = <INPUT_KEY_3>;
38+
};
39+
};
40+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CONFIG_BT=y
2+
CONFIG_BT_CLASSIC=y
3+
CONFIG_BT_HID_DEVICE=y
4+
CONFIG_BT_DEVICE_NAME="hid-mouse"
5+
CONFIG_BT_COD=0x002580
6+
CONFIG_BT_PAGE_TIMEOUT=0xFFFF
7+
CONFIG_INPUT=y
8+
CONFIG_GPIO=y

0 commit comments

Comments
 (0)