cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Increase Reading Speed

Kakyouka
Associate II

Hello,
I'm currently working on a USB project and i encounter some issues.

I would like to send data to the STM32 and the STM32 must re-send it as fast as possible. I already test the sending speed and it work great for me but the reading speed is low.
The function CDC_Receive_FS work as a callback function and is call at the right speed (as fast as the sending speed) but between the sending and the writing, there's a delay... I've looked into the library but i don't understant where it comes from or how to fix it.
The STM32 seems to be able to receive et write data with a latency of 10ms but combining these two operation make the board have a latency of (avg)124ms.

 

I suspect the USBD_CDC_ReceivePacket function to be the cause of this issue.

Do you have any idea ?

```C

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

{

/* USER CODE BEGIN 6 */

incrtest++;

 

TCountMsgReceive = StartingValueTCount;

 

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

CDC_Transmit_FS(UserRxBufferFS, *Len);

 

USBD_CDC_ReceivePacket(&hUsbDeviceFS);

 

 

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

{

//USB_CAN_SwitchReceive();

 

}

 

 

return (USBD_OK);

/* USER CODE END 6 */

}

```

9 REPLIES 9
Kakyouka
Associate II

Little precision:

I'm using a STM32F411E-Disco

Pavel A.
Evangelist III

Even 10 ms latency seems a bit too much. Depends on the size of the data, though.

The code snippet that you've shared does not provide enough clue to answer.

 

 

I don't know what part of code i must share because my question i about the HAL library provided by ST.

10ms is too much but i don't need less than that. The issue i encounter is that the switch between reading and writing is slow. If i just read, i can acheive 10ms without problem and it's the same if i just write.

I don't understand why the retransmit seems to be blocked while the board is receiving data. 

do you have any explanation why?

 

 

Just - how often you call the "USB service" , MX_USB_HOST_Process(); , in main  ?

I call it about every 300us and USB running fine.

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

The board is in Device mode and that's how my main function looks like.

I handle the data in the function CDC_Receive_FS() in the usbd_cdc_if.c file.

 

 

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */

  HAL_TIM_Base_Start_IT(&htim4);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 

 

 

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
	incrtest++;

  TCountMsgReceive = StartingValueTCount;

  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  CDC_Transmit_FS(UserRxBufferFS, *Len);

  USBD_CDC_ReceivePacket(&hUsbDeviceFS);


  if(((USBD_CDC_HandleTypeDef*) hUsbDeviceFS.pClassData)->RxState==0)
  {
	  //USB_CAN_SwitchReceive();

  }


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

In this function, i call CDC_Transmit_FS to re-send the data receive from the host PC. But no matter what i try, the transmit doesn't work until i stop sending data from the host to the board. If datas are send every 130ms there's no problem but below 130ms it cannot follow.

 

 

Oo, sorry, i did not see : device only. 

(I never did much with device ...more host .)

To receive i have :

 

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  return (USBD_OK);
  /* USER CODE END 6 */
}

 

and to transmit:

 

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 7 */
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0){
    return USBD_BUSY;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
  /* USER CODE END 7 */
  return result;
}

 

and program in main.c : " if xxx received , send (CDC_Transmit...) " . = > your program here. <

(To call transmit at receive interrupt level...maybe not best idea. And then call receive ... strange . (Dont do this.))

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

Ok thanks, i'll try but it seems weird because i've done what ST told to do in their tutorial.

I'll try and give you my results.

it doesn't work because CDC_Receive_FS is called by an interrupt so the main() function is blocked during the execution of CDC_Receive_FS.

I also tried using a Timer with a higher priority but i don't success to make it work. Depending on the frequency and the period i gave to CubeMX the latency is reduced or not.

Sometimes i acheive a transfert with 124ms and sometimes with 30ms.... The timer is running correctly but don't transmit the data directly....

Ok, i dont remember details ... i did about 11 years ago, got (close to limit) almost 1 MB/s (sending).

Send and receive same time ... max. 50% of this.

So look on git , at examples, how to do.

https://github.com/search?q=stm32%20cdc%20&type=repositories

+

read in HAL usb functions , to find , how to check "something received" -> read it.

(Maybe : USBD_CtlReceiveStatus() to start it, then check with  USBD_GetRxCount(..), if > 0 then copy it. )

Not call just (blocking) "receive now" ... look at examples, ok ?

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