aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-04-19 22:33:36 +0200
committerHarald Welte <laforge@gnumonks.org>2019-05-16 23:05:21 +0200
commit34a8706e455944ab4eaf20cdc87d67bb81c48e4f (patch)
tree525944c619ffec32857ac9267db6e9039b5dfeec
parentcdb1ee3be837086993a5ecc6554eceea720c9245 (diff)
Re-structure USB descriptors
Use structures to define the USB descriptors of the sysmoOCTSIM device. While at it, turn it from a pure CDC-ACM to a CDC-ACM + CCID interface, so we can expose a virtual UART at the same time as the chip card reader device. Change-Id: I0423d733476f37c16bdb6abc651b7ad5ca7ac63e
-rw-r--r--sysmoOCTSIM/atmel_start.c2
-rw-r--r--sysmoOCTSIM/config/hpl_usb_config.h4
-rw-r--r--sysmoOCTSIM/gcc/Makefile3
-rw-r--r--sysmoOCTSIM/usb_descriptors.c241
-rw-r--r--sysmoOCTSIM/usb_start.c25
5 files changed, 250 insertions, 25 deletions
diff --git a/sysmoOCTSIM/atmel_start.c b/sysmoOCTSIM/atmel_start.c
index fd566dd..bee1ed2 100644
--- a/sysmoOCTSIM/atmel_start.c
+++ b/sysmoOCTSIM/atmel_start.c
@@ -12,8 +12,8 @@ static void M2M_DMA_complete_cb(void)
void atmel_start_init(void)
{
system_init();
- usb_init();
dma_memory_init();
dma_memory_register_callback(DMA_MEMORY_COMPLETE_CB, M2M_DMA_complete_cb);
stdio_redirect_init();
+ usb_init();
}
diff --git a/sysmoOCTSIM/config/hpl_usb_config.h b/sysmoOCTSIM/config/hpl_usb_config.h
index 73a9fea..bbfd99d 100644
--- a/sysmoOCTSIM/config/hpl_usb_config.h
+++ b/sysmoOCTSIM/config/hpl_usb_config.h
@@ -39,7 +39,7 @@
// <CONF_USB_D_N_EP_MAX"> Max possible (by "Max Endpoint Number" config)
// <id> usbd_num_ep_sp
#ifndef CONF_USB_D_NUM_EP_SP
-#define CONF_USB_D_NUM_EP_SP CONF_USB_N_4
+#define CONF_USB_D_NUM_EP_SP CONF_USB_N_6
#endif
// </h>
@@ -60,7 +60,7 @@
// <i> The number of physical endpoints - 1
// <id> usbd_arch_max_ep_n
#ifndef CONF_USB_D_MAX_EP_N
-#define CONF_USB_D_MAX_EP_N CONF_USB_N_2
+#define CONF_USB_D_MAX_EP_N CONF_USB_N_4
#endif
// <y> USB Speed Limit
diff --git a/sysmoOCTSIM/gcc/Makefile b/sysmoOCTSIM/gcc/Makefile
index 080aa41..7684204 100644
--- a/sysmoOCTSIM/gcc/Makefile
+++ b/sysmoOCTSIM/gcc/Makefile
@@ -84,6 +84,7 @@ hal/src/hal_usb_device.o \
main.o \
manual_test.o \
talloc.o \
+usb_descriptors.o \
i2c_bitbang.o \
octsim_i2c.o \
ncn8025.o \
@@ -136,6 +137,7 @@ OBJS_AS_ARGS += \
"main.o" \
"manual_test.o" \
"talloc.o" \
+"usb_descriptors.o" \
"i2c_bitbang.o" \
"octsim_i2c.o" \
"ncn8025.o" \
@@ -194,6 +196,7 @@ DEPS_AS_ARGS += \
"main.d" \
"manual_test.d" \
"talloc.d" \
+"usb_descriptors.d" \
"i2c_bitbang.d" \
"octsim_i2c.d" \
"ncn8025.d" \
diff --git a/sysmoOCTSIM/usb_descriptors.c b/sysmoOCTSIM/usb_descriptors.c
new file mode 100644
index 0000000..429e8c2
--- /dev/null
+++ b/sysmoOCTSIM/usb_descriptors.c
@@ -0,0 +1,241 @@
+#include "usbd_config.h"
+#include "usbdc.h"
+#include "usb_protocol.h"
+#include "usb_protocol_cdc.h"
+#include "ccid_proto.h"
+#include "cdcdf_acm_desc.h"
+
+/* aggregate descriptors for the combined CDC-ACM + CCID device that we expose
+ * from sysmoQMOD */
+
+enum str_desc_num {
+ STR_DESC_MANUF = 1,
+ STR_DESC_PRODUCT,
+ STR_DESC_CONFIG,
+ STR_DESC_INTF_ACM_COMM,
+ STR_DESC_INTF_ACM_DATA,
+ STR_DESC_INTF_CCID,
+ STR_DESC_SERIAL,
+};
+
+/* a struct of structs representing the concatenated collection of USB descriptors */
+struct usb_desc_collection {
+ struct usb_dev_desc dev;
+ struct usb_config_desc cfg;
+
+ /* CDC-ACM: Two interfaces, one with IRQ EP and one with BULK IN + OUT */
+ struct {
+ struct {
+ struct usb_iface_desc iface;
+ struct usb_cdc_hdr_desc cdc_hdr;
+ struct usb_cdc_call_mgmt_desc cdc_call_mgmt;
+ struct usb_cdc_acm_desc cdc_acm;
+ struct usb_cdc_union_desc cdc_union;
+ struct usb_ep_desc ep[1];
+ } comm;
+ struct {
+ struct usb_iface_desc iface;
+ struct usb_ep_desc ep[2];
+ } data;
+ } cdc;
+
+ /* CCID: One interface with CCID class descriptor and three endpoints */
+ struct {
+ struct usb_iface_desc iface;
+ struct usb_ccid_class_descriptor class;
+ struct usb_ep_desc ep[3];
+ } ccid;
+ uint8_t str[116];
+} __attribute__((packed));
+
+static const struct usb_desc_collection usb_fs_descs = {
+ .dev = {
+ .bLength = sizeof(struct usb_dev_desc),
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = USB_V2_0,
+ .bDeviceClass = 0x02,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .bMaxPacketSize0 = CONF_USB_CDCD_ACM_BMAXPKSZ0,
+ .idVendor = CONF_USB_CDCD_ACM_IDVENDER,
+ .idProduct = CONF_USB_CDCD_ACM_IDPRODUCT,
+ .iManufacturer = STR_DESC_MANUF,
+ .iProduct = STR_DESC_PRODUCT,
+ .iSerialNumber = STR_DESC_SERIAL,
+ .bNumConfigurations = 1,
+ },
+ .cfg = {
+ .bLength = sizeof(struct usb_config_desc),
+ .bDescriptorType = USB_DT_CONFIG,
+ .wTotalLength = sizeof(usb_fs_descs.cfg) +
+ sizeof(usb_fs_descs.cdc) +
+ sizeof(usb_fs_descs.ccid),
+ .bNumInterfaces = 3,
+ .bConfigurationValue = CONF_USB_CDCD_ACM_BCONFIGVAL,
+ .iConfiguration = STR_DESC_CONFIG,
+ .bmAttributes = CONF_USB_CDCD_ACM_BMATTRI,
+ .bMaxPower = CONF_USB_CDCD_ACM_BMAXPOWER,
+ },
+ .cdc = {
+ .comm = {
+ .iface = {
+ .bLength = sizeof(struct usb_iface_desc),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = CONF_USB_CDCD_ACM_COMM_BIFCNUM,
+ .bAlternateSetting = CONF_USB_CDCD_ACM_COMM_BALTSET,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = CDC_CLASS_COMM,
+ .bInterfaceSubClass = CDC_SUBCLASS_ACM,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = STR_DESC_INTF_ACM_COMM,
+ },
+ .cdc_hdr = {
+ .bFunctionLength = sizeof(struct usb_cdc_hdr_desc),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_SCS_HEADER,
+ .bcdCDC = LE16(0x1001),
+ },
+ .cdc_call_mgmt = {
+ .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_SCS_CALL_MGMT,
+ .bmCapabilities = 0x01,
+ .bDataInterface = 0x00,
+ },
+ .cdc_acm = {
+ .bFunctionLength = sizeof(struct usb_cdc_acm_desc),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_SCS_ACM,
+ .bmCapabilities = 0x02,
+ },
+ .cdc_union = {
+ .bFunctionLength = sizeof(struct usb_cdc_union_desc),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_SCS_UNION,
+ .bMasterInterface = CONF_USB_CDCD_ACM_COMM_BIFCNUM,
+ .bSlaveInterface0 = 0x01,
+ },
+ .ep = {
+ {
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = CONF_USB_CDCD_ACM_COMM_INT_EPADDR,
+ .bmAttributes = USB_EP_TYPE_INTERRUPT,
+ .wMaxPacketSize = CONF_USB_CDCD_ACM_COMM_INT_MAXPKSZ,
+ .bInterval = CONF_USB_CDCD_ACM_COMM_INT_INTERVAL,
+ },
+ },
+ },
+ .data = {
+ .iface = {
+ .bLength = sizeof(struct usb_iface_desc),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = CONF_USB_CDCD_ACM_DATA_BIFCNUM,
+ .bAlternateSetting = CONF_USB_CDCD_ACM_DATA_BALTSET,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = CDC_CLASS_DATA,
+ .bInterfaceSubClass = 0x00,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = STR_DESC_INTF_ACM_DATA,
+ },
+ .ep = {
+ {
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = CONF_USB_CDCD_ACM_DATA_BULKOUT_EPADDR,
+ .bmAttributes = USB_EP_TYPE_BULK,
+ .wMaxPacketSize = CONF_USB_CDCD_ACM_DATA_BULKOUT_MAXPKSZ,
+ .bInterval = 0,
+ },
+ {
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = CONF_USB_CDCD_ACM_DATA_BULKIN_EPADDR,
+ .bmAttributes = USB_EP_TYPE_BULK,
+ .wMaxPacketSize = CONF_USB_CDCD_ACM_DATA_BULKIN_MAXPKSZ,
+ .bInterval = 0,
+ },
+ },
+ },
+ },
+ .ccid = {
+ .iface = {
+ .bLength = sizeof(struct usb_iface_desc),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 2,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = 11,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = STR_DESC_INTF_CCID,
+ },
+ .class = {
+ .bLength = sizeof(struct usb_ccid_class_descriptor),
+ .bDescriptorType = 33,
+ .bcdCCID = LE16(0x0110),
+ .bMaxSlotIndex = 7,
+ .dwProtocols = 0x07, /* 5/3/1.8V */
+ .dwDefaultClock = LE32(2500),
+ .dwMaximumClock = LE32(20000),
+ .bNumClockSupported = 4,
+ .dwDataRate = LE32(9600),
+ .dwMaxDataRate = LE32(921600),
+ .bNumDataRatesSupported = 0,
+ .dwMaxIFSD = LE32(0),
+ .dwSynchProtocols = LE32(0),
+ .dwMechanical = LE32(0),
+ .dwFeatures = LE32(0x10),
+ .dwMaxCCIDMessageLength = 272,
+ .bClassGetResponse = 0xff,
+ .bClassEnvelope = 0xff,
+ .wLcdLayout = LE16(0),
+ .bPINSupport = 0,
+ .bMaxCCIDBusySlots = 8,
+ },
+ .ep = {
+ { /* Bulk-OUT descriptor */
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x02,
+ .bmAttributes = USB_EP_TYPE_BULK,
+ .wMaxPacketSize = 64,
+ .bInterval = 0,
+ },
+ { /* Bulk-IN descriptor */
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x83,
+ .bmAttributes = USB_EP_TYPE_BULK,
+ .wMaxPacketSize = 64,
+ .bInterval = 0,
+ },
+ { /* Interrupt dscriptor */
+ .bLength = sizeof(struct usb_ep_desc),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x84,
+ .bmAttributes = USB_EP_TYPE_INTERRUPT,
+ .wMaxPacketSize = 64,
+ .bInterval = 0x10,
+ },
+ },
+ },
+ //DFURT_IF_DESCRIPTOR,
+ .str = {
+#if 0
+ CDCD_ACM_STR_DESCES
+#else
+ 4, 3, 0x09, 0x04,
+ 18, 3, 's',0, 'y',0, 's',0, 'm',0, 'o',0, 'c',0, 'o',0, 'm',0,
+ 24, 3, 's',0, 'y',0, 's',0, 'm',0, 'o',0, 'O',0, 'C',0, 'T',0, 'S',0, 'I',0, 'M',0,
+ 4, 3, 'A', 0,
+ 22, 3, 'd',0, 'e',0, 'b',0, 'u',0, 'g',0, ' ',0, 'U',0, 'A',0, 'R',0, 'T',0,
+ 22, 3, 'd',0, 'e',0, 'b',0, 'u',0, 'g',0, ' ',0, 'U',0, 'A',0, 'R',0, 'T',0,
+ 10, 3, 'C',0, 'C',0, 'I',0, 'D',0,
+ 12, 3, 'F',0, 'I',0, 'X',0, 'M',0, 'E',0,
+#endif
+ }
+};
+
+const struct usbd_descriptors usb_descs[]
+ = {{ (uint8_t *)&usb_fs_descs, (uint8_t *)&usb_fs_descs + sizeof(usb_fs_descs) }};
diff --git a/sysmoOCTSIM/usb_start.c b/sysmoOCTSIM/usb_start.c
index d02edc0..83fac81 100644
--- a/sysmoOCTSIM/usb_start.c
+++ b/sysmoOCTSIM/usb_start.c
@@ -8,28 +8,7 @@
#include "atmel_start.h"
#include "usb_start.h"
-#if CONF_USBD_HS_SP
-static uint8_t single_desc_bytes[] = {
- /* Device descriptors and Configuration descriptors list. */
- CDCD_ACM_HS_DESCES_LS_FS};
-static uint8_t single_desc_bytes_hs[] = {
- /* Device descriptors and Configuration descriptors list. */
- CDCD_ACM_HS_DESCES_HS};
-#define CDCD_ECHO_BUF_SIZ CONF_USB_CDCD_ACM_DATA_BULKIN_MAXPKSZ_HS
-#else
-static uint8_t single_desc_bytes[] = {
- /* Device descriptors and Configuration descriptors list. */
- CDCD_ACM_DESCES_LS_FS};
#define CDCD_ECHO_BUF_SIZ CONF_USB_CDCD_ACM_DATA_BULKIN_MAXPKSZ
-#endif
-
-static struct usbd_descriptors single_desc[]
- = {{single_desc_bytes, single_desc_bytes + sizeof(single_desc_bytes)}
-#if CONF_USBD_HS_SP
- ,
- {single_desc_bytes_hs, single_desc_bytes_hs + sizeof(single_desc_bytes_hs)}
-#endif
-};
/** Buffers to receive and echo the communication bytes. */
static uint32_t usbd_cdc_buffer[CDCD_ECHO_BUF_SIZ / 4];
@@ -77,6 +56,8 @@ static bool usb_device_cb_state_c(usb_cdc_control_signal_t state)
return false;
}
+extern const struct usbd_descriptors usb_descs[];
+
/**
* \brief CDC ACM Init
*/
@@ -88,7 +69,7 @@ void cdc_device_acm_init(void)
/* usbdc_register_funcion inside */
cdcdf_acm_init();
- usbdc_start(single_desc);
+ usbdc_start((struct usbd_descriptors *) usb_descs);
usbdc_attach();
}