Skip to content

Commit b0bb483

Browse files
Add backwards compatibility for old consumer control format
Translate old 1-byte bitmap format to new 16-bit usage selector format for Report ID 3 (Consumer Control). This allows old MouthPad firmware to work with the updated HID descriptor. Old format: 8 individual bit flags (1 byte) New format: 16-bit usage code selector (2 bytes) Mapping: - bit 0 -> 0x00CD (Play/Pause) - bit 1 -> 0x0183 (AL Consumer Control Config) - bit 2 -> 0x00B5 (Scan Next Track) - bit 3 -> 0x00B6 (Scan Previous Track) - bit 4 -> 0x00EA (Volume Decrement) - bit 5 -> 0x00E9 (Volume Increment) - bit 6 -> 0x0225 (AC Forward) - bit 7 -> 0x0224 (AC Back)
1 parent c45fe34 commit b0bb483

1 file changed

Lines changed: 55 additions & 6 deletions

File tree

ncs/app/src/ble_hid.c

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,40 @@ LOG_MODULE_REGISTER(ble_hid, LOG_LEVEL_INF);
4141
static ble_hid_data_received_cb_t data_received_callback = NULL;
4242
static ble_hid_ready_cb_t ready_callback = NULL;
4343

44+
/**
45+
* Consumer Control usage codes for backwards compatibility.
46+
* Maps old 1-byte bitmap format to new 16-bit usage selector format.
47+
* Old firmware used 8 individual bit flags, new descriptor uses usage codes.
48+
*/
49+
static const uint16_t consumer_bitmap_to_usage[] = {
50+
0x00CD, /* bit 0: Play/Pause */
51+
0x0183, /* bit 1: AL Consumer Control Configuration */
52+
0x00B5, /* bit 2: Scan Next Track */
53+
0x00B6, /* bit 3: Scan Previous Track */
54+
0x00EA, /* bit 4: Volume Decrement */
55+
0x00E9, /* bit 5: Volume Increment */
56+
0x0225, /* bit 6: AC Forward */
57+
0x0224, /* bit 7: AC Back */
58+
};
59+
60+
/**
61+
* Translate old consumer control bitmap to new 16-bit usage format.
62+
* Returns the usage code for the first set bit, or 0 if no bits set.
63+
*/
64+
static uint16_t translate_consumer_bitmap(uint8_t bitmap)
65+
{
66+
if (bitmap == 0) {
67+
return 0;
68+
}
69+
/* Find first set bit and return corresponding usage */
70+
for (int i = 0; i < 8; i++) {
71+
if (bitmap & (1 << i)) {
72+
return consumer_bitmap_to_usage[i];
73+
}
74+
}
75+
return 0;
76+
}
77+
4478
/**
4579
* Switch between boot protocol and report protocol mode.
4680
*/
@@ -172,14 +206,29 @@ static uint8_t hogp_notify_cb(struct bt_hogp *hogp,
172206

173207
// Parse and forward each report ID independently
174208
if (size >= 1) {
175-
/* Send directly to USB for zero latency */
176-
uint8_t report_with_id[size + 1];
177-
report_with_id[0] = report_id;
178-
for (uint8_t i = 0; i < size; i++) {
179-
report_with_id[i + 1] = data[i];
209+
int ret;
210+
211+
/* Handle Report ID 3 (Consumer Control) backwards compatibility */
212+
if (report_id == 3 && size == 1) {
213+
/* Old firmware sends 1-byte bitmap, translate to 16-bit usage */
214+
uint16_t usage = translate_consumer_bitmap(data[0]);
215+
uint8_t consumer_report[3] = {
216+
0x03, /* Report ID 3 */
217+
usage & 0xFF, /* Usage low byte */
218+
(usage >> 8) & 0xFF /* Usage high byte */
219+
};
220+
LOG_DBG("Consumer control: bitmap 0x%02x -> usage 0x%04x", data[0], usage);
221+
ret = hid_device_submit_report(hid_dev, sizeof(consumer_report), consumer_report);
222+
} else {
223+
/* Send directly to USB for zero latency */
224+
uint8_t report_with_id[size + 1];
225+
report_with_id[0] = report_id;
226+
for (uint8_t i = 0; i < size; i++) {
227+
report_with_id[i + 1] = data[i];
228+
}
229+
ret = hid_device_submit_report(hid_dev, size + 1, report_with_id);
180230
}
181231

182-
int ret = hid_device_submit_report(hid_dev, size + 1, report_with_id);
183232
if (ret) {
184233
LOG_ERR("HID write error, %d", ret);
185234
} else {

0 commit comments

Comments
 (0)