]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
RoCoN: USB CDC ACM target for command processor implemented.
authorPavel Pisa <ppisa@pikron.com>
Sun, 17 May 2015 18:12:29 +0000 (20:12 +0200)
committerPavel Pisa <ppisa@pikron.com>
Sun, 17 May 2015 18:12:29 +0000 (20:12 +0200)
The support is based on new USB CDC ACM implementation.

Signed-off-by: Pavel Pisa <ppisa@pikron.com>
sw/app/rocon/Makefile.omk
sw/app/rocon/appl_usb.c
sw/app/rocon/usb/usb_defs.h
sw/config.omk

index 201eaab25d64e24510221933df674f0972cf1bf3..df5bf0c549edb5fc229721c8c4d7251c7be8180f 100644 (file)
@@ -143,7 +143,7 @@ rocon_SOURCES += appl_usb.c
 ifeq ($(CONFIG_LIB_U2U_V2),y)
 lib_LOADLIBES += u2u_dcnv
 endif
-lib_LOADLIBES += usbbase usbmore
+lib_LOADLIBES += usbcdc usbbase usbmore
 ifeq ($(CONFIG_USB_LPCUSB),y)
 lib_LOADLIBES += lpcusb
 endif
index 1bdc8b009ac7a0977daaec2c238d3b29b31a1aaf..d87fe159882358a1c203b986db0b53a2c3c3f29a 100644 (file)
 usb_device_t usb_device;
 usb_ep_t eps[NUM_ENDPOINTS];
 
-#define MASK_EP1RX 0x01
-#define MASK_EP1TX 0x02
-
-unsigned char ep1_rx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
-unsigned char ep1_tx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
+#define CDC0_EPIDX_NOTIFY 0
+#define CDC0_EPIDX_RXD    1
+#define CDC0_EPIDX_TXD    2
+#define CDC0_MASK_EP_NOTIFY  (1<<CDC0_EPIDX_NOTIFY)
+#define CDC0_MASK_EP_RXD     (1<<CDC0_EPIDX_RXD)
+#define CDC0_MASK_EP_TXD     (1<<CDC0_EPIDX_TXD)
+
+unsigned char cdc0_ep_tx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
+unsigned char cdc0_ep_rx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
 unsigned char ep0_buffer[USB_MAX_PACKET0] __attribute__ ((aligned (8)));
+int cdc0_tx_index = 0, cdc0_tx_ready = 1;
+int cdc0_rx_index = 0, cdc0_rx_chars = 0;
+
+uint16_t cdc0_serial_state = 0; /* USBCDC_SERIAL_STATE_xxx */
+acm_desc_t usbcdc_acm_description;
+
 int usb_active = 0;
-int ep1_rx_index = 0, ep1_rx_ready = 1;
-int ep1_tx_index = 0, ep1_tx_chars = 0;
 
 #ifdef CONFIG_OC_CMDPROC
 
