summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2021-11-30 21:53:28 +0700
committerGitHub <[email protected]>2021-11-30 21:53:28 +0700
commit6af58e3385837e8cbcee2fb4df42b62ad6772547 (patch)
tree363a1f6b1aeb526c53dfeab07a7fa08ba8fcec4b /src
parent9775e76910d569ec73b8dd946f3fa5fe5414acdb (diff)
parent3e3fe1e429aed7bd0000f49b1ef15f83eb815a19 (diff)
Merge pull request #1193 from rppicomidi/implement_usbh_replug_on_pico
Implement usbh replug on pico
Diffstat (limited to 'src')
-rw-r--r--src/host/usbh.c6
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c24
2 files changed, 25 insertions, 5 deletions
diff --git a/src/host/usbh.c b/src/host/usbh.c
index f74e7114c..b8439addc 100644
--- a/src/host/usbh.c
+++ b/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;
}
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 768cccc86..3e80dd872 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/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)