Explorar o código

Better serial port auto-detect and re-detect methods.
Also should fix Windows 7.

Keir Fraser %!s(int64=5) %!d(string=hai) anos
pai
achega
cd66e7d17d
Modificáronse 1 ficheiros con 33 adicións e 21 borrados
  1. 33 21
      scripts/greaseweazle/tools/util.py

+ 33 - 21
scripts/greaseweazle/tools/util.py

@@ -57,25 +57,39 @@ def with_drive_selected(fn, usb, args):
 def valid_ser_id(ser_id):
     return ser_id and ser_id.upper().startswith("GW")
 
-def find_port(ser_id=None):
-    for x in serial.tools.list_ports.comports():
-        if x.manufacturer == "Keir Fraser":
-            if not valid_ser_id(x.serial_number) or not valid_ser_id(ser_id) \
-               or x.serial_number == ser_id:
-                return x.device
-        elif x.manufacturer == "Microsoft" and x.vid == 0x1209 \
-             and x.pid == 0x0001:
-            if not valid_ser_id(x.serial_number) or not valid_ser_id(ser_id) \
-               or x.serial_number == ser_id:
+def find_port(old_port=None):
+    # If we are reopening, and we know the location of the old port, require
+    # to match on location.
+    if old_port and old_port.location:
+        for x in serial.tools.list_ports.comports():
+            if x.location and x.location == old_port.location:
                 return x.device
-    raise serial.SerialException('Could not auto-detect Greaseweazle device')
-
-def get_ser_id(devname):
+        return None
+    # Score each serial port
+    best_score, best_port = 0, None
+    for x in serial.tools.list_ports.comports():
+        score = 0
+        if x.manufacturer == "Keir Fraser" and x.product == "Greaseweazle":
+            score = 20
+        elif x.vid == 0x1209 and x.pid == 0x0001:
+            score = 10
+        if score > 0 and valid_ser_id(x.serial_number):
+            if not old_port or not valid_ser_id(old_port.serial_number):
+                score = 20
+            elif x.serial_number == old_port.serial_number:
+                score = 30
+            else:
+                score = 0
+        if score > best_score:
+            best_score, best_port = score, x
+    if best_port:
+        return best_port.device
+    raise serial.SerialException('Could not auto-probe Greaseweazle device')
+
+def port_info(devname):
     for x in serial.tools.list_ports.comports():
         if x.device == devname:
-            if valid_ser_id(x.serial_number):
-                return x.serial_number
-            return None
+            return x
     return None
 
 def usb_reopen(usb, is_update):
@@ -90,15 +104,14 @@ def usb_reopen(usb, is_update):
     for i in range(10):
         time.sleep(0.5)
         try:
-            devicename = find_port(usb.ser_id)
+            devicename = find_port(usb.port_info)
             new_ser = serial.Serial(devicename)
         except serial.SerialException:
             # Device not found
             pass
         else:
             new_usb = USB.Unit(new_ser)
-            new_usb.ser_id = usb.ser_id
-            new_usb.devname = devicename
+            new_usb.port_info = port_info(devicename)
             return new_usb
     raise serial.SerialException('Could not reopen port after mode switch')
 
@@ -109,8 +122,7 @@ def usb_open(devicename, is_update=False):
         devicename = find_port()
     
     usb = USB.Unit(serial.Serial(devicename))
-    usb.ser_id = get_ser_id(devicename)
-    usb.devname = devicename
+    usb.port_info = port_info(devicename)
 
     print("** %s v%u.%u [F%u], Host Tools v%u.%u"
           % (("Greaseweazle", "Bootloader")[usb.update_mode],