Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/13998 )
Change subject: Re-structure USB descriptors ...................................................................... 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 --- M sysmoOCTSIM/atmel_start.c M sysmoOCTSIM/config/hpl_usb_config.h M sysmoOCTSIM/gcc/Makefile A sysmoOCTSIM/usb_descriptors.c M sysmoOCTSIM/usb_start.c 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 @@ 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 @@ main.o \ manual_test.o \ talloc.o \ +usb_descriptors.o \ i2c_bitbang.o \ octsim_i2c.o \ ncn8025.o \ @@ -136,6 +137,7 @@ "main.o" \ "manual_test.o" \ "talloc.o" \ +"usb_descriptors.o" \ "i2c_bitbang.o" \ "octsim_i2c.o" \ "ncn8025.o" \ @@ -194,6 +196,7 @@ "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 @@ return false; } +extern const struct usbd_descriptors usb_descs[]; + /** * \brief CDC ACM Init */ @@ -88,7 +69,7 @@ /* usbdc_register_funcion inside */ cdcdf_acm_init(); - usbdc_start(single_desc); + usbdc_start((struct usbd_descriptors *) usb_descs); usbdc_attach(); } -- To view, visit https://gerrit.osmocom.org/13998 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ccid-firmware Gerrit-Branch: master Gerrit-MessageType: merged Gerrit-Change-Id: I0423d733476f37c16bdb6abc651b7ad5ca7ac63e Gerrit-Change-Number: 13998 Gerrit-PatchSet: 3 Gerrit-Owner: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Jenkins Builder (1000002)