title: Detect STM32L442 USB disconnection
body: <p>I'm developing a project that uses STM32L442KC and I can't detect when USB device mode is disconnected (USB cable unplugged).</p>
  
  <p>What can I do to detect USB disconnection? Is there some interruption? Or do I need check some flag?</p>
  
  <hr>
  
  <p><strong>Update:</strong></p>
  
  <p>Below is the IRQ Handler generated by STM32CubeMX. It doesn't have the <strong>HAL_PCD_DisconnectCallback</strong> callback and <strong>HAL_PCD_SuspendCallback</strong> isn't called when the cable is unplugged.</p>
  
  <pre class="lang-c prettyprint-override"><code>void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  {
    uint32_t wInterrupt_Mask = 0;
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
    {
      /* servicing of the endpoint correct transfer interrupt */
      /* clear of the CTR flag into the sub */
      PCD_EP_ISR_Handler(hpcd);
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
    {
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
      HAL_PCD_ResetCallback(hpcd);
      HAL_PCD_SetAddress(hpcd, 0);
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
    {
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);    
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
    {
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); 
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
    {
  
      hpcd-&gt;Instance-&gt;CNTR &amp;= ~(USB_CNTR_LPMODE);
  
      /*set wInterrupt_Mask global variable*/
      wInterrupt_Mask = USB_CNTR_CTRM  | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
        | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
  
      /*Set interrupt mask*/
      hpcd-&gt;Instance-&gt;CNTR = wInterrupt_Mask;
  
      /* enable L1REQ interrupt */ 
      if (hpcd-&gt;Init.lpm_enable ==1)
      {
        wInterrupt_Mask |= USB_CNTR_L1REQM;
  
        /* Enable LPM support and enable ACK answer to LPM request*/
        USB_TypeDef *USBx = hpcd-&gt;Instance;
        hpcd-&gt;lpm_active = ENABLE;
        hpcd-&gt;LPM_State = LPM_L0;
  
        USBx-&gt;LPMCSR |= (USB_LPMCSR_LMPEN);
        USBx-&gt;LPMCSR |= (USB_LPMCSR_LPMACK);
      } 
  
      if(hpcd-&gt;LPM_State == LPM_L1)
      {
        hpcd-&gt;LPM_State = LPM_L0;
        HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
      }
  
      HAL_PCD_ResumeCallback(hpcd);
  
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);     
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
    {    
      /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);  
  
      /* Force low-power mode in the macrocell */
      hpcd-&gt;Instance-&gt;CNTR |= USB_CNTR_FSUSP;
      hpcd-&gt;Instance-&gt;CNTR |= USB_CNTR_LPMODE;
  
      if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0)
      {
        HAL_PCD_SuspendCallback(hpcd);
      }
    }
  
    /* Handle LPM Interrupt */ 
    if(__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
    {
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);      
      if( hpcd-&gt;LPM_State == LPM_L0)
      {   
        /* Force suspend and low-power mode before going to L1 state*/
        hpcd-&gt;Instance-&gt;CNTR |= USB_CNTR_LPMODE;
        hpcd-&gt;Instance-&gt;CNTR |= USB_CNTR_FSUSP;
  
        hpcd-&gt;LPM_State = LPM_L1;
        hpcd-&gt;BESL = (hpcd-&gt;Instance-&gt;LPMCSR &amp; USB_LPMCSR_BESL) &gt;&gt;2 ;  
        HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
      }
      else
      {
        HAL_PCD_SuspendCallback(hpcd);
      }
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
    {
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); 
      HAL_PCD_SOFCallback(hpcd);
    }
  
    if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
    {
      /* clear ESOF flag in ISTR */
      __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); 
    }
  }
  </code></pre>