2024-04-05 02:51 AM - last edited on 2024-04-05 04:59 AM by Peter BENSCH
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 */
}
```
2024-04-05 03:01 AM
Little precision:
I'm using a STM32F411E-Disco
2024-04-05 04:28 PM
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.
2024-04-08 01:58 AM
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?
2024-04-08 02:28 AM
Just - how often you call the "USB service" , MX_USB_HOST_Process(); , in main ?
I call it about every 300us and USB running fine.
2024-04-08 02:34 AM - edited 2024-04-08 02:40 AM
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.
2024-04-08 05:12 AM - edited 2024-04-08 05:13 AM
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.))
2024-04-08 05:37 AM
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.
2024-04-08 08:24 AM - edited 2024-04-08 08:26 AM
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....
2024-04-08 09:41 AM - edited 2024-04-08 09:50 AM
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 ?