cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX USB CDC VCP - Transmission problem

Jamal Panah
Associate II
Posted on December 13, 2017 at 11:43

hello,

i am trying to send data to pc over the otg used as a virtual com port. The data is received with a terminal program (HTerm). In order to send data i am using the function CDC_Transmit_FS. For a basic test the string 'start' is sent to the pc. Therefor i use the following code. The code is implemented in the while loop of the int main function:

while(1)

{

if(((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState==0)

{

while(CDC_Transmit_FS(((uint8_t*)&'start'),sizeof('start')) != USBD_OK);

}

}

This works and i can receive the data on the terminal program on my pc.

What doesn't work: If i try to send 'stop' after the 'start' string.

while(1)

{

if(((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState==0)

{

while(CDC_Transmit_FS(((uint8_t*)&'start'),sizeof('start')) != USBD_OK);

}

if(((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState==0)

{

while(CDC_Transmit_FS(((uint8_t*)&'stop'),sizeof('stop')) != USBD_OK);

}

}

what i hoped to receive is: start stop start stop start stop.... in an alternating order

but what i get is somehow confusing because now there is no order of the received data. I get start start stop start stop stop ...   start and stop are in different orders

Thank you for your help!

#transmit #cubemx #cdc #vcp #cubehal
1 ACCEPTED SOLUTION

Accepted Solutions
Ben K
Senior III
Posted on December 14, 2017 at 10:46

If you don't wait for the TxState to turn 0, you cannot expect a sequential order of execution. How to fix it:

  1. while

    (

    1

  2. while

    (((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!=

    0

    );

  3. (void)CDC_Transmit_FS(((uint8_t*)&

    'start'

    ),

    sizeof

    (

    'start'

    )); 

  4.  

  5.  

  6. while

    (((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!=

    0

    );

  7. (void)

    CDC_Transmit_FS(((uint8_t*)&

    'stop'

    ),

    sizeof

    (

    'stop'

    ));

  8. }

View solution in original post

4 REPLIES 4
Jamal Panah
Associate II
Posted on December 13, 2017 at 14:23

i think it has something todo with the TxState flag. But i don't know wht it is not set to 0 directly after a successful transmission?!

After a successful transmission:

Interrupt occures:

OTG_FS_IRQHandler                       calls     HAL_PCD_IRQHandler

HAL_PCD_IRQHandler                     calls     HAL_PCD_DataInStageCallback

HAL_PCD_DataInStageCallback      calls     USBD_LL_DataInStage

USBD_LL_DataInStage                    calls     DataIn

and DataIn is USBD_CDC_DataIn and there you can find:

    hcdc->TxState = 0;

which sets the TxState to 0 and so the next transmission can be started. but somehow it looks like this happens to slow.

Ben K
Senior III
Posted on December 14, 2017 at 10:46

If you don't wait for the TxState to turn 0, you cannot expect a sequential order of execution. How to fix it:

  1. while

    (

    1

  2. while

    (((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!=

    0

    );

  3. (void)CDC_Transmit_FS(((uint8_t*)&

    'start'

    ),

    sizeof

    (

    'start'

    )); 

  4.  

  5.  

  6. while

    (((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!=

    0

    );

  7. (void)

    CDC_Transmit_FS(((uint8_t*)&

    'stop'

    ),

    sizeof

    (

    'stop'

    ));

  8. }

Posted on December 15, 2017 at 09:14

Hello Ben,

thank you for the information! this helped a lot.

What i didn't mentioned was that i invoked the transmit function in a Callback of an interrupt service routine. The clou is that the transmission is based on an interrupt either.

Because of the reason that i didn't distribute priorities to the interrupts the hole system fall in a loop.

in this postin a similar problem with the HAL_Delay function (the HAL_Delay function is also based on an interrupt (SysTick)) occures and there you can find a good explanation:

have a nice day

Posted on December 16, 2017 at 13:48

The timeout handling of HAL is definitely one of its most ill-conceived part. I already posted an interrupt-safe alternative HAL_Delay() method in this thread: