cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Bug in CubeMX firmware

richard239955
Associate II
Posted on April 11, 2014 at 10:07

Hey everybody,

in order to initialize a working Virtual Com Port with CubeMX on the STM32F4 Discovery, I had to change

   pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));

to

   pdev->pClassData = (void *) USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));

Without the type cast pClassData would always be null, which will make the parent function (USBD_CDC_Init in usbd_cdc.c) return before initializing the interface.

Btw I used firmware 1.1.0.

EDIT: Sorry, that was too fast. This line was actually not the root cause, it was the following line in USB_CDC.h

   &sharpdefine CDC_DATA_HS_MAX_PACKET_SIZE        512

Changing that value to 256 made it work for me now. In case anyone is interested, here's a small code example for a vcp mirror. Add this code to CDC_Receive in usb_cdc_if.c

    static uint8_t buff_RX[256];

    static uint8_t buff_TX[256];

    

    int i = 0;

    

    for (i = 0; i < *Len; i++)

        buff_TX[i] = buff_RX[i];

    

    USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0], *Len);

    USBD_CDC_TransmitPacket(&hUsbDeviceFS);

    

    USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &buff_RX[0]);

    USBD_CDC_ReceivePacket(&hUsbDeviceFS);

Also you will have to add

    extern USBD_HandleTypeDef hUsbDeviceFS;

to this file.

 

#usb #cdc #cdc #cdc #cdc_receive_fs #full-echo #usb-cdc #vcp #vcp
49 REPLIES 49
sdim
Associate III
Posted on July 13, 2014 at 01:39

I also have a similar problem

solved

1) Increase the heap and the stack size.

2) If you use the embedded phy of the HS port, change the buffers size and HS max packet size from 512 to 64. 

The maximum packet size for full speed devices is 64 bytes.

I guess that maybe HS on the STM32 HAL drivers stands for HS port , not for HS mode.

adriano
Associate II
Posted on December 09, 2014 at 17:52

Hi,

I'm tryin to implement serial communication via USB VCP; I tested your echo code and it works fine, but when I use the receive/transmit functions the CPU gets stuck in there and doesn't do anything else. Do you (or anybody else) know why?

(I'm using a STM32F3 board)

richard239955
Associate II
Posted on December 10, 2014 at 17:15

It's hard to answer this question. A little more input would be nice 🙂

giuseppe239955_st
Associate II
Posted on March 22, 2015 at 18:13

It seems that USB is always a nightmare... or, to be more precise, USB firmware libraries.

I am new to ST32 but have years of experience with Atmel AVR, and at start I experienced a lots of problems with a simple CDC application with theirs ASF 🙂

About the specific subject, I am able to implement a simple echo application, but it works well only if the amount of data is no more than 63 bytes.

Amel NASRI
ST Employee
Posted on March 24, 2015 at 11:10

Hi Giuseppe,

Could you please precise what are you using as device & which firmware?

It will be more helpful to create a new discussion where you describe clearly your issue with more details on your environment.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

kevinliao
Associate II
Posted on March 25, 2015 at 05:29

update~

I found the solution.

The low power enable setting in USBD_LL_Init need to disable.

  hpcd_USB_FS.Init.low_power_enable = DISABLE;

  //hpcd_USB_FS.Init.lpm_enable = ENABLE;

Then the code can run normally, and not always into interrupt service.

But I also want to know, when can I start to send data to PC?

Is there has flag to check?

------------------------------------------------------------------------

Hi, 

I have the same problem,

I can do the echo function used the CDC_Receive_FS() in the usb_cdc_if.c

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 7 */ 

  UserTxBufferFS[0]=Buf[0];

  CDC_Transmit_FS(UserTxBufferFS,*Len);

  

  USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]);

  USBD_CDC_ReceivePacket(hUsbDevice_0);  

  usbFlag=1;

  return (USBD_OK);

  /* USER CODE END 7 */ 

}

But when I want to do CDC_Transmit_FS() in the main function,

It is not work.

When I use the debug mode, I found the code in the main function always not run,

Because the SOF interrupt is always Hi,

It will always running the interrupt service HAL_PCD_IRQHandler()

How can I do?

Is there has any solution?

Thanks a lot.

giuseppe239955_st
Associate II
Posted on March 25, 2015 at 11:47

Hi Mayla,

perhaps we can keep the discussion in this thread, because I reckon it is still related with Cube.

I am currently testing a 32f4-discovery (that with the LCD on board) with Cube libraries 1.4.0.

The test application is very simple, the receive function sends a single char each time it is invoked. The input buffer is 512 but I read somewhere that CDC uses FS instead than HS, so the buffer is in facts 64.

I would expect to get an echo character for each block of 64 bytes received. Unfortunately this does not happen.

static int8_t CDC_Receive_HS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 12 */

    uint8_t array[1];

    array[0] = '*';

    if (Len > 0)

        return CDC_Transmit_HS(array,sizeof(array));

    else

        return (USBD_OK);

  /* USER CODE END 12 */

}

I suppose the issue has something to do with this warning found in usb_cdc_if.c

  *         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.

Possibly, it is a bad idea to send data inside the Receive handler. What I really have to do is writing a more complex function, which accumulates data into a buffer, and consume (send) the received data in the main.

petr239955
Associate III
Posted on March 25, 2015 at 14:35

Call USBD_CDC_ReceivePacket() for the next packet, at the end of your CDC_Receive_HS.

static int8_t CDC_Receive_HS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 12 */

    uint8_t array[1];

    array[0] = '*';

   

    CDC_Transmit_HS(array,sizeof(array));

    USBD_CDC_ReceivePacket(&hUsbDeviceHS);

  return (USBD_OK);

  /* USER CODE END 12 */

}

giuseppe239955_st
Associate II
Posted on March 25, 2015 at 16:03

Thank you for the suggestion, but this does not change much the situation, and only part of the packet is echoed on the USB.

On the other hand, if I simply count the received bytes, and write periodically the result in the main loop:

static int8_t CDC_Receive_HS (uint8_t* Buf, uint32_t *Len)

{

    USBD_CDC_ReceivePacket(hUsbDevice_1);

    counter += *Len;

    return (USBD_OK);

}

The total count is always correct even in case a large amount of data is received.

So it really seems that sending data in the receive handler is not a good practice. I suspect this has not much to do with STM32Cube, but with how USB-CDC works. In facts, now I remember that Atmel ASF shows the same behaviour!

petr239955
Associate III
Posted on March 25, 2015 at 21:10

For full echo please try this:

static int8_t CDC_Receive_HS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 12 */

 

  CDC_Transmit_HS(Buf, *Len);

  USBD_CDC_ReceivePacket(&hUsbDeviceHS);

  return (USBD_OK);

  /* USER CODE END 12 */

}

This works

with

STM32F042

,

I

do not send

large amounts of data

,

but

only a

keystroke

in the terminal.

If you have problem with large data packet please check:

#define APP_RX_DATA_SIZE  512

#define APP_TX_DATA_SIZE  512

I think,

size should be

at least equal to

CDC_DATA_HS_MAX_PACKET_SIZE.