@@ -13,6 +13,7 @@ class Overseer(object): | |||
Factory for creation of AD2USB devices as well as provide4s attach/detach events." | |||
""" | |||
# Factory events | |||
on_attached = event.Event('Called when an AD2USB device has been detected.') | |||
on_detached = event.Event('Called when an AD2USB device has been removed.') | |||
@@ -152,13 +153,15 @@ class AD2USB(object): | |||
High-level wrapper around AD2USB/AD2SERIAL devices. | |||
""" | |||
# High-level Events | |||
on_open = event.Event('Called when the device has been opened') | |||
on_close = event.Event('Called when the device has been closed') | |||
on_message = event.Event('Called when a message has been received from the device.') | |||
# Low-level Events | |||
on_read = event.Event('Called when a line has been read from the device') | |||
on_write = event.Event('Called when data has been written to the device') | |||
on_message = event.Event('Called when a message has been received from the device.') | |||
def __init__(self, device): | |||
""" | |||
Constructor | |||
@@ -198,7 +201,7 @@ class AD2USB(object): | |||
""" | |||
Parses messages from the panel. | |||
""" | |||
if data[0] == '!': | |||
if data[0] == '!': # TEMP: Remove this. | |||
return None | |||
msg = Message() | |||
@@ -19,6 +19,7 @@ class Device(object): | |||
Generic parent device to all AD2USB products. | |||
""" | |||
# Generic device events | |||
on_open = event.Event('Called when the device has been opened') | |||
on_close = event.Event('Called when the device has been closed') | |||
on_read = event.Event('Called when a line has been read from the device') | |||
@@ -59,7 +60,7 @@ class Device(object): | |||
try: | |||
self._device.read_line(timeout=10) | |||
except util.CommError, err: | |||
traceback.print_exc(err) | |||
traceback.print_exc(err) # TEMP | |||
except util.TimeoutError, err: | |||
pass | |||
@@ -70,6 +71,7 @@ class USBDevice(Device): | |||
AD2USB device exposed with PyFTDI's interface. | |||
""" | |||
# Constants | |||
FTDI_VENDOR_ID = 0x0403 | |||
FTDI_PRODUCT_ID = 0x6001 | |||
BAUDRATE = 115200 | |||
@@ -113,6 +115,7 @@ class USBDevice(Device): | |||
""" | |||
self._running = True | |||
# Set up defaults | |||
if baudrate is None: | |||
baudrate = USBDevice.BAUDRATE | |||
@@ -125,6 +128,7 @@ class USBDevice(Device): | |||
if index is None: | |||
index = 0 | |||
# Open the device and start up the thread. | |||
try: | |||
self._device.open(self._vendor_id, | |||
self._product_id, | |||
@@ -226,6 +230,8 @@ class SerialDevice(Device): | |||
""" | |||
AD2USB or AD2SERIAL device exposed with the pyserial interface. | |||
""" | |||
# Constants | |||
BAUDRATE = 19200 | |||
@staticmethod | |||
@@ -264,6 +270,8 @@ class SerialDevice(Device): | |||
""" | |||
Opens the device. | |||
""" | |||
# Set up the defaults | |||
if baudrate is None: | |||
baudrate = SerialDevice.BAUDRATE | |||
@@ -276,6 +284,7 @@ class SerialDevice(Device): | |||
self._device.baudrate = baudrate | |||
self._device.port = self._interface | |||
# Open the device and start up the reader thread. | |||
try: | |||
self._device.open() | |||
@@ -338,7 +347,7 @@ class SerialDevice(Device): | |||
while self._running: | |||
buf = self._device.read(1) | |||
if buf != '' and buf != "\xff": # WTF is this \xff and why is it in my buffer?! | |||
if buf != '' and buf != "\xff": # AD2SERIAL specifically apparently sends down \xFF on boot. | |||
self._buffer += buf | |||
if buf == "\n": | |||
@@ -29,6 +29,7 @@ class Firmware(object): | |||
Represents firmware for the AD2USB/AD2SERIAL devices. | |||
""" | |||
# Constants | |||
STAGE_START = 0 | |||
STAGE_WAITING = 1 | |||
STAGE_BOOT = 2 | |||
@@ -53,7 +54,12 @@ class Firmware(object): | |||
""" | |||
Uploads firmware to an AD2USB/AD2SERIAL device. | |||
""" | |||
def do_upload(): | |||
""" | |||
Perform the actual firmware upload to the device. | |||
""" | |||
with open(filename) as f: | |||
for line in f: | |||
line = line.rstrip() | |||
@@ -68,6 +74,9 @@ class Firmware(object): | |||
time.sleep(0.05) | |||
def read_until(pattern, timeout=0.0): | |||
""" | |||
Read characters until a specific pattern is found or the timeout is hit. | |||
""" | |||
start_time = time.time() | |||
buf = '' | |||
position = 0 | |||
@@ -96,6 +105,8 @@ class Firmware(object): | |||
if progress_callback is not None: | |||
progress_callback(Firmware.STAGE_START) | |||
# Close the reader thread and wait for it to die, otherwise | |||
# it interferes with our reading. | |||
dev.close_reader() | |||
while dev._read_thread.is_alive(): | |||
if progress_callback is not None: | |||
@@ -107,19 +118,23 @@ class Firmware(object): | |||
if progress_callback is not None: | |||
progress_callback(Firmware.STAGE_BOOT) | |||
# Reboot the device and wait for the boot loader. | |||
dev.write("=") | |||
read_until('!boot', timeout=10.0) | |||
if progress_callback is not None: | |||
progress_callback(Firmware.STAGE_LOAD) | |||
# Get ourselves into the boot loader and wait for indication | |||
# that it's ready for the firmware upload. | |||
dev.write("=") | |||
read_until('!load', timeout=10.0) | |||
# And finally do the upload. | |||
do_upload() | |||
if progress_callback is not None: | |||
progress_callback(Firmware.STAGE_DONE) | |||
except TimeoutError, err: | |||
print traceback.print_exc(err) | |||
print traceback.print_exc(err) # TEMP | |||
pass |