Skip to content

Commit 898c62f

Browse files
committed
device info works with samd21 + max3421e
not too reliable probably due to tinyusb stack core issue: USBH Defer Attach until current enumeration complete
1 parent 70605b7 commit 898c62f

File tree

8 files changed

+127
-45
lines changed

8 files changed

+127
-45
lines changed

examples/DualRole/Simple/device_info/device_info.ino

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
bNumConfigurations 1
4141
*
4242
*/
43-
4443
#ifdef ARDUINO_ARCH_RP2040
4544
// pio-usb is required for rp2040 host
4645
#include "pio_usb.h"
@@ -63,6 +62,7 @@
6362
#include "Adafruit_TinyUSB.h"
6463

6564
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
65+
6666
#include "SPI.h"
6767

6868
// USB Host object using MAX3421E: SPI, CS, INT
@@ -86,18 +86,20 @@ typedef struct {
8686
dev_info_t dev_info[CFG_TUH_DEVICE_MAX] = { 0 };
8787

8888
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
89+
8990
void setup() {
9091
Serial.begin(115200);
91-
//while ( !Serial ) delay(10); // wait for native usb
92-
93-
Serial.println("TinyUSB Dual Device Info Example");
9492

95-
// run host stack on controller (rhport) 1
93+
// init host stack on controller (rhport) 1
9694
USBHost.begin(1);
95+
96+
while ( !Serial ) delay(10); // wait for native usb
97+
Serial.println("TinyUSB Dual Device Info Example");
9798
}
9899

99100
void loop() {
100101
USBHost.task();
102+
Serial.flush();
101103
}
102104

103105
#elif defined(ARDUINO_ARCH_RP2040)
@@ -171,19 +173,20 @@ void loop1() {
171173
//--------------------------------------------------------------------+
172174
// TinyUSB Host callbacks
173175
//--------------------------------------------------------------------+
174-
void print_device_descriptor(tuh_xfer_t* xfer);
176+
void print_device_descriptor(tuh_xfer_t *xfer);
177+
175178
void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len);
176179

177180
void print_lsusb(void) {
178181
bool no_device = true;
179-
for ( uint8_t daddr = 1; daddr < CFG_TUH_DEVICE_MAX+1; daddr++ ) {
182+
for (uint8_t daddr = 1; daddr < CFG_TUH_DEVICE_MAX + 1; daddr++) {
180183
// TODO can use tuh_mounted(daddr), but tinyusb has an bug
181184
// use local connected flag instead
182-
dev_info_t* dev = &dev_info[daddr-1];
183-
if ( dev->mounted ) {
185+
dev_info_t *dev = &dev_info[daddr - 1];
186+
if (dev->mounted) {
184187
Serial.printf("Device %u: ID %04x:%04x %s %s\r\n", daddr,
185188
dev->desc_device.idVendor, dev->desc_device.idProduct,
186-
(char*) dev->manufacturer, (char*) dev->product);
189+
(char *) dev->manufacturer, (char *) dev->product);
187190

188191
no_device = false;
189192
}
@@ -195,39 +198,35 @@ void print_lsusb(void) {
195198
}
196199

197200
// Invoked when device is mounted (configured)
198-
void tuh_mount_cb (uint8_t daddr)
199-
{
201+
void tuh_mount_cb(uint8_t daddr) {
200202
Serial.printf("Device attached, address = %d\r\n", daddr);
201203

202-
dev_info_t* dev = &dev_info[daddr-1];
204+
dev_info_t *dev = &dev_info[daddr - 1];
203205
dev->mounted = true;
204206

205207
// Get Device Descriptor
206208
tuh_descriptor_get_device(daddr, &dev->desc_device, 18, print_device_descriptor, 0);
207209
}
208210

209211
/// Invoked when device is unmounted (bus reset/unplugged)
210-
void tuh_umount_cb(uint8_t daddr)
211-
{
212+
void tuh_umount_cb(uint8_t daddr) {
212213
Serial.printf("Device removed, address = %d\r\n", daddr);
213-
dev_info_t* dev = &dev_info[daddr-1];
214+
dev_info_t *dev = &dev_info[daddr - 1];
214215
dev->mounted = false;
215216

216217
// print device summary
217218
print_lsusb();
218219
}
219220

220-
void print_device_descriptor(tuh_xfer_t* xfer)
221-
{
222-
if ( XFER_RESULT_SUCCESS != xfer->result )
223-
{
221+
void print_device_descriptor(tuh_xfer_t *xfer) {
222+
if (XFER_RESULT_SUCCESS != xfer->result) {
224223
Serial.printf("Failed to get device descriptor\r\n");
225224
return;
226225
}
227226

228227
uint8_t const daddr = xfer->daddr;
229-
dev_info_t* dev = &dev_info[daddr-1];
230-
tusb_desc_device_t* desc = &dev->desc_device;
228+
dev_info_t *dev = &dev_info[daddr - 1];
229+
tusb_desc_device_t *desc = &dev->desc_device;
231230

232231
Serial.printf("Device %u: ID %04x:%04x\r\n", daddr, desc->idVendor, desc->idProduct);
233232
Serial.printf("Device Descriptor:\r\n");
@@ -244,23 +243,26 @@ void print_device_descriptor(tuh_xfer_t* xfer)
244243

245244
// Get String descriptor using Sync API
246245
Serial.printf(" iManufacturer %u ", desc->iManufacturer);
247-
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, dev->manufacturer, sizeof(dev->manufacturer)) ) {
246+
if (XFER_RESULT_SUCCESS ==
247+
tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, dev->manufacturer, sizeof(dev->manufacturer))) {
248248
utf16_to_utf8(dev->manufacturer, sizeof(dev->manufacturer));
249-
Serial.printf((char*) dev->manufacturer);
249+
Serial.printf((char *) dev->manufacturer);
250250
}
251251
Serial.printf("\r\n");
252252

253253
Serial.printf(" iProduct %u ", desc->iProduct);
254-
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, dev->product, sizeof(dev->product))) {
254+
if (XFER_RESULT_SUCCESS ==
255+
tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, dev->product, sizeof(dev->product))) {
255256
utf16_to_utf8(dev->product, sizeof(dev->product));
256-
Serial.printf((char*) dev->product);
257+
Serial.printf((char *) dev->product);
257258
}
258259
Serial.printf("\r\n");
259260

260261
Serial.printf(" iSerialNumber %u ", desc->iSerialNumber);
261-
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, dev->serial, sizeof(dev->serial))) {
262+
if (XFER_RESULT_SUCCESS ==
263+
tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, dev->serial, sizeof(dev->serial))) {
262264
utf16_to_utf8(dev->serial, sizeof(dev->serial));
263-
Serial.printf((char*) dev->serial);
265+
Serial.printf((char *) dev->serial);
264266
}
265267
Serial.printf("\r\n");
266268

@@ -276,21 +278,21 @@ void print_device_descriptor(tuh_xfer_t* xfer)
276278

277279
static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) {
278280
// TODO: Check for runover.
279-
(void)utf8_len;
281+
(void) utf8_len;
280282
// Get the UTF-16 length out of the data itself.
281283

282284
for (size_t i = 0; i < utf16_len; i++) {
283285
uint16_t chr = utf16[i];
284286
if (chr < 0x80) {
285287
*utf8++ = chr & 0xff;
286288
} else if (chr < 0x800) {
287-
*utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F));
288-
*utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
289+
*utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F));
290+
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
289291
} else {
290292
// TODO: Verify surrogate.
291-
*utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F));
292-
*utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F));
293-
*utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
293+
*utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F));
294+
*utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F));
295+
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
294296
}
295297
// TODO: Handle UTF-16 code points that take two entries.
296298
}
@@ -318,6 +320,5 @@ void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) {
318320
size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len);
319321

