diff options
author | root <root@lab2.panaceas.james.local> | 2014-11-02 10:57:51 +0000 |
---|---|---|
committer | root <root@lab2.panaceas.james.local> | 2014-11-02 10:57:51 +0000 |
commit | 38003ce02f2492d1f4e24ec03167db0725cd69ce (patch) | |
tree | 21875b447e28fdd418581f938fea8160349460d4 | |
parent | 1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0 (diff) | |
download | stm32_usb_kvm-38003ce02f2492d1f4e24ec03167db0725cd69ce.tar.gz stm32_usb_kvm-38003ce02f2492d1f4e24ec03167db0725cd69ce.tar.bz2 stm32_usb_kvm-38003ce02f2492d1f4e24ec03167db0725cd69ce.zip |
fish
-rw-r--r-- | Makefile.rules | 16 | ||||
-rw-r--r-- | src/Makefile | 22 | ||||
-rw-r--r-- | src/dfu.c | 58 | ||||
-rw-r--r-- | src/hid.c | 126 | ||||
-rw-r--r-- | src/kvm.ld (renamed from stm32-h103.ld) | 0 | ||||
-rw-r--r-- | src/main.c | 39 | ||||
-rw-r--r-- | src/project.h | 17 | ||||
-rw-r--r-- | src/prototypes.h | 21 | ||||
-rw-r--r-- | src/usb.c | 94 | ||||
-rw-r--r-- | src/usbhid.c | 317 |
10 files changed, 384 insertions, 326 deletions
diff --git a/Makefile.rules b/Makefile.rules index 5d9d998..685caad 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -1,4 +1,4 @@ -## +# ## This file is part of the libopencm3 project. ## ## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> @@ -49,7 +49,7 @@ STYLECHECKFILES := $(shell find . -name '*.[ch]') LDSCRIPT ?= $(BINARY).ld -OBJS += $(BINARY).o +#OBJS += $(BINARY).o ifeq ($(strip $(OPENCM3_DIR)),) @@ -79,7 +79,7 @@ SCRIPT_DIR = $(OPENCM3_DIR)/scripts # C flags CFLAGS += -Os -g -CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration +CFLAGS += -Wextra -Wimplicit-function-declaration CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes CFLAGS += -fno-common -ffunction-sections -fdata-sections @@ -95,7 +95,11 @@ CXXFLAGS += -fno-common -ffunction-sections -fdata-sections CPPFLAGS += -MD CPPFLAGS += -Wall -Wundef -CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) + +INCLUDES = -I$(INCLUDE_DIR) +DEFINES = $(DEFS) + +CPPFLAGS += $(INCLUDES) $(DEFINES) ############################################################################### # Linker flags @@ -153,6 +157,10 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list +fish: + echo %.elf %.map: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + echo $(BINARY).elf + %.elf %.map: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a @#printf " LD $(*).elf\n" $(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(*).elf diff --git a/src/Makefile b/src/Makefile index c833404..5927739 100644 --- a/src/Makefile +++ b/src/Makefile @@ -17,15 +17,27 @@ ## along with this library. If not, see <http://www.gnu.org/licenses/>. ## +CPROTO=cproto +PROG=kvm + V=1 -default: usbhid.hex +default: ${PROG}.elf +CSRCS=dfu.c hid.c main.c usb.c -BINARY = usbhid -LDSCRIPT = ../stm32-h103.ld +BINARY = ${PROG} +OBJS = ${CSRCS:%.c=%.o} -include ../Makefile.include +program: ${PROG}.elf + echo halt | nc -t localhost 4444 + echo flash write_image erase ${PWD}/$< | nc -t localhost 4444 + echo reset run | nc -t localhost 4444 -program: usbhid.hex +protos: + echo -n > prototypes.h + ${CPROTO} $(INCLUDES) $(DEFINES) -e -v ${CSRCS} > prototypes.h.tmp + mv -f prototypes.h.tmp prototypes.h + +include ../Makefile.include diff --git a/src/dfu.c b/src/dfu.c new file mode 100644 index 0000000..4e10843 --- /dev/null +++ b/src/dfu.c @@ -0,0 +1,58 @@ +#include "project.h" + +#ifdef INCLUDE_DFU_INTERFACE + +const struct usb_dfu_descriptor dfu_function = { + .bLength = sizeof(struct usb_dfu_descriptor), + .bDescriptorType = DFU_FUNCTIONAL, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, + .wDetachTimeout = 255, + .wTransferSize = 1024, + .bcdDFUVersion = 0x011A, +}; + +const struct usb_interface_descriptor dfu_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = 0xFE, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 1, + .iInterface = 0, + + .extra = &dfu_function, + .extralen = sizeof(dfu_function), +}; + + +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) +{ + (void)req; + (void)usbd_dev; + + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO10); + gpio_set(GPIOA, GPIO10); + scb_reset_core(); +} + +int dfu_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)buf; + (void)len; + (void)usbd_dev; + + if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) + return 0; /* Only accept class request. */ + + *complete = dfu_detach_complete; + + return 1; +} +#endif + + diff --git a/src/hid.c b/src/hid.c new file mode 100644 index 0000000..8feb1cb --- /dev/null +++ b/src/hid.c @@ -0,0 +1,126 @@ +#include "project.h" + +static const uint8_t hid_report_descriptor[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x09, 0x01, /* USAGE (Pointer) */ + 0xa1, 0x00, /* COLLECTION (Physical) */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ + 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x05, /* REPORT_SIZE (5) */ + 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x30, /* USAGE (X) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x09, 0x38, /* USAGE (Wheel) */ + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ + 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ + 0xc0, /* END_COLLECTION */ + 0x09, 0x3c, /* USAGE (Motion Wakeup) */ + 0x05, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */ + 0x09, 0x01, /* USAGE (Vendor Usage 1) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0xb1, 0x22, /* FEATURE (Data,Var,Abs,NPrf) */ + 0x75, 0x06, /* REPORT_SIZE (6) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0xb1, 0x01, /* FEATURE (Cnst,Ary,Abs) */ + 0xc0 /* END_COLLECTION */ +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0100, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + }, +}; + +const struct usb_endpoint_descriptor hid_endpoint = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x81, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 4, + .bInterval = 0x20, +}; + +const struct usb_interface_descriptor hid_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 1, /* boot */ + .bInterfaceProtocol = 2, /* mouse */ + .iInterface = 0, + + .endpoint = &hid_endpoint, + + .extra = &hid_function, + .extralen = sizeof(hid_function), +}; + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; + +int hid_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; + + /* Handle the HID report descriptor. */ + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + + return 1; +} + +void hid_test(void) +{ + static int x = 0; + static int dir = 1; + uint8_t buf[4] = {0, 0, 0, 0}; + + buf[1] = dir; + x += dir; + if (x > 30) + dir = -dir; + if (x < -30) + dir = -dir; + + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); +} + diff --git a/stm32-h103.ld b/src/kvm.ld index e15beca..e15beca 100644 --- a/stm32-h103.ld +++ b/src/kvm.ld diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..655a0bc --- /dev/null +++ b/src/main.c @@ -0,0 +1,39 @@ +#include "project.h" + +void sys_tick_handler(void) +{ + hid_test(); +} + +int main(void) +{ + int i; + + + rcc_clock_setup_in_hsi_out_48mhz(); + + rcc_periph_clock_enable(RCC_GPIOC); + + + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); + /* SysTick interrupt every N clock pulses: set reload to N-1 */ + systick_set_reload(99999); + systick_interrupt_enable(); + systick_counter_enable(); + + gpio_set(GPIOC, GPIO11); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); + + + usb_init(); + for (i = 0; i < 0x80000; i++) + __asm__("nop"); + + gpio_clear(GPIOC, GPIO11); + + usb_run(); + + return 0; +} + diff --git a/src/project.h b/src/project.h new file mode 100644 index 0000000..de86ece --- /dev/null +++ b/src/project.h @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/usb/usbd.h> +#include <libopencm3/usb/hid.h> + +#define INCLUDE_DFU_INTERFACE + + +#ifdef INCLUDE_DFU_INTERFACE +#include <libopencm3/cm3/scb.h> +#include <libopencm3/usb/dfu.h> +#endif + + +#include "prototypes.h" diff --git a/src/prototypes.h b/src/prototypes.h new file mode 100644 index 0000000..79c56ec --- /dev/null +++ b/src/prototypes.h @@ -0,0 +1,21 @@ +/* dfu.c */ +extern const struct usb_dfu_descriptor dfu_function; +extern const struct usb_interface_descriptor dfu_iface; +extern int dfu_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)); +/* hid.c */ +extern const struct usb_endpoint_descriptor hid_endpoint; +extern const struct usb_interface_descriptor hid_iface; +extern uint8_t usbd_control_buffer[128]; +extern int hid_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)); +extern void hid_test(void); +/* main.c */ +extern void sys_tick_handler(void); +extern int main(void); +/* usb.c */ +extern const struct usb_device_descriptor dev; +extern const struct usb_interface ifaces[]; +extern const struct usb_config_descriptor config; +extern usbd_device *usbd_dev; +extern void usb_set_config(usbd_device *usbd_dev, uint16_t wValue); +extern void usb_init(void); +extern void usb_run(void); diff --git a/src/usb.c b/src/usb.c new file mode 100644 index 0000000..fdefd75 --- /dev/null +++ b/src/usb.c @@ -0,0 +1,94 @@ +#include "project.h" + +/* Define this to include the DFU APP interface. */ +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 = 0x0483, + .idProduct = 0x5710, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = &hid_iface, +#ifdef INCLUDE_DFU_INTERFACE +}, { + .num_altsetting = 1, + .altsetting = &dfu_iface, +#endif +}}; + +const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, +#ifdef INCLUDE_DFU_INTERFACE + .bNumInterfaces = 2, +#else + .bNumInterfaces = 1, +#endif + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xC0, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "Cabbages are good for you", + "fish", + "soup", +}; + + + +usbd_device *usbd_dev; + +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_register_control_callback( + usbd_dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request); +#ifdef INCLUDE_DFU_INTERFACE + 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); +#endif +} + +void usb_init(void) +{ + + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 3, 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); +} + + diff --git a/src/usbhid.c b/src/usbhid.c deleted file mode 100644 index d0c0aa9..0000000 --- a/src/usbhid.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <libopencm3/stm32/rcc.h> -#include <libopencm3/stm32/gpio.h> -#include <libopencm3/cm3/systick.h> -#include <libopencm3/usb/usbd.h> -#include <libopencm3/usb/hid.h> - -/* Define this to include the DFU APP interface. */ -#define INCLUDE_DFU_INTERFACE - -#ifdef INCLUDE_DFU_INTERFACE -#include <libopencm3/cm3/scb.h> -#include <libopencm3/usb/dfu.h> -#endif - -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 = 0x0483, - .idProduct = 0x5710, - .bcdDevice = 0x0200, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, -}; - -static const uint8_t hid_report_descriptor[] = { - 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ - 0x09, 0x02, /* USAGE (Mouse) */ - 0xa1, 0x01, /* COLLECTION (Application) */ - 0x09, 0x01, /* USAGE (Pointer) */ - 0xa1, 0x00, /* COLLECTION (Physical) */ - 0x05, 0x09, /* USAGE_PAGE (Button) */ - 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ - 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */ - 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ - 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ - 0x95, 0x03, /* REPORT_COUNT (3) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x81, 0x02, /* INPUT (Data,Var,Abs) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0x75, 0x05, /* REPORT_SIZE (5) */ - 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ - 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ - 0x09, 0x30, /* USAGE (X) */ - 0x09, 0x31, /* USAGE (Y) */ - 0x09, 0x38, /* USAGE (Wheel) */ - 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ - 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ - 0x75, 0x08, /* REPORT_SIZE (8) */ - 0x95, 0x03, /* REPORT_COUNT (3) */ - 0x81, 0x06, /* INPUT (Data,Var,Rel) */ - 0xc0, /* END_COLLECTION */ - 0x09, 0x3c, /* USAGE (Motion Wakeup) */ - 0x05, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */ - 0x09, 0x01, /* USAGE (Vendor Usage 1) */ - 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ - 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ - 0x75, 0x01, /* REPORT_SIZE (1) */ - 0x95, 0x02, /* REPORT_COUNT (2) */ - 0xb1, 0x22, /* FEATURE (Data,Var,Abs,NPrf) */ - 0x75, 0x06, /* REPORT_SIZE (6) */ - 0x95, 0x01, /* REPORT_COUNT (1) */ - 0xb1, 0x01, /* FEATURE (Cnst,Ary,Abs) */ - 0xc0 /* END_COLLECTION */ -}; - -static const struct { - struct usb_hid_descriptor hid_descriptor; - struct { - uint8_t bReportDescriptorType; - uint16_t wDescriptorLength; - } __attribute__((packed)) hid_report; -} __attribute__((packed)) hid_function = { - .hid_descriptor = { - .bLength = sizeof(hid_function), - .bDescriptorType = USB_DT_HID, - .bcdHID = 0x0100, - .bCountryCode = 0, - .bNumDescriptors = 1, - }, - .hid_report = { - .bReportDescriptorType = USB_DT_REPORT, - .wDescriptorLength = sizeof(hid_report_descriptor), - }, -}; - -const struct usb_endpoint_descriptor hid_endpoint = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x81, - .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, - .wMaxPacketSize = 4, - .bInterval = 0x20, -}; - -const struct usb_interface_descriptor hid_iface = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 1, /* boot */ - .bInterfaceProtocol = 2, /* mouse */ - .iInterface = 0, - - .endpoint = &hid_endpoint, - - .extra = &hid_function, - .extralen = sizeof(hid_function), -}; - -#ifdef INCLUDE_DFU_INTERFACE -const struct usb_dfu_descriptor dfu_function = { - .bLength = sizeof(struct usb_dfu_descriptor), - .bDescriptorType = DFU_FUNCTIONAL, - .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, - .wDetachTimeout = 255, - .wTransferSize = 1024, - .bcdDFUVersion = 0x011A, -}; - -const struct usb_interface_descriptor dfu_iface = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = 0xFE, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, - .iInterface = 0, - - .extra = &dfu_function, - .extralen = sizeof(dfu_function), -}; -#endif - -const struct usb_interface ifaces[] = {{ - .num_altsetting = 1, - .altsetting = &hid_iface, -#ifdef INCLUDE_DFU_INTERFACE -}, { - .num_altsetting = 1, - .altsetting = &dfu_iface, -#endif -}}; - -const struct usb_config_descriptor config = { - .bLength = USB_DT_CONFIGURATION_SIZE, - .bDescriptorType = USB_DT_CONFIGURATION, - .wTotalLength = 0, -#ifdef INCLUDE_DFU_INTERFACE - .bNumInterfaces = 2, -#else - .bNumInterfaces = 1, -#endif - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0xC0, - .bMaxPower = 0x32, - - .interface = ifaces, -}; - -static const char *usb_strings[] = { - "Cabbages are good for you", - "fish", - "soup", -}; - -/* Buffer to be used for control requests. */ -uint8_t usbd_control_buffer[128]; - -static int hid_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; - - /* Handle the HID report descriptor. */ - *buf = (uint8_t *)hid_report_descriptor; - *len = sizeof(hid_report_descriptor); - - return 1; -} - -#ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) -{ - (void)req; - (void)usbd_dev; - - gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO10); - gpio_set(GPIOA, GPIO10); - scb_reset_core(); -} - -static int dfu_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)buf; - (void)len; - (void)usbd_dev; - - if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) - return 0; /* Only accept class request. */ - - *complete = dfu_detach_complete; - - return 1; -} -#endif - -static void hid_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_register_control_callback( - usbd_dev, - USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - hid_control_request); -#ifdef INCLUDE_DFU_INTERFACE - 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); -#endif - - systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); - /* SysTick interrupt every N clock pulses: set reload to N-1 */ - systick_set_reload(99999); - systick_interrupt_enable(); - systick_counter_enable(); -} - -int main(void) -{ - int i; - - usbd_device *usbd_dev; - - rcc_clock_setup_in_hsi_out_48mhz(); - - rcc_periph_clock_enable(RCC_GPIOC); - - gpio_set(GPIOC, GPIO11); - gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); - - usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); - usbd_register_set_config_callback(usbd_dev, hid_set_config); - - for (i = 0; i < 0x80000; i++) - __asm__("nop"); - - gpio_clear(GPIOC, GPIO11); - - while (1) - usbd_poll(usbd_dev); -} - -#if 0 /* is this used? */ -void sys_tick_handler(void) -{ - static int x = 0; - static int dir = 1; - uint8_t buf[4] = {0, 0, 0, 0}; - - buf[1] = dir; - x += dir; - if (x > 30) - dir = -dir; - if (x < -30) - dir = -dir; - - usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); -} -#endif |