From 7da1967056c1cdba2b37c57015451224605a8a65 Mon Sep 17 00:00:00 2001 From: Mike Smith Date: Mon, 2 Jan 2012 21:06:48 -0800 Subject: [PATCH] Add an interface for soft disconnection, and hook it up in the F107 driver. --- include/libopencm3/usb/usbd.h | 1 + lib/usb/usb.c | 7 +++++++ lib/usb/usb_f107.c | 11 +++++++++++ lib/usb/usb_private.h | 1 + 4 files changed, 20 insertions(+) diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index 391c80b7..c39ba014 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -56,6 +56,7 @@ extern void usbd_register_set_config_callback(void (*callback)(u16 wValue)); /* Functions to be provided by the hardware abstraction layer */ extern void usbd_poll(void); +extern void usbd_disconnect(bool disconnected); extern void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep)); diff --git a/lib/usb/usb.c b/lib/usb/usb.c index e15f5b2a..abb870ee 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -108,6 +108,13 @@ void usbd_poll(void) _usbd_device.driver->poll(); } +void usbd_disconnect(bool disconnected) +{ + /* not all drivers support disconnection */ + if (_usbd_device.driver->disconnect) + _usbd_device.driver->disconnect(disconnected); +} + void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep)) { _usbd_device.driver->ep_setup(addr, type, max_size, callback); diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index 0797cba0..1cd3eecd 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -42,6 +42,7 @@ static void stm32f107_ep_nak_set(u8 addr, u8 nak); static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len); static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len); static void stm32f107_poll(void); +static void stm32f107_disconnect(bool disconnected); /* * We keep a backup copy of the out endpoint size registers to restore them @@ -60,6 +61,7 @@ const struct _usbd_driver stm32f107_usb_driver = { .ep_write_packet = stm32f107_ep_write_packet, .ep_read_packet = stm32f107_ep_read_packet, .poll = stm32f107_poll, + .disconnect = stm32f107_disconnect, }; /** Initialize the USB device controller hardware of the STM32. */ @@ -376,3 +378,12 @@ static void stm32f107_poll(void) OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF; } } + +static void stm32f107_disconnect(bool disconnected) +{ + if (disconnected) { + OTG_FS_DCTL |= OTG_FS_DCTL_SDIS; + } else { + OTG_FS_DCTL &= ~OTG_FS_DCTL_SDIS; + } +} \ No newline at end of file diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index 39716b52..5b367fb3 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -84,6 +84,7 @@ struct _usbd_driver { u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len); u16 (*ep_read_packet)(u8 addr, void *buf, u16 len); void (*poll)(void); + void (*disconnect)(bool disconnected); }; #define _usbd_hw_init() _usbd_device.driver->init()