cancel
Showing results for 
Search instead for 
Did you mean: 

Speeding up VCP OTG USB communication

tszewczyk
Associate II
Posted on January 16, 2014 at 12:29

Hi there!

I'm trying to transfer as much ASCII as possible from my STM32F4Discovery board.

Basically I'm doing this:

while (1) {

  APP_Rx_Buffer[APP_Rx_ptr_in]=APP_Rx_ptr_in;

  APP_Rx_ptr_in++;

  if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)

  {

APP_Rx_ptr_in = 0;

  }

}

Why it doesn't work? If I slow down this loop, I can get some data..

Best regards,

Tom
7 REPLIES 7
chen
Associate II
Posted on January 16, 2014 at 12:45

Hi Tom

Sorry, you are going to have to give more contextual information here!

What exactly are you seeing as a result of the code?

The snipet of code is no enough detail for us to work out what is going on.

Post more of the code and we might work out what is going on for you.

tszewczyk
Associate II
Posted on January 16, 2014 at 12:59

Hi!

Well, sorry for this.. In general I'm running the code form VCPdemo. As long as I execute the above code slowly enough, I receive the data. Whenever I'm ''putting'' data to APP_Rx_Buffer to fast, the communication breaks. I also check whether I don't overwrite cyclic buffer, but still no good. The code for USB I have in my main(), is this:

while (1)

  {

 if((APP_Rx_ptr_in+1)%APP_RX_DATA_SIZE != APP_Rx_ptr_out) { // checking for buffer overwrite

 APP_Rx_Buffer[APP_Rx_ptr_in]=APP_Rx_ptr_in;

 APP_Rx_ptr_in++;

 if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)

 {

APP_Rx_ptr_in = 0;

 }

 }

 Timer1=1; // slowing down timer

 while(Timer1);

  }

}

Still the problem is somewhat weird imho.

Best regards,

Tom

chen
Associate II
Posted on January 16, 2014 at 13:27

Hi

Pasting the same code with the delay still does not tell me where you are executing the code!

Where are you running that code - in your main loop?

If that is the case - it is not surprising you are not seeing anything.

The APP_Rx_Buffer[] is a private buffer for the USB driver code/layer to process data.

You should modify/write code in usbd_cdc.c  to fill the buffer when you want to send.

You call the 'send' function in usbd_cdc.c to send data over USB.

tszewczyk
Associate II
Posted on January 16, 2014 at 13:33

There is 'extern' definition of  APP_Rx_Buffer[]  buffer at the beginning of main.c, but that's not the problem. 

The code you are seeing works just fine as long as you don't execute it in constant loop. If you put it into while(1) without anything, the communication breaks.

Tom

chen
Associate II
Posted on January 16, 2014 at 13:56

Tom

''Why it doesn't work? If I slow down this loop, I can get some data..''

Because you are bypassing the buffering/code in usbd_cdc.c

''There is 'extern' definition of  APP_Rx_Buffer[] buffer at the beginning of main.c''

As I Said - it is suppose to be a PRIVATE buffer for the USB driver.

Go look at what the VCP demo does - it has functions in usbd_cdc.c which allow send/recieve over USB. These funcions are suppose to fill/empty the APP_Rx_Buffer[]

buffer. If I remember correctly, the VCP demo transfered the USB CDC to the USART.

tszewczyk
Associate II
Posted on January 17, 2014 at 09:45

As far as I see, the VCP example uses this function to send data:

static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)

{

  if (linecoding.datatype == 7)

  {

    APP_Rx_Buffer[APP_Rx_ptr_in] = USART_ReceiveData(EVAL_COM1) & 0x7F;

  }

  else if (linecoding.datatype == 😎

  {

    APP_Rx_Buffer[APP_Rx_ptr_in] = USART_ReceiveData(EVAL_COM1);

  }

  

  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;

}

This is the same method I was trying to use. The problem is, that UART is slow and therefore USB work just fine. In my case I'm trying to put it into loop and this fails. The same problem was discussed here: [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/problems%20with%20USB%20lib%20CDC%20example&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=14]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fproblems%20with%20USB%20lib%20CDC%20example&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=14

but I guess I don't get the idea.

Tom

From: sung.chen_chung

Posted: Thursday, January 16, 2014 1:56 PM

Subject: Speeding up VCP OTG USB communication

Tom

''Why it doesn't work? If I slow down this loop, I can get some data..''

Because you are bypassing the buffering/code in usbd_cdc.c

''There is 'extern' definition of  APP_Rx_Buffer[] buffer at the beginning of main.c''

As I Said - it is suppose to be a PRIVATE buffer for the USB driver.

Go look at what the VCP demo does - it has functions in usbd_cdc.c which allow send/recieve over USB. These funcions are suppose to fill/empty the APP_Rx_Buffer[]

buffer. If I remember correctly, the VCP demo transfered the USB CDC to the USART.

chen
Associate II
Posted on January 17, 2014 at 10:32

Hi Tom

''As far as I see, the VCP example uses this function to send data:

static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)''

Yes - correct. this is the function that should be called to sends to USB. The input parameters of the function appear to do nothing (this is a hint)

There is another function which receives data from the USB.

''but I guess I don't get the idea.''

Correct - you are not understanding.

The VCP example simply takes the data from USB and sends it to the USART

and does it in the opposite direction.

It is however, the basis to start from. Start looking at how the code sends data to the USART and how it manages flow and buffer limits.

Search the whole example for ''APP_Rx_Buffer''. You should find that there is another layer in the USB driver code which take data out of this buffer and 'empties it'

Once you understand this - you can strip out the USART code and replace it with your own.

static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)

is the Function you should be calling to send data through USB, you will have to remove the keyword ''static'' and put it in the header file.

The idea is to build a 'driver' which has a Application Programmers Interface (API) which does what the function name implies. Once the driver is written - you no longer have to worry about how to send data over USB CDC, you just call the driver function.