Scan should work on win32.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 24 May 2010 05:03:50 +0000 (05:03 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 24 May 2010 05:03:50 +0000 (05:03 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@564 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/goodfet
client/scanwin32.py [new file with mode: 0644]

index d580c26..070f810 100755 (executable)
@@ -14,12 +14,38 @@ from GoodFETConsole import GoodFETConsole;
 from intelhex import IntelHex;
 
 if(len(sys.argv)==1):
-    print "Usage: %s driver\n" % sys.argv[0];
-    print "driver:= monitor | cc | avr | spi | msp430";
-    print;
+    print "Usage: %s [driver|verb]\n" % sys.argv[0];
+    print "driver:= monitor | cc | avr | spi | msp430 | nrf";
+    print "verb:=   scan";
+    print "";
     print "This is an unfinished client.  You probably want goodfet.$chip instead.";
     sys.exit(1);
 
+verb=sys.argv[1];
+if verb=="scan":
+    from scanwin32 import *;
+    # INIT COMPORT SCAN
+    scan=winScan();
+    scan.comports();
+
+    for order, port, desc, hwid in sorted(scan.comports()):
+        # Look for FTDIBUS
+        try:
+            hwid.index('FTDI')
+            print "*************"
+            print "GOODFET FOUND"
+            print "*************"
+            print "%s: (%s) ->" % (port, hwid),
+            try:
+                serial.Serial(port)
+            except serial.serialutil.SerialException:
+                print "Not Ready - Is the process in use?"
+            else:
+                print "Ready"
+        except:
+            pass
+
+
 driver=sys.argv[1];
 print "Using driver %s" % driver;
 #client=eval("%s()" % driver);
diff --git a/client/scanwin32.py b/client/scanwin32.py
new file mode 100644 (file)
index 0000000..9aa9720
--- /dev/null
@@ -0,0 +1,260 @@
+# Win32 serial port scanner from PySerial.
+# Modified by Andrew Q Righter for the GoodFET Project.
+
+import ctypes
+import re
+import serial
+
+def ValidHandle(value):
+    if value == 0:
+        raise ctypes.WinError()
+    return value
+
+NULL = 0
+HDEVINFO = ctypes.c_int
+BOOL = ctypes.c_int
+CHAR = ctypes.c_char
+PCTSTR = ctypes.c_char_p
+HWND = ctypes.c_uint
+DWORD = ctypes.c_ulong
+PDWORD = ctypes.POINTER(DWORD)
+ULONG = ctypes.c_ulong
+ULONG_PTR = ctypes.POINTER(ULONG)
+#~ PBYTE = ctypes.c_char_p
+PBYTE = ctypes.c_void_p
+
+class GUID(ctypes.Structure):
+    _fields_ = [
+        ('Data1', ctypes.c_ulong),
+        ('Data2', ctypes.c_ushort),
+        ('Data3', ctypes.c_ushort),
+        ('Data4', ctypes.c_ubyte*8),
+    ]
+    def __str__(self):
+        return "{%08x-%04x-%04x-%s-%s}" % (
+            self.Data1,
+            self.Data2,
+            self.Data3,
+            ''.join(["%02x" % d for d in self.Data4[:2]]),
+            ''.join(["%02x" % d for d in self.Data4[2:]]),
+        )
+
+class SP_DEVINFO_DATA(ctypes.Structure):
+    _fields_ = [
+        ('cbSize', DWORD),
+        ('ClassGuid', GUID),
+        ('DevInst', DWORD),
+        ('Reserved', ULONG_PTR),
+    ]
+    def __str__(self):
+        return "ClassGuid:%s DevInst:%s" % (self.ClassGuid, self.DevInst)
+PSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA)
+
+class SP_DEVICE_INTERFACE_DATA(ctypes.Structure):
+    _fields_ = [
+        ('cbSize', DWORD),
+        ('InterfaceClassGuid', GUID),
+        ('Flags', DWORD),
+        ('Reserved', ULONG_PTR),
+    ]
+    def __str__(self):
+        return "InterfaceClassGuid:%s Flags:%s" % (self.InterfaceClassGuid, self.Flags)
+
+PSP_DEVICE_INTERFACE_DATA = ctypes.POINTER(SP_DEVICE_INTERFACE_DATA)
+
+PSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p
+
+class dummy(ctypes.Structure):
+    _fields_=[("d1", DWORD), ("d2", CHAR)]
+    _pack_ = 1
+SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_A = ctypes.sizeof(dummy)
+
+SetupDiDestroyDeviceInfoList = ctypes.windll.setupapi.SetupDiDestroyDeviceInfoList
+SetupDiDestroyDeviceInfoList.argtypes = [HDEVINFO]
+SetupDiDestroyDeviceInfoList.restype = BOOL
+
+SetupDiGetClassDevs = ctypes.windll.setupapi.SetupDiGetClassDevsA
+SetupDiGetClassDevs.argtypes = [ctypes.POINTER(GUID), PCTSTR, HWND, DWORD]
+SetupDiGetClassDevs.restype = ValidHandle # HDEVINFO
+
+SetupDiEnumDeviceInterfaces = ctypes.windll.setupapi.SetupDiEnumDeviceInterfaces
+SetupDiEnumDeviceInterfaces.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, ctypes.POINTER(GUID), DWORD, PSP_DEVICE_INTERFACE_DATA]
+SetupDiEnumDeviceInterfaces.restype = BOOL
+
+SetupDiGetDeviceInterfaceDetail = ctypes.windll.setupapi.SetupDiGetDeviceInterfaceDetailA
+SetupDiGetDeviceInterfaceDetail.argtypes = [HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA]
+SetupDiGetDeviceInterfaceDetail.restype = BOOL
+
+SetupDiGetDeviceRegistryProperty = ctypes.windll.setupapi.SetupDiGetDeviceRegistryPropertyA
+SetupDiGetDeviceRegistryProperty.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD]
+SetupDiGetDeviceRegistryProperty.restype = BOOL
+
+
+GUID_CLASS_COMPORT = GUID(0x86e0d1e0L, 0x8089, 0x11d0,
+    (ctypes.c_ubyte*8)(0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73))
+
+DIGCF_PRESENT = 2
+DIGCF_DEVICEINTERFACE = 16
+INVALID_HANDLE_VALUE = 0
+ERROR_INSUFFICIENT_BUFFER = 122
+SPDRP_HARDWAREID = 1
+SPDRP_FRIENDLYNAME = 12
+SPDRP_LOCATION_INFORMATION = 13
+ERROR_NO_MORE_ITEMS = 259
+
+class winScan():
+
+    def comports(available_only=True):
+        """This generator scans the device registry for com ports and yields
+        (order, port, desc, hwid).  If available_only is true only return currently
+        existing ports. Order is a helper to get sorted lists. it can be ignored
+        otherwise."""
+        flags = DIGCF_DEVICEINTERFACE
+        if available_only:
+            flags |= DIGCF_PRESENT
+        g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, flags);
+        #~ for i in range(256):
+        for dwIndex in range(256):
+            did = SP_DEVICE_INTERFACE_DATA()
+            did.cbSize = ctypes.sizeof(did)
+
+            if not SetupDiEnumDeviceInterfaces(
+                g_hdi,
+                None,
+                ctypes.byref(GUID_CLASS_COMPORT),
+                dwIndex,
+                ctypes.byref(did)
+            ):
+                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
+                    raise ctypes.WinError()
+                break
+
+            dwNeeded = DWORD()
+            # get the size
+            if not SetupDiGetDeviceInterfaceDetail(
+                g_hdi,
+                ctypes.byref(did),
+                None, 0, ctypes.byref(dwNeeded),
+                None
+            ):
+                # Ignore ERROR_INSUFFICIENT_BUFFER
+                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
+                    raise ctypes.WinError()
+            # allocate buffer
+            class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):
+                _fields_ = [
+                    ('cbSize', DWORD),
+                    ('DevicePath', CHAR*(dwNeeded.value - ctypes.sizeof(DWORD))),
+                ]
+                def __str__(self):
+                    return "DevicePath:%s" % (self.DevicePath,)
+            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()
+            idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_A
+            devinfo = SP_DEVINFO_DATA()
+            devinfo.cbSize = ctypes.sizeof(devinfo)
+            if not SetupDiGetDeviceInterfaceDetail(
+                g_hdi,
+                ctypes.byref(did),
+                ctypes.byref(idd), dwNeeded, None,
+                ctypes.byref(devinfo)
+            ):
+                raise ctypes.WinError()
+
+            # hardware ID
+            szHardwareID = ctypes.create_string_buffer(250)
+            if not SetupDiGetDeviceRegistryProperty(
+                g_hdi,
+                ctypes.byref(devinfo),
+                SPDRP_HARDWAREID,
+                None,
+                ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1,
+                None
+            ):
+                # Ignore ERROR_INSUFFICIENT_BUFFER
+                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
+                    raise ctypes.WinError()
+
+            # friendly name
+            szFriendlyName = ctypes.create_string_buffer(1024)
+            if not SetupDiGetDeviceRegistryProperty(
+                g_hdi,
+                ctypes.byref(devinfo),
+                SPDRP_FRIENDLYNAME,
+                None,
+                ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1,
+                None
+            ):
+                # Ignore ERROR_INSUFFICIENT_BUFFER
+                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
+                    #~ raise ctypes.WinError()
+                    # not getting friendly name for com0com devices, try something else
+                    szFriendlyName = ctypes.create_string_buffer(1024)
+                    if SetupDiGetDeviceRegistryProperty(
+                        g_hdi,
+                        ctypes.byref(devinfo),
+                        SPDRP_LOCATION_INFORMATION,
+                        None,
+                        ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1,
+                        None
+                    ):
+                        port_name = "\\\\.\\" + szFriendlyName.value
+                        order = None
+                    else:
+                        port_name = szFriendlyName.value
+                        order = None
+            else:
+                try:
+                    m = re.search(r"\((.*?(\d+))\)", szFriendlyName.value)
+                    #~ print szFriendlyName.value, m.groups()
+                    port_name = m.group(1)
+                    order = int(m.group(2))
+                except AttributeError, msg:
+                    port_name = szFriendlyName.value
+                    order = None
+            yield order, port_name, szFriendlyName.value, szHardwareID.value
+
+        SetupDiDestroyDeviceInfoList(g_hdi)
+
+'''
+if __name__ == '__main__':
+    import serial
+    #print "-"*78
+    #print "Serial ports"
+    #print "-"*78
+
+    for order, port, desc, hwid in sorted(comports()):
+        print "%-10s: %s (%s) ->" % (port, desc, hwid),
+        try:
+            serial.Serial(port) # test open
+        except serial.serialutil.SerialException:
+            print "Can't be openend"
+        else:
+            print "Ready"
+    print
+
+    #
+    # ADDED ITERATORS TO LIST FOR CONVENIENCE
+    #
+    aList = []
+    for order, port, desc, hwid in comports():
+        aList.append(port)
+        aList.append(desc)
+        aList.append(hwid)
+    print aList
+
+    try:
+        serial.Serial(port)
+    except serial.serialutil.SerialException:
+        print "Can not be opened."
+    else:
+        print "Ready"
+     
+    #
+    # List of all ports the system knows (registry)
+    #
+    print "-"*78
+    print "All serial ports (registry)"
+    print "-"*78
+    for order, port, desc, hwid in sorted(comports(False)):
+        print "%-10s: %s (%s)" % (port, desc, hwid)
+'''