robustify python USB discovery/communication

This commit is contained in:
Samuel Sadok
2018-03-23 17:10:29 -07:00
parent a0d440bff3
commit 153b904732
2 changed files with 24 additions and 3 deletions
+7 -1
View File
@@ -35,6 +35,12 @@ class USBBulkTransport(odrive.protocol.PacketSource, odrive.protocol.PacketSink)
return string
def init(self):
# Under some conditions, the Linux USB/libusb stack ends up in a corrupt
# state where there are a few packets in a receive queue but a call
# to epr.read() does not return these packet until a new packet arrives.
# This undesirable queue can be cleared by resetting the device.
self.dev.reset()
try:
if self.dev.is_kernel_driver_active(1):
self.dev.detach_kernel_driver(1)
@@ -106,7 +112,7 @@ class USBBulkTransport(odrive.protocol.PacketSource, odrive.protocol.PacketSink)
else:
# Try resetting halt/stall condition
try:
self.epw.clear_halt()
self.epr.clear_halt()
except usb.core.USBError:
raise odrive.protocol.ChannelBrokenException()
# Retry transfer
+17 -2
View File
@@ -73,11 +73,15 @@ class Event():
"""
Alternative to threading.Event(), enhanced by the subscribe() function
that the original fails to provide.
@param Trigger: if supplied, the newly created event will be triggered
as soon as the trigger event becomes set
"""
def __init__(self):
def __init__(self, trigger=None):
self._evt = threading.Event()
self._subscribers = []
self._mutex = threading.Lock()
if not trigger is None:
trigger.subscribe(self.set())
def is_set(self):
return self._evt.is_set()
@@ -120,7 +124,18 @@ class Event():
self._mutex.release()
def wait(self, timeout=None):
return self._evt.wait(timeout=timeout)
if not self._evt.wait(timeout=timeout):
raise TimeoutError()
def trigger_after(self, timeout):
"""
Triggers the event after the specified timeout.
This function returns immediately.
"""
def delayed_trigger():
if not self.wait(timeout=timeout):
self.set()
threading.Thread(target=delayed_trigger, daemon=True).start()
def wait_any(*events, timeout=None):
"""