You can also search the /sys/devices/ tree.  On my system (SUSE 11.1, Linux 
2.6), all usb devices appear in /sys/devices/pci0000:00/ subdirectories.  The 
particular hardware-to-subdirectory mapping varies by boot, but there's lots of 
configuration information if you go sufficiently leafward in the tree, 
including vendorID, productID, /dev/ entry, and available configurations, 
interfaces, etc.

The exact info and placement which shows up depends on the driver / hardware 
which you're using.  I've three different USB/RS232 adapters, and have to 
identify each one in a different way - but I use the /sys/devices tree for all 
of them.  Here's some code to do the search.  Hopefully the comments and 
doc-strings are enough documentation to get it working.  (You'll probably want 
to change all "runlog" calls to print statements since that references my own 
logging utility.)

def sercheck(dirname,subdirstem,SerNumRE,Interface):
    '''Check if a given sysfs directory matches regular expression SerNumRE

    dirname is the full path to the subdirectory of /sys/devices/ containing 
the description of the device.
    subdirstem is a partial path to be used in forming the names of further 
subdirectories.
    SerNumRE is a regular expression describing the serial number of the target 
device
    Interface is a digit indexing the appropriate USB interface which 
corresponds to thte target scope.

    This function is designed for the USB-16COM-RM 16-port USB/RS-232 hub, but
    also works for the SeaLevel SeaLink #2113 USB/RS-232 adapter.'''
    if os.path.isfile(dirname+'/serial'):
        serialfile=open(dirname+'/serial',mode='r')
        sernum=serialfile.readline()
        serialfile.close()
        if SerNumRE.match(sernum):
            intflist=shortdir(dirname, re.escape(subdirstem+':1.'+Interface))
            intfdir=intflist[0]
            foundlist=shortdir(dirname+'/'+intfdir, r'ttyUSB[0-9]+')
            foundat=foundlist[0]
            return foundat
    return False

def MoxaCheck(dirname,subdirstem,DesiredName,rl):
    '''Check if a given sysfs directory matches the target scope number.

    dirname is the full path to the subdirectory of /sys/devices/ containing 
the description of the device.
    subdirstem is a partial path to be used in forming the names of further 
subdirectories.
    DesiredName is the name of a directory to seek on the prospective scope.
        The prospective scope is assumed to be the correct one iff a directory
        with this name is found on it.

    This function is designed for the MOXA UPort 1450I 4-port USB/RS-232 hub.'''
        #first check to see if this is a MOXA hub.
    if not os.path.isfile(dirname+'/manufacturer'):
        return False
    manufile=open(dirname+'/manufacturer',mode='r')
    manu=manufile.readline()
    manufile.close()
    if not manu.startswith('MOXA'):
        return False
            #now know we have a MOXA hub - look in its interface dir for 
subdirectories corresponding to the /dev entries
    intflist=shortdir(dirname, re.escape(subdirstem+':1.0'))
    intfdir=intflist[0]
    portlist=shortdir(dirname+'/'+intfdir, r'ttyMXUSB[0-9]+')
        #reorder portlist as a guess at the best order to search for the scope
    num=int(DesiredName[-1])    #assumes scopes 1-8 are attached to the MOXA 
hubs in order, 1-4 on one, 5-8 on the other
    num=(num-1)%4   #get the remainder modulo 4
    while num!=int((portlist[0])[-1])%4:
        port=portlist.pop(-1)
        portlist.insert(0,port)
    for port in portlist:
        DevToCheck=port
            #contact this scope - assuming it's connected
        try:
            tempScope=SerScope((0,'TEMP','/dev/'+DevToCheck),rl,set([]))
            fileset=tempScope.ask('FILES:DIR?')
            if '"'+DesiredName+'"' in fileset:    #check if this scope has the 
desired directory
                tempScope.close()
                return DevToCheck
            rl.log(2,'%s is a scope, but not the target one.'%DevToCheck)
        except IOError,msg:
            rl.log(2,'%s is not a scope, gave message %s'%(DevToCheck,msg))
    return False

