2025-09-18 12:53 PM
Hello everyone,
I’m facing an issue with an STM32L4-based design where the USB FS Device stack (CDC) sporadically fails to start correctly. Maybe someone has seen similar behavior or can point me to potential root causes.
System overview / setup
MCU: STM32L4 (CubeMX / HAL / FreeRTOS)
Clocking:
MSI as system clock (16 MHz)
USB via PLLSAI1 (48 MHz)
USB: FS Device Stack (CDC), initialized after HAL_Init() / SystemClock_Config() in the first Task
ESD protection: USBLC6-2SC6
Lines: no series resistors on D+ / D-
Observed behavior
On several boards, the USB stack does not reliably start after power-up.
In that case, the firmware blocks → Watchdog reset after ~8 s → endless reset loop.
Disconnecting/reconnecting the supply sometimes fixes the issue, and the USB connection to the PC works normally.
Interesting: When probing D+ or D- with an oscilloscope, the USB stack suddenly starts working – presumably because the probe affects the signal lines.
On another board with the same firmware, the issue never occurs.
Questions / assumptions
Series resistors on D+ / D-
Could the missing 22Ohm resistors be the root cause?
Does ST recommend these in general for STM32L4 designs (see e.g. USB tutorial on mikrocontroller.net)?
ESD protection (USBLC6-2SC6)
Could this component disturb the USB lines under certain conditions?
Layout / signal integrity
Are there known issues if USB differential pairs are not perfectly routed (impedance, symmetry)?
USB stack initialization
What exactly does the stack expect at startup?
Are certain voltage levels on D+ / D- required to be stable?
Looking for:
Experiences whether missing series resistors are really critical.
Layout recommendations for USB FS with STM32
Known pitfalls with ESD protection and USB initialization
Thanks a lot for any hints or ideas!
Best regards,
Martin
2025-09-18 7:49 PM
You say you get a watchdog reset. So the processor is getting stuck somewhere in the code. Perhaps waiting for something to complete that never does. Or maybe one of the setup routines returned an error code and so the processor jumped to an error handler that doesn’t know how to recover from that particular failure.
it would be very useful to know what never completed or threw an error. For example if your system got stuck waiting for a crystal oscillator to start because the loop gain is marginal, then you know what to fix.
I recently encountered an issue where a USB call (to set the peripheral into master or slave mode) would time out and throw an error if it took longer than 200ms, a hardcoded time period. This only happened on some boards and not consistently. I couldn’t find any guidance in the data sheet or reference manual for how long to allow; that was the period in the original ST-supplied code. Increasing this to 500 ms made all boards work reliably.
2025-09-21 11:28 PM
Hello,
thank you for you answer.
I have noticed that the issue occurs when setting the interrupt register in the USB_EnableGlobalInt() function. Specifically, the system hangs at the following line:
USBx->CNTR |= (uint16_t)winterruptmask;
In the function:
HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
{
uint32_t winterruptmask;
/* Set winterruptmask variable */
winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
USB_CNTR_SUSPM | USB_CNTR_ERRM |
USB_CNTR_SOFM | USB_CNTR_ESOFM |
USB_CNTR_RESETM | USB_CNTR_L1REQM;
/* Set interrupt mask */
USBx->CNTR |= (uint16_t)winterruptmask;
return HAL_OK;
}
Below is the call sequence for this issue:
Has anyone experienced a similar issue or has any idea why setting the interrupt mask could cause the system to hang? Are there any known problems with accessing the CNTR register or timing issues during USB stack initialization?
Thanks a lot for any hints or ideas!
Best regards,
Martin
2025-09-22 12:20 AM
I performed a test where I removed the USB protection circuitry and connected D+ and D– directly to the USB-C connector. Interestingly, the firmware still occasionally hangs during startup in this configuration.
However, when I plug a USB-C cable into the connector, the firmware starts reliably without any issues.
Question:
What could be causing this behavior?
Is it possible that the presence of the cable influences the line termination or voltage levels in a way that stabilizes the USB stack initialization? Could this be related to pull-up/pull-down behavior, impedance matching, or floating lines when no cable is present?
Any insights or similar experiences would be greatly appreciated.