2 Commits

Author SHA1 Message Date
kenji 75d8f87b40 suppress hid events from host when device is disconnected 2026-05-08 11:40:49 -04:00
kenji 9762476e4b handle resending failed HID reports 2025-09-30 12:39:33 -04:00
4 changed files with 54 additions and 17 deletions
+4
View File
@@ -360,11 +360,15 @@ void startADC() {
// forward HID report after processing // forward HID report after processing
bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) { bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) {
if (device_state == DEVICE_ACTIVE ) {
if (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) { if (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) {
mute = !mute; mute = !mute;
} }
return tud_hid_n_report(instance, 0, report, len); return tud_hid_n_report(instance, 0, report, len);
}
return true;
} }
// save RGB configuration to flash // save RGB configuration to flash
+10 -8
View File
@@ -75,19 +75,17 @@ void usb_device_main(void) {
while (true) { while (true) {
switch ( device_state ) { switch ( device_state ) {
case DEVICE_ACTIVE: case DEVICE_ACTIVE:
if (!tud_mounted()) {
device_state = DEVICE_INACTIVE;
}
break; break;
case DEVICE_INACTIVE: case DEVICE_INACTIVE:
break; break;
case DEVICE_RESTART: case DEVICE_RESTART:
if (tud_disconnect()) { if (tud_disconnect()) {
sleep_ms(10);
if (tud_connect()) {
if ( host_state == HOST_INACTIVE ) {
device_state = DEVICE_INACTIVE; device_state = DEVICE_INACTIVE;
} else { sleep_ms(10);
device_state = DEVICE_ACTIVE; tud_connect();
}
}
} }
break; break;
default: default:
@@ -214,7 +212,6 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf)
return NULL; return NULL;
} }
// Invoked when received SET_REPORT control request or // Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 ) // received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
@@ -238,6 +235,11 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
return 0; return 0;
} }
// Invoked when device is mounted
void tud_mount_cb(void) {
device_state = DEVICE_ACTIVE;
}
// print message to CDC in raw hex // print message to CDC in raw hex
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) { void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
(void) msg; (void) msg;
+28 -4
View File
@@ -19,6 +19,7 @@ uint8_t num_mounted=0;
static absolute_time_t request_time; static absolute_time_t request_time;
static bool enabled=false; static bool enabled=false;
static uint8_t kb_addr=0; static uint8_t kb_addr=0;
static struct hid_report last_report;
static void usb_host_init(void); static void usb_host_init(void);
static void host_ready(void); static void host_ready(void);
@@ -79,6 +80,22 @@ void usb_host_main(void) {
if (enabled) { if (enabled) {
rgb_task(kb_addr); rgb_task(kb_addr);
} }
if (last_report.len > 0 ) {
// previous report was not forwarded, resend
if ( forward_report(last_report.instance, last_report.report, last_report.len) ) {
// clear queue
last_report.len = 0;
memset(last_report.report, 0x00, REPORT_MAX_SIZE);
// continue requesting reports
if ( !tuh_hid_receive_report(last_report.dev_addr, last_report.instance) ) {
tud_cdc_write_str("Error: cannot request report\r\n");
}
} else {
tud_cdc_write_str("Error: failed resend report\r\n");
}
}
break; break;
default: default:
break; break;
@@ -142,13 +159,20 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
cdc_print_hex(report, len); cdc_print_hex(report, len);
} }
forward_report(instance, report, len); // forward report to device output
if ( !forward_report(instance, report, len) ) {
tud_cdc_write_str("Error: cannot forward report\r\n");
// queue report for resending
last_report.dev_addr = dev_addr;
last_report.instance = instance;
last_report.len = len;
memcpy(last_report.report, report, len);
} else {
// continue to request to receive report // continue to request to receive report
if ( !tuh_hid_receive_report(dev_addr, instance) ) if ( !tuh_hid_receive_report(dev_addr, instance) ) {
{
tud_cdc_write_str("Error: cannot request report\r\n"); tud_cdc_write_str("Error: cannot request report\r\n");
} }
}
} }
// start listening on host for HID events // start listening on host for HID events
+7
View File
@@ -23,6 +23,13 @@ struct report_desc {
bool listening; bool listening;
}; };
struct hid_report {
uint8_t dev_addr;
uint8_t instance;
uint16_t len;
uint8_t report[REPORT_MAX_SIZE];
};
#define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc)) #define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc))
extern host_state_t host_state; extern host_state_t host_state;