@@ -533,14 +541,18 @@ int usb_app_init(void)
 {
   memset(&usb_device, 0, sizeof(usb_device));
 
-  eps[0].max_packet_size = USB_MAX_PACKET;
-  eps[1].max_packet_size = USB_MAX_PACKET;
-  eps[0].epnum = 0x81;
-  eps[1].epnum = 0x01;
-  eps[0].event_mask = 0x08;
-  eps[1].event_mask = 0x04;
-  eps[0].udev = &usb_device;
-  eps[1].udev = &usb_device;
+  eps[CDC0_EPIDX_NOTIFY].max_packet_size = USB_MAX_PACKET;
+  eps[CDC0_EPIDX_RXD].max_packet_size = USB_MAX_PACKET;
+  eps[CDC0_EPIDX_TXD].max_packet_size = USB_MAX_PACKET;
+  eps[CDC0_EPIDX_NOTIFY].epnum = CDC0_EP_NOTIFY;
+  eps[CDC0_EPIDX_RXD].epnum = CDC0_EP_RXD;
+  eps[CDC0_EPIDX_TXD].epnum = CDC0_EP_TXD;
+  eps[CDC0_EPIDX_NOTIFY].event_mask = 0x08;
+  eps[CDC0_EPIDX_RXD].event_mask = 0x10;
+  eps[CDC0_EPIDX_TXD].event_mask = 0x20;
+  eps[CDC0_EPIDX_NOTIFY].udev = &usb_device;
+  eps[CDC0_EPIDX_RXD].udev = &usb_device;
+  eps[CDC0_EPIDX_TXD].udev = &usb_device;
 
   usb_device.id = 1;
   usb_device.devdes_table = &usb_devdes_table;
@@ -549,6 +561,7 @@ int usb_app_init(void)
   usb_device.cntep = NUM_ENDPOINTS;
   usb_device.ep = eps;
   usb_device.vendor_fnc = appl_usb_vendor;
+  usb_device.class_fnc = usbcdc_acm_class_response;
 
   usb_init(&usb_device);
   usb_connect(&usb_device);
@@ -556,21 +569,21 @@ int usb_app_init(void)
   return 0;
 }
 
-int usb_check_ep1()
+int cdc0_txd_check_ep()
 {
-  if (usb_device.ep_events & MASK_EP1RX)
+  if (usb_device.ep_events & CDC0_MASK_EP_TXD)
   {
-    usb_device.ep_events &= ~MASK_EP1RX;
+    usb_device.ep_events &= ~CDC0_MASK_EP_TXD;
     //TODO: Use some field in the structure, probably flags
-    ep1_rx_ready = 1;
+    cdc0_tx_ready = 1;
   }
 
   /* Respond if there is something to send and RX is ready */
-  if (ep1_rx_ready && ep1_rx_index != 0)
+  if (cdc0_tx_ready && cdc0_tx_index != 0)
   {
-    usb_udev_write_endpoint(&eps[0], ep1_rx_buff, ep1_rx_index);
-    ep1_rx_index = 0;
-    ep1_rx_ready = 0;
+    usb_udev_write_endpoint(&eps[CDC0_EPIDX_TXD], cdc0_ep_tx_buff, cdc0_tx_index);
+    cdc0_tx_index = 0;
+    cdc0_tx_ready = 0;
     hal_gpio_set_value(LED2_PIN, 0);
     return 1;
   }
@@ -586,18 +599,26 @@ int usb_app_poll(void)
   usb_check_events(&usb_device);
   usb_control_response(&usb_device);
 
-  /* Check TX endpoint */
-  if (usb_device.ep_events & MASK_EP1TX)
+  /* Check RXD/OUT endpoint */
+  if (usb_device.ep_events & CDC0_MASK_EP_NOTIFY)
+  {
+    usb_udev_read_endpoint(&eps[CDC0_EPIDX_NOTIFY], &cdc0_serial_state, 2);
+    usb_device.ep_events &= ~CDC0_MASK_EP_NOTIFY;
+    usb_active = 1;
+  }
+
+  /* Check RXD/OUT endpoint */
+  if (usb_device.ep_events & CDC0_MASK_EP_RXD)
   {
-    ep1_tx_chars = usb_udev_read_endpoint(&eps[1], ep1_tx_buff, USB_MAX_PACKET);
-    ep1_tx_index = 0;
-    usb_device.ep_events &= ~MASK_EP1TX;
+    cdc0_rx_chars = usb_udev_read_endpoint(&eps[CDC0_EPIDX_RXD], cdc0_ep_rx_buff, USB_MAX_PACKET);
+    cdc0_rx_index = 0;
+    usb_device.ep_events &= ~CDC0_MASK_EP_RXD;
     hal_gpio_set_value(LED2_PIN, 0);
     usb_active = 1;
   }
 
   /* Check RX endpoint */
-  usb_active |= usb_check_ep1();
+  usb_active |= cdc0_txd_check_ep();
 
   return active;
 }
