Skip to content

Commit 37afebb

Browse files
authored
Merge pull request #3025 from FoamyGuy/usb_host_mouse
Usb host mouse examples
2 parents 7d22755 + 4b8feb2 commit 37afebb

File tree

12 files changed

+683
-4
lines changed

12 files changed

+683
-4
lines changed

USB_Host_Examples/Arduino_Feather_RP2040_USB_Host_Mouse/usbhost_mouse_simpletest/.feather_rp2040_usbhost_tinyusb.test.only

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
// HID reports for standard boot mouse
6+
7+
// Byte indices for the gamepad report
8+
#define BYTE_BUTTONS 0 // Left, right, middle click buttons
9+
#define BYTE_DELTA_X 1 // Mouse movement horizontal
10+
#define BYTE_DELTA_Y 2 // Mouse movement vertical
11+
12+
#define BUTTON_NEUTRAL 0x00
13+
#define BUTTON_LEFT 0x01
14+
#define BUTTON_RIGHT 0x02
15+
#define BUTTON_MIDDLE 0x04
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-FileCopyrightText: 2024 Ha Thach for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/*********************************************************************
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
MIT license, check LICENSE for more information
11+
Copyright (c) 2019 Ha Thach for Adafruit Industries
12+
All text above, and the splash screen below must be included in
13+
any redistribution
14+
*********************************************************************/
15+
16+
#ifndef USBH_HELPER_H
17+
#define USBH_HELPER_H
18+
19+
#ifdef ARDUINO_ARCH_RP2040
20+
// pio-usb is required for rp2040 host
21+
#include "pio_usb.h"
22+
23+
// Pin D+ for host, D- = D+ + 1
24+
#ifndef PIN_USB_HOST_DP
25+
#define PIN_USB_HOST_DP 16
26+
#endif
27+
28+
// Pin for enabling Host VBUS. comment out if not used
29+
#ifndef PIN_5V_EN
30+
#define PIN_5V_EN 18
31+
#endif
32+
33+
#ifndef PIN_5V_EN_STATE
34+
#define PIN_5V_EN_STATE 1
35+
#endif
36+
#endif // ARDUINO_ARCH_RP2040
37+
38+
#ifdef ARDUINO_ARCH_RP2350
39+
40+
// pio-usb is required for rp2040 host
41+
#include "pio_usb.h"
42+
43+
// Pin D+ for host, D- = D+ + 1
44+
#ifndef PIN_USB_HOST_DP
45+
#define PIN_USB_HOST_DP 32
46+
#endif
47+
48+
// Pin for enabling Host VBUS. comment out if not used
49+
#ifndef PIN_5V_EN
50+
#define PIN_5V_EN 29
51+
#endif
52+
53+
#ifndef PIN_5V_EN_STATE
54+
#define PIN_5V_EN_STATE 1
55+
#endif
56+
#endif // ARDUINO_ARCH_RP2350
57+
58+
#include "Adafruit_TinyUSB.h"
59+
60+
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
61+
// USB Host using MAX3421E: SPI, CS, INT
62+
#include "SPI.h"
63+
64+
#if defined(ARDUINO_METRO_ESP32S2)
65+
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
66+
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
67+
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
68+
#else
69+
// Default CS and INT are pin 10, 9
70+
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
71+
#endif
72+
#else
73+
// Native USB Host such as rp2040
74+
Adafruit_USBH_Host USBHost;
75+
#endif
76+
77+
//--------------------------------------------------------------------+
78+
// Helper Functions
79+
//--------------------------------------------------------------------+
80+
81+
#ifdef ARDUINO_ARCH_RP2040
82+
static void rp2040_configure_pio_usb(void) {
83+
//while ( !Serial ) delay(10); // wait for native usb
84+
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
85+
86+
#ifdef PIN_5V_EN
87+
pinMode(PIN_5V_EN, OUTPUT);
88+
digitalWrite(PIN_5V_EN, PIN_5V_EN_STATE);
89+
#endif
90+
91+
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
92+
pio_cfg.pin_dp = PIN_USB_HOST_DP;
93+
94+
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
95+
// For pico-w, PIO is also used to communicate with cyw43
96+
// Therefore we need to alternate the pio-usb configuration
97+
// details https://github.com/sekigon-gonnoc/Pico-PIO-USB/issues/46
98+
pio_cfg.sm_tx = 3;
99+
pio_cfg.sm_rx = 2;
100+
pio_cfg.sm_eop = 3;
101+
pio_cfg.pio_rx_num = 0;
102+
pio_cfg.pio_tx_num = 1;
103+
pio_cfg.tx_ch = 9;
104+
#endif
105+
106+
USBHost.configure_pio_usb(1, &pio_cfg);
107+
}
108+
#endif
109+
110+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/*********************************************************************
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
MIT license, check LICENSE for more information
11+
Copyright (c) 2019 Ha Thach for Adafruit Industries
12+
All text above, and the splash screen below must be included in
13+
any redistribution
14+
*********************************************************************/
15+
16+
/* This example demonstrates use of usb host with a standard HID boot mouse.
17+
* - Host depends on MCU:
18+
* - rp2040: bit-banging 2 GPIOs with Pico-PIO-USB library (roothub port1)
19+
*
20+
* Requirements:
21+
* - For rp2040:
22+
* - Pico-PIO-USB library
23+
* - 2 consecutive GPIOs: D+ is defined by PIN_USB_HOST_DP, D- = D+ +1
24+
* - Provide VBus (5v) and GND for peripheral
25+
*/
26+
27+
// USBHost is defined in usbh_helper.h
28+
#include "usbh_helper.h"
29+
#include "tusb.h"
30+
#include "Adafruit_TinyUSB.h"
31+
#include "hid_mouse_reports.h"
32+
33+
34+
bool printed_blank = false;
35+
36+
void setup() {
37+
Serial.begin(115200);
38+
39+
// configure pio-usb: defined in usbh_helper.h
40+
rp2040_configure_pio_usb();
41+
42+
// run host stack on controller (rhport) 1
43+
// Note: For rp2040 pico-pio-usb, calling USBHost.begin() on core1 will have most of the
44+
// host bit-banging processing works done in core1 to free up core0 for other works
45+
USBHost.begin(1);
46+
delay(3000);
47+
Serial.print("USB D+ Pin:");
48+
Serial.println(PIN_USB_HOST_DP);
49+
Serial.print("USB 5V Pin:");
50+
Serial.println(PIN_5V_EN);
51+
}
52+
53+
void loop() {
54+
USBHost.task();
55+
Serial.flush();
56+
57+
}
58+
59+
//--------------------------------------------------------------------+
60+
// HID Host Callback Functions
61+
//--------------------------------------------------------------------+
62+
63+
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len)
64+
{
65+
Serial.printf("HID device mounted (address %d, instance %d)\n", dev_addr, instance);
66+
67+
// Start receiving HID reports
68+
if (!tuh_hid_receive_report(dev_addr, instance))
69+
{
70+
Serial.printf("Error: cannot request to receive report\n");
71+
}
72+
}
73+
74+
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
75+
{
76+
Serial.printf("HID device unmounted (address %d, instance %d)\n", dev_addr, instance);
77+
}
78+
79+
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) {
80+
81+
if (len > 0){
82+
83+
//debug print report data
84+
// Serial.print("Report data: ");
85+
// for (int i = 0; i < len; i++) {
86+
// if (i == 0 || i == 3){
87+
// Serial.print(report[i], HEX);
88+
// Serial.print(" ");
89+
// }else { // i==1 or i==2
90+
// Serial.print((int8_t)report[i]);
91+
// Serial.print(" ");
92+
// }
93+
// }
94+
// Serial.println();
95+
96+
Serial.print("X: ");
97+
Serial.print((int8_t)report[1]);
98+
Serial.print(" ");
99+
Serial.print("Y: ");
100+
Serial.print((int8_t)report[2]);
101+
Serial.print(" ");
102+
103+
if (report[BYTE_BUTTONS] != BUTTON_NEUTRAL){
104+
if ((report[BYTE_BUTTONS] & BUTTON_LEFT) == BUTTON_LEFT){
105+
Serial.print("Left ");
106+
}
107+
if ((report[BYTE_BUTTONS] & BUTTON_RIGHT) == BUTTON_RIGHT){
108+
Serial.print("Right ");
109+
}
110+
if ((report[BYTE_BUTTONS] & BUTTON_MIDDLE) == BUTTON_MIDDLE){
111+
Serial.print("Middle ");
112+
}
113+
}
114+
Serial.println();
115+
}
116+
117+
// Continue to receive the next report
118+
if (!tuh_hid_receive_report(dev_addr, instance)) {
119+
Serial.println("Error: cannot request to receive report");
120+
}
121+
}