def HubSearch1Tier(Target,IDmode,path,prefix,tier,Interface,runlog):
    '''Recursively searches for an RS-232 port attached via a USB-RS-232 hub.

    declaration:
        HubSearch1Tier(Target,IDmode,path,tier,runlog)
    Target - the identification string (Serial number or directory name) for 
the target scope
    IDmode - 1 or 3, depending on the hardware used to connect to the scope
    path - the base path where the search should begin
    prefix - portion of valid subdirectories which reflects higher-level search 
path
    tier - integer between 1 and 7, inclusive.  Tier 1 is the root USB hub.  
Tier 7 is the leafmost possible device.
    Interface - 0 to 7 if the device interface specifies which scope to 
contact; -1 otherwise
    runlog - runlog.runlog instance for message logging

    This function is only intended to be called by USBRS232HubSearch() and by 
itself.
    This routine does a depth-first search.'''
    runlog.log(2,'Searching for %s in %s'%(Target,path))
        #USB specifies max of 7 tiers.
    if tier==1: #This is the root hub, Tier 1.  Is USB always in 0000:00:1d.x 
?; get USB directories
        pattern=r'0000:00:1d\.[0-7]'    #pattern is passed to shortdir to find 
directories for the next tier
    elif tier==2:   #e.g. path='/sys/devices/pci0000:00/0000:00:1d.0'      
[Tier 2]
        pattern=r'usb[1-7]' #0 is hub controller itself?
    elif tier==3:   #e.g. path='/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2' 
[Tier 3]
        pattern=prefix+r'-[1-7]'
    elif tier in [4,5,6,7]:
            #Tier 4 e.g. 
path='/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2.1'
            #Tier 5 e.g. 
path='/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2.1/1-2.1.7'
            #Tier 6 e.g. 
'/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2.1/1-2.1.7/1-2.1.7.4'
            #Tier 7 e.g. 
'/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2.1/1-2.1.7/1-2.1.7.4.5'
        pattern=prefix+r'\.[1-7]'
    else:
        raise ValueError,'Tier must be an integer between 1 and 7, inclusive, 
not %f'%tier
    dirlist=shortdir(path,pattern)
    for subdir in dirlist:
        newpath=path+'/'+subdir
        if tier==2:
            newprefix=subdir[3] #1 char (usually?) for bus number
        else:
            newprefix=subdir
        if tier>=3:   #can't attach serial scopes at tiers 1-3
            if IDmode==1:
                foundat=sercheck(newpath,newprefix,Target,Interface)
            else:   #IDmode==3
                foundat=MoxaCheck(newpath,newprefix,Target,runlog)
            if foundat:
                runlog.log(2,'%s on %s.'%(Target, foundat))
                return foundat
        if tier<7:
            
foundat=HubSearch1Tier(Target,IDmode,newpath,newprefix,tier+1,Interface,runlog)
            if foundat:
                return foundat
    return False

def USBRS232HubSearch(TargetSerNum,runlog):
    '''Searches for an RS-232 port attached via a USB-RS-232 hub.

    declaration:
        USBRS232HubSearch(TargetSerNum,runlog)
    TargetSerNum - serial number of the hardware USB/RS-232 converter for the 
target scope.
        The serial number of the leafmost USB device should be xxx, where the 
input TargetSerNum is
        SERxxxD.  D should be the USB interface for the RS-232 port and must be 
between 0 and 7.
    runlog - runlog.runlog instance for message logging'''
    if TargetSerNum=='TEMP':      #temporary serial number generated by 
MoxaCheck() to search for a scope
        raise IOError, "No scope at target location."
    runlog.log(0,'Searching for %s'%TargetSerNum)
    basepath='/sys/devices/pci0000:00'
    if TargetSerNum.startswith('SER'):
           #16-port USB/RS-232 hub or 1-port SeaLevel SeaLink adapter; ID by 
adapter's serial # & interface
        TSNre=re.compile(r'\ASER\S+?[0-7]\Z')
        if not TSNre.match(TargetSerNum):
            raise ValueError, 'Invalid serial number %s'%TargetSerNum
                #serial number
        devstr=TargetSerNum[3:len(TargetSerNum)-1]
        SerNumRE=re.compile(devstr+r'\s*')
        Interface=TargetSerNum[len(TargetSerNum)-1] #single-character interface 
num
        return HubSearch1Tier(SerNumRE,1,basepath,'',1,Interface,runlog)
    elif TargetSerNum.startswith('COM'): #RS-232 port directly on the computer
        return '/dev/ttyS0' #This might even be general - anything's possible
    elif TargetSerNum.startswith('moxa'): #MOXA UPort 1450I 4-port USB/RS-232 
