[Tutor] Using pyusb

Michael Holloway me at mikeholloway.co.uk
Thu Mar 20 15:08:09 CET 2008


I hope I'm using this system correctly by just hitting reply-all in my 
email client :s

Thanks very much Michael, I've been a bit thin on the other details I see.
My platform is Mac Os 10.4, I'm using USB snooper to get the data I 
need, I'll post it at the end of this message.

Forgive me, I've been trying to be bloody-minded about getting this to 
work and haven't read the USB spec. I'm not the sort of person to sit 
down and read pages of information before I get to the stuff I need, as 
I loose interest fast, I'd much rather bash away until I start seeing 
results.

Regarding the actual hardware, here's a pic:
http://www.maplin.co.uk/images/Full/tf06g_new.jpg

I brought it from Maplin, here's a link (note that the first picture 
shown ISN'T the same cable):
http://www.maplin.co.uk/Search.aspx?criteria=TF06G&DOY=20m3

I can't actually find the manufacturers site, but I have since learned 
that Prolific Tech. are the company responsible for the chip that deals 
with the routing, I believe it goes usb a -> serial -> chip -> serial -> 
usb a

When I run my script, I am definately connecting, if I don't have the 
cable plugged in it tells me so, when I plug the cable in and run it, I 
get the following output:

//some help description
8
(160,160,160,160,160,160,160,160)

I'm using bulk read/write just because it sounded right, your insight 
has definately opened my eyes a bit, I guess I really need to help 
myself by spoffing up on the books.

The cable documentation is extremely basic and poor. Where can I get the 
information I need specifically on how to get the cable to accept data 
sent from my mac?

Here's the snoop:

Full Speed device @ 3 (0x1D100000): 
.............................................   Composite device from 
Prolific Technology, Inc.
    Device Descriptor
        Descriptor Version Number:   0x0100
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   8
        Device VendorID/ProductID:   0x067B/0x0000   (Prolific 
Technology, Inc.)
        Device Version Number:   0x0000
        Number of Configurations:   1
        Manufacturer String:   1 "Prolific Technology Inc."
        Product String:   0 (none)
        Serial Number String:   0 (none)
    Configuration Descriptor
        Length (and contents):   39
            Raw Descriptor (hex)    0000: 09 02 27 00 01 01 00 A0  32 09 
04 00 00 03 FF 00
            Raw Descriptor (hex)    0010: 00 00 07 05 81 03 01 00  01 07 
05 02 02 40 00 00
            Raw Descriptor (hex)    0020: 07 05 83 02 40 00 00
        Number of Interfaces:   1
        Configuration Value:   1
        Attributes:   0xA0 (bus-powered, remote wakeup)
        MaxPower:   100 ma
        Interface #0 - Vendor-specific
            Alternate Setting   0
            Number of Endpoints   3
            Interface Class:   255   (Vendor-specific)
            Interface Subclass;   0   (Vendor-specific)
            Interface Protocol:   0
            Endpoint 0x81 - Interrupt Input
                Address:   0x81  (IN)
                Attributes:   0x03  (Interrupt no synchronization data 
endpoint)
                Max Packet Size:   1
                Polling Interval:   1 ms
            Endpoint 0x02 - Bulk Output
                Address:   0x02  (OUT)
                Attributes:   0x02  (Bulk no synchronization data endpoint)
                Max Packet Size:   64
                Polling Interval:   0 ms
            Endpoint 0x83 - Bulk Input
                Address:   0x83  (IN)
                Attributes:   0x02  (Bulk no synchronization data endpoint)
                Max Packet Size:   64
                Polling Interval:   0 ms


