From 49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 3 Mar 2021 15:24:13 +0000 Subject: support cheap chinese blue pill boards, make usb dfu compatible with dfuse --- app/cdcacm.c | 188 +++++++++++++++++++---------------------------------------- 1 file changed, 60 insertions(+), 128 deletions(-) (limited to 'app/cdcacm.c') diff --git a/app/cdcacm.c b/app/cdcacm.c index b300241..f6a1b0f 100644 --- a/app/cdcacm.c +++ b/app/cdcacm.c @@ -9,30 +9,17 @@ static uint8_t cdcacm_rx_ring_buf[BUFFER_SIZE]; ring_t cdcacm_tx_ring; static uint8_t cdcacm_tx_ring_buf[BUFFER_SIZE]; +static int cdcacm_ready = 0; -static const struct usb_device_descriptor dev = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = USB_CLASS_CDC, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = 64, - .idVendor = ID_VENDOR, - .idProduct = ID_PRODUCT, - .bcdDevice = 0x0200, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, -}; - +#define COMM_EP 0x83 +#define DATA_IN 0x01 +#define DATA_OUT 0x82 static const struct usb_endpoint_descriptor comm_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x83, + .bEndpointAddress = COMM_EP, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 16, .bInterval = 255, @@ -43,7 +30,7 @@ static const struct usb_endpoint_descriptor data_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, + .bEndpointAddress = DATA_IN, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = 64, .bInterval = 1, @@ -51,7 +38,7 @@ static const struct usb_endpoint_descriptor data_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = DATA_OUT, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = 64, .bInterval = 1, @@ -63,7 +50,7 @@ static const struct { struct usb_cdc_call_management_descriptor call_mgmt; struct usb_cdc_acm_descriptor acm; struct usb_cdc_union_descriptor cdc_union; -} __attribute__ ( (packed)) cdcacm_functional_descriptors = { +} __attribute__ ((packed)) cdcacm_functional_descriptors = { .header = { .bFunctionLength = sizeof (struct usb_cdc_header_descriptor), .bDescriptorType = CS_INTERFACE, @@ -76,7 +63,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, .bmCapabilities = 0, - .bDataInterface = 1, + .bDataInterface = 3, }, .acm = { .bFunctionLength = sizeof (struct usb_cdc_acm_descriptor), @@ -88,15 +75,15 @@ static const struct { .bFunctionLength = sizeof (struct usb_cdc_union_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, - .bControlInterface = 0, - .bSubordinateInterface0 = 1, + .bControlInterface = 2, + .bSubordinateInterface0 = 3, } }; -static const struct usb_interface_descriptor comm_iface = { +const struct usb_interface_descriptor comm_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, + .bInterfaceNumber = 2, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_CDC, @@ -108,10 +95,10 @@ static const struct usb_interface_descriptor comm_iface = { .extralen = sizeof (cdcacm_functional_descriptors) }; -static const struct usb_interface_descriptor data_iface = { +const struct usb_interface_descriptor data_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, + .bInterfaceNumber = 3, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_DATA, @@ -121,71 +108,30 @@ static const struct usb_interface_descriptor data_iface = { .endpoint = data_endp, }; -static const struct usb_interface ifaces[] = { - { - .num_altsetting = 1, - .altsetting = &comm_iface, - }, - { - .num_altsetting = 1, - .altsetting = &data_iface, - }, -#ifdef INCLUDE_DFU_INTERFACE - { - .num_altsetting = 1, - .altsetting = &dfu_iface, - }, -#endif -}; - -static const struct usb_config_descriptor config = { - .bLength = USB_DT_CONFIGURATION_SIZE, - .bDescriptorType = USB_DT_CONFIGURATION, - .wTotalLength = 0, -#ifdef INCLUDE_DFU_INTERFACE - .bNumInterfaces = 3, -#else - .bNumInterfaces = 2, -#endif - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 0x32, - .interface = ifaces, -}; -static const char *usb_strings[] = { - "Meh", - "Fish", - "Soup", -#ifdef INCLUDE_DFU_INTERFACE - "DFU", -#endif +const struct usb_iface_assoc_descriptor cdc_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_CDC_PROTOCOL_AT, + .iFunction = 6, }; -/* Buffer to be used for control requests. */ -uint8_t usbd_control_buffer[128]; - -usbd_device *usbd_dev; - -static int cdcacm_control_request (usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, - uint16_t *len, - usbd_control_complete_callback *complete) +int cdcacm_control_request (usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) { (void) complete; (void) buf; (void) usbd_dev; -#ifdef INCLUDE_DFU_INTERFACE - - if (dfu_control_request (usbd_dev, req, buf, len, complete)) { - return 1; - } -#endif switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -194,24 +140,12 @@ static int cdcacm_control_request (usbd_device *usbd_dev, * even though it's optional in the CDC spec, and we don't * advertise it in the ACM functional descriptor. */ - char local_buf[10]; - struct usb_cdc_notification *notif = (void *) local_buf; - /* We echo signals back to host as notification. */ - notif->bmRequestType = 0xA1; - notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; - notif->wValue = 0; - notif->wIndex = 0; - notif->wLength = 2; - local_buf[8] = req->wValue & 3; - local_buf[9] = 0; - // usbd_ep_write_packet(0x83, buf, 10); return 1; } - case USB_CDC_REQ_SET_LINE_CODING: - if (*len < sizeof (struct usb_cdc_line_coding)) { + case USB_CDC_REQ_SET_LINE_CODING: + if (*len < sizeof (struct usb_cdc_line_coding)) return 0; - } return 1; } @@ -220,69 +154,67 @@ static int cdcacm_control_request (usbd_device *usbd_dev, } + void cdcacm_tick (void) { - unsigned ep = 0x82; + unsigned ep = DATA_OUT; uint8_t buf[16]; uint8_t *ptr = buf; size_t n = 0; - if (ring_empty (&cdcacm_tx_ring)) { + if (!cdcacm_ready) return; - } - if ( (*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) { + if (ring_empty (&cdcacm_tx_ring)) + return; + + /* Return if endpoint is already enabled. */ + if ((*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) return; - } while (!ring_read_byte (&cdcacm_tx_ring, ptr++)) { n++; + + if (n == sizeof (buf)) break; } - usbd_ep_write_packet (usbd_dev, ep, buf, n); + usbd_ep_write_packet (usb_device, ep, buf, n); +} + +int cdcacm_write (char *ptr, int len) +{ + int ret; + + ret = ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len); + return ret; } + static void cdcacm_data_rx_cb (usbd_device *usbd_dev, uint8_t ep) { (void) ep; uint8_t buf[64]; - int len = usbd_ep_read_packet (usbd_dev, 0x01, buf, 64); + int len = usbd_ep_read_packet (usbd_dev, DATA_IN, buf, 64); - if (len) { + if (len) ring_write (&cdcacm_rx_ring, buf, len); - } } -static void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue) +void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue) { (void) wValue; - usbd_ep_setup (usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_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); - usbd_register_control_callback (usbd_dev, - USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - cdcacm_control_request); + + usbd_ep_setup (usbd_dev, DATA_IN, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup (usbd_dev, DATA_OUT, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup (usbd_dev, COMM_EP, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + cdcacm_ready = 1; } -void usb_init (void) +void cdcacm_rings_init (void) { ring_init (&cdcacm_rx_ring, cdcacm_rx_ring_buf, sizeof (cdcacm_rx_ring_buf)); ring_init (&cdcacm_tx_ring, cdcacm_tx_ring_buf, sizeof (cdcacm_tx_ring_buf)); - usbd_dev = usbd_init (&stm32f103_usb_driver, - &dev, - &config, - usb_strings, -#ifdef INCLUDE_DFU_INTERFACE - 4, -#else - 3, -#endif - usbd_control_buffer, - sizeof (usbd_control_buffer)); - usbd_register_set_config_callback (usbd_dev, cdcacm_set_config); } - -- cgit v1.2.3