hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
5.05k stars 1.06k forks source link

[Question] configuring samd for low-speed USB? #284

Closed lukehsiao closed 4 years ago

lukehsiao commented 4 years ago

Here is my question

Some devices like the SAMD51 support both full-speed USB and low-speed USB. Currently, tinyusb hard-codes full-speed:

https://github.com/hathach/tinyusb/blob/cb3de676635948f46a8dda93330ccc7fbbcb3e5d/src/portable/microchip/samd/dcd_samd.c#L89

Simply changing this value to low-speed (USB_DEVICE_CTRLB_SPDCONF_LS) is insufficient since tinyusb still tries to send 64-byte packets, causing devices to fail enumeration (e.g. https://github.com/hathach/tinyusb/issues/184). Is there a way to configure tinyusb for low-speed USB operation?

pigrew commented 4 years ago

AFAIK, nobody has tried low speed USB.

You will need to define CFG_TUD_ENDPOINT0_SIZE as 8 to get the proper packet length. This can be set in tusb_config.h. Last Fall, there were some bugs related to 8 byte packets lengths, but it should now work correctly with them. Let us know if this makes low speed work?

lukehsiao commented 4 years ago

It looks like changing just those two parameters is insufficient. Specifically, it doesn't appear that changing the CFG_TUD_ENDPOINT0_SIZE is actually effecting the dcd_samd.c code. When I use wireshark to capture the USB packets I still see that the device is transmitting bMaxPacketSize0 = 64. Similarly, I see that maxpacket value in dmesg logs:

[ 2120.258955] usb 1-3: new low-speed USB device number 33 using xhci_hcd
[ 2120.406960] usb 1-3: Invalid ep0 maxpacket: 64
[ 2120.534958] usb 1-3: new low-speed USB device number 34 using xhci_hcd
[ 2120.682903] usb 1-3: Invalid ep0 maxpacket: 64
[ 2120.683037] usb usb1-port3: attempt power cycle
[ 2121.338957] usb 1-3: new low-speed USB device number 35 using xhci_hcd
[ 2121.361054] usb 1-3: Invalid ep0 maxpacket: 64
[ 2121.486964] usb 1-3: new low-speed USB device number 36 using xhci_hcd
[ 2121.509177] usb 1-3: Invalid ep0 maxpacket: 64
[ 2121.509420] usb usb1-port3: unable to enumerate USB device

In contrast, for the samg, there is a line like: https://github.com/hathach/tinyusb/blob/cb3de676635948f46a8dda93330ccc7fbbcb3e5d/src/portable/microchip/samg/dcd_samg.c#L116

I seems like I'm missing the link of how that configuration value effects the samd code.

In contrast, the samd code appears to be hard-coded:

https://github.com/hathach/tinyusb/blob/cb3de676635948f46a8dda93330ccc7fbbcb3e5d/src/portable/microchip/samd/dcd_samd.c#L51-L65

lukehsiao commented 4 years ago

@tannewt Would you happen to have any insights on configuring the SAMD51 for low-speed USB?

pigrew commented 4 years ago

Yes, this looks like an omission in the driver that size is always set to 64 bytes. I'm unfamiliar with SAMD mcus (and don't have one to test it). The constant I mentioned is also used to set the device descriptors in the USBD core.

In addition to it, perhaps try setting the two SIZE registers to equal 0x0, which represents 8 bytes?

bank_in->PCKSIZE.bit.SIZE = 0x0; 
bank_out->PCKSIZE.bit.SIZE = 0x0;

The driver should be updated to set the SIZE values based on CFG_TUD_ENDPOINT0_SIZE.

I apologise that I can't be of more help, I don't have any of these microcontrollers.

hathach commented 4 years ago

Thanks @pigrew for answering, @lukehsiao low speed isn't used by anyone yet, beside changing the control ep size and update descriptor, you will need to update the dcd_samd.c as you figured out as well. Since Scott is not interested in samd low speed mode (99% won't ), you will need to get your hand dirty by modifying dcd_samd.c

PS: Why would you want to run samd on LS mode, I guess it is power related ? If so, do you know how much it would save LS vs FS ?

lukehsiao commented 4 years ago

Thank you all for the helpful pointers. I'll dig into dcd_samd.c.

We are interested in running in low speed mode for latency reasons, we are planning to run this MCU with a very long USB extender (over 100ft and a couple USB hubs). We hypothesize that low speed mode should tolerate this additional latency (based on testing with a low speed USB mouse) while we know from testing that full speed does not. We will need to implement low speed USB and test to know for sure.

