From: Anatoly V. <an...@gm...> - 2014-11-13 14:14:34
|
Hi, I'm writing a driver for a device. It was originally using MDB ICP, but now it ships with a USB to MDB bridge, why they have chosen to do it as HID rather then USB Serial i have no idea. So behind the usb there is a simple serial protocol. Here is what lsusb gives: Bus 001 Device 027: ID 155d:0002 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x155d idProduct 0x0002 bcdDevice 2.95 iManufacturer 1 (error) iProduct 2 NRI-USB-HID-DEV-01 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 8 Main Configuration bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 5 Alternate Setting1 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 30 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 8 Device Status: 0x0001 Self Powered I take it, this means one configuration, one interface, one end point. So the data should be read from endpoint at address 0x82, and data should be written to endpoint 0x00 with ctrl_transfer, is that correct? Here is a SnoopyPro trace of control software running on windows, for message sent to device: URB Header (length: 80) SequenceNumber: 21 Function: 001b (CLASS_INTERFACE) PipeHandle: 00000000 SetupPacket: 0000: 22 09 00 03 00 00 00 00 bmRequestType: 22 DIR: Host-To-Device TYPE: Class RECIPIENT: Endpoint bRequest: 09 TransferBuffer: 0x00000008 (8) length 0000: 03 02 85 0a 05 14 ff ff The payload of this is [0x02 0x85 0x0a], that's the init command as described in device docs. The device replies with this: URB Header (length: 80) SequenceNumber: 22 Function: 0008 (CONTROL_TRANSFER) PipeHandle: 86d039cc SetupPacket: 0000: a1 01 00 03 00 00 08 00 bmRequestType: a1 DIR: Device-To-Host TYPE: Class RECIPIENT: Interface bRequest: 01 TransferBuffer: 0x00000008 (8) length 0000: 01 2e ff ff ff ff ff ff Payload of this is [0x2E] again per spec. Now my goal is to reproduce this simple exchange, once i have that i can go on to implement all other needed commands. I'm guessing that the protocol messages are prepended with message size byte and padded up to 8 bytes with 0xFF or random data Curiously snoopyPro generates traces even if the control application is not loaded, i assume these messages don't make it to the actual device. Here is the gist of my code: dev = usb.core.find(idVendor=0x155d, idProduct=0x0002) # check and remove kernel driver dev.set_configuration() dev.reset() # bmRequestType, bRequest are taken from SnoopyPro trace. res = dev.ctrl_transfer(0x22, 0x9, 0, 0, [0x02, 0x85, 0x0a], 1000) data = dev.read(0x82, 32, timeout=10000) ctrl_transfer fails with USBError(32, 'Pipe error') and after couple of retries : USBError(19, 'No such device (it may have been disconnected)') i have also tried the whole byte string from the capture res = dev.ctrl_transfer(0x22, 0x9, 0, 0, [0x03, 0x02, 0x85, 0x0a, 0x05, 0x14, 0xff, 0xff], 1000) to same effect. So what am i missing? Why is the trace saying that host to device message is using function 0x1b (Class interface) and device to host is using function 0x08 (control transfer), shouldn't it be the other way around? thanks, Anatoli |