stm32-rs / stm32h7xx-hal

Peripheral access API for STM32H7 series microcontrollers
BSD Zero Clause License
216 stars 102 forks source link

USB fails to enumerate when running CPU at 480MHz #503

Open ryan-summers opened 1 month ago

ryan-summers commented 1 month ago

It was noted today that USB devices appear to not function if the CPU SYSCLK is set to 480MHz. However, if the CPU is dropped to 400MHz, USB works fine.

It's unknown if this is a HAL-related issue, USB-device issue, or silicon defect at this time.

I'm opening this just so we can get an initial read on things and get this documented somewhere.

ryan-summers commented 1 month ago

@jamesmunns noted that he fixed an errata around this in embassy in https://github.com/embassy-rs/embassy/pull/2823 that relates to USB being used in multiple ISR contexts

olback commented 1 month ago

I think I ran in to this when I started my Arduino H7 project. I'm running at 480MHz but I'm specifying that USB should use the HSI48 clock source which seems to work fine.

https://github.com/olback/h7/blob/907250a846aacf50beab726f9387dd30a5ee3129/h7-cm7/src/main.rs#L123-L125

ryan-summers commented 1 month ago

@olback That's interesting to me because we're running with very similar clock configurations: https://github.com/quartiq/stabilizer/blob/main/src/hardware/setup.rs#L292

Can you confirm that you're not seeing any USB-related issues with the cod eyou just referenced? I'm confused because yous aid you ran into this issue, but also that it seems to work fine now

rockboynton commented 1 month ago

I experienced this issue. The USB peripheral did work ~1 out of 5 flashing attempts. Also, I noticed my code specifically hang in the usb_device::device_builder::UsbDeviceBuilder::build() call

jamesmunns commented 1 month ago

Noting that ::build() is where the USB core is enabled via RCC, meaning it might actually be closer to https://github.com/embassy-rs/embassy/pull/2677, where it takes a little bit before the RCC is actually active, which the software may be racing.

My suggestion is to insert a delay here: https://docs.rs/synopsys-usb-otg/latest/src/synopsys_usb_otg/bus.rs.html#366-517 after USB::enable().

ryan-summers commented 1 month ago

On Matrix, it was noted that a user was able to resolve this by adding a ~1ms delay after the FDMOD register is configured. The datasheet specifies this needs to be at least 25ms: image

This is likely a defect in synopsys-usb-otg.

Rock Boynton it actually seems like I need to wait until after the // Configure USB PHY section to do the delay, otherwise I still see the issue. I can't just do the delay after the the FDMOD pin being set