hub
        DesiredName=TargetSerNum[4:]
        return HubSearch1Tier(DesiredName,3,basepath,'',1,-1,runlog)
    else:
        raise ValueError, 'Invalid serial number %s'%TargetSerNum


Your milage may vary.

-Sarah

--- On Wed, 6/17/09, Santiago Palomino Sanchez-Manjavacas <[email protected]> 
wrote:

From: Santiago Palomino Sanchez-Manjavacas <[email protected]>
Subject: Re: [Pyusb-users] Mapping usb serial devices to device filenames
To: [email protected], [email protected]
Date: Wednesday, June 17, 2009, 3:08 AM

Hi,

This is based on a script that I downloaded with Porus. I think it was called 
porustest.py: http://prdownload.berlios.de/porus/porus-0.1.1.tgz


I recommend you to test it. It has a command interface that is useful for 
debugging. 

Self is the command interpreter object, 

def getdevs():
    """Returns a flat array of configs on all busses -- ie an 

    array of tuples of (bus,dev,conf).  Array is guaranteed to be 
    sorted by bus and dev.  Used for giving numbers to configs"""
    rtn=[]
    for b in usb.busses():
    for d in b.devices:

        for c in d.configurations:
        rtn.append((b,d,c))
    return rtn

I don't know much about the serial part, but I would look into how 
serial.Serial(port) is implemented. May be you need to change it a bit if you 
want to open a device by PID and VID. I guess that it opens the device and 
claims an interface, but I haven't used that library. I hope this helps. Ah, I 
forgot




On Wed, Jun 17, 2009 at 9:27 AM, Brendan Simon (eTRIX) 
<[email protected]> wrote:

Thanks Santiago :)

Unfortunately I'm new to usb so it's not making too much sense at the

moment.



What is the class object that self is referring to here ?



Is getdevs() your own function or a standard os function ?

Presumably getdevs calls something like usb.busses() somewhere ?



I don't see how this gives me the name of the serial device (eg.

/dev/cu.usbmodem0001) that I can then reference with pyserial Serial()

function.

example:

    port = '/dev/cu.usbmodem0001'  # need to auto detect/determine this

    ser = serial.Serial( port )



Thanks Brendan.





Santiago Palomino Sanchez-Manjavacas wrote:

> Well, you can use the device VID and PID to select which device to open.

> I use something like:

>

>    def do_d(self, args):

>         if self.devh is not None:

>         self.do_close('')

> #ls

>     if self.devh is None:

>         self.devs=getdevs()

>     shortlist(self.devs)

>         dn = -1;

>         index = 0;

>         for d in self.devs:

>                 if (d[1].idVendor == 0xFFFF and d[1].idProduct == 0x0000):

>                         dn = index;

>                 index = index + 1;

>         if(dn == -1):

>                 return 1

>     self.curdev=self.devs[dn]

>     self.devh=self.curdev[1].open()

>     self.devn=dn

>     self.devh.setConfiguration(self.curdev[2])

>

>     self.devh.claimInterface(self.curdev[2].interfaces[0][0])

>     self.devh.setAltInterface(0)

>

>

>

> On Wed, Jun 17, 2009 at 7:14 AM, Brendan Simon (eTRIX)

> <[email protected] <mailto:[email protected]>> wrote:


>

>     I have a device with a usb connection that presents itself as a serial

>     device to operating system (OS X).

>     It appears as /dev/cu.usbmodem0001 and /dev/tty.usbmodem0001 on the

>     filesystem when the device is plugged in.

>

>     I can successfully detect the device USB Vendor ID and Product ID using

>     pyusb :)

>

>     Now I have to use pyserial to talk to the device -- which I have

>     successfully done by opening the serial port with a hard coded device

>     filename (/dev/cu.usbmodem0001).

>

>     There must be some way for me to use the pyusb information to be able to

>     determine the appropriate device filename to open with pyusb.

>

>     Does anyone know how to do this or have any suggestions ???

>

>     Thanks, Brendan.






-----Inline Attachment Follows-----

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
-----Inline Attachment Follows-----

_______________________________________________
Pyusb-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyusb-users



      
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Pyusb-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyusb-users

Reply via email to