cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 usb data loss

MMala.3
Associate II

I'm trying out a test program to measure data rate between pc and mcu over usb.
I'm using winusb with winusbnet wrapper on pc side and for mcu firmware i followed this github repo 

https://github.com/MichaelTien8901/STM32WINUSB

to get it built with winusb support.

On the device I have allocated 1024 byte TX and RX buffers for usb.
And used the same code from the repo 

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
extern volatile int8_t data_out_flag;
#define RX_DATA_LEN 1024
uint32_t receive_len = *Len;
if ((data_received + receive_len)> RX_DATA_LEN ) {
receive_len = RX_DATA_LEN - data_received;
if ( receive_len != 0 )
memcpy(RxData+data_received, Buf, receive_len);
data_received= RX_DATA_LEN;
} else {
memcpy(RxData+data_received, Buf, receive_len);
data_received += receive_len;
}
data_out_flag = 1;

USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);

return (USBD_OK);
/* USER CODE END 6 */
}

 

  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
    if ( data_out_flag ) {
       extern int8_t CDC_is_busy(void);
       if ( CDC_is_busy()) continue;
       data_out_flag = 0;
       data_sent = data_received;
       memmove( TxData, RxData, data_received );
       data_received = 0;
       CDC_Transmit_FS( TxData, data_sent );
    }
  }
  /* USER CODE END 3 */

}
int8_t CDC_is_busy(void)
{
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0)
      return 1;
  else return 0;  
}

 

From my tests on pc software in a loop I make

1. Test1: 5 calls to `writePipe` with 60 bytes each  

2. Test2: 5 calls to `writePipe` with 120 bytes each

3. Test3: 5 calls to `writePipe` with 240 bytes each  

Each of this is a seperate test...

I notice with a USB analyzer that I only get 3 calls of data back from device... and the last call is much bigger than the first 2.

Even if i increase the 5 calls to 10 calls on pc side i only get 3 back...and I see typically the last result i get back is truncated and the data is limited to 1024 byte similar to the buffer that is allocated on the device.

so the first response and second response from the device is typically around 64 bytes and the third one is a  much bigger packet as if its trying to stuff everything else in that response..

I'm probably thinking there is something wrong going on in my device code... and its unable to process the requests at a fast enough rate.
Any ideas and clues on this would be really helpful.

  

4 REPLIES 4
TDK
Super User

Calling CDC_Transmit_FS before the previous transaction completes will silently fail. You need to put data into a buffer and then send that buffer out piece by piece, as each transaction completes.

Setting a 1:1 ratio of receive to transmit won't work. Receive needs to handle data immediately and transmit needs to be compatible with random delays of up to 50 ms or so.

If you feel a post has answered your question, please click "Accept as Solution".

Hi, 

TxState flag is being checked before calling CDC_Transmit_FS.. would that not be sufficient?

What happens when CDC_Receive_FS is called but data_out_flag is already = 1? Data is lost.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks...Let me think about that...