Abstracted USB driver interface to to allow driver selection.

This commit is contained in:
Gareth McMullin 2011-01-30 17:04:56 +13:00
parent c11cdaf2a7
commit aac65d8560
10 changed files with 97 additions and 20 deletions

View File

@ -260,7 +260,7 @@ int main(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(hid_set_config);
/* delay some seconds to show that pull-up switch works */

View File

@ -234,7 +234,7 @@ int main(void)
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(cdcacm_set_config);
gpio_set(GPIOA, GPIO15);

View File

@ -255,7 +255,7 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,

View File

@ -247,7 +247,7 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(hid_set_config);
gpio_set(GPIOA, GPIO15);

View File

@ -235,7 +235,7 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(cdcacm_set_config);
for (i = 0; i < 0x800000; i++)

View File

@ -248,7 +248,7 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
usbd_init(&dev, &config, usb_strings);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(hid_set_config);
{int i; for (i=0;i<0x80000;i++);}

View File

@ -22,13 +22,17 @@
#include <libopencm3/usb/usbstd.h>
typedef struct _usbd_driver usbd_driver;
extern const usbd_driver stm32f103_usb_driver;
/* Static buffer for control transactions:
* This is defined as weak in the library, applicaiton
* may provide if a larger buffer is requred. */
extern u8 usbd_control_buffer[];
/* <usb.c> */
extern int usbd_init(const struct usb_device_descriptor *dev,
extern int usbd_init(const usbd_driver *driver,
const struct usb_device_descriptor *dev,
const struct usb_config_descriptor *conf,
const char **strings);
extern void usbd_set_control_buffer_size(u16 size);

View File

@ -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);
}

View File

@ -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;

View File

@ -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