// Proof-of-concept: KB2040 as composite HID + WebUSB using Adafruit TinyUSB // // Board/IDE requirements: // - Board: Adafruit KB2040 (RP2040) // - Tools -> USB Stack: Adafruit TinyUSB // - Library: Adafruit TinyUSB Library #include // HID report descriptor: Consumer Control for media keys static const uint8_t desc_hid_report[] = { TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(1)) }; Adafruit_USBD_HID usb_hid; Adafruit_USBD_WebUSB usb_web; WEBUSB_URL_DEF(landing_url, 1 /* https */, "example.com/nsigner/kb2040"); static uint32_t last_hid_ms = 0; static uint8_t rx_buf[64]; void setup() { // WebUSB vendor interface usb_web.setLandingPage(&landing_url); usb_web.setStringDescriptor("n_signer WebUSB"); usb_web.begin(); // HID interface (media keys) usb_hid.setPollInterval(2); usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); usb_hid.setStringDescriptor("KB2040 Media"); usb_hid.begin(); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); // Wait for host enumeration while (!TinyUSBDevice.mounted()) { delay(1); } digitalWrite(LED_BUILTIN, HIGH); } void loop() { // Demonstrate HID activity: send volume-up every 5 seconds if (millis() - last_hid_ms >= 5000) { last_hid_ms = millis(); if (usb_hid.ready()) { uint16_t key = HID_USAGE_CONSUMER_VOLUME_INCREMENT; usb_hid.sendReport16(1, key); delay(30); usb_hid.sendReport16(1, 0); digitalWrite(LED_BUILTIN, LOW); delay(80); digitalWrite(LED_BUILTIN, HIGH); } } // Demonstrate WebUSB activity: echo back received bytes with prefix if (usb_web.available()) { uint32_t n = usb_web.read(rx_buf, sizeof(rx_buf)); if (n > 0) { usb_web.write((const uint8_t *)"KB2040:", 7); usb_web.write(rx_buf, n); usb_web.flush(); for (int i = 0; i < 2; i++) { digitalWrite(LED_BUILTIN, LOW); delay(50); digitalWrite(LED_BUILTIN, HIGH); delay(50); } } } }