@@ -612,26 +633,26 @@ int usb_app_stop(void)
 
 int cmd_io_getc_usbcon(struct cmd_io *cmd_io)
 {
-  if (ep1_tx_index >= ep1_tx_chars)
+  if (cdc0_rx_index >= cdc0_rx_chars)
     return -1;
 
-  return ep1_tx_buff[ep1_tx_index++];
+  return cdc0_ep_rx_buff[cdc0_rx_index++];
 }
 
 int cmd_io_putc_usbcon(struct cmd_io *cmd_io, int ch)
 {
-  if (ep1_rx_index >= USB_MAX_PACKET)
+  if (cdc0_tx_index >= USB_MAX_PACKET)
   {
     /* Check EP1 status and return -1 if unavailable */
     usb_check_events(&usb_device);
-    usb_check_ep1();
+    cdc0_txd_check_ep();
 
     /* Check again if it wasn't emptied */
-    if (ep1_rx_index >= USB_MAX_PACKET)
+    if (cdc0_tx_index >= USB_MAX_PACKET)
       return -1;
   }
 
-  ep1_rx_buff[ep1_rx_index++] = (unsigned char)ch;
+  cdc0_ep_tx_buff[cdc0_tx_index++] = (unsigned char)ch;
   return ch;
 }
 
index 01042c66ccd41bbdd9be06b8ac433d5afa380ab1..0fbf6a390445f582ba63cd32c7bd79ff3f4f053e 100644 (file)
@@ -3,6 +3,7 @@
 #define USB_DEFS_MODULE
 
 #include <usb/usb_spec.h>
+#include <usb/usb_cdc.h>
 #include <usb/lpcusb.h>
 #include <endian.h>
 #include <cpu_def.h>
 #define USB_RELEASE_VER    0x0100
 
 /*** Class codes for device description ***/
-#define USB_CLASS_CODE      0xFF
+#define USB_CLASS_CODE      USB_DEVICE_CLASS_COMMUNICATIONS
 #define USB_SUBCLASS_CODE   0x00
 #define USB_PROTOCOL_CODE   0x00
 
