aboutsummaryrefslogtreecommitdiffstats
path: root/app/cdcacm.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/cdcacm.c')
-rw-r--r--app/cdcacm.c188
1 files changed, 60 insertions, 128 deletions
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);
}
-