cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX USB CDC Problem

Hossein mokhtare
Associate
Posted on August 18, 2017 at 11:27

i am working with STM32F446RE in a custom board and my Cube MX version is 4.22.0 and CubeF4 version is 1.16.0

i want to send large data from USB HS in CDC class to PC.i don't change any cube parameters except Enable IP Internal DMA that i set this enabled.

the code that i used to send data is:

&sharpdefine TEST_PACKET_LEN                                    1024

uint8_t test_buff[TEST_PACKET_LEN];

while(1)

    {

        while(CDC_Transmit_HS((uint8_t*)test_buff,TEST_PACKET_LEN)!=USBD_OK);

    }

this works.but when i change the TEST_PACKET_LEN to 2048 first packet would be sent but after it USB TX busy will never reset and code loops on inner while.i check the code and see that no interrupt occurs on OTG_HS_IRQHandler.

i guess this is a driver bug.can any one help me?

#usb #usb-cdc-cdc_transmit #stm32f446 #cdc_transmit_hs #cdc
6 REPLIES 6
Nathan Conrad
Associate II
Posted on September 06, 2017 at 05:54

I'm also having issues with the USB CDC driver (I asked 

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

).

My understanding is that you have have to wait for CDC_Busy() to be false before calling the Transmit function.

Also, I've read that data being a multiple of 64 bytes is a bad idea since it has a special interpretation in Windows. Try sending only 63 bytes at a time. Even then, I think that the maximum packet length may be 512 bytes, so it's likely a bad idea to try transmitting more than than.

renchin shr
Associate
Posted on February 10, 2018 at 15:24

I have the same problem when transfer 64 bytes data from stm32f4 MCU to PC, but there is no problem for transferring 63 or 65 bytes.

By the way, I have tried to using USB HID, I can transfer 64 bytes data each time successfully.

gbm
Lead III
Posted on February 10, 2018 at 17:47

First, you must call Transmit from a code run at the same priority as USB interrupt handler - might be the routine called by USB interrupt or any other interrupt of the same priority, but NOT the main loop (if it exists).

Second, AFAIIK, the ST CDC does not transfer ZLP by itself, which is necessary for a correct  CDC implementation. Your 64 bytes get transferred, but the receiver thinks there is still something left to be sent. It will get the data as soon as you send another USB packet of the size  other than the endpoint size. Try to send a packet with zero length (I am not sure if Transmit handles this correctly - I use my own implementation of CDC on STM32).

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Your comment helped me resolve the following issue: I was processing CDC input and sending output back out the CDC interface in the same ISR I received the input in.  Of course CDC would stop working after this. Once I moved the transmit function out of the ISR processing the CDC input into the main loop, everything started working correctly. Thanks!

Most likely you cannot even imagine how far this parody of a USB stack and your code based on it is from working correctly:

https://community.st.com/t5/stm32-mcus-embedded-software/32f417-can-one-detect-when-a-usb-host-is-connected/m-p/601826/highlight/true#M42845

Well, actually it stopped working but you didn't notice it yet. Please read my post again. You can't reliably call Trasmit from the "main loop". You may call it from CDC Receive (not always practical) or from an ISR of the same priority as USB interrupt.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice