Skip to content

USB does not disconnect on USBDevice.detach() #171

@matthijskooijman

Description

@matthijskooijman

It turns out that stopping the USB peripheral does not automatically
reset the D+ pullup, so stopping USB (e.g. through USBDevice.detach())
would let the pullup enabled, making the USB host think the board was
still connected (but any subsequent communication would fail).
Additionally, this would use around 300μA of current.

I've found this is a bug in the USB HAL, which is fixed by v1.11.3: STMicroelectronics/STM32CubeL0@8b26821

I tried backporting the single change that seems to fix this, which works as expected (the diff is slightly different from the linked upstream commit, probably because this core is using an even older HAL version, I suspect):

--- a/system/STM32L0xx/Source/USB/HAL/Src/stm32l0xx_hal_pcd.c
+++ b/system/STM32L0xx/Source/USB/HAL/Src/stm32l0xx_hal_pcd.c
@@ -240,7 +240,7 @@ HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
   hpcd->State = HAL_PCD_STATE_BUSY;
 
   /* Stop Device */
-  (void)HAL_PCD_Stop(hpcd);
+  (void)USB_StopDevice(hpcd->Instance);
 
 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
   if (hpcd->MspDeInitCallback == NULL)
@@ -998,7 +998,7 @@ HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
   __HAL_LOCK(hpcd);
   __HAL_PCD_DISABLE(hpcd);
 
-  (void)USB_StopDevice(hpcd->Instance);
+  (void)USB_DevDisconnect(hpcd->Instance);
 
   __HAL_UNLOCK(hpcd);
 

However, it's probably better to just update the HAL completely. Since I'm not sure what the procedure for that is, I'll leave it at this issue rather than a full PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions