cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 Won't Trigger USB Interrupt on One Project, But Will On Another

jvavra
Associate III

I have a custom board based around the STM32L496 that creates a USB HID device. I have two projects (built in IAR Embedded Workbench), both of which have this board and micro as their target. On the exact same board, one will enumerate USB at FS, one won't. On the one that doesn't enumerate, the OTG_FS_IRQHandler never fires. I can readily switch between projects, emulating using an STLink, and one works perfectly, while one doesn't work at all.

All of the libary code (HAL Drivers, USB Middleware, etc.) is 100% identical and taken directly from the latest version of STCube. I have verified it is identical using a WinMerge compare. My application code is virtually identical between the two projects. In fact, the "working" project is really a subset of the code in the non-working project.

To troubleshoot, I have combed through the two projects looking for differences that would explain the difference in behavior. I have isolated a subset of the code in the non-working project. This code does nothing but init the system clock, init the HAL, and init the USB. It's the first code hit when run from main(). This section of code works on the good project, but not on the bad project. I can set a breakpoint just after this init code, and the good project will have enumerated USB, while the bad project shows absolutely no USB traffic of any kind (verified on a protocol analyzer). A breakpoint in the IRQ handler in the bad project is never hit; the device state never changes from "Default" (i.e., never changes to Addressed, Configured or Suspended).

I'm getting kind of desperate here and starting to think of the possibility of weird, one-off issues. Obviously, there are differences in exactly which memory locations variables and functions are stored in; the bad project has more code that the linker is placing. But beyond memory location differences, can anyone think of anything else that might be stopping the IRQ from firing? Assume the code is indeed identical. I've included it here for the record.

HAL_Init();
 
RCC_Configuration();       
 
SystemClock_Config();  
 
MX_USB_OTG_FS_PCD_Init();    
 
InitUsbVars();  
 
/* Enable USB power on Pwrctrl CR2 register */
 
HAL_PWREx_EnableVddUSB();  
 
/* Init Device Library */
 
USBD_Init(g_pdev, &HID_Desc, 0);
 
/* Add Supported Class */
 
USBD_RegisterClass(g_pdev, &USBD_HID);
 
/* Add Custom HID callbacks */
 
USBD_HID_RegisterInterface(g_pdev, &USBD_fops);
 
/* Start Device Process */
 
USBD_Start(g_pdev);
 
WaitUntilConfigured();enter code here 
 

9 REPLIES 9

Those are only function calls, what's behind them may be vastly different.

Read out and check/compare USB and relevant GPIO registers content. Check GPIO pins for bad soldering/shorts (e.g. by setting to output, togging and observing). Go through the usual suspects for non-firing interrupts.

JW

jvavra
Associate III

I know they're just function calls; I mostly posted it to give an idea of the scope of what I'm talking about. The definions of the function calls are identical. I can post that code if needed.

There is no short on the board; as I said, on the exact same board I can readily switch between the two projects and one works and one doesn't. I'm past the usual suspects, I'm looking for the unusual suspects.

jvavra
Associate III

Just getting back to this. Not sure how I missed it before, but for the project that is not enumerating properly, the BSVLD bit in FS_GOTGCTL is NOT getting set, indicating the "B-session is not valid". Not entirely sure what this means, as in neither case do I have VBUS sensing enabled (VBUSBSEN and VBUSASEN in FS_GCCFG are both 0).

Interesting.

Are there differences in PA9 settings between the two projects?

What is content of OTG_GCCFG ?

JW

jvavra
Associate III

I found a difference in how PA9 was set but it seems inconsequential; in the "working" project PA9 wasn't init'd at all (so I assume tri-stated). In the non-working project, it was init'd as an input with no pull-up, which I think effectively makes it also tri-stated. Either way, removing the init made no difference.

The contents of OTG_GCCFG are identical for both: the only bit that is set is the VBUS Enable Detection bit (VBDEN, bit 21).

> the only bit that is set is the VBUS Enable Detection bit (VBDEN, bit 21).

This does not make sense.

If you don't use PA9 to detect VBUS, you should have VBDEN cleared.

OTOH, if OTG_GCCFG.PWRDWN=0, the USB can't be working in either case.

JW

Waitaminute.

> (VBUSBSEN and VBUSASEN in FS_GCCFG are both 0).

How comes you have VBUSBSEN and VBUSASEN in GCCFG, on an 'L496?

0693W00000Kc7z7QAB.png 

JW

Ah, that's because I (foolishly) trusted IAR to be giving me the correct names for the bits in the register:

0693W00000Kc88KQAR.png

I apologize, I had a breakpoint inserted at the wrong position. After calling USBD_Start, the working project has ONLY PWRDWN set. The non-working project has PWRDWN AND VBUS Detection Enable set. So it looks like I need to figure out where VBDEN is getting set, and eliminate it.