diff options
Diffstat (limited to 'bluefnorf/usb.c')
-rw-r--r-- | bluefnorf/usb.c | 326 |
1 files changed, 118 insertions, 208 deletions
diff --git a/bluefnorf/usb.c b/bluefnorf/usb.c index 7894b81..00f363d 100644 --- a/bluefnorf/usb.c +++ b/bluefnorf/usb.c @@ -14,7 +14,6 @@ #include <libopencm3/stm32/rcc.h> #include <libopencm3/stm32/gpio.h> -#include <libopencm3/stm32/timer.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/cdc.h> #include <libopencm3/cm3/nvic.h> @@ -31,136 +30,128 @@ #define RX_ECHO 1 #define RX_BUF_LEN 256 -static char _rx_tmp[RX_BUF_LEN]; -static char _rx_buf[RX_BUF_LEN]; +static char rx_tmp[RX_BUF_LEN]; +static char rx_buf[RX_BUF_LEN]; -static size_t _rx_tmp_len; -static uint8_t _rx_buf_ready; +static size_t rx_tmp_len; +static uint8_t rx_buf_ready; + +static usbd_device *usbd_dev; /* Buffer to be used for control requests. */ uint8_t usbd_control_buffer[128]; -static usbd_device* __USBDEV; - static const struct usb_device_descriptor device_descriptor = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = 0xfe, // USB_CLASS_CDC, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = 64, - .idVendor = 0x1209, - .idProduct = 0x4001, - .bcdDevice = 0x0200, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0xfe, // USB_CLASS_CDC, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x1209, + .idProduct = 0x4001, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, }; - static const struct usb_endpoint_descriptor comm_endp[] = {{ - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x83, - .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, - .wMaxPacketSize = 16, - .bInterval = 255, + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x83, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, }}; - static const struct usb_endpoint_descriptor data_endp[] = {{ - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 64, - .bInterval = 1, + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, }, { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, - .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 64, - .bInterval = 1, + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, }}; - static const struct usb_interface_descriptor comm_iface[] = {{ - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 1, - .bInterfaceClass = 0xfe, // USB_CLASS_CDC, - .bInterfaceSubClass = 0x00, // USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = 0x00, // USB_CDC_PROTOCOL_AT, - .iInterface = 0, - - .endpoint = comm_endp, - - .extra = NULL, // &cdcacm_functional_descriptors, - .extralen = 0, + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = 0xfe, // USB_CLASS_CDC, + .bInterfaceSubClass = 0x00, // USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = 0x00, // USB_CDC_PROTOCOL_AT, + .iInterface = 0, + + .endpoint = comm_endp, + + .extra = NULL, // &cdcacm_functional_descriptors, + .extralen = 0, }}; static const struct usb_interface_descriptor data_iface[] = {{ - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0, - - .endpoint = data_endp, + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + + .endpoint = data_endp, }}; static const struct usb_interface ifaces[] = {{ - .num_altsetting = 1, - .altsetting = comm_iface, + .num_altsetting = 1, + .altsetting = comm_iface, }, { - .num_altsetting = 1, - .altsetting = data_iface, + .num_altsetting = 1, + .altsetting = data_iface, }}; static const struct usb_config_descriptor config = { - .bLength = USB_DT_CONFIGURATION_SIZE, - .bDescriptorType = USB_DT_CONFIGURATION, - .wTotalLength = 0, - .bNumInterfaces = 2, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 0x32, - - .interface = ifaces, + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 2, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + + .interface = ifaces, }; static const char *usb_strings[] = { - "Chaos Computer Club Berlin e.V.", - "bluefnorf", - "bf1", + "Chaos Computer Club Berlin e.V.", + "bluefnorf", + "bf1", }; - -/* - * Initialize GPIO for D+ and status LED - */ -void usb_gpio_init() -{ +void usb_gpio_init() { // Clock - rcc_periph_clock_enable(RCC_GPIOA); - rcc_periph_clock_enable(RCC_GPIOC); + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOC); // D+ - gpio_set_mode(USBD_PORT, + gpio_set_mode(USBD_PORT, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, + GPIO_CNF_OUTPUT_PUSHPULL, USBDP); // LED @@ -171,90 +162,37 @@ void usb_gpio_init() } -/* - * Switch status led on / off - */ -inline void usb_status_led_toggle() -{ +void usb_status_led_toggle() { gpio_toggle(STATUS_LED_PORT, STATUS_LED_PIN); } +static void usb_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) { + char buf[64]; -/* - * Poll usb interface using TIM4 - */ -void usb_timer_init() -{ - // Enable clock - rcc_periph_clock_enable(RCC_TIM4); - - // Enable interrupts - nvic_enable_irq(NVIC_TIM4_IRQ); - nvic_set_priority(NVIC_TIM4_IRQ, 1); - - timer_reset(TIM4); - - // Edge aligned - TIM4_CR1 |= TIM_CR1_CKD_CK_INT | - TIM_CR1_CMS_EDGE | - TIM_CR1_DIR_UP; - - TIM4_PSC = 32; - TIM4_ARR = 65535; - - // Interrupts: - // - Update / Overflow Event (UIE) - TIM4_DIER |= TIM_DIER_UIE; -} - -void usb_timer_start() -{ - TIM4_CR1 |= TIM_CR1_CEN; -} - - -void tim4_isr() -{ - // Poll USBDEV - usbd_poll(__USBDEV); - - // Blink status LED - usb_status_led_toggle(); - TIM4_SR &= ~TIM_SR_UIF; // Clear flag -} - - - -static void usb_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) -{ - char buf[64]; + int len = usbd_ep_read_packet(usbd_dev, ep, buf, 64); - int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); - - if (len) { - // We received data, let's handle it - - usbd_ep_write_packet(usbd_dev, 0x82, "fnorf", 6); - } + if (len) { + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); + } } - -static int usb_control_request_cb(usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, - uint16_t *len, - usbd_control_complete_callback *complete) -{ +static enum usbd_request_return_codes usb_control_request_cb(usbd_device *usbd_dev, struct usb_setup_data *req, + uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) { + (void)usbd_dev; + (void)req; + (void)buf; + (void)len; + (void)complete; return 0; } -static void usb_set_config_cb(usbd_device *usbd_dev, uint16_t wValue) -{ - usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, usb_data_rx_cb); - usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); +static void usb_set_config_cb(usbd_device *usbd_dev, uint16_t wValue) { + (void)wValue; + + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, usb_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_register_control_callback( + usbd_register_control_callback( usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, @@ -262,70 +200,42 @@ static void usb_set_config_cb(usbd_device *usbd_dev, uint16_t wValue) ); } - -usbd_device *usb_serial_init() -{ - usbd_device *usbd_dev; - +usbd_device *usb_serial_init() { // Initialize GPIO usb_gpio_init(); - // Initialize timers - usb_timer_init(); - // Initialize buffers - memset(_rx_tmp, 0, RX_BUF_LEN); - memset(_rx_buf, 0, RX_BUF_LEN); + memset(rx_tmp, 0, RX_BUF_LEN); + memset(rx_buf, 0, RX_BUF_LEN); - _rx_tmp_len = 0; - _rx_buf_ready = 0; + rx_tmp_len = 0; + rx_buf_ready = 0; // Pull down D+ gpio_clear(USBD_PORT, USBDP); - for (int i = 0; i < 0x10000; i++) { - __asm__("nop"); + for (int i = 0; i < 0x10000; i++) { + __asm__("nop"); } gpio_set(USBD_PORT, USBDP); // Initialize usb device - usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, + usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, &device_descriptor, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); - usbd_register_set_config_callback(usbd_dev, usb_set_config_cb); - - // Make available - __USBDEV = usbd_dev; + usbd_register_set_config_callback(usbd_dev, usb_set_config_cb); // Pull down gpio_clear(USBD_PORT, USBDP); - // Poll a bit - for (int i = 0; i < 0x80000; i++) { - usbd_poll(usbd_dev); - } - - // Start polling - usb_timer_start(); + nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); return usbd_dev; } - -/* - * Override _write and redirect stdout to usb - */ - /* -int _write(int file, char* data, int len) -{ - if (file < 2) { - return usb_serial_tx(data, len); - } - - // Set error and return failure - errno = EIO; - return -1; +void usb_lp_can_rx0_isr() { + usbd_poll(usbd_dev); + nvic_clear_pending_irq(NVIC_USB_LP_CAN_RX0_IRQ); } -*/ |