aboutsummaryrefslogtreecommitdiff
path: root/lib/usb
diff options
context:
space:
mode:
authorGareth McMullin2011-01-30 17:04:56 +1300
committerGareth McMullin2011-01-30 17:04:56 +1300
commitaac65d8560a59105cc02132860b77cfe61835b2e (patch)
treeb65035dbe53137c8a7c8de60f6d198f1248155b6 /lib/usb
parentc11cdaf2a70a1fadbcf2f942a29b75040b0a0a75 (diff)
Abstracted USB driver interface to to allow driver selection.
Diffstat (limited to 'lib/usb')
-rw-r--r--lib/usb/usb.c37
-rw-r--r--lib/usb/usb_f103.c42
-rw-r--r--lib/usb/usb_private.h20
3 files changed, 86 insertions, 13 deletions
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 <libopencm3/usb/usbd.h>
#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