STM32F7 USB CDC Device Descriptor Request failing
I am struggling to get USB CDC working. I am very far down a rabbit hole and I'm completely stuck.
I am using HAL libraries for USB_OTG_HS on the STM32F746ZGT6, with a 16MHz HSE.
I am running in bus powered mode, VBUS detect disabled, and I have hardwired an external D+ pullup, because I have not been able to get the internal pullup to activate. I know the hardwired pullup is not recommended, but I don't think that is what is causing my problems. My IOC file is attached.
When I connect the device to my computer, windows reports "device descriptor request failed" in device manager. I have determined the following sequence of events is occurring:
1. Connect STM32 to computer (powers on STM32)
2. USB suspend interrupt (USBSUSP)
3. USB wakeup interrupt (WKUPINT)
4. USB reset interrupt (USBRST)
5. Enumeration done interrupt (ENUMDNE)
6. RX fill level interrupt (RXFLVL), packet status == STS_SETUP_UPDT
7. RX fill level interrupt (RXFLVL), packet status == STS_SETUP_UPDT
8. RX fill level interrupt (RXFLVL), packet status == STS_SETUP_UPDT
9. Nothing for about 500ms
10. Steps (4) to (9) repeat 2 more times
11. USB suspend interrupt (USBSUSP)
My interpretation of this sequence:
1. USB suspend triggers immediately on startup because the USB lines are inactive for a few ms
2. Windows detects the device and begins its enumeration sequence, which triggers interrupts on the STM32
3. The device does not respond to the device descriptor request, so after 500ms windows tries again, and then again.
4. After 3 failures, windows reports device descriptor request failed.
After this sequence has completed, I have checked the contents of hpcd_USB_OTG_HS->Setup, and the bytes match up with a USB device descriptor request. To me this all seems to mean that the USG_OTG_HS core is active, and is correctly receiving data on the USB lines.
From what I can tell, the critical step that is missing is the "setup stage done" packet, which should trigger another RXFLVL interrupt with packet status == STS_STUP_COMP. When this packet is read out of the FIFO, a setup done interrupt (STUP) should be triggered, which triggers the OEPINT interrupt. In the handler for OEPINT, the setup packet is parsed and the reply to the device descriptor request should be sent.
According to the RM0385 reference manual: "When the setup stage changes to a data IN/OUT stage, the core writes an entry (setup stage done word) to the receive FIFO, indicating the completion of the setup stage."
Any insight into what is going wrong here would be much appreciated. Thanks!
