CDC_Transmit_FS function always returns USBD_BUSY
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-25 12:12 AM
I am now trying to implement CDC-VCP connection between a PC and a STM32 board. Just my goal is a STM32 echo server.
I have done like this:
- STM32 Cube MX :
- USB FS endable
- USB Device : CDC Enable, rx/tx buffer size as 128<-1000
- Clock config : USB 48MHz and other config is done by "resolve clock issue"
- SYS : serial debug enabled
- RCC : Enable LSC as Crystal/Ceramic
- Code :
- in "while" body,
- #include "usbd_cdc_if.h"
- add Hal_Delay(500)
- CDC_Transmit_FS(tx, strlen(tx));
- in "while" body,
- Debug :
- debug by STLink
- connection : PC <-USB cable->STM32 (L432KC, L073RZ both)
- Result :
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; //<-Always triggered
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
Can anybody tell me how resolve this problem?
- Labels:
-
STM32CubeMX
-
STM32L0 Series
-
STM32L4 series
-
USB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-25 1:02 AM
- Do you check for the CDC connection being active before sending your data? From my experience, you canot send anything until at least 20 ms after the connection is estabilished, which is signaled via SetControlLineState service. Alternatively, you may wait for some character being sent to your device.
- CDC_Transmit must be called from an ISR of the same priority as USB interrupt; otherwise it will break sooner or later.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-25 2:10 AM
1. In my firmware, it calls HAL_Delay(500) before CDC_transmit(..) in while body.
So I think it is not the reason of this problem.
2. I don't understand which is ISR. Do you mean CDC_transmit cannot work in "main while body"? If so, could you tell me where can I call CDC_transmit function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-25 4:59 AM
Basically you cannot send anything if the other party is not connected = until USB device is properly initialized AND the terminal session is open.
ISR = Interrupt Service Routine. You may use CDC_Transmit in any ISR of the same priority as USB interrupt, so, for example, you may echo the received data in CDC_Receive, which is called by USB ISR.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-09-25 5:40 AM
Oh I understand. I will apply it and respond in tomorrow.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-10-25 2:48 AM
Hello, I'm having this problem too.
I created a solution as follows;
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;
while (hcdc->TxState != 0)
{
if(usbdata_send_cntrl==1)
{
usb_com_rst=1;
usbdata_send_cntrl=0;
break;
}
usbdata_send_cntrl++;
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
USB_FlushTxFifo(USB, 0x15U);
USB_FlushRxFifo(USB);
/* USER CODE END 7 */
return result;
}
" usb_com_rst=1;" in the function The variable is processed in the main() function as follows;
if(usb_com_rst==1)
{
USBD_DeInit(&hUsbDeviceFS);
HAL_Delay(50);
MX_USB_DEVICE_Init();
usb_com_rst=2;
}
As a result, the COM port is reset and this cycle is broken and the function starts working again.
However, the COM reset process sometimes causes problems on the other side (the program running on the PC).
For this reason, I want to learn how to get out of the infinite loop without resetting COM.
