9
9
any redistribution
10
10
*********************************************************************/
11
11
12
+ /* This example demonstrates use of both device and host, where
13
+ * - Device run on native usb controller (roothub port0)
14
+ * - Host depending on MCUs run on either:
15
+ * - rp2040: bit-banging 2 GPIOs with the help of Pico-PIO-USB library (roothub port1)
16
+ * - samd21/51, nrf52840, esp32: using MAX3421e controller (host shield)
17
+ *
18
+ * Requirements:
19
+ * - For rp2040:
20
+ * - [Pico-PIO-USB](https://github.com/sekigon-gonnoc/Pico-PIO-USB) library
21
+ * - 2 consecutive GPIOs: D+ is defined by PIN_USB_HOST_DP, D- = D+ +1
22
+ * - Provide VBus (5v) and GND for peripheral
23
+ * - CPU Speed must be either 120 or 240 Mhz. Selected via "Menu -> CPU Speed"
24
+ * - For samd21/51, nrf52840, esp32:
25
+ * - Additional MAX2341e USB Host shield or featherwing is required
26
+ * - SPI instance, CS pin, INT pin are correctly configured in usbh_helper.h
27
+ */
12
28
13
29
/* This example demonstrates use of Host Serial (CDC). SerialHost (declared below) is
14
30
* an object to manage an CDC peripheral connected to our USB Host connector. This example
15
31
* will forward all characters from Serial to SerialHost and vice versa.
16
- *
17
- * Note:
18
- * - Device run on native usb controller (controller0)
19
- * - Host run on bit-banging 2 GPIOs with the help of Pico-PIO-USB library (controller1)
20
-
21
- * Requirements:
22
- * - [Pico-PIO-USB](https://github.com/sekigon-gonnoc/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
- * - CPU Speed must be either 120 or 240 Mhz. Selected via "Menu -> CPU Speed"
26
32
*/
27
33
28
- // pio-usb is required for rp2040 host
29
- #include " pio_usb.h"
30
-
31
- // TinyUSB lib
32
- #include " Adafruit_TinyUSB.h"
33
-
34
- // Pin D+ for host, D- = D+ + 1
35
- #ifndef PIN_USB_HOST_DP
36
- #define PIN_USB_HOST_DP 16
34
+ // nRF52 and ESP32 use freeRTOS, we may need to run USBhost.task() in its own rtos's thread.
35
+ // Since USBHost.task() will put loop() into dormant state and prevent followed code from running
36
+ // until there is USB host event.
37
+ #if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_ESP32)
38
+ #define USE_FREERTOS
37
39
#endif
38
40
39
- // Pin for enabling Host VBUS. comment out if not used
40
- #ifndef PIN_5V_EN
41
- #define PIN_5V_EN 18
42
- #endif
43
-
44
- #ifndef PIN_5V_EN_STATE
45
- #define PIN_5V_EN_STATE 1
46
- #endif
47
-
48
- // USB Host object
49
- Adafruit_USBH_Host USBHost;
41
+ // USBHost is defined in usbh_helper.h
42
+ #include " usbh_helper.h"
50
43
51
44
// CDC Host object
52
- Adafruit_USBH_CDC SerialHost;
53
-
54
- // --------------------------------------------------------------------+
55
- // Setup and Loop on Core0
56
- // --------------------------------------------------------------------+
45
+ Adafruit_USBH_CDC SerialHost;
57
46
58
- void setup () {
59
- Serial.begin (115200 );
60
- // while ( !Serial ) delay(10); // wait for native usb
61
-
62
- Serial.println (" TinyUSB Host Serial Echo Example" );
63
- }
64
-
65
- void loop ()
66
- {
47
+ // forward Seral <-> SerialHost
48
+ void forward_serial (void ) {
67
49
uint8_t buf[64 ];
68
50
69
51
// Serial -> SerialHost
70
52
if (Serial.available ()) {
71
53
size_t count = Serial.read (buf, sizeof (buf));
72
- if ( SerialHost && SerialHost.connected () ) {
54
+ if (SerialHost && SerialHost.connected ()) {
73
55
SerialHost.write (buf, count);
74
56
SerialHost.flush ();
75
57
}
76
58
}
77
59
78
60
// SerialHost -> Serial
79
- if ( SerialHost.connected () && SerialHost.available () ) {
61
+ if (SerialHost.connected () && SerialHost.available ()) {
80
62
size_t count = SerialHost.read (buf, sizeof (buf));
81
63
Serial.write (buf, count);
64
+ Serial.flush ();
82
65
}
83
66
}
84
67
68
+ #if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
85
69
// --------------------------------------------------------------------+
86
- // Setup and Loop on Core1
70
+ // Using Host shield MAX3421E controller
87
71
// --------------------------------------------------------------------+
88
72
89
- void setup1 () {
90
- // while ( !Serial ) delay(10); // wait for native usb
91
- Serial.println (" Core1 setup to run TinyUSB host with pio-usb" );
92
-
93
- // Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
94
- uint32_t cpu_hz = clock_get_hz (clk_sys);
95
- if ( cpu_hz != 120000000UL && cpu_hz != 240000000UL ) {
96
- while ( !Serial ) {
97
- delay (10 ); // wait for native usb
98
- }
99
- Serial.printf (" Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n " , cpu_hz);
100
- Serial.printf (" Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n " );
101
- while (1 ) {
102
- delay (1 );
103
- }
73
+ #ifdef USE_FREERTOS
74
+ void usbhost_rtos_task (void *param) {
75
+ (void ) param;
76
+ while (1 ) {
77
+ USBHost.task ();
104
78
}
79
+ }
105
80
106
- #ifdef PIN_5V_EN
107
- pinMode (PIN_5V_EN, OUTPUT);
81
+ void create_usbhost_rtos_task (void ) {
82
+ const uint32_t usbh_stack_size = 200 ;
83
+ xTaskCreate (usbhost_rtos_task, " usbh" , usbh_stack_size, NULL , TASK_PRIO_HIGH, NULL );
84
+ }
85
+ #endif
108
86
109
- // power off first
110
- digitalWrite (PIN_5V_EN, 1 -PIN_5V_EN_STATE);
111
- delay (1 );
87
+ void setup () {
88
+ Serial.begin (115200 );
89
+
90
+ // init host stack on controller (rhport) 1
91
+ USBHost.begin (1 );
112
92
113
- // power on
114
- digitalWrite (PIN_5V_EN, PIN_5V_EN_STATE);
115
- delay (10 );
93
+ // Initialize SerialHost
94
+ SerialHost.begin (115200 );
95
+
96
+ #ifdef USE_FREERTOS
97
+ create_usbhost_rtos_task ();
116
98
#endif
117
99
118
- pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
119
- pio_cfg.pin_dp = PIN_USB_HOST_DP;
120
-
121
- #if defined(ARDUINO_RASPBERRY_PI_PICO_W)
122
- // For pico-w, PIO is also used to communicate with cyw43
123
- // Therefore we need to alternate the pio-usb configuration
124
- // details https://github.com/sekigon-gonnoc/Pico-PIO-USB/issues/46
125
- pio_cfg.sm_tx = 3 ;
126
- pio_cfg.sm_rx = 2 ;
127
- pio_cfg.sm_eop = 3 ;
128
- pio_cfg.pio_rx_num = 0 ;
129
- pio_cfg.pio_tx_num = 1 ;
130
- pio_cfg.tx_ch = 9 ;
100
+ // while ( !Serial ) delay(10); // wait for native usb
101
+ Serial.println (" TinyUSB Host Serial Echo Example" );
102
+ }
103
+
104
+ void loop () {
105
+ #ifndef USE_FREERTOS
106
+ USBHost.task ();
131
107
#endif
132
108
133
- USBHost.configure_pio_usb (1 , &pio_cfg);
109
+ forward_serial ();
110
+ }
111
+
112
+ #elif defined(ARDUINO_ARCH_RP2040)
113
+ // --------------------------------------------------------------------+
114
+ // For RP2040 use both core0 for device stack, core1 for host stack
115
+ // --------------------------------------------------------------------+
116
+
117
+ // ------------- Core0 -------------//
118
+ void setup () {
119
+ Serial.begin (115200 );
120
+ // while ( !Serial ) delay(10); // wait for native usb
121
+ Serial.println (" TinyUSB Host Serial Echo Example" );
122
+ }
123
+
124
+ void loop () {
125
+ forward_serial ();
126
+ }
127
+
128
+ // ------------- Core1 -------------//
129
+ void setup1 () {
130
+ // configure pio-usb: defined in usbh_helper.h
131
+ rp2040_configure_pio_usb ();
134
132
135
133
// run host stack on controller (rhport) 1
136
134
// Note: For rp2040 pico-pio-usb, calling USBHost.begin() on core1 will have most of the
137
135
// host bit-banging processing works done in core1 to free up core0 for other works
138
136
USBHost.begin (1 );
139
137
138
+ // Initialize SerialHost
140
139
SerialHost.begin (115200 );
141
140
}
142
141
143
- void loop1 ()
144
- {
142
+ void loop1 () {
145
143
USBHost.task ();
146
-
147
- // periodically flush SerialHost if connected
148
- if ( SerialHost && SerialHost.connected () ) {
149
- SerialHost.flush ();
150
- }
151
144
}
152
145
146
+ #endif
147
+
153
148
// --------------------------------------------------------------------+
154
149
// TinyUSB Host callbacks
155
150
// --------------------------------------------------------------------+
@@ -169,4 +164,4 @@ void tuh_cdc_umount_cb(uint8_t idx) {
169
164
Serial.println (" SerialHost is disconnected" );
170
165
}
171
166
172
- }
167
+ }
0 commit comments