From aac65d8560a59105cc02132860b77cfe61835b2e Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 30 Jan 2011 17:04:56 +1300 Subject: Abstracted USB driver interface to to allow driver selection. --- lib/usb/usb.c | 37 ++++++++++++++++++++++++++++++++++++- lib/usb/usb_f103.c | 42 +++++++++++++++++++++++++++++++++--------- lib/usb/usb_private.h | 20 +++++++++++++++++--- 3 files changed, 86 insertions(+), 13 deletions(-) (limited to 'lib/usb') diff --git a/lib/usb/usb.c b/lib/usb/usb.c index c88de55..f24f2f9 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -42,9 +42,11 @@ u8 usbd_control_buffer[128] __attribute__((weak)); * @param strings TODO * @return Zero on success (currently cannot fail). */ -int usbd_init(const struct usb_device_descriptor *dev, +int usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, const struct usb_config_descriptor *conf, const char **strings) { + _usbd_device.driver = driver; _usbd_device.desc = dev; _usbd_device.config = conf; _usbd_device.strings = strings; @@ -93,3 +95,36 @@ void _usbd_reset(void) if (_usbd_device.user_callback_reset) _usbd_device.user_callback_reset(); } + +/* Functions to wrap the low-level driver */ +void usbd_poll(void) +{ + _usbd_device.driver->poll(); +} + +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); +} + +u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len) +{ + return _usbd_device.driver->ep_write_packet(addr, buf, len); +} + +u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len) +{ + return _usbd_device.driver->ep_read_packet(addr, buf, len); +} + +void usbd_ep_stall_set(u8 addr, u8 stall) +{ + _usbd_device.driver->ep_stall_set(addr, stall); +} + +u8 usbd_ep_stall_get(u8 addr) +{ + return _usbd_device.driver->ep_stall_get(addr); +} + diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c index 9b995e4..a587978 100644 --- a/lib/usb/usb_f103.c +++ b/lib/usb/usb_f103.c @@ -23,8 +23,31 @@ #include #include "usb_private.h" +static void stm32f103_usbd_init(void); +static void stm32f103_set_address(u8 addr); +static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, + void (*callback) (u8 ep)); +static void stm32f103_endpoints_reset(void); +static void stm32f103_ep_stall_set(u8 addr, u8 stall); +static u8 stm32f103_ep_stall_get(u8 addr); +static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len); +static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len); +static void stm32f103_poll(void); + +const struct _usbd_driver stm32f103_usb_driver = { + ._init = stm32f103_usbd_init, + ._set_address = stm32f103_set_address, + .ep_setup = stm32f103_ep_setup, + ._ep_reset = stm32f103_endpoints_reset, + .ep_stall_set = stm32f103_ep_stall_set, + .ep_stall_get = stm32f103_ep_stall_get, + .ep_write_packet = stm32f103_ep_write_packet, + .ep_read_packet = stm32f103_ep_read_packet, + .poll = stm32f103_poll, +}; + /** Initialize the USB device controller hardware of the STM32. */ -void _usbd_hw_init(void) +static void stm32f103_usbd_init(void) { SET_REG(USB_CNTR_REG, 0); SET_REG(USB_BTABLE_REG, 0); @@ -35,7 +58,7 @@ void _usbd_hw_init(void) USB_CNTR_SUSPM | USB_CNTR_WKUPM); } -void _usbd_hw_set_address(u8 addr) +static void stm32f103_set_address(u8 addr) { /* Set device address and enable. */ SET_REG(USB_DADDR_REG, (addr & USB_DADDR_ADDR) | USB_DADDR_ENABLE); @@ -60,7 +83,8 @@ static void usb_set_ep_rx_bufsize(u8 ep, u32 size) } } -void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback) (u8 ep)) +static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, + void (*callback) (u8 ep)) { /* Translate USB standard type codes to STM32. */ const u16 typelookup[] = { @@ -102,7 +126,7 @@ void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback) (u8 ep)) } } -void _usbd_hw_endpoints_reset(void) +static void stm32f103_endpoints_reset(void) { int i; @@ -114,7 +138,7 @@ void _usbd_hw_endpoints_reset(void) _usbd_device.pm_top = 0x40 + (2 * _usbd_device.desc->bMaxPacketSize0); } -void usbd_ep_stall_set(u8 addr, u8 stall) +static void stm32f103_ep_stall_set(u8 addr, u8 stall) { if (addr == 0) USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL : @@ -139,7 +163,7 @@ void usbd_ep_stall_set(u8 addr, u8 stall) } } -u8 usbd_ep_stall_get(u8 addr) +static u8 stm32f103_ep_stall_get(u8 addr) { if (addr & 0x80) { if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) == @@ -169,7 +193,7 @@ static void usb_copy_to_pm(volatile void *vPM, const void *buf, u16 len) *PM = *lbuf; } -u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len) +static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len) { addr &= 0x7F; @@ -203,7 +227,7 @@ static void usb_copy_from_pm(void *buf, const volatile void *vPM, u16 len) *(u8 *) lbuf = *(u8 *) PM; } -u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len) +static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) { if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == USB_EP_RX_STAT_VALID) return 0; @@ -217,7 +241,7 @@ u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len) return len; } -void usbd_poll(void) +static void stm32f103_poll(void) { u16 istr = *USB_ISTR_REG; diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index 6303285..bef225d 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -53,6 +53,8 @@ extern struct _usbd_device { /* User callback function for some standard USB function hooks */ void (*user_callback_set_config)(u16 wValue); + + struct _usbd_driver *driver; } _usbd_device; enum _usbd_transaction { @@ -70,8 +72,20 @@ int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len); void _usbd_reset(void); /* Functions provided by the hardware abstraction. */ -void _usbd_hw_init(void); -void _usbd_hw_set_address(u8 addr); -void _usbd_hw_endpoints_reset(void); +struct _usbd_driver { + void (*_init)(void); + void (*_set_address)(u8 addr); + void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep)); + void (*_ep_reset)(void); + void (*ep_stall_set)(u8 addr, u8 stall); + u8 (*ep_stall_get)(u8 addr); + u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len); + u16 (*ep_read_packet)(u8 addr, void *buf, u16 len); + void (*poll)(void); +}; + +#define _usbd_hw_init() _usbd_device.driver->_init() +#define _usbd_hw_set_address(addr) _usbd_device.driver->_set_address(addr) +#define _usbd_hw_endpoints_reset() _usbd_device.driver->_ep_reset() #endif -- cgit v1.2.3