cancel
Showing results for 
Search instead for 
Did you mean: 

Broken usbd_cdc_if_template in USBlib v2.1?

benjamin239955_st
Associate II
Posted on May 12, 2014 at 15:12

Hello everyone.

I'm trying to get USB VCP communication to my STM32F107 working (using USB to communicate via minicom with my µc). Looking at the example and the STM32_USB_Device_Library of the STM32_USB-Host-Device_Lib_V2.1.0 package, I saw the template but the code doesn't seem to make sense. usbd_cdc_if_template.c:

/**
* @brief TEMPLATE_DataTx
* CDC received data to be send over USB IN endpoint are managed in 
* this function.
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static
uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len)
{
/* Get the data to be sent */
for
(i = 0; i < Len; i++)
{
/* APP_Rx_Buffer[APP_Rx_ptr_in] = ***_ReceiveData(***); */
}
/* Increment the in pointer */
APP_Rx_ptr_in++;
/* To avoid buffer overflow */
if
(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_in = 0;
} 
return
USBD_OK;
}

So APP_Rx_ptr_in is incremented

after

the loop? And the first parameter, Buf, is never touched? Shouldn't it be more like: APP_Rx_Buffer[APP_Rx_ptr_in++] = ***_ReceiveData(***); And there might be more to be found. Just makes me question how reliable the code is. Or maybe I just don't understand the intention of this routine. Would also be happy about any further resources about using the STM32F1XX's USB CDC capabilities. Regards, Ben PS: Also, please STM, use less convoluted site layouts and create a modern, usable community and not this antiquated one-tiered 90ies forum, where information can hardly be found again. #stm32 #usb #vcp
7 REPLIES 7
chen
Associate II
Posted on May 12, 2014 at 15:29

Hi

No, it works as is BUT is horribly flawed. It is flawed in that there is no flow control management with the layer below. So, some people have found that when trying to get max data through put - funny things happen or data is lost. Search for ''

APP_Rx_Buffer

'' and you find where it is actually read out and data written into the USB pipe. This will give you a better understanding of what the variables are used for.
benjamin239955_st
Associate II
Posted on May 12, 2014 at 16:01

Thank you for your reply.

Do you have more information on the solution to the problem you described? I have experienced funny behavior with some code (a nibble being altered, some data out of sync...).

chen
Associate II
Posted on May 12, 2014 at 16:23

Hi

''Do you have more information on the solution to the problem you described? '' When you understand what usbd_cdc_core.c is doing with APP_Rx_Buffer APP_Rx_ptr_in APP_Rx_length then you can write a better function for

static
uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len)
 to do flow control properly. 

By the way - get rid of the 'TEMPLATE_' in the name
benjamin239955_st
Associate II
Posted on May 12, 2014 at 16:47

OK thank you, I will investigate.

I was just wondering what you meant by flow control, bc. I read something about a missing transmission of a zero length packet after a 64 byte packet. Since my packets shouldn't get that long, I was wondering whether that could even cause the behavior I've seen, or whether there is something else to watch out for.

And of course I will rename everything with ''template'' in it's name.

Regards,

Ben

chen
Associate II
Posted on May 12, 2014 at 17:26

''I was just wondering what you meant by flow control''

The library provided by ST is not very good. Their example code does not handle large amounts of characters very well. There is no sychnronisation between your code in

static
uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len)

and the 'lower level' code in usbd_cdcd_core.c It is not (apparently) clear how Handle_USBAsynchXfer() or usbd_cdc_DataIn() know when there is data to transmit. So, from you application's point of view - you just keep putting data into APP_Rx_Buffer[] and update the inPtr and hope the data is send up the USB. ie there is no flags or anything to control the flow of data. That is what I mean by 'flow control'. If you work out what is going on in usbd_cdcd_core.c - you can work it out!
benjamin239955_st
Associate II
Posted on May 12, 2014 at 20:02

>The library provided by ST is not very good.

>Their example code does not handle large amounts of characters very >well.

Glad to hear that. I thought I'm the only one thinking that.

I got your point. So I might have to edit the library code itself, which I don't like too much. Anyways, not sure if that can be the reason of the weird behavior I see. When disconnecting and re-connecting USB, my board lags one message behind, i.e., I send Req1 and get Resp1, but after unplugging I send Req2 and get Resp1, Req3 and Resp2 etc.

But I guess I should open a new thread for this.

Going back to the original question: I still think the template is erroneous. There is no incrementation of the _in index. the code loops over it ''Len'' times, writing to the same element of the buffer and increments it only afterwards. This will only work for ''Len'' equals 1 and you don't need a loop for that.

chen
Associate II
Posted on May 13, 2014 at 12:29

''When disconnecting and re-connecting USB, my board lags one message behind, i.e., I send Req1 and get Resp1, but after unplugging I send Req2 and get Resp1, Req3 and Resp2 etc.''

Flush (or reset) the buffer when USB disconnect/reconnect.

''Going back to the original question: I still think the template is erroneous.''

No. What the code does is fill the buffer with your data, increments the 'in_ptr' and then hopes that the next layer down will transmit the data before you add more data.

Problems start arising if the data to put into the buffer is larger than the buffer. The library code just over writes (wraps).