AnsweredAssumed Answered

stm32 USB OTG mass storage device enumeration failed

Question asked by r_spb on Nov 3, 2015

In my device based on stm32f107 connectivity line model i use http://www.st.com/web/en/catalog/tools/PF257882#this standart library. When i connect device to the PC with Windows 7, last one recognizes stm32f107 as "Unknown Device". This means that USB enumeration process has been failed and i can't understand "why?"

The early interrupt routine can be found in usb_dcd_int.c of standart library.

uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
  USB_OTG_GINTSTS_TypeDef  gintr_status;
  uint32_t retval = 0;
 
  if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
  {
    gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
    if (!gintr_status.d32) /* avoid spurious interrupt */
    {
      return 0;
    }
 
    if (gintr_status.b.outepintr)
    {
      retval |= DCD_HandleOutEP_ISR(pdev);
    }   
 
    if (gintr_status.b.inepint)
    {
      retval |= DCD_HandleInEP_ISR(pdev);
    }
 
    if (gintr_status.b.modemismatch)
    {
      USB_OTG_GINTSTS_TypeDef  gintsts;
 
      /* Clear interrupt */
      gintsts.d32 = 0;
      gintsts.b.modemismatch = 1;
      USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
    }
 
    if (gintr_status.b.wkupintr)
    {
      retval |= DCD_HandleResume_ISR(pdev);
    }
 
    if (gintr_status.b.usbsuspend)
    {
      retval |= DCD_HandleUSBSuspend_ISR(pdev);
    }
    if (gintr_status.b.sofintr)
    {
      retval |= DCD_HandleSof_ISR(pdev);
 
    }
 
    if (gintr_status.b.rxstsqlvl)
    {
      retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
 
    }
 
    if (gintr_status.b.usbreset)
    {
      retval |= DCD_HandleUsbReset_ISR(pdev);
 
    }
    if (gintr_status.b.enumdone)
    {
      retval |= DCD_HandleEnumDone_ISR(pdev);
    }
 
    if (gintr_status.b.incomplisoin)
    {
      retval |= DCD_IsoINIncomplete_ISR(pdev);
    }
 
    if (gintr_status.b.incomplisoout)
    {
      retval |= DCD_IsoOUTIncomplete_ISR(pdev);
    }   
#ifdef VBUS_SENSING_ENABLED
    if (gintr_status.b.sessreqintr)
    {
      retval |= DCD_SessionRequest_ISR(pdev);
    }
 
    if (gintr_status.b.otgintr)
    {
      retval |= DCD_OTG_ISR(pdev);
    }  
#endif   
  }
  return retval;
}

In debug mode i've found that switch process stops in DCD_HandleEnumDone_ISR.

static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
{
  USB_OTG_GINTSTS_TypeDef  gintsts;
  USB_OTG_GUSBCFG_TypeDef  gusbcfg;
 
  USB_OTG_EP0Activate(pdev);
 
  /* Set USB turn-around time based on device speed and PHY interface. */
  gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
 
  /* Full or High speed */
  if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
  {
    pdev->cfg.speed            = USB_OTG_SPEED_HIGH;
    pdev->cfg.mps              = USB_OTG_HS_MAX_PACKET_SIZE ;   
    gusbcfg.b.usbtrdtim = 9;
  }
  else
  {
    pdev->cfg.speed            = USB_OTG_SPEED_FULL;
    pdev->cfg.mps              = USB_OTG_FS_MAX_PACKET_SIZE ; 
    gusbcfg.b.usbtrdtim = 5;
  }
 
  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
 
  /* Clear interrupt */
  gintsts.d32 = 0;
  gintsts.b.enumdone = 1;
  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
  return 1;
}


Here host should give device address and check it's descriptors. And  after that there are no actions. What can be the reason of failing  enumeration process?

 

BTW i  have flash chip in device and i didn't mounted any filesystems on it.

UPDATE: After checking the signal processes with oscilloscope i've found that data flows only in one way. PC sends some commands, i think stm32 even reads this input data with

USB_OTG_READ_REG32() 

and then tries to send data with

USB_OTG_WRITE_REG32() 

but i see no signal on oscilloscope display.



Outcomes