USB_Host_Examples/Arduino_Metro_RP2350_Mouse_USB_Host/usbhost_mouse_simpletest/.metro_rp2350_tinyusb.test.only

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
// HID reports for standard boot mouse
6+
7+
// Byte indices for the gamepad report
8+
#define BYTE_BUTTONS 0 // Left, right, middle click buttons
9+
#define BYTE_DELTA_X 1 // Mouse movement horizontal
10+
#define BYTE_DELTA_Y 2 // Mouse movement vertical
11+
12+
#define BUTTON_NEUTRAL 0x00
13+
#define BUTTON_LEFT 0x01
14+
#define BUTTON_RIGHT 0x02
15+
#define BUTTON_MIDDLE 0x04
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-FileCopyrightText: 2024 Ha Thach for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/*********************************************************************
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
MIT license, check LICENSE for more information
11+
Copyright (c) 2019 Ha Thach for Adafruit Industries
12+
All text above, and the splash screen below must be included in
13+
any redistribution
14+
*********************************************************************/
15+
16+
#ifndef USBH_HELPER_H
17+
#define USBH_HELPER_H
18+
19+
#ifdef ARDUINO_ARCH_RP2040
20+
// pio-usb is required for rp2040 host
21+
#include "pio_usb.h"
22+
23+
// Pin D+ for host, D- = D+ + 1
24+
#ifndef PIN_USB_HOST_DP
25+
#define PIN_USB_HOST_DP 16
26+
#endif
27+
28+
// Pin for enabling Host VBUS. comment out if not used
29+
#ifndef PIN_5V_EN
30+
#define PIN_5V_EN 18
31+
#endif
32+
33+
#ifndef PIN_5V_EN_STATE
34+
#define PIN_5V_EN_STATE 1
35+
#endif
36+
#endif // ARDUINO_ARCH_RP2040
37+
38+
#ifdef ARDUINO_ARCH_RP2350
39+
40+
// pio-usb is required for rp2040 host
41+
#include "pio_usb.h"
42+
43+
// Pin D+ for host, D- = D+ + 1
44+
#ifndef PIN_USB_HOST_DP
45+
#define PIN_USB_HOST_DP 32
46+
#endif
47+
48+
// Pin for enabling Host VBUS. comment out if not used
49+
#ifndef PIN_5V_EN
50+
#define PIN_5V_EN 29
51+
#endif
52+
53+
#ifndef PIN_5V_EN_STATE
54+
#define PIN_5V_EN_STATE 1
55+
#endif
56+
#endif // ARDUINO_ARCH_RP2350
57+
58+
#include "Adafruit_TinyUSB.h"
59+
60+
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
61+
// USB Host using MAX3421E: SPI, CS, INT
62+
#include "SPI.h"
63+
64+
#if defined(ARDUINO_METRO_ESP32S2)
65+
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
66+
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
67+
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
68+
#else
69+
// Default CS and INT are pin 10, 9
70+
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
71+
#endif
72+
#else
73+
// Native USB Host such as rp2040
74+
Adafruit_USBH_Host USBHost;
75+
#endif
76+
77+
//--------------------------------------------------------------------+
78+
// Helper Functions
79+
//--------------------------------------------------------------------+
80+
81+
#ifdef ARDUINO_ARCH_RP2040
82+
static void rp2040_configure_pio_usb(void) {
83+
//while ( !Serial ) delay(10); // wait for native usb
84+
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
85+
86+
#ifdef PIN_5V_EN
87+
pinMode(PIN_5V_EN, OUTPUT);
88+
digitalWrite(PIN_5V_EN, PIN_5V_EN_STATE);
89+
#endif
90+
91+
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
92+
pio_cfg.pin_dp = PIN_USB_HOST_DP;
93+
94+
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
95+
// For pico-w, PIO is also used to communicate with cyw43
96+
// Therefore we need to alternate the pio-usb configuration
97+
// details https://github.com/sekigon-gonnoc/Pico-PIO-USB/issues/46
98+
pio_cfg.sm_tx = 3;
99+
pio_cfg.sm_rx = 2;
100+
pio_cfg.sm_eop = 3;
101+
pio_cfg.pio_rx_num = 0;
102+
pio_cfg.pio_tx_num = 1;
103+
pio_cfg.tx_ch = 9;
104+
#endif
105+
106+
USBHost.configure_pio_usb(1, &pio_cfg);
107+
}
108+
#endif
109+
110+
#endif

0 commit comments

Comments
 (0)