cancel
Showing results for 
Search instead for 
Did you mean: 

Simplest possible CubeMX USB app fails to enumerate

Gavin Baker
Associate III
Posted on October 20, 2017 at 07:13

I have a brand-new STM32F303 Nucleo144 and cannot get any CubeMX generated apps to work with USB. The app builds and runs fine, and I can see printf output via SWO, but the device never evenbegins enumeration. The following procedure was used to develop a minimal reproducible example:

  1. Start new project in CubeMX
  2. Select Board Selector, Type of Board: Nucelo144, MCU Series: STM32F3, Board NUCLEO-F303ZE
  3. Under RCC, select HSE = Bypass Clock Source
  4. Under USB, select Device(FS)
  5. Under USB_DEVICE, Class for FS IP: Human Interface Class
  6. Select Clock Configuration tab, allow autoconfiguration, ensure USB clock is correctly set to 48MHz
  7. Go to Project Settings, changeMinimum Heap Size to 0x400, Minimum Stack Size to 0x800
  8. Choose toolchain to be Makefile (using GCC-ARM for Windows)
  9. Save file, Generate Source
  10. Edit main.c to insert some trivial test code (such as the `USBD_HID_SendReport` sample in the 'STM32 USB in 10 Minutes' video)
  11. Run make, verify build success
  12. Using ST-Link Utility, flash bin file onto device
  13. Observe the tragic lack ofUSB enumeration (evenno 'Unknown Device')

Plugging and unplugging the device's user USB port does nothing on the PC - not even showing an unknown device. Device Manager does not attempt a refresh (which is visually quite noticeable) when you plug in the device. So the failure is at a very early stage, perhaps not even beginning to enumerate. This leads me to suspect perhaps a clock or interrupt issue.

I have tried many fixes, including the following changes, and nothing helps at all:

  • Set heap and stack to much higher values
  • Set explicit priorities for SysTick and USB in NVCC (higher and lower)
  • Set HSE to crystal (rather than bypass, which it should be according to the docs)
  • Switch to using CDC and MSC classes
  • Use or disable FreeRTOS
  • Comment out SysTick handler

I also tried starting from scratch and following along with the official STM tutorial as shown in this video:

But that didn't work either. Thinking perhaps there was some faulty hardware, I tried another board. Still nothing. I've tried nearly every suggestion I could find in the forums.

TheUSB HAL code that ships with theSDK is not actually generated by CubeMX (and doesn't have gcc Makefiles) so it's not really that useful.

So is there a minimalist USB example that is actually generated from CubeMX that actually works?

Thanks -

:: Gavin

https://community.st.com/tags#/?tags=stm32%20cubemx

https://community.st.com/tags#/?tags=usb

#stm32-cubemx #usb

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Ben K
Senior III
Posted on October 20, 2017 at 09:56

The STM32F3 series USB FS PHY is lacking the 1.5K pullup resistor on the DP line, therefore this resistor has to be externally provided on the PCB. In order to enable setting the connection state of the USB device without physically removing the device from the host, it is recommended to connect this resistor to a GPIO output instead of tying it to VDD.

This is done on this Nucleo board according to the schematics as well. Here the PG6 pin has to be driven with VDD for the FS USB device to be detected by the host. The HAL PCD library has a callout that has to be implemented by the user:

/* Let's assume PG6 is configured as output no pull in CubeMX, and initialization of the pin is done */

void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)

{

  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, (GPIO_PinState)state);

}

By adding this function to your code the device should be detected by the host after the USBD_Start() has been called.

View solution in original post

16 REPLIES 16
Posted on October 20, 2017 at 08:22

Hello Gavin!

Is HSE_VALUE 8000000?

Did you tried to change the computer or usb socket, usb cable?

Ben K
Senior III
Posted on October 20, 2017 at 09:56

The STM32F3 series USB FS PHY is lacking the 1.5K pullup resistor on the DP line, therefore this resistor has to be externally provided on the PCB. In order to enable setting the connection state of the USB device without physically removing the device from the host, it is recommended to connect this resistor to a GPIO output instead of tying it to VDD.

This is done on this Nucleo board according to the schematics as well. Here the PG6 pin has to be driven with VDD for the FS USB device to be detected by the host. The HAL PCD library has a callout that has to be implemented by the user:

