1616
1717static char const TAG [] = "BADGE_HID_DRIVER" ;
1818
19+ static mouse_field_layout_t mouse_layout = {0 };
20+ static gamepad_field_layout_t gamepad_layout = {0 };
21+
22+ static uint32_t extract_unsigned_bits (const uint8_t * data , int bit_offset , int bit_size ) {
23+ uint32_t value = 0 ;
24+ for (int i = 0 ; i < bit_size ; i ++ ) {
25+ int byte_index = (bit_offset + i ) / 8 ;
26+ int bit_index = (bit_offset + i ) % 8 ;
27+ if (data [byte_index ] & (1 << bit_index )) {
28+ value |= (1u << i );
29+ }
30+ }
31+ return value ;
32+ }
33+
1934static int32_t extract_signed_bits (const uint8_t * data , uint16_t bit_offset , uint8_t bit_size ) {
2035 uint32_t raw = 0 ;
2136 for (int i = 0 ; i < ((bit_size + 7 ) / 8 ) + 1 ; ++ i ) {
@@ -33,6 +48,13 @@ static int32_t extract_signed_bits(const uint8_t* data, uint16_t bit_offset, uin
3348 return value ;
3449}
3550
51+ static void decode_hat_to_dpad (uint8_t hat , gamepad_report_t * rpt ) {
52+ rpt -> buttons .up = (hat == 0x00 || hat == 0x01 || hat == 0x07 );
53+ rpt -> buttons .right = (hat == 0x01 || hat == 0x02 || hat == 0x03 );
54+ rpt -> buttons .down = (hat == 0x03 || hat == 0x04 || hat == 0x05 );
55+ rpt -> buttons .left = (hat == 0x05 || hat == 0x06 || hat == 0x07 );
56+ }
57+
3658esp_err_t analyze_mouse_layout (const uint8_t * desc , int desc_len , mouse_field_layout_t * layout_out ) {
3759 memset (layout_out , 0 , sizeof (* layout_out ));
3860
@@ -68,7 +90,11 @@ esp_err_t analyze_mouse_layout(const uint8_t* desc, int desc_len, mouse_field_la
6890 report_size = data ;
6991 else if (tag == HID_TAG_REPORT_COUNT )
7092 report_count = data ;
71- break ;
93+ else if (tag == HID_TAG_REPORT_ID ) {
94+ layout_out -> report_id = data ;
95+ bit_offset += 8 ;
96+ }
97+ break ;;
7298
7399 case HID_TYPE_LOCAL :
74100 if (tag == HID_TAG_USAGE && usage_index < 32 )
@@ -144,7 +170,7 @@ esp_err_t analyze_mouse_layout(const uint8_t* desc, int desc_len, mouse_field_la
144170 return layout_out -> x .present && layout_out -> y .present && layout_out -> buttons .present ? ESP_OK : ESP_FAIL ;
145171}
146172
147- esp_err_t analyze_gamepad_layout (const uint8_t * desc , int desc_len , gamepad_field_layout_t * layout_out ) {
173+ esp_err_t analyze_gamepad_layout (const uint8_t * desc , const int desc_len , gamepad_field_layout_t * layout_out ) {
148174 memset (layout_out , 0 , sizeof (* layout_out ));
149175
150176 uint16_t bit_offset = 0 ;
@@ -282,6 +308,87 @@ esp_err_t analyze_gamepad_layout(const uint8_t* desc, int desc_len, gamepad_fiel
282308 return ESP_OK ;
283309}
284310
311+ mouse_report_t parse_mouse_event (const uint8_t * data , const int length , mouse_field_layout_t * layout ) {
312+
313+ // ESP_LOG_BUFFER_HEX(TAG, data, length);
314+
315+ mouse_report_t report = {0 };
316+ if (!layout ) {
317+ ESP_LOGW (TAG , "No layout for mouse!" );
318+ return report ;
319+ }
320+
321+ if (layout -> buttons .present ) {
322+ report .buttons .val = extract_unsigned_bits (data , layout -> buttons .offset , layout -> buttons .size );
323+ }
324+
325+ if (layout -> x .present ) {
326+ report .x_displacement = extract_signed_bits (data , layout -> x .offset , layout -> x .size );
327+ }
328+
329+ if (layout -> y .present ) {
330+ report .y_displacement = extract_signed_bits (data , layout -> y .offset , layout -> y .size );
331+ }
332+
333+ if (layout -> scroll .present ) {
334+ report .scroll = extract_signed_bits (data , layout -> scroll .offset , layout -> scroll .size );
335+ }
336+
337+ if (layout -> tilt .present ) {
338+ report .tilt = extract_signed_bits (data , layout -> tilt .offset , layout -> tilt .size );
339+ }
340+
341+ return report ;
342+ }
343+
344+ gamepad_report_t parse_gamepad_report (const uint8_t * data , int length , gamepad_field_layout_t * layout ) {
345+
346+ ESP_LOG_BUFFER_HEX (TAG , data , length );
347+
348+ gamepad_report_t report = {0 };
349+ if (!layout ) {
350+ ESP_LOGW (TAG , "No layout for gamepad!" );
351+ return report ;
352+ }
353+ if (layout -> dpad .present ) {
354+ uint8_t hat = extract_unsigned_bits (data , layout -> dpad .offset , layout -> dpad .size );
355+ decode_hat_to_dpad (hat , & report );
356+ }
357+
358+ if (layout -> buttons .present ) {
359+ uint32_t btn_bits = extract_unsigned_bits (data , layout -> buttons .offset , layout -> buttons .size );
360+ // Preserve bits that were already set by decode_hat_to_dpad()
361+ btn_bits |= report .buttons .val ;
362+ report .buttons .val = btn_bits ;
363+ }
364+
365+ if (layout -> lx .present ) {
366+ report .lx = extract_signed_bits (data , layout -> lx .offset , layout -> lx .size );
367+ }
368+
369+ if (layout -> ly .present ) {
370+ report .ly = extract_signed_bits (data , layout -> ly .offset , layout -> ly .size );
371+ }
372+
373+ if (layout -> rx .present ) {
374+ report .rx = extract_signed_bits (data , layout -> rx .offset , layout -> rx .size );
375+ }
376+
377+ if (layout -> ry .present ) {
378+ report .ry = extract_signed_bits (data , layout -> ry .offset , layout -> ry .size );
379+ }
380+
381+ if (layout -> lt .present ) {
382+ report .lt = extract_signed_bits (data , layout -> lt .offset , layout -> lt .size );
383+ }
384+
385+ if (layout -> rt .present ) {
386+ report .rt = extract_signed_bits (data , layout -> rt .offset , layout -> rt .size );
387+ }
388+
389+ return report ;
390+ }
391+
285392esp_err_t decode_descriptor_register_driver (const uint8_t * const desc , const int desc_len , const uint8_t proto ) {
286393 if (HID_PROTOCOL_KEYBOARD == proto ) {
287394 ESP_LOGI (TAG , "Keyboard uses generic (boot) driver" );
@@ -291,63 +398,69 @@ esp_err_t decode_descriptor_register_driver(const uint8_t* const desc, const int
291398 if (HID_PROTOCOL_MOUSE == proto ) {
292399 ESP_LOGI (TAG , "Mouse driver analysing" );
293400 ESP_LOG_BUFFER_HEX (TAG , desc , desc_len );
294- mouse_field_layout_t layout = {0 };
295- if (ESP_OK == analyze_mouse_layout (desc , desc_len , & layout )) {
401+ if (ESP_OK == analyze_mouse_layout (desc , desc_len , & mouse_layout )) {
296402 ESP_LOGI (TAG , "Parsed mouse layout:" );
297- ESP_LOGI (TAG , " Buttons: offset %u bits, count %u" , layout .buttons .offset , layout .buttons .size );
298- if (layout .x .present ) ESP_LOGI (TAG , " X: offset %u bits, size %u bits" , layout .x .offset , layout .x .size );
299- if (layout .y .offset ) ESP_LOGI (TAG , " Y: offset %u bits, size %u bits" , layout .y .offset , layout .y .size );
300- if (layout .scroll .present )
301- ESP_LOGI (TAG , " Scroll: offset %u bits, size %u bits" , layout .scroll .offset , layout .scroll .size );
302- if (layout .tilt .present )
303- ESP_LOGI (TAG , " Tilt: offset %u bits, size %u bits" , layout .tilt .offset , layout .tilt .size );
403+ ESP_LOGI (TAG , " Buttons: offset %u bits, count %u" , mouse_layout .buttons .offset , mouse_layout .buttons .size );
404+ if (mouse_layout .x .present ) ESP_LOGI (TAG , " X: offset %u bits, size %u bits" , mouse_layout .x .offset , mouse_layout .x .size );
405+ if (mouse_layout .y .offset ) ESP_LOGI (TAG , " Y: offset %u bits, size %u bits" , mouse_layout .y .offset , mouse_layout .y .size );
406+ if (mouse_layout .scroll .present )
407+ ESP_LOGI (TAG , " Scroll: offset %u bits, size %u bits" , mouse_layout .scroll .offset , mouse_layout .scroll .size );
408+ if (mouse_layout .tilt .present )
409+ ESP_LOGI (TAG , " Tilt: offset %u bits, size %u bits" , mouse_layout .tilt .offset , mouse_layout .tilt .size );
304410 } else {
305411 ESP_LOGW (TAG , "Could not parse mouse layout" );
306412 }
307413 } else {
308414 ESP_LOGI (TAG , "Gamepad driver analysing" );
309415 ESP_LOG_BUFFER_HEX (TAG , desc , desc_len );
310- gamepad_field_layout_t layout ;
311- if ( ESP_OK == analyze_gamepad_layout ( desc , desc_len , & layout )) {
312- ESP_LOGI ( TAG , "Parsed gamepad layout:" );
313- if ( layout .dpad .present ) {
314- ESP_LOGI ( TAG , " D-Pad: offset %d bits, size %d bits" , layout . dpad . offset , layout .dpad .size );
416+ if ( ESP_OK == analyze_gamepad_layout ( desc , desc_len , & gamepad_layout )) {
417+ ESP_LOGI ( TAG , "Parsed gamepad gamepad_layout:" );
418+ if ( gamepad_layout . dpad . present ) {
419+ ESP_LOGI ( TAG , " D-Pad: offset %d bits, size %d bits" , gamepad_layout .dpad .offset ,
420+ gamepad_layout .dpad .size );
315421 }
316422
317- if (layout .buttons .present ) {
318- ESP_LOGI (TAG , " Buttons: offset %d bits, count %d" , layout .buttons .offset , layout .buttons .size );
423+ if (gamepad_layout .buttons .present ) {
424+ ESP_LOGI (TAG , " Buttons: offset %d bits, count %d" , gamepad_layout .buttons .offset ,
425+ gamepad_layout .buttons .size );
319426 }
320427
321- if (layout .lx .present && layout .ly .present ) {
322- ESP_LOGI (TAG , " Left Stick: X@%dbits (%d bits), Y@%dbits (%d bits)" , layout .lx .offset , layout . lx . size ,
323- layout . ly .offset , layout .ly .size );
428+ if (gamepad_layout .lx .present && gamepad_layout .ly .present ) {
429+ ESP_LOGI (TAG , " Left Stick: X@%dbits (%d bits), Y@%dbits (%d bits)" , gamepad_layout .lx .offset ,
430+ gamepad_layout . lx . size , gamepad_layout . ly .offset , gamepad_layout .ly .size );
324431 } else {
325- if (layout .lx .present ) {
326- ESP_LOGI (TAG , " Left Stick X: offset %d bits, size %d bits" , layout .lx .offset , layout .lx .size );
432+ if (gamepad_layout .lx .present ) {
433+ ESP_LOGI (TAG , " Left Stick X: offset %d bits, size %d bits" , gamepad_layout .lx .offset ,
434+ gamepad_layout .lx .size );
327435 }
328- if (layout .ly .present ) {
329- ESP_LOGI (TAG , " Left Stick Y: offset %d bits, size %d bits" , layout .ly .offset , layout .ly .size );
436+ if (gamepad_layout .ly .present ) {
437+ ESP_LOGI (TAG , " Left Stick Y: offset %d bits, size %d bits" , gamepad_layout .ly .offset ,
438+ gamepad_layout .ly .size );
330439 }
331440 }
332441
333- if (layout .rx .present && layout .ry .present ) {
334- ESP_LOGI (TAG , " Right Stick: X@%dbits (%d bits), Y@%dbits (%d bits)" , layout .rx .offset , layout . rx . size ,
335- layout . ry .offset , layout .ry .size );
442+ if (gamepad_layout .rx .present && gamepad_layout .ry .present ) {
443+ ESP_LOGI (TAG , " Right Stick: X@%dbits (%d bits), Y@%dbits (%d bits)" , gamepad_layout .rx .offset ,
444+ gamepad_layout . rx . size , gamepad_layout . ry .offset , gamepad_layout .ry .size );
336445 } else {
337- if (layout .rx .present ) {
338- ESP_LOGI (TAG , " Right Stick X: offset %d bits, size %d bits" , layout .rx .offset , layout .rx .size );
446+ if (gamepad_layout .rx .present ) {
447+ ESP_LOGI (TAG , " Right Stick X: offset %d bits, size %d bits" , gamepad_layout .rx .offset ,
448+ gamepad_layout .rx .size );
339449 }
340- if (layout .ry .present ) {
341- ESP_LOGI (TAG , " Right Stick Y: offset %d bits, size %d bits" , layout .ry .offset , layout .ry .size );
450+ if (gamepad_layout .ry .present ) {
451+ ESP_LOGI (TAG , " Right Stick Y: offset %d bits, size %d bits" , gamepad_layout .ry .offset ,
452+ gamepad_layout .ry .size );
342453 }
343454 }
344455
345- if (layout .lt .present ) {
346- ESP_LOGI (TAG , " Trigger L: offset %d bits, size %d bits" , layout .lt .offset , layout .lt .size );
456+ if (gamepad_layout .lt .present ) {
457+ ESP_LOGI (TAG , " Trigger L: offset %d bits, size %d bits" , gamepad_layout .lt .offset ,
458+ gamepad_layout .lt .size );
347459 }
348460
349- if (layout .rt .present ) {
350- ESP_LOGI (TAG , " Trigger R: offset %d bits, size %d bits" , layout .rt .offset , layout .rt .size );
461+ if (gamepad_layout .rt .present ) {
462+ ESP_LOGI (TAG , " Trigger R: offset %d bits, size %d bits" , gamepad_layout .rt .offset ,
463+ gamepad_layout .rt .size );
351464 }
352465
353466 } else {
0 commit comments