diff options
Diffstat (limited to 'app/usb.c')
-rw-r--r-- | app/usb.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/app/usb.c b/app/usb.c new file mode 100644 index 0000000..659a491 --- /dev/null +++ b/app/usb.c @@ -0,0 +1,133 @@ +#include "project.h" + +const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = ID_VENDOR, + .idProduct = ID_PRODUCT, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +const struct usb_interface ifaces[] = { + { + .num_altsetting = 1, + .altsetting = &keyboard_iface, + }, + { + .num_altsetting = 1, + .altsetting = &consumer_iface, + }, + { + .num_altsetting = 1, + .altsetting = &dfu_iface, + }, +}; + +const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 3, + .bConfigurationValue = 1, + .iConfiguration = 4, + .bmAttributes = 0xa0, + .bMaxPower = 0x31, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "James", + "Tim's keyboard", + "000001", + "composite", + "keyboard", + "media buttons", + "dfu device", +}; + + + +usbd_device *usbd_dev; + + +static int +usb_control_request (usbd_device * usbd_dev, struct usb_setup_data *req, + uint8_t ** buf, uint16_t * len, + void (**complete) (usbd_device * usbd_dev, + struct usb_setup_data * req)) +{ + + (void) complete; + (void) usbd_dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || (req->wValue != 0x2200)) + return 0; + + switch (req->wIndex) + { + case 0: + keyboard_get_descriptor (buf, len); + return 1; + case 1: + consumer_get_descriptor (buf, len); + return 1; + } + + *len = 0; + return 0; +} + + +void +usb_set_config (usbd_device * usbd_dev, uint16_t wValue) +{ + (void) wValue; + (void) usbd_dev; + + usbd_ep_setup (usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup (usbd_dev, 0x82, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + + usbd_register_control_callback (usbd_dev, + USB_REQ_TYPE_STANDARD | + USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + usb_control_request); + + usbd_register_control_callback (usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + dfu_control_request); +} + +/* Buffer to be used for control requests. */ +static uint8_t usbd_control_buffer[128]; + +void +usb_init (void) +{ + + usbd_dev = + usbd_init (&stm32f103_usb_driver, &dev, &config, usb_strings, 8, + usbd_control_buffer, sizeof (usbd_control_buffer)); + + usbd_register_set_config_callback (usbd_dev, usb_set_config); + +} + +void +usb_run (void) +{ + while (1) + usbd_poll (usbd_dev); +} |