320322
_convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, buf_len);
321-
((uint8_t*) temp_buf)[utf8_len] = '\0';
323+
((uint8_t *) temp_buf)[utf8_len] = '\0';
322324
}
323-

examples/MassStorage/msc_ramdisk/msc_ramdisk.ino

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ Adafruit_USBD_MSC usb_msc;
3535

3636

3737
// the setup function runs once when you press reset or power the board
38-
void setup()
39-
{
38+
void setup() {
4039
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
4140
// Manual begin() is required on core without built-in support for TinyUSB such as
4241
// - mbed rp2040

src/arduino/Adafruit_TinyUSB_API.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,34 @@ void TinyUSB_Device_FlushCDC(void) {
5757

5858
// Debug log with Serial1
5959
#if CFG_TUSB_DEBUG && defined(CFG_TUSB_DEBUG_PRINTF)
60+
// #define USE_SEGGER_RTT
61+
62+
#ifdef USE_SEGGER_RTT
63+
#include "SEGGER_RTT/RTT/SEGGER_RTT.h"
64+
#endif
65+
6066
__attribute__((used)) int CFG_TUSB_DEBUG_PRINTF(const char *__restrict format,
6167
...) {
68+
#ifndef USE_SEGGER_RTT
6269
static bool ser1_inited = false;
6370
if (!ser1_inited) {
6471
ser1_inited = true;
6572
Serial1.begin(115200);
6673
}
74+
#endif
6775

6876
char buf[256];
6977
int len;
7078
va_list ap;
7179
va_start(ap, format);
7280
len = vsnprintf(buf, sizeof(buf), format, ap);
81+
82+
#ifdef USE_SEGGER_RTT
83+
SEGGER_RTT_Write(0, buf, len);
84+
#else
7385
Serial1.write(buf);
86+
#endif
87+
7488
va_end(ap);
7589
return len;
7690
}

src/arduino/Adafruit_USBH_Host.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,34 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf,
138138
return false;
139139
}
140140

141+
Adafruit_USBH_Host *host = Adafruit_USBH_Host::_instance;
142+
143+
// MAX3421e max clock is 26MHz
144+
// Depending on mcu ports, it may need to be clipped down
145+
// uint32_t max_clock = 26000000ul;
146+
uint32_t max_clock = 4000000ul;
147+
148+
SPISettings config(max_clock, MSBFIRST, SPI_MODE0);
149+
host->_spi->beginTransaction(config);
150+
151+
size_t count = 0;
152+
while (count < tx_len || count < rx_len) {
153+
uint8_t data = 0x00;
154+
155+
if (count < tx_len) {
156+
data = tx_buf[count];
157+
}
158+
159+
data = host->_spi->transfer(data);
160+
161+
if (count < rx_len) {
162+
rx_buf[count] = data;
163+
}
164+
165+
count++;
166+
}
167+
168+
host->_spi->endTransaction();
141169
return true;
142170
}
143171

src/arduino/Adafruit_USBH_Host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
#define ADAFRUIT_USBH_HOST_H_
2727

2828
#include "Adafruit_USBD_Interface.h"
29-
#include "SPI.h"
3029
#include "tusb.h"
30+
#include <SPI.h>
3131

3232
#ifdef ARDUINO_ARCH_ESP32
3333
#include "esp32-hal-tinyusb.h"

src/arduino/ports/samd/Adafruit_TinyUSB_samd.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,8 @@ void TinyUSB_Port_InitDevice(uint8_t rhport) {
112112
NVIC_SetPriority((IRQn_Type)USB_IRQn, 0UL);
113113
#endif
114114

115-
#if CFG_TUSB_DEBUG
116-
Serial1.begin(115200);
117-
#endif
118-
119-
tusb_init();
115+
// Init port 0 as device
116+
tud_init(0);
120117
}
121118

122119
void TinyUSB_Port_EnterDFU(void) {

src/arduino/ports/samd/tusb_config_samd.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,49 @@ extern "C" {
8585
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
8686
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
8787

88+
//--------------------------------------------------------------------
89+
// Host Configuration
90+
//--------------------------------------------------------------------
91+
92+
// Size of buffer to hold descriptors and other data used for enumeration
93+
#define CFG_TUH_ENUMERATION_BUFSIZE 256
94+
95+
// Number of hub devices
96+
#define CFG_TUH_HUB 1
97+
98+
// max device support (excluding hub device): 1 hub typically has 4 ports
99+
#define CFG_TUH_DEVICE_MAX (3 * CFG_TUH_HUB + 1)
100+
101+
// Enable tuh_edpt_xfer() API
102+
// #define CFG_TUH_API_EDPT_XFER 1
103+
104+
// Number of mass storage
105+
#define CFG_TUH_MSC 1
106+
107+
// Number of HIDs
108+
// typical keyboard + mouse device can have 3,4 HID interfaces
109+
#define CFG_TUH_HID (3 * CFG_TUH_DEVICE_MAX)
110+
111+
// Number of CDC interfaces
112+
// FTDI and CP210x are not part of CDC class, only to re-use CDC driver API
113+
#define CFG_TUH_CDC 1
114+
#define CFG_TUH_CDC_FTDI 1
115+
#define CFG_TUH_CDC_CP210X 1
116+
117+
// RX & TX fifo size
118+
#define CFG_TUH_CDC_RX_BUFSIZE 64
119+
#define CFG_TUH_CDC_TX_BUFSIZE 64
120+
121+
// Set Line Control state on enumeration/mounted:
122+
// DTR ( bit 0), RTS (bit 1)
123+
#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
124+
125+
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
126+
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
127+
// This need Pico-PIO-USB at least 0.5.1
128+
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM \
129+
{ 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
130+
88131
#ifdef __cplusplus
89132
}
90133
#endif

src/portable/analog/max3421/hcd_max3421.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_is
263263

264264
max3421_spi_lock(rhport, in_isr);
265265

266-
tuh_max3421_spi_xfer_api(rhport, &reg, 1, &hirq, 0);
266+
tuh_max3421_spi_xfer_api(rhport, &reg, 1, &hirq, 1);
267267
_hcd_data.hirq = hirq;
268268
tuh_max3421_spi_xfer_api(rhport, NULL, 0, buffer, len);
269269

0 commit comments

Comments
 (0)