cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Device demo on STM32F4 Discovery with STM32CubeMX code?

nate1
Associate II
Posted on October 27, 2014 at 00:34

I am trying to get a USB CDC Device demo working on an STM32F4 Discovery board (with the STM32F407) with code from the STM32CubeMX generator application. The process has been murky at best, hopefully one of you can set me straight. 

So far, I have configured the project in STM32CubeMX, exported the code, merged the src and inc files with my project template (to use arm gcc). Included in my project template is the CMSIS, HAL and USB driver libraries. Additionally, I have updated my Makefile to build all of the required files. Here is the entire project: https://github.com/thenatefisher/stm32cube-usb-cdc-device-demo

After connecting both the mini and micro USB ports to my PC, I am able to build the application and load it to my device using openocd and arm-none-eabi-gdb. I can also run the application, but I do not see the device enumerate on my PC. I can verify this by performing an ls /dev/tty.usb* and I see no results. In addition, in the OSX System Information window, under USB, the virtual com device is not showing up. 

I am probably missing some very large steps here. Any pointers will be helpful. Thanks.

#stm32cubemx #c #usb #discovery #cdc #vcp #stm32
8 REPLIES 8
nate1
Associate II
Posted on October 27, 2014 at 08:32

As a follow up, I also have just downloaded the latest version of MX (4.4.0) and uvision (5.12). Tried creating a cube project with USB_OTG_HS selected, using internal PHY device-only mode. Selected VBUS and SOF checkboxes. Exported the project, built with MDK and flashed the board. After plugging in the OTG port to my machine, I still cannot see any new devices show up. 

nate1
Associate II
Posted on October 27, 2014 at 08:40

Tried with FS mode too. Here is a shot of my latest attempted.

0690X00000605Y8QAI.png

ilias
Associate II
Posted on January 16, 2015 at 09:19

I have exactly the same problem. Did you manage to get it work? Can you help me?

igoal
Associate
Posted on January 21, 2015 at 03:45

Please try change Heap_Size from 0x0000200 to 0x0000400 in startup_stm32f407xx.s

ilias
Associate II
Posted on January 21, 2015 at 07:36

I tried it (changed the size to 0x00000400) but no lack.

Any other thoughts?

Posted on January 22, 2015 at 13:33

There is a bug in the USB wakeup interrupt service routine generated by CubeMX for this application.  It affects the F4 parts (OTG) but not F3 etc.  Edit the file stm32f4xx_it.c that CubeMX generated and add the following line of code to the OTG_FS_WKUP_IRQHandler() routine:

void OTG_FS_WKUP_IRQHandler(void)

{

  /* USER CODE BEGIN OTG_FS_WKUP_IRQn 0 */

 __HAL_GPIO_EXTI_CLEAR_IT(EXTI_PR_PR18);

  /* USER CODE END OTG_FS_WKUP_IRQn 0 */

  HAL_NVIC_ClearPendingIRQ(OTG_FS_WKUP_IRQn);

  HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);

  /* USER CODE BEGIN OTG_FS_WKUP_IRQn 1 */

  /* USER CODE END OTG_FS_WKUP_IRQn 1 */

}

It fixed the problem for me.  Hopefully they will fix it in the next version of the F4 package (It is in there, not in the base Cube itself).

Posted on January 22, 2015 at 13:45

also, FYI, once you get past the Wakeup ISR problem, if you use the status return from the USB Tx data routines, there is a bug in usbd_cdc.c around line 830 where the internal busy flag is set after the call to the Low Level routine that starts the transmit packet function.  It is possible for this to set up a race condition where this is cleared by the process that sends a short message before returning to set this flag.  On return, the flag is set but the routine that should clear it has already come and gone.  You can fix it by moving the flag set instruction ahead of calling the LL packet send call as follows:

uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)

{     

  USBD_CDC_HandleTypeDef   *hcdc = pdev->pClassData;

 

  if(pdev->pClassData != NULL)

  {

    if(hcdc->TxState == 0)

    {

     

/* Tx Transfer in progress */

 

      hcdc->TxState = 1;                     // These two lines were moved up from below

 

      

      /* Transmit next packet */

      USBD_LL_Transmit(pdev,

                       CDC_IN_EP,

                       hcdc->TxBuffer,

                       hcdc->TxLength);

     

     return USBD_OK;

    }

    else

    {

      return USBD_BUSY;

    }

  }

  else ...

ilias
Associate II
Posted on January 26, 2015 at 09:06

Thanks for your post.

It was really, really helpful!!!

BR

Ilias