0
votes

I'm stumped on communicating with a USB card reader using an embedded controller as the host. With great patience, I have been able to send control transactions and manipulate the LEDs and I am able to receive status updates on the IN pipe when a card is inserted. What I am unable to do is send what I believe should be a report request on the control pipe to request the card data.

My question is how do I set up this report request to get the HID card reader to send me the card data (report ID = 0x65, usage ID = 0x61C)? If my understanding is correct this should come down to a simple manipulation of flags in the setup packet, but for the life of me I cannot figure out which ones are correct.

The following code is used to setup the set_config transaction sent on the control EP to manipulate LEDs and is known good:

//Format the setup transaction 
req.bmRequestType = USB_REQ_DIR_OUT         |   // 7    - Transfer is OUT   
                    USB_REQ_TYPE_CLASS      |   // 5,6  - Transfer type is Class 
                    USB_REQ_RECIP_INTERFACE;    // 4    - recipient is the device

//Set the request type to USB_REQ_SET_CONFIGURATION
req.bRequest = USB_REQ_SET_CONFIGURATION;   

//Set the descriptor type to string
req.wValue = (USB_DT_STRING << 8) | usb_dt;     //wValue type. On Linux ==> 0x302 for init msg,
                                                //                          0x35f for led on control

req.wIndex = 0;                         
req.wLength = len;  

The function uses the value passed in 0x302 for the init message and 0x35f for LED control. It then starts a transfer which moves a buffer containing the report ID at index 0 for the desired command, then some data (RGB values).

Lastly Here are the descriptors for the device I'm working with:

Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x6352
idProduct 0x240a
bcdDevice 3.01
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0022
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 3
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA\

Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 4\

HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 730\

Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 46

Any guidance or help would be tremendously appreciated,
-Justin

1

1 Answers

0
votes

Ah Ha! I had failed to realize the 16-bit wValue field needs to contain the Report Id. The solution was two-fold, first set the first byte of the payload to the report ID on the application level. Then in the low-level request descriptor shown in the question setting the wValue field like this:

req.wValue = (USB_DT_STRING << 8) | pkt[0];