cancel
Showing results for 
Search instead for 
Did you mean: 

CDC_Transmit_FS function always returns USBD_BUSY

SSON.2
Associate II

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:

  1. ​STM32 Cube MX :
    1. USB FS endable
    2. USB Device : CDC Enable, rx/tx buffer size as 128<-1000
    3. Clock config : USB 48MHz and other config is done by "resolve clock issue"
    4. SYS : serial debug enabled
    5. RCC : Enable LSC as Crystal/Ceramic
  2. Code :
    1. in "while" body,
      1. #include "usbd_cdc_if.h"
      2. add Hal_Delay(500)
      3. CDC_Transmit_FS(tx, strlen(tx));
  3. Debug :
    1. debug by STLink
    2. connection : PC <-USB cable->STM32 (L432KC, L073RZ both)
  4. 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?

5 REPLIES 5
gbm
Lead III
  1. 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.
  2. CDC_Transmit must be called from an ISR of the same priority as USB interrupt; otherwise it will break sooner or later.
My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
SSON.2
Associate II

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?

gbm
Lead III

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.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
SSON.2
Associate II

Oh I understand. I will apply it and respond in tomorrow.

irfaninci
Associate

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.