Skip to content

Commit ecb9097

Browse files
authored
Merge pull request #190 from vanbwodonk/master
add example for USB host HID report for RP2040
2 parents 2ab122c + 04400f8 commit ecb9097

File tree

3 files changed

+144
-5
lines changed

3 files changed

+144
-5
lines changed

examples/DualRole/HID_device_report/.feather_rp2040_tinyusb.test.only

Whitespace-only changes.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*********************************************************************
2+
Adafruit invests time and resources providing this open source code,
3+
please support Adafruit and open-source hardware by purchasing
4+
products from Adafruit!
5+
6+
MIT license, check LICENSE for more information
7+
Copyright (c) 2019 Ha Thach for Adafruit Industries
8+
All text above, and the splash screen below must be included in
9+
any redistribution
10+
*********************************************************************/
11+
12+
13+
/* This example demonstrates use of both device and host, where
14+
* - Device run on native usb controller (controller0)
15+
* - Host run on bit-banging 2 GPIOs with the help of Pico-PIO-USB library (controller1)
16+
*
17+
* Requirements:
18+
* - [Pico-PIO-USB](https://github.com/sekigon-gonnoc/Pico-PIO-USB) library
19+
* - 2 consecutive GPIOs: D+ is defined by HOST_PIN_DP (gpio2), D- = D+ +1 (gpio3)
20+
* - Provide VBus (5v) and GND for peripheral
21+
* - CPU Speed must be either 120 or 240 Mhz. Selected via "Menu -> CPU Speed"
22+
*
23+
* RP2040 host stack will get device descriptors of attached devices and print it out via
24+
* device cdc (Serial) as follows:
25+
* Device 1: ID 046d:c52f
26+
Device Descriptor:
27+
bLength 18
28+
bDescriptorType 1
29+
bcdUSB 0200
30+
bDeviceClass 0
31+
bDeviceSubClass 0
32+
bDeviceProtocol 0
33+
bMaxPacketSize0 8
34+
idVendor 0x046d
35+
idProduct 0xc52f
36+
bcdDevice 2200
37+
iManufacturer 1 Logitech
38+
iProduct 2 USB Receiver
39+
iSerialNumber 0
40+
bNumConfigurations 1
41+
*
42+
*/
43+
44+
// pio-usb is required for rp2040 host
45+
#include "pio_usb.h"
46+
#define HOST_PIN_DP 2 // Pin used as D+ for host, D- = D+ + 1
47+
48+
#include "Adafruit_TinyUSB.h"
49+
50+
#define LANGUAGE_ID 0x0409 // English
51+
52+
// USB Host object
53+
Adafruit_USBH_Host USBHost;
54+
55+
// holding device descriptor
56+
tusb_desc_device_t desc_device;
57+
58+
// the setup function runs once when you press reset or power the board
59+
void setup()
60+
{
61+
Serial1.begin(115200);
62+
63+
Serial.begin(115200);
64+
//while ( !Serial ) delay(10); // wait for native usb
65+
66+
Serial.println("TinyUSB Dual Device Info Example");
67+
}
68+
69+
void loop()
70+
{
71+
}
72+
73+
// core1's setup
74+
void setup1() {
75+
//while ( !Serial ) delay(10); // wait for native usb
76+
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
77+
78+
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
79+
uint32_t cpu_hz = clock_get_hz(clk_sys);
80+
if ( cpu_hz != 120000000UL && cpu_hz != 240000000UL ) {
81+
while ( !Serial ) delay(10); // wait for native usb
82+
Serial.printf("Error: CPU Clock = %u, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
83+
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n", cpu_hz);
84+
while(1) delay(1);
85+
}
86+
87+
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
88+
pio_cfg.pin_dp = HOST_PIN_DP;
89+
USBHost.configure_pio_usb(1, &pio_cfg);
90+
91+
// run host stack on controller (rhport) 1
92+
// Note: For rp2040 pico-pio-usb, calling USBHost.begin() on core1 will have most of the
93+
// host bit-banging processing works done in core1 to free up core0 for other works
94+
USBHost.begin(1);
95+
}
96+
97+
// core1's loop
98+
void loop1()
99+
{
100+
USBHost.task();
101+
}
102+
103+
// Invoked when device with hid interface is mounted
104+
// Report descriptor is also available for use.
105+
// tuh_hid_parse_report_descriptor() can be used to parse common/simple enough
106+
// descriptor. Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE,
107+
// it will be skipped therefore report_desc = NULL, desc_len = 0
108+
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
109+
(void)desc_report;
110+
(void)desc_len;
111+
uint16_t vid, pid;
112+
tuh_vid_pid_get(dev_addr, &vid, &pid);
113+
114+
Serial.printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
115+
Serial.printf("VID = %04x, PID = %04x\r\n", vid, pid);
116+
if (!tuh_hid_receive_report(dev_addr, instance)) {
117+
Serial.printf("Error: cannot request to receive report\r\n");
118+
}
119+
}
120+
121+
// Invoked when device with hid interface is un-mounted
122+
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
123+
Serial.printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
124+
}
125+
126+
// Invoked when received report from device via interrupt endpoint
127+
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
128+
Serial.printf("HIDreport : ");
129+
for (uint16_t i = 0; i < len; i++) {
130+
Serial.printf("0x%02X ", report[i]);
131+
}
132+
Serial.println();
133+
// continue to request to receive report
134+
if (!tuh_hid_receive_report(dev_addr, instance)) {
135+
Serial.printf("Error: cannot request to receive report\r\n");
136+
}
137+
}

src/arduino/Adafruit_USBH_Host.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,25 @@ void Adafruit_USBH_Host::task(void) { tuh_task(); }
5252
// tuh_hid_parse_report_descriptor() can be used to parse common/simple enough
5353
// descriptor. Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE,
5454
// it will be skipped therefore report_desc = NULL, desc_len = 0
55-
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance,
56-
uint8_t const *desc_report, uint16_t desc_len) {
55+
TU_ATTR_WEAK void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance,
56+
uint8_t const *desc_report,
57+
uint16_t desc_len) {
5758
(void)dev_addr;
5859
(void)instance;
5960
(void)desc_report;
6061
(void)desc_len;
6162
}
6263

6364
// Invoked when device with hid interface is un-mounted
64-
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
65+
TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
6566
(void)dev_addr;
6667
(void)instance;
6768
}
6869

6970
// Invoked when received report from device via interrupt endpoint
70-
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance,
71-
uint8_t const *report, uint16_t len) {
71+
TU_ATTR_WEAK void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance,
72+
uint8_t const *report,
73+
uint16_t len) {
7274
(void)dev_addr;
7375
(void)instance;
7476
(void)report;

0 commit comments

Comments
 (0)