0
\$\begingroup\$

I am trying to use the built-it USB to implement a simple HID device in STM32F072. Of course, it is not working. This is my first experience with USB, so I needed some help in figuring out what could be going wrong.

I am using the STM32F0x2xx USB FS device library and am right now testing with their HID example.

When I plug the USB cable to my device and computer, nothing happens. Not even "Unknown Device" or "Yellow exclamation" which leads me to believe it is getting screwed up in the enumeration stage itself.

Doing a USB dump with Wireshark shows some data transfer, which includes lots of "malformed packets".

Enter image description here

So I am not sure what could be wrong. Some things which I think may be going wrong...

  1. Do I need termination resistors on the DM and DP lines? No as per the STM32F072 reference manual; we don't need them Enter image description here

  2. Do I need an external pull-up resistor on the DP line? Nope, as per reference manual, F072 has built-in pull-up resistors for that. Enter image description here

  3. As per F072 datasheet, there is a USB_NOE line on pin PA13 which I have left unconnected. I am not sure, but I don't think this pin needs to be connected.

  4. In the STM32 USB library, in the file usb_bsp.c (where all the pins, etc. are dealt with), I don't see the DP and DM pins being initialized or set to their alternate USB functions. Only thing they do is enable the USB clock.

    void USB_BSP_Init(USB_CORE_HANDLE * pdev) { GPIO_InitTypeDef GPIO_InitStructure;

      #
      if defined USB_DEVICE_LOW_PWR_MGMT_SUPPORT
      EXTI_InitTypeDef EXTI_InitStructure;#
      endif
    
      /* Enable all GPIO clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOF, ENABLE);
    
      /* Configure all GPIOs in AN mode to disable current to flow into or out of GPIOs when in suspend mode  */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_Init(GPIOB, & GPIO_InitStructure);
      GPIO_Init(GPIOC, & GPIO_InitStructure);
      GPIO_Init(GPIOD, & GPIO_InitStructure);
      GPIO_Init(GPIOE, & GPIO_InitStructure);
      GPIO_Init(GPIOF, & GPIO_InitStructure);
    
      /* Disable all GPIO clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOF, DISABLE);
    
      /* Enable USB clock */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
    
      #
      if defined USB_CLOCK_SOURCE_CRS
      /*For using CRS, you need to do the following:
      - Enable HSI48 (managed by the SystemInit() function at the application startup)
        - Select HSI48 as USB clock
        - Enable CRS clock
        - Set AUTOTRIMEN
        - Set CEN
        */
    
      /* Select HSI48 as USB clock */
      RCC_USBCLKConfig(RCC_USBCLK_HSI48);
    
      /* Configure the Clock Recovery System */
      CRS_Config();#
      else
      /* Configure PLL to be used as USB clock:
         - Enable HSE external clock (for this example the system is clocked by HSI48
             managed by the SystemInit() function at the application startup)
           - Enable PLL
           - Select PLL as USB clock */
      /* Enable HSE */
        RCC_HSEConfig(RCC_HSE_ON);
    
      /* Wait till HSE is ready */
      while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {}
    
      /* Enable PLL */
      RCC_PLLCmd(ENABLE);
    
      /* Wait till PLL is ready */
      while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
    
      /* Configure USBCLK from PLL clock */
      RCC_USBCLKConfig(RCC_USBCLK_PLLCLK);
    
      #
      endif /*USB_CLOCK_SOURCE_CRS */
    
      /*JoyStick IOs Configuration*/
      //  STM_EVAL_PBInit(BUTTON_RIGHT, BUTTON_MODE_GPIO);
      //  STM_EVAL_PBInit(BUTTON_LEFT, BUTTON_MODE_GPIO);
      //  STM_EVAL_PBInit(BUTTON_UP, BUTTON_MODE_GPIO);
      //  STM_EVAL_PBInit(BUTTON_DOWN, BUTTON_MODE_GPIO);
    
      /* Configure the Tamper button in EXTI mode */
      //  STM_EVAL_PBInit(BUTTON_TAMPER, Mode_EXTI);
    
      /* Clear the Tamper EXTI line pending bit */
      //  EXTI_ClearITPendingBit(TAMPER_BUTTON_EXTI_LINE);
    
      # ifdef USB_DEVICE_LOW_PWR_MGMT_SUPPORT
    
      /* Enable the PWR clock */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    
      /* EXTI line 18 is connected to the USB Wakeup from suspend event   */
      EXTI_ClearITPendingBit(EXTI_Line18);
      EXTI_InitStructure.EXTI_Line = EXTI_Line18;
      /*Must Configure the EXTI Line 18 to be sensitive to rising edge*/
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init( & EXTI_InitStructure);#
      endif /*USB_DEVICE_LOW_PWR_MGMT_SUPPORT */
    }
    

