new usb device class
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
new usb device class
Hello,
How can I add a new class USB device ("CCID") in combo with CDC and MSC?
Tips on where to start to implement something like that?
Special arrangements for the implementation of pyboard?
thanks,
Francesco
How can I add a new class USB device ("CCID") in combo with CDC and MSC?
Tips on where to start to implement something like that?
Special arrangements for the implementation of pyboard?
thanks,
Francesco
Re: new usb device class
I've never messed around with the descriptors and stuff to add a new class, but the gist of what you need to do is this (if its even possible):
1 - modify the USB descriptors to advertise that the device supports CCID. These can be found in the stmhal/usbd_desc.h/.c files.
2 - Add a new class driver that supports the combination of descriptors you want to support. We're currently using usbdev/class/src/usbd_cdc_msc_hid.c You'd need to create a new file that implements the portions that you want.
3 - When initializing the USB device in the pyb_usb_dev_init function, call into your new code to register callbacks etc to handle the new interface.
While developing the USB stuff, you'll want to use a HW UART for the REPL, since the USB-serial will almost certainly be broken. One simple way to add a UART REPL is to change the stmhal/boards/PYBV10/mpconfigboard.h (assumes you're using the pyboard) and add these 2 lines: which will setup a UART REPL on UART6.
1 - modify the USB descriptors to advertise that the device supports CCID. These can be found in the stmhal/usbd_desc.h/.c files.
2 - Add a new class driver that supports the combination of descriptors you want to support. We're currently using usbdev/class/src/usbd_cdc_msc_hid.c You'd need to create a new file that implements the portions that you want.
3 - When initializing the USB device in the pyb_usb_dev_init function, call into your new code to register callbacks etc to handle the new interface.
While developing the USB stuff, you'll want to use a HW UART for the REPL, since the USB-serial will almost certainly be broken. One simple way to add a UART REPL is to change the stmhal/boards/PYBV10/mpconfigboard.h (assumes you're using the pyboard) and add these 2 lines:
Code: Select all
#define MICROPY_HW_UART_REPL PYB_UART_6
#define MICROPY_HW_UART_REPL_BAUD 115200
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: new usb device class
Hi Dave,
for ccid class i need 3 ep, 1 in, 1 out and 1 for int.
hid and msc implementation on pyboard only use 1 for in e 1 for out, where can i find the third ep for int?
Any hint?
Thanks,
Francesco
for ccid class i need 3 ep, 1 in, 1 out and 1 for int.
hid and msc implementation on pyboard only use 1 for in e 1 for out, where can i find the third ep for int?
Any hint?
Thanks,
Francesco
Re: new usb device class
I think you'll have to disable one of CDC or MSC then.
Looking at the 405 datasheet, there are only a total 3 IN endpoints, and 3 OUT endpoints (and these can be configured to be bulk or INT).
Personally, I'd recommend disabling MSC and use CDC + CCID. You can use something like rshell to copy files into and out of the pyboard using CDC.
Looking at the 405 datasheet, there are only a total 3 IN endpoints, and 3 OUT endpoints (and these can be configured to be bulk or INT).
Personally, I'd recommend disabling MSC and use CDC + CCID. You can use something like rshell to copy files into and out of the pyboard using CDC.
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: new usb device class
Hi Dave,
this is my configuration:
this is my configuration:
Code: Select all
#define CCID_BULK_EP_MAX_PACKET 64
#define CCID_INTR_EP_MAX_PACKET 8
#define CCID_BULK_EPIN_SIZE CCID_BULK_EP_MAX_PACKET
#define CCID_BULK_EPOUT_SIZE CCID_BULK_EP_MAX_PACKET
#define CCID_INTR_EPIN_SIZE CCID_INTR_EP_MAX_PACKET
#define CCID_BULK_OUT_EP_WITH_CDC 0x01
#define CCID_BULK_IN_EP_WITH_CDC 0x81
#define CCID_INTR_IN_EP_WITH_CDC 0x02
#define CDC_CCID_TEMPLATE_CONFIG_DESC_SIZE (159)
#define CCID_IFACE_NUM_WITH_CDC (0)
#define CDC_IFACE_NUM_WITH_CCID (1)
// USB CDC CCID device Configuration Descriptor
static const uint8_t cdc_ccid_template_config_desc[CDC_CCID_TEMPLATE_CONFIG_DESC_SIZE] = {
//--------------------------------------------------------------------------
// Configuration Descriptor
0x09, // bLength: Configuration Descriptor size
USB_DESC_TYPE_CONFIGURATION, // bDescriptorType: Configuration
LOBYTE(CDC_CCID_TEMPLATE_CONFIG_DESC_SIZE), // wTotalLength: no of returned bytes
HIBYTE(CDC_CCID_TEMPLATE_CONFIG_DESC_SIZE),
0x03, // bNumInterfaces: 3 interfaces
0x01, // bConfigurationValue: Configuration value
0x04, // iConfiguration: Index of string descriptor describing the configuration
0x80, // bmAttributes: bus powered; 0xc0 for self powered
0xfa, // bMaxPower: in units of 2mA
// CCID only has 1 interface so doesn't need an IAD
/******************** CCID **** interface ********************/
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
CCID_IFACE_NUM_WITH_CDC, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
0x0B, /* bInterfaceClass: user's interface for CCID */
0x00, /* bInterfaceSubClass : */
0x00, /* nInterfaceProtocol : None */
0x05, /* iInterface: */
/******************* CCID class descriptor ********************/
0x36, /* bLength: CCID Descriptor size */
0x21, /* bDescriptorType: Functional Descriptor type. */
0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */
0x01, /* bcdCCID(MSB) */
0x00, /* bMaxSlotIndex :highest available slot on this device */
0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V
04h 1.8V*/
0x02,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0, 0002h = Protocol T=1 */
0x68,0x10,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10,
for 4 Mhz the value is (0x00000FA0), 4.2 Mhz (0x00001068) :
This is used in ETU and waiting time calculations*/
0x68,0x10,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency
in KHz. So, 3.6Mhz = 3600kHz = 0x0E10,
4 Mhz (0x00000FA0), 4.2 Mhz (0x00001068):*/
0x00, /* bNumClockSupported : no setting from PC
If the value is 00h, the
supported clock frequencies are assumed to be the
default clock frequency defined by dwDefaultClock
and the maximum clock frequency defined by
dwMaximumClock */
0x1A,0x2C,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps
9677 bps = 0x25CD
for example 10752 bps (0x00002A00), 11290 bps = (0x00002C1A) */
0x1A,0x2C,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data
rate in bps */
0x00, /* bNumDataRatesSupported :
The number of data rates that are supported by the CCID
If the value is 00h, all data rates between the default
data rate dwDataRate and the maximum data rate
dwMaxDataRate are supported.
Dont support GET_CLOCK_FREQUENCIES
*/
0xFE,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) 0x000000FE (T=1) */
0x00,0x00,0x00,0x00, /* dwSynchProtocols */
0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */
0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00,
/* dwFeatures: clk, baud rate, voltage : automatic */
/* 00000008h Automatic ICC voltage selection
00000010h Automatic ICC clock frequency change
00000020h Automatic baud rate change according to
active parameters provided by the Host or self
determined 00000100h CCID can set
ICC in clock stop mode
Only one of the following values may be present to
select a level of exchange:
00010000h TPDU level exchanges with CCID
00020000h Short APDU level exchange with CCID
00040000h Short and Extended APDU level exchange
If none of those values : character level of exchange*/
0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/
/* 261 + 10 */
0x00, /* bClassGetResponse*/
0x00, /* bClassEnvelope */
0x00,0x00, /* wLcdLayout : 0000h no LCD. */
0x00, /* bPINSupport : no PIN verif and modif */
0x01, /* bMaxCCIDBusySlots */
/******************** CCID Endpoints ********************/
0x07, /*Endpoint descriptor length = 7*/
USB_DESC_TYPE_ENDPOINT, /*Endpoint descriptor type */
CCID_BULK_IN_EP_WITH_CDC, /*Endpoint address (IN, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(CCID_BULK_EPIN_SIZE),
HIBYTE(CCID_BULK_EPIN_SIZE),
0x00, /*Polling interval in milliseconds */
0x07, /*Endpoint descriptor length = 7 */
USB_DESC_TYPE_ENDPOINT, /*Endpoint descriptor type */
CCID_BULK_OUT_EP_WITH_CDC, /*Endpoint address (OUT, address 1) */
0x02, /*Bulk endpoint type */
LOBYTE(CCID_BULK_EPOUT_SIZE),
HIBYTE(CCID_BULK_EPOUT_SIZE),
0x00, /*Polling interval in milliseconds*/
0x07, /*bLength: Endpoint Descriptor size*/
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
CCID_INTR_IN_EP_WITH_CDC, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /* bmAttributes: Interrupt endpoint */
LOBYTE(CCID_INTR_EPIN_SIZE),
HIBYTE(CCID_INTR_EPIN_SIZE),
0x18, /*Polling interval in milliseconds */
//==========================================================================
// Interface Association for CDC VCP
0x08, // bLength: 8 bytes
USB_DESC_TYPE_ASSOCIATION, // bDescriptorType: IAD
CDC_IFACE_NUM_WITH_CCID, // bFirstInterface: first interface for this association
0x02, // bInterfaceCount: nummber of interfaces for this association
0x02, // bFunctionClass: Communication Interface Class
0x02, // bFunctionSubClass: Abstract Control Model
0x01, // bFunctionProtocol: Common AT commands
0x00, // iFunction: index of string for this function
//--------------------------------------------------------------------------
// Interface Descriptor
0x09, // bLength: Interface Descriptor size
USB_DESC_TYPE_INTERFACE, // bDescriptorType: Interface
CDC_IFACE_NUM_WITH_CCID, // bInterfaceNumber: Number of Interface
0x00, // bAlternateSetting: Alternate setting
0x01, // bNumEndpoints: One endpoints used
0x02, // bInterfaceClass: Communication Interface Class
0x02, // bInterfaceSubClass: Abstract Control Model
0x01, // bInterfaceProtocol: Common AT commands
0x00, // iInterface:
// Header Functional Descriptor
0x05, // bLength: Endpoint Descriptor size
0x24, // bDescriptorType: CS_INTERFACE
0x00, // bDescriptorSubtype: Header Func Desc
0x10, // bcdCDC: spec release number
0x01, // ?
// Call Management Functional Descriptor
0x05, // bFunctionLength
0x24, // bDescriptorType: CS_INTERFACE
0x01, // bDescriptorSubtype: Call Management Func Desc
0x00, // bmCapabilities: D0+D1
CDC_IFACE_NUM_WITH_CCID + 1, // bDataInterface: 1
// ACM Functional Descriptor
0x04, // bFunctionLength
0x24, // bDescriptorType: CS_INTERFACE
0x02, // bDescriptorSubtype: Abstract Control Management desc
0x02, // bmCapabilities
// Union Functional Descriptor
0x05, // bFunctionLength
0x24, // bDescriptorType: CS_INTERFACE
0x06, // bDescriptorSubtype: Union func desc
CDC_IFACE_NUM_WITH_CCID + 0, // bMasterInterface: Communication class interface
CDC_IFACE_NUM_WITH_CCID + 1, // bSlaveInterface0: Data Class Interface
// Endpoint 2 Descriptor
0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_CMD_EP, // bEndpointAddress
0x03, // bmAttributes: Interrupt
LOBYTE(CDC_CMD_PACKET_SIZE), // wMaxPacketSize:
HIBYTE(CDC_CMD_PACKET_SIZE),
0x20, // bInterval: polling interval in frames of 1ms
//--------------------------------------------------------------------------
// Data class interface descriptor
0x09, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_INTERFACE, // bDescriptorType: interface
CDC_IFACE_NUM_WITH_CCID + 1, // bInterfaceNumber: Number of Interface
0x00, // bAlternateSetting: Alternate setting
0x02, // bNumEndpoints: Two endpoints used
0x0A, // bInterfaceClass: CDC
0x00, // bInterfaceSubClass: ?
0x00, // bInterfaceProtocol: ?
0x00, // iInterface:
// Endpoint OUT Descriptor
0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_OUT_EP, // bEndpointAddress
0x02, // bmAttributes: Bulk
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize:
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00, // bInterval: ignore for Bulk transfer
// Endpoint IN Descriptor
0x07, // bLength: Endpoint Descriptor size
USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint
CDC_IN_EP, // bEndpointAddress
0x02, // bmAttributes: Bulk
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),// wMaxPacketSize:
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00, // bInterval: ignore for Bulk transfer
};
but from:
USBD_CDC_MSC_HID_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) {
...
uncomment:
printf("SU: %x %x %x %x\n", req->bmRequest, req->bRequest, req->wValue, req->wIndex);
...
}
i see:
MicroPython v1.5 on 2015-11-17; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>> SU: a1 21 0 1
SU: 21 22 0 1
SU: 21 20 0 1
SU: a1 21 0 1
SU: a1 21 0 1
SU: a1 21 0 1
SU: a1 21 0 1
SU: a1 21 0 1
SU: 21 20 0 1
SU: a1 21 0 1
SU: 21 22 3 1
SU: 21 20 0 1
SU: a1 21 0 1
req->wIndex "0" is missing, any suggest?
Attached the screen capture of device manager, i can see the cdc and ccid device correctly configured and ready to use, but isn't corrent ...
Thanks,
Francesco
- Attachments
-
- devices.PNG (8.38 KiB) Viewed 10524 times
Re: new usb device class
Sorry, but I'm not sure what the issue is.
My recommendation would be to hook this up to a linux machine and use lsusb -v to see what the descriptors look like. (and perhaps looks through http://www.beyondlogic.org/usbnutshell/usb5.shtml)
There is probably an equivalent tool under Windows, but its been a long time since I've done any active Windows development.
My recommendation would be to hook this up to a linux machine and use lsusb -v to see what the descriptors look like. (and perhaps looks through http://www.beyondlogic.org/usbnutshell/usb5.shtml)
There is probably an equivalent tool under Windows, but its been a long time since I've done any active Windows development.
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: new usb device class
Someone else can help me?
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: new usb device class
Hi Dave,
But I have some doubts, with 6 endpoints 3 input and 3 output specifically:
I can not use 0x02 as the endpoint interrupts because it is an output, how can I do? suggestions?
Thanks,
As you counsel'm trying configuration ccid + CDC.dhylands wrote:I think you'll have to disable one of CDC or MSC then.
Looking at the 405 datasheet, there are only a total 3 IN endpoints, and 3 OUT endpoints (and these can be configured to be bulk or INT).
Personally, I'd recommend disabling MSC and use CDC + CCID. You can use something like rshell to copy files into and out of the pyboard using CDC.
But I have some doubts, with 6 endpoints 3 input and 3 output specifically:
Code: Select all
#define CDC_IN_EP (0x83)
#define CDC_OUT_EP (0x03)
#define CDC_CMD_EP (0x82)
#define CCID_BULK_IN_EP_WITH_CDC (0x81)
#define CCID_BULK_OUT_EP_WITH CDC (0x01)
#define CCID_INTR_IN_EP_WITH CDC (0x02)
Thanks,
-
- Posts: 89
- Joined: Fri Sep 11, 2015 10:47 pm
- Location: Italy
Re: new usb device class
Can someone help me?