Monday 30 December 2019

stm32 USB composite device


There is a need to implement on stm32 usb composite device. The problem is that all USB devices are the same, will not work in parallel (three smart card readers connected to one UART). That is, you just need to track which device the command is sent to and do some machinations outside the USB logic (turn on the selected card, turn off the rest).


It seems to me that the full implementation of USB Composite device complicates the code too much, and I can not defeat it in any way.


Is there an easier option to implement this task without unnecessary code complications?


Once again, you need to display 3 USB devices in the device Manager, each of which will accept commands, but from the microcontroller they will act on the same algorithm.


UPDATE


The problem is this. At the present time one unit uses 3 end points. In total, I should have three - it's 9 endpoints + zero.


And stm only supports 7. I need to somehow at the software level to display three connected devices, but from the stm side to process the data coming to them through one processor.


For my purposes, I need only some device ID, which was accessed from the host (address, index, anything). Is it possible to do this without increasing the number of endpoints and not prescribing each individual device initialization and handler?



Hope, so a bit clearer)


Give the device descriptor


  0x09,   /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
SMARTCARD_SIZ_CONFIG_DESC,

0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
0x04, /* iConfiguration: */

0x80, /*bmAttributes: bus powered */
0x32, /* MaxPower 100 mA */

/******************** CCID **** interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* 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) */


0x02, /* bMaxSlotIndex :highest available slot on this device */
0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V
04h 1.8V*/

0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */
0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10,
for 4 Mhz the value is (0x00000FA0) :
This is used in ETU and waiting time calculations*/
0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency
in KHz. So, 3.6Mhz = 3600kHz = 0x0E10,

4 Mhz (0x00000FA0) : */
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 */

0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps
9677 bps = 0x25CD

for example 10752 bps (0x00002A00) */

0xCD,0x25,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

*/

0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */
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 */
0x03, /* bMaxCCIDBusySlots */


/******************** CCID Endpoints ********************/
0x07, /*Endpoint descriptor length = 7*/
0x05, /*Endpoint descriptor type */
CCID_BULK_IN_EP, /*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 */

0x05, /*Endpoint descriptor type */
CCID_BULK_OUT_EP, /*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*/
0x05, /*bDescriptorType:*/

CCID_INTR_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /* bmAttributes: Interrupt endpoint */
LOBYTE(CCID_INTR_EPIN_SIZE),
HIBYTE(CCID_INTR_EPIN_SIZE),
0x18 /*Polling interval in milliseconds */

In response to RDR_to_PC_NotifySlotChange, I send the answer 3F, which, in theory, should mean that I have three slots with cards, each of which is inserted into the slot and works. However, windows displays and sees only one slot. In General,that is why it was decided to try to make a composite device.


UPDATE


Well, the previous idea was bad. What could be the error of the multi-slot approach? As I understand it, the maximum slot index is set in the descriptor, and the state of each of the available slots is passed to RDR_to_PC_NotifySlotChange. But why change these values in the required Windows stubbornly continues to appeal only to the zero slot number and ignores the rest (checked on the UWP app, in debug it is visible that Windows only gets one card). Maybe I'm missing something?




No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...