/* Let's assume PG6 is configured as output no pull in CubeMX, and initialization of the pin is done */

void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)

{

  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, (GPIO_PinState)state);

}

By adding this function to your code the device should be detected by the host after the USBD_Start() has been called.

Posted on October 20, 2017 at 08:42

Hi Vangelis,

Yes, I've tried CDC, MSC and HID. I have also tried two different cables, and I just tried different sockets on the root hub (not a peripheral hub), with no effect.

I have been trying to debug the interrupts and USB stack, and have found something very interesting. Putting either a printf or flashing an LED in the USB_LP_CAN_RX0_IRQHandler shows that when the USB cable is _unplugged_, interrupts flow constantly (but don't really do anything useful). Once you plug the cable in to the user port, interrupts stop completely!

I see HAL_PCD_Reset when the cable is unplugged, but there's no other meaningful messages being decoded.

So the problem seems very low level - why would interrupts stop once the cable is plugged in??

Posted on October 20, 2017 at 08:48

I also checked the success of all the init code, and the following code in MX_USB_DEVICE_Init all succeeds:

USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);

USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);

USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);

USBD_Start(&hUsbDeviceFS);

I added printf trace to all the HAL_PCD_**Callback functions, and only the RESET one gets triggered.

Posted on October 20, 2017 at 08:56

Yes, the clock is right, and the USB frequency is 48MHz

#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */

Khouloud GARSI
Lead II
Posted on October 23, 2017 at 15:13

Hi

gavin.baker

‌,

A full speed device, uses a pull up resistor attached to D+ to specify itself as a full speed device (and to indicate its speed).

The pull up resistor at the device end will also be used by the host or hub to detect the presence of a device connected to its port. Without a pull up resistor, USB assumes there is nothing connected to the bus.

For some STM32, the pull up resistor is already embedded. Otherwise, the customer needs to add it: Case of STM32F3 devices.

The USB_DP (D+) pin should be pulled up with a 1.5 kΩ resistor to a 3.0-to-3.6 V voltage range. Please add this external resistor and tell us if the issue persists.

Khouloud.

Posted on October 24, 2017 at 00:18

Hi Ben,

Thanks very much for your lucid explanation. I tried adding the suggested code, and it worked perfectly. I only wish this information had been documented effectively in the Nucleo Manual! I will suggest this to ST.

Thanks and regards -

  :: Gavin

Posted on October 24, 2017 at 00:43

 ,

 ,

Hello Khouloud,

As documented in the original question, this was not my own board but rather the ST Nucelo 144 evaluation module. Since one of the key features of this module is the user USB port, it is reasonable to expect that it be fully functional out of the box.

I tried ,activating the pullup using PG6 as ,per

https://community.st.com/0D70X000006SypmSAC

 ,and that resolved the problem. The test code now works just fine, and the board enumerates and works as expected.

Unfortunately, the documentation in UM1974 for the Nucleo144 board is sorely lacking a clear explanation of this critical piece of information required to make the board function correctly. The docs only mention PG6 in passing under '6.10 USB OTG FS or device' with the following text:

USB disconnection simulation is implemented by PG6, which controls 1.5 K pull-up resistor (R70) on USB D+ line.

Most readers would see that and think 'well I don't need 'disconnection simulation', whatever that is, so this doesn't apply here'. I thought it related to OTG behaviour, not USB Device behaviour. When I read about the solder bridges in Table 12, it says only:

PG6 is connected to R70 to control USB D+ pull up

but this is ON by default, which I incorrectly assumed meant that it would provide the correct behaviour.

On the schematic, PG6 is labelled USB_Disconnect, which also doesn't exactly reveal its true purpose either. It's really required to enable USB connection!

So I urge you to ,add an explanation equivalent to Ben's answer above, including the code sample, to the ,UM1974 documentation for the Nucelo144 boards. It is critical information and will save users a great deal of time and effort to have this information clearly documented.

Thanks,

 , :: Gavin

Posted on December 18, 2017 at 15:45

Ben,

I am using STM32F070RB controller for my application. I have generated USB CDC/ USB HID codes and flashed on board and tried by connecting PC. But there is no enumeration as explained by Gavin. I have taken STM32F072B-Discovery example project and modified for 

STM32F070RB and tried. but same seeing same issue. Do we need to have same fix for STM32F070RB also as you explained here?