-#define NUM_ENDPOINTS       2
+#define NUM_ENDPOINTS       3
+#define CDC0_EP_NOTIFY      0x81
+#define CDC0_EP_RXD         0x02
+#define CDC0_EP_TXD         0x82
+
+#define CONFIG_DESCRIPTOR_LENGTH \
+  sizeof(USB_CONFIGURATION_DESCRIPTOR) \
+   + sizeof(USB_INTERFACE_DESCRIPTOR) \
+   + sizeof(USBCDC_HEADER_FCN_DESCRIPTOR) \
+   + sizeof(USBCDC_CALLMGMT_FCN_DESCRIPTOR) \
+   + sizeof(USBCDC_ACM_FCN_DESCRIPTOR) \
+   + sizeof(USBCDC_UNION_FCN_DESCRIPTOR) \
+   + sizeof(USB_INTERFACE_DESCRIPTOR) \
+   + (NUM_ENDPOINTS*sizeof(USB_ENDPOINT_DESCRIPTOR))
 
 /*** Device descriptor ***/
 CODE const USB_DEVICE_DESCRIPTOR DeviceDescription =
 {
   sizeof(USB_DEVICE_DESCRIPTOR),
   USB_DESCRIPTOR_TYPE_DEVICE,
-  SWAP(0x0100),
+  SWAP(0x0120),
   USB_CLASS_CODE,
   USB_SUBCLASS_CODE,
   USB_PROTOCOL_CODE,
@@ -49,60 +63,118 @@ CODE const USB_DEVICE_DESCRIPTOR DeviceDescription =
   1, /* manufacturer string ID */
   2, /* product string ID */
   3, /* serial number string ID */
-  1
+  1  /* bNumConfigs */
 };
 
 /*** All In Configuration 0 ***/
 CODE const struct
 {
   USB_CONFIGURATION_DESCRIPTOR configuration;
-  USB_INTERFACE_DESCRIPTOR interface;
-  USB_ENDPOINT_DESCRIPTOR endpoint_tx;
-  USB_ENDPOINT_DESCRIPTOR endpoint_rx;
-} ConfigDescription =
+  USB_INTERFACE_DESCRIPTOR        iface_comm;
+  USBCDC_HEADER_FCN_DESCRIPTOR    cdcheader;
+  USBCDC_CALLMGMT_FCN_DESCRIPTOR  cdccallmgt;
+  USBCDC_ACM_FCN_DESCRIPTOR       cdcacm;
+  USBCDC_UNION_FCN_DESCRIPTOR     cdcunion;
+  USB_ENDPOINT_DESCRIPTOR         ep_notification;
+  USB_INTERFACE_DESCRIPTOR        iface_data;
+  USB_ENDPOINT_DESCRIPTOR         ep_rxd;
+  USB_ENDPOINT_DESCRIPTOR         ep_txd;
+} PACKED ConfigDescription =
 {
-  /*** Configuration descriptor ***/
   {
+    /*** Configuration descriptor ***/
     sizeof(USB_CONFIGURATION_DESCRIPTOR),
     USB_DESCRIPTOR_TYPE_CONFIGURATION,
-    sizeof(ConfigDescription),
-    1, /* cnt of interfaces */
+    SWAP(CONFIG_DESCRIPTOR_LENGTH),
+    2, /* cnt of interfaces */
     1, /* this configuration ID */
     4, /* config.name string ID */
-    0x80, /* cfg, in spec is, taha bit 7 must be set to one -> 0xe0 , orig 0x60*/
+    USB_CONFIG_BUS_POWERED, /* CbmAttributes (bus powered) */
     250    /* device power current from host 500mA / 2 */
   },
-  /*** Interface Descriptor ***/
   {
+    /*** Interface Descriptor ***/
     sizeof(USB_INTERFACE_DESCRIPTOR),
     USB_DESCRIPTOR_TYPE_INTERFACE,
     0,    /* index of this interface for SetInterface request */
     0,    /* ID alternate interface */
-    NUM_ENDPOINTS,
-    USB_CLASS_CODE,
-    USB_SUBCLASS_CODE,
-    USB_PROTOCOL_CODE,
+    1,    /* number of endpoints in interface */
+    USB_DEVICE_CLASS_COMMUNICATIONS,
+    USBCDC_COM_IFACE_SUBCLS_ACM,
+    0,    /* protocol */
     5
   },
-  /*** Endpoint 1 - Rx,Bulk ***/
   {
+    /*** CDC Header Descriptor ***/
+    sizeof(USBCDC_HEADER_FCN_DESCRIPTOR),
+    USBCDC_COM_FCN_TYPE_CS_INTERFACE,
+    USBCDC_COM_FCN_SUBTYPE_HEADER,    /* bDescriptorSubtype */
+    SWAP(0x0120),                     /* bcdCDC (spec. release 1.2) */
+  },
+  {
+    /*** CDC CALL MANAGEMENT Descriptor ***/
+    sizeof(USBCDC_CALLMGMT_FCN_DESCRIPTOR),
+    USBCDC_COM_FCN_TYPE_CS_INTERFACE,
+    USBCDC_COM_FCN_SUBTYPE_CALLMGMT,
+    0,
+    1,
+  },
+  {
+    /*** CDC ABSTRACT CONTROL MANAGEMENT Descriptor ***/
+    sizeof(USBCDC_ACM_FCN_DESCRIPTOR),
+    USBCDC_COM_FCN_TYPE_CS_INTERFACE,
+    USBCDC_COM_FCN_SUBTYPE_ACMGMT,
+    USBCDC_ACM_FCN_CAP_SUPPORT_LINECTRL,
+  },
+  {
+    /*** CDC UNION Descriptor ***/
+    sizeof(USBCDC_UNION_FCN_DESCRIPTOR),
+    USBCDC_COM_FCN_TYPE_CS_INTERFACE,
+    USBCDC_COM_FCN_SUBTYPE_UNION,
+    0,
+    1,
+  },
+  {
+    /*** Endpoint 1 IN, type interrupt ***/
     sizeof(USB_ENDPOINT_DESCRIPTOR),
     USB_DESCRIPTOR_TYPE_ENDPOINT,
-    0x81,
+    CDC0_EP_NOTIFY,                   /* bEndpointAddress */
+    USB_ENDPOINT_TYPE_INTERRUPT,
+    SWAP(USB_MAX_PACKET),
+    0x80,                             /* bInterval (polling interval: 50ms) */
+  },
+  {
+    /*** Interface Descriptor ***/
+    sizeof(USB_INTERFACE_DESCRIPTOR),
+    USB_DESCRIPTOR_TYPE_INTERFACE,
+    1,                                /* bInterfaceNumber */
+    0,                                /* bAlternateSetting */
+    2,                                /* number of EPs */
+    USB_DEVICE_CLASS_CDC_DATA,        /* bInterfaceClass */
+    0,                                /* bInterfaceSubclass */
+    0,                                /* bDeviceProtocol */
+    0,                                /* iInterface (string, 0=none) */
+  },
+  {
+    /*** Endpoint 2 OUT, type bulk ***/
+    sizeof(USB_ENDPOINT_DESCRIPTOR),
+    USB_DESCRIPTOR_TYPE_ENDPOINT,
+    CDC0_EP_RXD,                      /* bEndpointAddress */
     USB_ENDPOINT_TYPE_BULK,
     SWAP(USB_MAX_PACKET),
-    0
+    0,                                /* bInterval (polling interval: 50ms) */
   },
-  /*** Endpoint 1 - Tx,Bulk ***/
   {
+    /*** Endpoint 2 IN, type bulk ***/
     sizeof(USB_ENDPOINT_DESCRIPTOR),
     USB_DESCRIPTOR_TYPE_ENDPOINT,
-    0x01,
+    CDC0_EP_TXD,                      /* bEndpointAddress */
     USB_ENDPOINT_TYPE_BULK,
     SWAP(USB_MAX_PACKET),
-    0
+    0,                                /* bInterval (polling interval: 50ms) */
   }
 };
