AnsweredAssumed Answered

STM32L4 USB host BulkSendData problem

Question asked by krestan.michal.001 on Dec 26, 2017

I'd like to know the correct prodecure of using BulkSendData in the ST USB driver. I've a problem with STM32L4 with code generated from CubeMX for USB host. I've connected to the USB port LTE modem which has CDC-ACM and CDC-NCM. I'm able to communicate with the modem, but after some while BulkSendData fails sending the data. I've done some realtime debugging of the ST USB driver and it looks like at one point calling BulkSendData does not fire intterupt. When bulk out is working, then I see after calling BulkSendData always followed by interrupt of the particular pipe with USB_OTG_HCINT_XFRC and then followed by USB_OTG_HCINT_CHH, however at one point none of those interrupts are called. The other pipes i.e. BulkRecieveData seems working normaly. This abnormality comes always after sending some few packets over the pipe regardless of it's total size. I've tried to look at the driver's code, but I need to explain how the host scheduler is working. What for example happens when connected periphelar sends NAK on my call BulkSendData? What is the correct prodecure then to retransmitt the data which were NAKed? Is it required to find of FIFO for USB OTG has sufficient space before sending bulk data? In the driver is checking of FIFO available in the function USB_USB_HC_StartXfer, however ST driver in stm32lxx_hal_hcd.c does not handle any interrupts for NPTXFEM so I assume this part of the code is missing in the IRQ handler of the ST driver.

 

USB_WritePacket - according errata, is it required to block all interrupts during FIFO write? I've modifed the code like this:

HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(USBx);
  UNUSED(dma);
  __disable_irq();//disable all IRQ - as required from ERRATA
  uint32_t count32b= 0 , index= 0;
  count32b =  (len + 3) / 4;
  for (index = 0; index < count32b; index++, src += 4)
  {
    USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
  }
  __enable_irq();
  return HAL_OK;
}

Outcomes