Răsfoiți Sursa

Merge pull request #1193 from rppicomidi/implement_usbh_replug_on_pico

Implement usbh replug on pico
Ha Thach 4 ani în urmă
părinte
comite
6af58e3385
2 a modificat fișierele cu 25 adăugiri și 5 ștergeri
  1. 4 2
      src/host/usbh.c
  2. 21 3
      src/portable/raspberrypi/rp2040/hcd_rp2040.c

+ 4 - 2
src/host/usbh.c

@@ -541,10 +541,12 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port
         usbh_class_drivers[drv_id].close(dev_addr);
       }
 
+      hcd_device_close(rhport, dev_addr);
+
+      // release all endpoints associated with the device
       memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping
       memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping
-
-      hcd_device_close(rhport, dev_addr);
+      tu_memclr(dev->ep_status, sizeof(dev->ep_status));
 
       dev->state = TUSB_DEVICE_STATE_UNPLUG;
     }

+ 21 - 3
src/portable/raspberrypi/rp2040/hcd_rp2040.c

@@ -412,10 +412,28 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
 // Close all opened endpoint belong to this device
 void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
 {
-    (void) rhport;
-    (void) dev_addr;
+  pico_trace("hcd_device_close %d\n", dev_addr);
+  (void) rhport;
+
+  if (dev_addr == 0) return;
+
+  for (size_t i = 1; i < TU_ARRAY_SIZE(ep_pool); i++)
+  {
+    hw_endpoint_t* ep = &ep_pool[i];
 
-    pico_trace("hcd_device_close %d\n", dev_addr);
+    if (ep->dev_addr == dev_addr && ep->configured)
+    {
+      // in case it is an interrupt endpoint, disable it
+      usb_hw_clear->int_ep_ctrl = (1 << (ep->interrupt_num + 1));
+      usb_hw->int_ep_addr_ctrl[ep->interrupt_num] = 0;
+
+      // unconfigure the endpoint
+      ep->configured = false;
+      *ep->endpoint_control = 0;
+      *ep->buffer_control = 0;
+      hw_endpoint_reset_transfer(ep);
+    }
+  }
 }
 
 uint32_t hcd_frame_number(uint8_t rhport)