Michael Langford wrote:
> Btw, the win32 version of libusb is not maintained anymore, and bogus
> in my experience. I didn't really get to use libusb much on linux, but
> it seemed to get a descriptor at least. IIRC, they were upset with
> their interface and in the middle of vastly changing it.
>
>       --Michael
>
> On Wed, Mar 19, 2008 at 7:26 PM, Michael Langford
> <mlangford.cs03 at gtalumni.org> wrote:
>   
>> I've never heard of the type of cable you're using. Can you send a
>>  link to one to the list?
>>
>>  You're missing most of the USB ideas more than the python ideas.
>>
>>  USB is very very complicated. The USB spec (of which you care about
>>  chapter 9) is nothing like how most people actually use USB. Most
>>  people use a HID device (even for things that have nothing to do with
>>  human interfaces) and communicate that way.
>>
>>  If you're going to go with a raw control then:
>>  First off: Are you sure you're getting  handle to the device? What is
>>  the fault you are seeing?
>>
>>  Secondly: How do you know what endpoints your device has? Are you sure
>>  you have the right addresses for them? You should be able to see this
>>  with a USB snooping utility.
>>
>>  Control is used to use channel 0 on the USB. It only allows 8 bytes of
>>  data and a time and is usually used to switch between modes on a
>>  device in my experience. You may have to do a write here to put the
>>  device in a mode to do something . This is incredibly device specific.
>>
>>  Secondly, why are you using two different endpoints for read and
>>  write? Usually you can use 82 and 02 both. Is this something in the
>>  cable documentation that tells you to do this?
>>
>>  As you have bulk endpoints, you should be using bulk read/write. There
>>  are 4 types of USB endpoints: Control, Isochronous, Interrupt and
>>  Bulk.
>>
>>  Control Transfers are only sent over endpoint 0.
>>  Isochronous Transfers are sent periodically and are used for "real
>>  time" devices such as web cams (in practice, very very few people ever
>>  use this mode)
>>  Interrupts Transfers are next, they have a high priority after the
>>  first two types and are limited to 256 bytes (IIRC)
>>  Bulk Transfers are JUST like interrupt transfers, except, they are
>>  lower priority.
>>
>>  As you apparently are using a bulk endpoint, you need to use bulk
>>  transfers with it. The priorities are only with regards to the USB
>>  system. Just as long as your device is using all the same priority,
>>  don't worry about which one you use.
>>
>>  Your OS should have some tool to allow you to view the USB descriptors
>>  of the device. This will at least tell you where the endpoints are
>>  that you maybe could be communicating over.
>>
>>  Please check your control panel or the command line utils (or /proc
>>  device) that tells you this info, as well as where you're stuck before
>>  we can help you more.
>>
>>          --Michael
>>
>>  PS: I would have loved to have know about these modules a couple
>>  months ago. I could have avoided some C kernel modules perhaps.
>>
>>
>>
>>
>>  On Wed, Mar 19, 2008 at 4:14 PM, Mike Holloway <me at mikeholloway.co.uk> wrote:
>>  > Hi all,
>>  >
>>  >  I'm very new to this list, so hello all!
>>  >  I'm just starting out using python, my background is lamp.
>>  >  t
>>  >  I have a Prolific Technologies bridged usb cable that I wish to talk to
>>  >  using pyusb and libusb, I've tried following examples and compiling my
>>  >  own code but I'm really struggling getting it to work.
>>  >
>>  >  I'm trying to send a sequence of letters to the cable, for them to
>>  >  reappear on the other side. I've been trying to use bulkWrite and
>>  >  bulkRead methods but I'm not sure I'm using them right. There's also
>>  >  controlMethod, but I'm not sure what that is used for.
>>  >
>>  >  Can anyone help get me started, I'm concerned mostly with the
>>  >  communication, I reckon I could actually get somewhere if I can just
>>  >  nail the first bit, here's my code so far:
>>  >
>>  >  * Cheers in advance, Mike.
>>  >
>>  >
>>  >  import usb
>>  >  import sys
>>  >  import os
>>  >  import time
>>  >  from array import array
>>  >
>>  >  class DeviceDescriptor:
>>  >     def __init__(self, vendor_id, product_id, interface_id) :
>>  >         self.vendor_id = vendor_id
>>  >         self.product_id = product_id
>>  >         self.interface_id = interface_id
>>  >
>>  >     def get_device(self) :
>>  >         buses = usb.busses()
>>  >         for bus in buses :
>>  >             for device in bus.devices :
>>  >                 if device.idVendor == self.vendor_id :
>>  >                     if device.idProduct == self.product_id :
>>  >                         return device
>>  >         return None
>>  >
>>  >  class XFPS():
>>  >     VENDOR_ID      = 0x067B #: Vendor Id
>>  >     PRODUCT_ID   = 0x0000   #: Product Id for the bridged usb cable
>>  >     INTERFACE_ID = 0        #: The interface we use to talk to the device
>>  >     BULK_IN_EP   = 0x83     #: Endpoint for Bulk reads
>>  >     BULK_OUT_EP  = 0x02     #: Endpoint for Bulk writes
>>  >     PACKET_LENGTH = 0x40    #: 64 bytes
>>  >
>>  >     device_descriptor = DeviceDescriptor(VENDOR_ID, \
>>  >                                          PRODUCT_ID, INTERFACE_ID)
>>  >
>>  >     def __init__(self,) :
>>  >         # The actual device (PyUSB object)
>>  >         self.device = self.device_descriptor.get_device()
>>  >         # Handle that is used to communicate with device. Setup in L{open}
>>  >         self.handle = None
>>  >
>>  >     def open(self) :
>>  >         self.device = self.device_descriptor.get_device()
>>  >         if not self.device:
>>  >             print >> sys.stderr, "Cable isn't plugged in"
>>  >         try:
>>  >             self.handle = self.device.open()
>>  >             self.handle.claimInterface(self.device_descriptor.interface_id)
>>  >         except usb.USBError, err:
>>  >             print >> sys.stderr, err
>>  >
>>  >     def close(self):
>>  >         """ Release device interface """
>>  >         try:
>>  >             self.handle.reset()
>>  >             self.handle.releaseInterface()
>>  >         except Exception, err:
>>  >             print >> sys.stderr, err
>>  >         self.handle, self.device = None, None
>>  >
>>  >     def my_bulk_write(self):
>>  >         A = chr(0x75) # u
>>  >         B = chr(0x69) # i
>>  >         X = chr(0x6F) # o
>>  >         Y = chr(0x70) # p
>>  >         LB = chr(0x6C) # l
>>  >         RB = chr(0x6B) # k
>>  >         LT = chr(0x68) # h
>>  >         RT = chr(0x6A) # j
>>  >
>>  >         S = chr(0x32)
>>  >         s = chr(0x73)
>>  >
>>  >         self.close()
>>  >         self.open()
>>  >
>>  >         msg = [A,B,A,B,A,B,A,B]
>>  >         #help(self.handle.bulkWrite)
>>  >         help(self.handle.interruptWrite)
>>  >         sent_bytes = self.handle.interruptWrite(XFPS.BULK_OUT_EP,msg,1000)
>>  >         print sent_bytes
>>  >         if sent_bytes:
>>  >             read_bytes = self.handle.interruptRead(0x81,sent_bytes);
>>  >             print read_bytes
>>  >
>>  >  xfps = XFPS()
>>  >  xfps.open()
>>  >  xfps.my_bulk_write()
>>  >
>>  >  _______________________________________________
>>  >  Tutor maillist  -  Tutor at python.org
>>  >  http://mail.python.org/mailman/listinfo/tutor
>>  >
>>
>>
>>
>>  --
>>  Michael Langford
>>  Phone: 404-386-0495
>>  Consulting: http://www.RowdyLabs.com
>>
>>     
>
>
>
>   



More information about the Tutor mailing list