Skip to content

Commit 99f87a5

Browse files
authored
Merge pull request tinyfpga#45 from mbuesch/portexception
Handle port errors gracefully and print proper error messages
2 parents 092eedc + 00a1f11 commit 99f87a5

File tree

2 files changed

+198
-168
lines changed

2 files changed

+198
-168
lines changed

programmer/tinyprog/__init__.py

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,14 @@ def get_ports(device_id):
6868
import usb
6969
vid, pid = [int(x, 16) for x in device_id.split(":")]
7070

71-
ports += [
72-
UsbPort(d)
73-
for d in usb.core.find(idVendor=vid, idProduct=pid, find_all=True)
74-
if not d.is_kernel_driver_active(1)
75-
]
71+
try:
72+
ports += [
73+
UsbPort(usb, d)
74+
for d in usb.core.find(idVendor=vid, idProduct=pid, find_all=True)
75+
if not d.is_kernel_driver_active(1)
76+
]
77+
except usb.core.USBError as e:
78+
raise PortError("Failed to open USB:\n%s" % str(e))
7679

7780
# MacOS is not playing nicely with the serial drivers for the bootloader
7881
if platform.system() != "Darwin" or use_pyserial:
@@ -84,6 +87,9 @@ def get_ports(device_id):
8487
return ports
8588

8689

90+
class PortError(Exception):
91+
pass
92+
8793
class SerialPort(object):
8894
def __init__(self, port_name):
8995
self.port_name = port_name
@@ -93,24 +99,39 @@ def __str__(self):
9399
return self.port_name
94100

95101
def __enter__(self):
96-
self.ser = serial.Serial(
97-
self.port_name, timeout=1.0, writeTimeout=1.0).__enter__()
102+
try:
103+
self.ser = serial.Serial(
104+
self.port_name, timeout=1.0, writeTimeout=1.0).__enter__()
105+
except serial.SerialException as e:
106+
raise PortError("Failed to open serial port:\n%s" % str(e))
98107

99108
def __exit__(self, exc_type, exc_val, exc_tb):
100-
self.ser.__exit__(exc_type, exc_val, exc_tb)
109+
try:
110+
self.ser.__exit__(exc_type, exc_val, exc_tb)
111+
except serial.SerialException as e:
112+
raise PortError("Failed to close serial port:\n%s" % str(e))
101113

102114
def write(self, data):
103-
self.ser.write(data)
115+
try:
116+
self.ser.write(data)
117+
except serial.SerialException as e:
118+
raise PortError("Failed to write to serial port:\n%s" % str(e))
104119

105120
def flush(self):
106-
self.ser.flush()
121+
try:
122+
self.ser.flush()
123+
except serial.SerialException as e:
124+
raise PortError("Failed to flush serial port:\n%s" % str(e))
107125

108126
def read(self, length):
109-
return self.ser.read(length)
110-
127+
try:
128+
return self.ser.read(length)
129+
except serial.SerialException as e:
130+
raise PortError("Failed to read from serial port:\n%s" % str(e))
111131

112132
class UsbPort(object):
113-
def __init__(self, device):
133+
def __init__(self, usb, device):
134+
self.usb = usb
114135
self.device = device
115136
usb_interface = device.configurations()[0].interfaces()[1]
116137
self.OUT = usb_interface.endpoints()[0]
@@ -126,19 +147,24 @@ def __exit__(self, exc_type, exc_val, exc_tb):
126147
pass
127148

128149
def write(self, data):
129-
self.OUT.write(data)
150+
try:
151+
self.OUT.write(data)
152+
except self.usb.core.USBError as e:
153+
raise PortError("Failed to write to USB:\n%s" % str(e))
130154

131155
def flush(self):
132156
# i don't think there's a comparable function on pyusb endpoints
133157
pass
134158

135159
def read(self, length):
136-
if length > 0:
137-
data = self.IN.read(length)
138-
return bytearray(data)
139-
else:
140-
return ""
141-
160+
try:
161+
if length > 0:
162+
data = self.IN.read(length)
163+
return bytearray(data)
164+
else:
165+
return ""
166+
except self.usb.core.USBError as e:
167+
raise PortError("Failed to read from USB:\n%s" % str(e))
142168

143169
def _mirror_byte(b):
144170
return bit_reverse_table[to_int(b)]

0 commit comments

Comments
 (0)