I would appreciate if someone can suggest what the issue here could be.

\$\endgroup\$
  • 1
    \$\begingroup\$ To rule out a hardware problem, try it with the Discovery/Nucleus board. \$\endgroup\$ – CL. Mar 2 '17 at 10:01
  • \$\begingroup\$ @CL.Unfortunately I do not have access to a dev board \$\endgroup\$ – Ankit Mar 2 '17 at 10:52
  • \$\begingroup\$ Verify your schematic by checking the schematic of an F0 dev board's schematic. \$\endgroup\$ – Bence Kaulics Mar 3 '17 at 7:36
  • \$\begingroup\$ Checked against STM32F072 Disco design schematic here and the hardware connections seems fine. So it seems to be a software issue \$\endgroup\$ – Ankit Mar 3 '17 at 10:18
  • \$\begingroup\$ Are # and if defined USB_DEVICE_LOW_PWR_MGMT_SUPPORT really on separate lines? The same with # and endif. \$\endgroup\$ – Peter Mortensen Mar 16 '17 at 18:30
-1
\$\begingroup\$

You need to set the pins to its alternative functions. See examples below (this is for stm32f7 series, so you probably cannot use it directly):

Full Speed Device

void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
{
    GPIO_InitTypeDef GPIO_Init;

    /* Configure USB FS GPIOs */
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_Init.Mode = GPIO_MODE_AF_PP;
    GPIO_Init.Pull = GPIO_NOPULL;
    GPIO_Init.Speed = GPIO_SPEED_HIGH;
    GPIO_Init.Alternate = GPIO_AF10_OTG_FS;

    /* Configure DM DP Pins */
    GPIO_Init.Pin = GPIO_PIN_11 | /* OTG_FS_DM */
                    GPIO_PIN_12;  /* OTG_FS_DP */
    HAL_GPIO_Init(GPIOA, &GPIO_Init); 

    /* Enable USB FS Clock */
    __HAL_RCC_USB_OTG_FS_CLK_ENABLE();

    /* Set USBFS Interrupt priority */
    HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0);

    /* Enable USBFS Interrupt */
    HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
}

High Speed Host

void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
{
    GPIO_InitTypeDef GPIO_Init;

    /* Enable GPIOs clock */
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_Init.Mode = GPIO_MODE_AF_PP;
    GPIO_Init.Pull = GPIO_PULLUP;
    GPIO_Init.Speed = GPIO_SPEED_HIGH;
    GPIO_Init.Alternate = GPIO_AF12_OTG_HS_FS;

    GPIO_Init.Pin = GPIO_PIN_14 |    /* OTG_HS_DM */
                    GPIO_PIN_15;     /* OTG_HS_DP */
    HAL_GPIO_Init(GPIOB, &GPIO_Init);

    /* Enable USB HS Clocks */
    __HAL_RCC_USB_OTG_HS_CLK_ENABLE();

    /* Set USBHS Interrupt to the lowest priority */
    HAL_NVIC_SetPriority(OTG_HS_IRQn, 5, 0);

    /* Enable USBHS Interrupt */
    HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
}

The functions above will typically be called when initializing the usb function with:

HAL_PCD_Init(&hpcd); // USBH_HandleTypeDef
HAL_HCD_Init(&hhcd); // USBD_HandleTypeDef
\$\endgroup\$
  • \$\begingroup\$ The first part may be somewhat parallel, but not the 2nd - the STM32F0's don't have a high speed host, or to the best of my recollection any host capability at all. \$\endgroup\$ – Chris Stratton Sep 16 '17 at 21:43
  • \$\begingroup\$ The first part is wrong also, you don't have to set the pins to alternate function on the f072c8, it's all taken care of by the usb peripheral. \$\endgroup\$ – Colin Aug 20 '18 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.