cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L475 USB host w/ memory stick doesn't work first insert

JGerb
Associate III

I'm using an STM32L475RC with USB host and using FAT FS to read a memory stick. This worked fine in previous hardware build, but since new hardware and update of CubeMX (now at MCU pkg 1.17.2) and updated USB host, an odd bug has appeared. When I run the init, the first attempt always fails. Init is only ever run when a USB stick is detected in the socket, to save power. There is a fair bit of other code involved, but this is the basics:

 

/* Init host Library, add supported class and start the library. */
MX_USB_HOST_Init();
 
PRINTDBG("Host stack init, waiting for USB stick",PRINT_NOTIME);
gTimeTick = 0;
while ((USBH_MSC_IsReady(&hUsbHostFS) == 0) && (gTimeTick < USB_STICK_TIMEOUT))
{
     /* USB Host Background task */
     USBH_Process(&hUsbHostFS);
}
//Not shown - do USB stuff if no timeout
//Shutdown
PRINTDBG("Shutting down USB stack",PRINT_TIMESTAMP);
//stop the USB
USBH_Stop(&hUsbHostFS);
/* De-Init */
USBH_DeInit(&hUsbHostFS);
 
On first insert after a micro reset/power up, it always fails, but on subsequent inserts it works fine. I can work around it by always calling init and then de-init, and then on second init it is fine. Anyone have any idea what is going on? I took a snapshop of the registers on the first and second run, with first run being the connect fail, and 2nd run the connect success. I would prefer not to have to use the workaround, and rather understand what is going on.
 
10 REPLIES 10

Thank you, those were all good suggestions. It's taken me a while to get time on this, and I've had the usual problems with inconsistent results under the debugger, so I've resorted to printf statements on a serial port to debug. I have found that the CSRST does get cleared AFTER the stack fails to initialise. However, it is being cleared by my added code below : 

//and to ensure it's fully released the pins, we perform a reset of the OTG
SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_OTGFSRST);
asm("nop");
asm("nop");
CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_OTGFSRST);

I also release the pins when the stack is not in use, so that I can use them to detect USB insertion without wasting power. This code is also placed before initialising the stack as well, so unfortunately that doesn't solve anything - before stack init doesn't make the first attempt work, but afterward does clear the bit, and does enable the second attempt to succeed - if I don't reset it, 2nd attempt fails too.

One other difference that I have found is that USBx_HOST->HCFG (as referenced in stm32l4xx_ll_usb.c, seems to be OTG_HCFG in the manual) is set to 0x200 when the connect fails, but is set to 0x204 when the connect succeeds. The difference appears to be the FSLSS bit, which, if set to 1, forces FS/LS only (I can only support FS, not HS). However, the code which writes to this appears to do so AFTER the core reset has failed on first connect, at which point the register appears to be read only. When the core reset succeeds on second connect, then register is read/write, and I can change it.

 

Here is the relevant code from stack, note that i have tried to set FSLSS to force FS operation, but as stated above, it is read only after a core reset fail.

HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
{
  HAL_StatusTypeDef ret = HAL_OK;
  uint32_t USBx_BASE = (uint32_t)USBx;
  uint32_t i;

  /* Restart the Phy Clock */
  USBx_PCGCCTL = 0U;
  /* Disable VBUS sensing */
  USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
  /* Disable Battery chargin detector */
  USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
  /* Set default Max speed support */
  USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
  /* Make sure the FIFOs are flushed. */
  if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
  {
    ret = HAL_ERROR;
  }
  if (USB_FlushRxFifo(USBx) != HAL_OK)
  {
    ret = HAL_ERROR;
  }

 Thanks for your help so far, I really appreciate the good suggestions. It may be that this is something I need to raise with ST, or perhaps just work around.