+
 /*** Strings - in unicode ***/
 CODE const char Str0Desc[] =    /* supported languages of strings */
 {
@@ -211,7 +283,8 @@ CODE const USB_DEVICE_CONFIGURATION_ENTRY usb_devdes_configurations[] =
 
 CODE const USB_INTERFACE_DESCRIPTOR *usb_devdes_interfaces[] =
 {
-  &ConfigDescription.interface
+  &ConfigDescription.iface_comm,
+  &ConfigDescription.iface_data
 };
 
 CODE const USB_DEVICE_DESCRIPTORS_TABLE usb_devdes_table =
@@ -223,7 +296,7 @@ CODE const USB_DEVICE_DESCRIPTORS_TABLE usb_devdes_table =
   .iNumStrings = CNT_STRINGS,
   .bNumEndpoints = NUM_ENDPOINTS,
   .bNumConfigurations = 1,
-  .bNumInterfaces = 1
+  .bNumInterfaces = 2
 };
 
 #endif /* USB_DEFS_MODULE */
index 75313bf0493d5e51bbd497d7a7b41a51adf7fc79..fa65c81ac2b6b264005f57370bb7fa0b8a5e37a2 100644 (file)
@@ -38,6 +38,7 @@ CONFIG_OC_MTD_DRV_SYSLESS=y
 CONFIG_USB_BASE=y
 CONFIG_USB_LPCUSB=y
 CONFIG_USB_MORE=y
+CONFIG_USB_CDC=y
 CONFIG_APP_ROCON_WITH_USB=y
 CONFIG_LIB_U2U_V2=n