cancel
Showing results for 
Search instead for 
Did you mean: 

(SOLVED) USB Device CDC middleware : unable to even understand how to use it.

JDoe.2
Associate III

(I'm still working on this, I'll edit this as I progress, keep reading)

Well, the title of this question should be clear enough. I wanted to add virtual COM port functionality to a project. Using STM32CubeIDE, I enabled the USB device on an SMT32F103 and then I enabled the USB CDC middleware. After generating the project, I get 20 new source files, none of which seem to contain anything even remotely comparable to the USART HAL functions, either in name or in purpose.

The code does compile. But when I connect the USB to my PC my board isn't even enumerated. The generated code calls an MX_USB_DEVICE_Init function which executes without error but then again, so would a bunch of NOP's.

The offical documentation at https://www.st.com/resource/en/user_manual/dm00108129-stm32cube-usb-device-library-stmicroelectronics.pdf seems like it's talking about an entirely different middleware. It mentions files that appear nowhere in the code I generated. The "how to use" section might as well be fiction.

Trying to be as thorough as possible, I look at the example projects that shipped with the HAL installed on my PC (version 1.8.0) and find a couple of CDC example which do contain the files mentioned in the documentation (usbd_cdc_interface.c and .h)

So I read those files, trying to find what they could be doing and how it matches what the code generator barfed. I'm hopeful at first : it looks like this code uses the USART HAL functions over the VCP, using a mysterious instance USARTx... except I look for its definition and it turns out to be USART2. I'm starting to get angry : how is a function named CDC_Itf_Init is supposed to work if it references USART2 ?

At this point I've spent the better part of 4 hours trying stuff, reading code, Googling left and right, and I know the pattern : once again, as with Ethernet, Cube is trying to sell me something that doesn't exist and I'm wasting my time.

So I'm going to ask : can anyone show me how to use the so-called Communication Device Class middleware that Cube claims to offer ? Namely, how do I open that serial port, setup its baud rate, and send and receive data ?

I swear, any time I try to use Cube for anything more complex than blinking an LED, this kind of crap happens. I may have to start billing ST for my time.

(Cue Spongebob meme) 5 hours later...

I've started reverse-engineering the stuff Cube vomited into my project and I'm getting somewhere...

First, regarding the enumeration issue : that was a bad cable on my part. Apparently I grabbed an old "charge only" cable from work, you know, those that don't let you steal work data using your phone. With an actual USB cable, the STM32 enumerated and a nice new COM port appeared on my system.

Next step was to figure out data transfers. I'll spare you the details but I ended up in a file named usbd_cdc_if.c and that file appeared to contain nearly everything I needed :

  • Tx and Rx buffer declarations
  • Transmit function
  • Receive function, that's apparently passed as a handler to... something
  • Assorted init functions

My stm32f1xx_it.c file also got a new interrupt handler : USB_LP_CAN1_RX0_IRQHandler, which my intuition tells me is in charge (among other things) of handling incoming data over the virtual COM port.

At that point it wasn't clear where I should look next; so I decided to try actually using what I found. Good news :

  • I can use the CDC_Transmit_FS function to send data over the VCP. It's non-blocking, by the way.
  • I can read incoming bytes directly from the receive buffer UserRxBufferFS though that's clearly not how it should be done.

I still need to figure out non-blocking reception of data. There's a CDC_Receive_FS function but... well here's what its comment says. If you understand what's supposed to happen don't hesitate to share :

 *     Data received over USB OUT endpoint are sent over CDC interface

 *     through this function.

 *

 *     @note

 *     This function will block any OUT packet reception on USB endpoint

 *     untill exiting this function. If you exit this function before transfer

 *     is complete on CDC interface (ie. using DMA controller) it will result

 *     in receiving more data while previous ones are still not sent.

They say that "the code is its own documentation" is a stupid saying, but hey in this case it's better than any form of documentation I've come across. I'll keep at it, meanwhile don't hesitate to contribute. Thanks.

BREAKING NEWS : I've done it !

Sorry, I forgot to update this post afterwards but I eventually managed to understand how to use the Cube library. On the plus side, I've documented absolutely everything on my website, and you can find it at :

https://nefastor.com/microcontrollers/stm32/usb/stm32cube-usb-device-library/

My site targets newbies, so there may be a lot of explanations you don't need, but I've tried to make it funny (depending on your sense of humor). There are four pages in that section, you can access them with the navigation menu on the right.

Constructive criticism is welcome !

On a personal note : the Cube library, while it works, is definitely not beginner-friendly. I'm far from a beginner and it was a painstaking process to use it. Perhaps I'm wrong to compare Cube to Arduino but if you need to develop something really quick, especially a proof of concept, Cube isn't for you.

Maybe next I'll tackle Ethernet and LWIP.

21 REPLIES 21
Piranha
Chief II

There is a simple, performing and reliable solution - TinyUSB.

https://github.com/hathach/tinyusb/tree/master/examples/device/cdc_dual_ports/src

One can get these examples running in a few hours!

Post edited to adhere community guidelines.

andreacrb
Associate

Hello there! 
Are you the owner of the website nefastor.com ? If yes, I read your posts about USB and found them very useful, thank you very much for that! I am a developer myself and I am struggling with the use of USB on the Host side and I was wondering if I could ask you a couple of questions about it, would you mind? 

Cheers,

Andrea