tannewt commented 4 years ago

@lukehsiao as @hathach said, I haven't looked into low speed at all. I'm much more interested in faster USB than slower USB.

pigrew commented 4 years ago

Yes, low speed will allow longer runs. There is quite a bit of detail on the allowed delays in the USB 1.1 specification document.

That said, I'd suggest either using "active" USB cables or RJ45 UTP Cat5 USB extenders (like Monoprice 106042. I've never used that model, but it may suit your needs).

lukehsiao commented 4 years ago

That said, I'd suggest either using "active" USB cables or RJ45 UTP Cat5 USB extenders (like Monoprice 106042. I've never used that model, but it may suit your needs).

Thanks for the tip. We are using custom RJ45 Cat7 USB extenders up to 200ft. We just need to implement and verify functionality with low-speed USB for the SAMD51 at this point.

ladyada commented 4 years ago

we've used https://www.adafruit.com/product/2676 with great success - with 100' cables - its cheaper than the effort to add LS

hudson-ayers commented 4 years ago

with great success - with 100' cables - its cheaper than the effort to add LS

Unfortunately our use case requires closer to 200' cable, and connecting close to 100 devices over cables of this length, so using active hardware for each one gets expensive. We will let you know if we get low speed to work. If you think of any additional tips that could be helpful in this regard, please let us know.

ladyada commented 4 years ago

do you have evidence that low speed USB runs that long?

hudson-ayers commented 4 years ago

We tested several low speed devices over a 200' cable successfully

ladyada commented 4 years ago

kk - have you tried full speed with active extender at 200'?

hudson-ayers commented 4 years ago

No, but I think that purchasing 100 active extenders probably exceeds our budget for this project. We do plan to test the adafruit link you shared and see what maximum distance we can achieve with it. The link claims to have accomplished 200 feet with a full speed Arduino, though we were unable to achieve that distance with our own prototype of that device.

hudson-ayers commented 4 years ago

Ah, after some more research I think we are out of luck after all. We are using the tinyusb stack in CircuitPython (with the feather m4 express). CircuitPython boards show up as mass storage devices when connected to a laptop, and the programming interface involves moving a firmware image or python file onto that mass storage device. Reading here: https://usb.org/sites/default/files/usb_msc_cbi_1.1.pdf , it seems that mass storage devices require the use of bulk endpoints, and reading here: http://www.jungo.com/st/support/documentation/windriver/10.2.1/wdusb_manual.mhtml/USB_data_transfer_types.html it appears that bulk endpoints cannot operate over low-speed USB.

Can any of you confirm that we will be unable to use an MSC device over low speed?

ladyada commented 4 years ago

that is correct, both CDC and MSD are Full Speed. only HID can be done over LS

lukehsiao commented 4 years ago

Thank you all for your prompt and helpful responses! We will need to reevaluate our system with the full-speed requirement in mind.

dhalbert commented 4 years ago

It is possible to build CircuitPython so that it only exposes HID. But if your application is using CDC or MSC, then that is of little help.

hudson-ayers commented 4 years ago

@dhalbert can you provide any pointers to documentation on how to build CircuitPython so that it only exposes HID? Is it still possible to flash firmware/apps over USB in this configuration? We would like the USB connection to enable us to reflash firmware or applications, though the actual applications we are using do not require CDC or MSC themselves.

dhalbert commented 4 years ago

You can't do flashing over HID. You'd need to move the board to a full-speed port, double-click reset, and use the UF2 bootloader to load a regular CircuitPython on it, and then update the filesystem, etc. So that may not meet your needs (but perhaps it will)

The way to select which USB devices to include is to add a line like this to mpconfigboard.mk.

USB_DEVICES="<list of devices separated by commas>"

e.g.,

USB_DEVICES="HID"

The default list of devices, if not specified, is:

USB_DEVICES="CDC,MSC,AUDIO,HID"
hathach commented 4 years ago

It is an interesting usage of LS.

Note: Though currently tinyusb doesn't support DFU yet :D https://github.com/hathach/tinyusb/issues/29

hathach commented 4 years ago

@lukehsiao how is your testing so far, did you manage to have samd running on LS mode ?

lukehsiao commented 4 years ago

Due to time constraints, we ended up lowering our maximum length constraints so that we could use full-speed USB, rather than LS.

hathach commented 4 years ago

if it is the case, I will close this issue. You could re-open it if there is more activity on this LS.