3 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
kenji 3014bc0c3b add schematic 2025-09-11 12:27:29 -04:00
8 changed files with 14830 additions and 22 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
/build/**/* /*/**/*
/external/**/* !/html/**/*
+2
View File
@@ -17,6 +17,8 @@ You will need the following hardware to make the device:
- light dependent resistor such as GL5528 (specific part number may vary) - light dependent resistor such as GL5528 (specific part number may vary)
- 10k ohm resistor (resistance value may vary) - 10k ohm resistor (resistance value may vary)
![Wiring schematic](schematic.svg)
You will need to cut the USB extension in half and connect the wires from the You will need to cut the USB extension in half and connect the wires from the
female end to the Raspberry Pi Pico (2). The default configuration is to attach female end to the Raspberry Pi Pico (2). The default configuration is to attach
the USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will the USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will
+7 -5
View File
@@ -312,8 +312,6 @@ void parse_colors(char * data, uint16_t len) {
if (token != NULL) { if (token != NULL) {
// first string is the RGB color code // first string is the RGB color code
uint8_t red, green, blue; uint8_t red, green, blue;
// sscanf(token, "%2x%2x%2x", &red, &green, &blue);
// sscanf causes Pico 1 to crash
red = hexbyte(token); red = hexbyte(token);
green = hexbyte(token+2); green = hexbyte(token+2);
blue = hexbyte(token+4); blue = hexbyte(token+4);
@@ -362,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 (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) { if (device_state == DEVICE_ACTIVE ) {
mute = !mute; if (instance == 0x01 && report[0] == 0x03 && report[1] == 0xE2) {
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
-1
View File
@@ -196,5 +196,4 @@ bool load_rgb_config(void);
#error "Unsupported device. Expected RP2040 or RP2350." #error "Unsupported device. Expected RP2040 or RP2350."
#endif #endif
#endif #endif
+14772
View File
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 268 KiB

+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()) {
device_state = DEVICE_INACTIVE;
sleep_ms(10); sleep_ms(10);
if (tud_connect()) { tud_connect();
if ( host_state == HOST_INACTIVE ) {
device_state = DEVICE_INACTIVE;
} else {
device_state = DEVICE_ACTIVE;
}
}
} }
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;
+30 -6
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,12 +159,19 @@ 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) ) {
// continue to request to receive report tud_cdc_write_str("Error: cannot forward report\r\n");
if ( !tuh_hid_receive_report(dev_addr, instance) ) // queue report for resending
{ last_report.dev_addr = dev_addr;
tud_cdc_write_str("Error: cannot request report\r\n"); last_report.instance = instance;
last_report.len = len;
memcpy(last_report.report, report, len);
} else {
// continue to request to receive report
if ( !tuh_hid_receive_report(dev_addr, instance) ) {
tud_cdc_write_str("Error: cannot request report\r\n");
}
} }
} }
+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;