Skip to main content
LHaze
Associate II
September 5, 2019
Question

Is there a known fix or patch for blocked USB communication caused by stuck USBD_BUSY?

  • September 5, 2019
  • 1 reply
  • 1618 views

This concerns the USB programming on on STM32F7 using the HAL libraries. The output for the USB transmission randomly goes blocked with USBD_BUSY. Nothing I have done so far has unblocked it. It would appear that this is not a new problem, as I have found comments on it as far back as four years ago. The suggestion for a "fix" is to switch from using HAL to the Standard Peripheral Libraries. Is there a fix or a patch for HAL libraries, or is the SPL suggestion still the only route to a working program? If the SPL is the only option, what is the procedure for accomplishing this? Is there some documentation to which I should refer?

This topic has been closed for replies.

1 reply

JoniS
Senior
September 5, 2019

Can you show your USB code which hangs? USB cdc mode? If possible smallest possible sample of the project which behaves like you descripe.​

LHaze
LHazeAuthor
Associate II
September 5, 2019

Here is the CDC_Receive_FS routine. If you want the Transmit, I can provide that, too. Thank you for looking at this.

-Lyman

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

{

   uint8_t i;               // counter

   uint8_t bHaveEOL = 0;

 /* USER CODE BEGIN 6 */

   for(i=0;i<*Len;i++)

   {

      if(Buf[i] == '\n')

      {

         /*while(CDC_Transmit_FS(Buf, *Len) == USBD_BUSY);*/

         USB_IN_BUF[uiUSB_In_CharCount] = Buf[i];

         bHaveEOL = 1;

         break;

      }

      else               // copy sent chars to real buffer

      {

         while(CDC_Transmit_FS(Buf, *Len) == USBD_BUSY);

         USB_IN_BUF[uiUSB_In_CharCount] = Buf[i];

         uiUSB_In_CharCount = uiUSB_In_CharCount + 1;

      }

   }

   if(bHaveEOL)

   {

      sprintf(USB_OUT_BUF, "Count = %i\r\n", 10);

      while(CDC_Transmit_FS((uint8_t *)USB_OUT_BUF, 10) == USBD_BUSY);

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

      USBD_CDC_ReceivePacket(&hUsbDeviceFS);

      memset(USB_OUT_BUF, 0, strlen(USB_OUT_BUF));

      strcpy(USB_OUT_BUF, USB_IN_BUF) ;

      while(CDC_Transmit_FS((uint8_t *)USB_OUT_BUF, uiUSB_In_CharCount) == USBD_BUSY);

      uiUSB_In_CharCount = 0;

      USB_IN_BUF[0] = '\0';

   }

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

 USBD_CDC_ReceivePacket(&hUsbDeviceFS);

 return (USBD_OK);

JoniS
Senior
September 6, 2019

Have you modified the other functions in that file? Mainly the one which sets linecoding parameters? I did have similar behaviour before implementing that.​

Besides that, I don't think you should transmit directly from the receive function since it's interrupt/callback context and should exit rather quickly so the processor can serve other interrupts, copy the data to other buffer and set a flag and exit, then do what needs to be done with the data somewhere else.