Skip to main content
Eqqman
Associate III
October 28, 2022
Question

How to detect when CDC device is not busy using STM32 USB stack

  • October 28, 2022
  • 2 replies
  • 3022 views

Using the STM32 USB stack in a project for the STM32 CubeMX IDE on a STM32L062 processor, there are issues with trying to get the CDC device to send data back up to the host at maximum throughput. If CDC_Transmit_FS() is called twice in a row, then the first packet goes through but the second does not. If you look into the implementation of this function you come across the line

if (hcdc->TxState != 0) return USBD_BUSY;

However, if you do

while(CDC_Transmit_FS()==USBD_BUSY);

then the code never breaks out of this loop and no data ever gets to the host. What is the proper way to detect that the USB pipe is available for the device to transmit with ST's USB stack? So far the only way I can get multiple packets to arrive at the host is to do

CDC_Transmit_FS(); HAL_Delay(); CDC_Transmit_FS();

which is not the way this kind of code should be written and still doesn't guarantee me that all packets should be expected to arrive at the host.

This topic has been closed for replies.

2 replies

gbm
Principal
October 28, 2022

There is a callback for exactly that purpose: CDC_TransmitCplt_FS

CDC_Transmit_FS may only be called from an interrupt service routine of the same priority as the USB interrupt. The USB stack will at some point hang if it's called from main() or an ISR of a different priority.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Eqqman
EqqmanAuthor
Associate III
October 28, 2022

If I do a project search CDC_TransmitCplt_FS doesn't appear in there.

If I'm implementing my own version of this function, then how do I tell the stack to transmit? Every online example uses CDC_Transmit_FS for sending data. Most common examples edit CDC_Receive_FS to call CDC_Transmit_FS, but even doing this if you call CDC_Transmit_FS twice the second time doesn't go through. Here's just one example :

https://www.teachmemicro.com/stm32-cdc-usb-send-receive-data

This code works because of the use of HAL_Delay(), if that was removed this would send one packet and then hang.

Piranha
Principal III
October 28, 2022

Stop wasting your time on a junk created by incompetent fools...

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

Eqqman
EqqmanAuthor
Associate III
October 29, 2022

The CubeMX stack was actually our last resort. I started with TinyUSB but after getting it to compile the hardware triggered no response at all when plugged up. Then I tried https://github.com/dmitrystu/libusb_stm32 which would at least get to the "unknown USB device" stage of Windows. The CubeMX stack is the only one I could get to successfully enumerate.