tinyvision-ai-inc / pico-ice

Raspberry Pi PICO board + Lattice iCE40 FPGA's
MIT License
152 stars 25 forks source link

Fix USB enumeration problem on macOS. #38

Closed dicristina closed 11 months ago

dicristina commented 11 months ago

The pico-ice board does not appear as an USB device on macOS with default firmware versions 1.3 and 1.4. The logs indicate that USB enumeration fails:

kernel: (AppleUSBXHCI) AppleUSBXHCIDevice: AppleUSBXHCIDevice::transferEvent: no endpoint 1 for event 0x0000010000003700 1b000000 01018001
kernel: (IOAccessoryManager) IOPortTransportState::setNominalSignalingFrequencies(): [Port-USB-C@1: USB2] Setting nominal signaling frequencies... (nominalSignalingFrequenciesHz: YES, nominalSignalingFrequenciesHz.count: 1)
kernel: (AppleUSBXHCI) AppleUSBXHCIRequest: AppleUSBXHCIRequest::finish: transfer completed with status 0xe00002ed
kernel: (IOUSBHostFamily) IOUSBHostDevice@00100000: IOUSBHostDevice::start_block_invoke: device descriptor fragment is invalid
kernel: (IOUSBHostFamily) IOUSBHostFamily::validateEndpointMaxPacketSize: USB 2.0 5.[5-8].3: endpoint 0x00 invalid wMaxPacketSize 0x0000
kernel: (IOUSBHostFamily) usb-drd0-port-hs@00100000: AppleUSBHostPort::enumerateDeviceComplete_block_invoke: enumeration failed
kernel: (IOUSBHostFamily) usb-drd0-port-hs@00100000: AppleUSBHostPort::terminateDevice: destroying 0x0000/0000/0000 (IOUSBHostDevice): enumeration failure
kernel: (IOUSBHostFamily) IOUSBHostDevice@00100000: IOUSBHostDevice::start_block_invoke: device will not be registered for matching

The tests were done on an M2 MacBook with macOS 14.1.


This was introduced with commit 5f37b79. The problem is that the delay in the main loop causes the RP2040 to send a lot of NAK responses and the Mac host gives up on the enumeration. I reproduced the same situation with the dev_hid_composite example by adding a sleep_ms(100) in the main loop. A solution is to ensure that USB enumeration has completed before going into the main loop:

while (!tud_ready())
  tud_task();

while (true) {
  // main loop
}
josuah commented 11 months ago

Such an extensive review! I think this is what we are expected to do for TinyUSB. I will merge it here first, but will consider propagating it further to ice_usb_init().

Thank you for the fix!

josuah commented 11 months ago

Indeed, the expected way is to skip everything until enumeration is there. https://github.com/raspberrypi/pico-examples/blob/master/usb/device/dev_hid_composite/main.c#L108

josuah commented 11 months ago

This got incorporated into the new release, along with other fixes. Thank you for this patch! https://github.com/tinyvision-ai-inc/pico-ice/releases/tag/pico-ice-default-v1.5