diff --git a/src/device/dcd.h b/src/device/dcd.h index 143a2de34..487ddb3b6 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -106,6 +106,12 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num); // Wake up host void dcd_remote_wakeup(uint8_t rhport); +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index beeec7e1c..817af20e3 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -65,6 +65,20 @@ static inline bool tud_ready(void) // Remote wake up host, only if suspended and enabled by host bool tud_remote_wakeup(void); +static inline bool tud_disconnect(void) +{ + TU_VERIFY(dcd_disconnect); + dcd_disconnect(TUD_OPT_RHPORT); + return true; +} + +static inline bool tud_connect(void) +{ + TU_VERIFY(dcd_connect); + dcd_connect(TUD_OPT_RHPORT); + return true; +} + // Carry out Data and Status stage of control transfer // - If len = 0, it is equivalent to sending status only // - If len > wLength : it will be truncated diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 148995520..c3d2985d4 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -154,10 +154,23 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num) void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; - USB->DEVICE.CTRLB.bit.UPRSM = 1; } +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH; +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2ce288d6c..c0dddef83 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -237,6 +237,20 @@ void dcd_remote_wakeup(uint8_t rhport) // We may manually raise DCD_EVENT_RESUME event here } +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + NRF_USBD->USBPULLUP = 0; +} + +// connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + NRF_USBD->USBPULLUP = 1; +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 638b2f979..320b7237e 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -46,22 +46,22 @@ struct usbdcd_driver_s static struct usbdcd_driver_s usbdcd_driver; static struct usbdev_s *usbdev; -static int dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); -static void dcd_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); -static int dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, - FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen); -static void dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); -static void dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); -static void dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static int _dcd_bind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_unbind (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static int _dcd_setup (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, + FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen); +static void _dcd_disconnect (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_suspend (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); +static void _dcd_resume (FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); static const struct usbdevclass_driverops_s g_driverops = { - dcd_bind, /* bind */ - dcd_unbind, /* unbind */ - dcd_setup, /* setup */ - dcd_disconnect, /* disconnect */ - dcd_suspend, /* suspend */ - dcd_resume, /* resume */ + _dcd_bind, /* bind */ + _dcd_unbind, /* unbind */ + _dcd_setup, /* setup */ + _dcd_disconnect, /* disconnect */ + _dcd_suspend, /* suspend */ + _dcd_resume, /* resume */ }; static void usbdcd_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) @@ -86,7 +86,7 @@ static void usbdcd_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_r } } -static int dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; @@ -111,13 +111,13 @@ static int dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s return 0; } -static void dcd_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +static void _dcd_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev; } -static int dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, +static int _dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen) { (void) driver; @@ -130,7 +130,7 @@ static int dcd_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_ return 0; } -static void dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +static void _dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; @@ -138,7 +138,7 @@ static void dcd_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct u DEV_CONNECT(dev); } -static void dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +static void _dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev; @@ -146,7 +146,7 @@ static void dcd_suspend(FAR struct usbdevclass_driver_s *driver, FAR struct usbd dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } -static void dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) +static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) { (void) driver; (void) dev;