Skip to content

Commit

Permalink
snekde: Make autobaud detection fancier
Browse files Browse the repository at this point in the history
Put the autobaud code in a separate thread. Try it twice; once after
100ms and once after another 1.5 seconds to allow devices without boot
loaders to start quickly while still supporting devices with boot
loaders that delay for 1.5 seconds.

Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
keith-packard committed Mar 28, 2022
1 parent b233bf8 commit 633494e
Showing 1 changed file with 54 additions and 22 deletions.
76 changes: 54 additions & 22 deletions snekde/snekde.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ def start(self):

self.alive = True
self._reader_alive = True
self.interrupt_pending = True

# start threads

Expand All @@ -230,6 +231,13 @@ def start(self):
self.transmitter_thread.daemon = True
self.transmitter_thread.start()

self.autobauder_thread = False
self.autobauder_cancel = False
if self.synchronous_put:
self.autobauder_thread = threading.Thread(target=self.autobauder, name="baud")
self.autobauder_thread.daemon = True
self.autobauder_thread.start()

def stop_reader(self):
if self.receiver_thread and threading.current_thread() != self.receiver_thread:
self.serial.cancel_read()
Expand All @@ -248,10 +256,17 @@ def stop_writer(self):
self.transmitter_thread.join()
self.interface.cv.acquire()

def stop_autobauder(self):
if self.autobauder_thread:
self.autobauder_cancel = True
self.dc4.notify_all()
self.autobauder_thread.join()

def close(self):
self.alive = False
self.stop_reader()
self.stop_writer()
self.stop_autobauder()
try:
self.serial.write_timeout = 1
self.serial.write(b"\x0f")
Expand Down Expand Up @@ -328,6 +343,34 @@ def writer(self):
finally:
self.transmitter_thread = False

def do_autobaud(self, delay=0):
global baud_selection, snek_lock
with snek_lock:
if delay > 0:
time.sleep(delay)
old_baud = baud_selection
for i in range(len(baud_rates)):
baud_selection = i
# snek_debug("try baud %d" % baud_rates[i])
if self.autobauder_cancel:
break
self.set_baud(baud_rates[baud_selection])
if snek_monitor.ping():
return True
baud_selection = old_baud
self.set_baud(baud_rates[baud_selection])
return False

def autobauder(self):
global baud_selection

# Try to autobaud right away, then wait 1.5 seconds
# for the device to boot and try again
if not self.do_autobaud(0.1):
self.do_autobaud(1.5)

self.autobauder_thread = False

def interrupt(self):
# snek_debug('pend interrupt waited')
self.interrupt_pending = True
Expand Down Expand Up @@ -1213,25 +1256,12 @@ def snekde_open_device():
if not port:
return
try:
device = SnekDevice(port, snek_monitor, rate=baud_rates[baud_selection])
device.start()
if snek_device:
snek_device.close()
del snek_device
snek_device = device

# Attempt to auto-baud synchronous devices
if snek_device.synchronous_put:
old_baud = baud_selection
for i in range(len(baud_rates)):
baud_selection = i
# snek_debug("try baud %d" % baud_rates[i])
snek_device.set_baud(baud_rates[baud_selection])
if snek_monitor.ping():
break
else:
baud_selection = old_baud
snek_device.set_baud(baud_rates[baud_selection])
old_device = snek_device
snek_device = SnekDevice(port, snek_monitor, rate=baud_rates[baud_selection])
snek_device.start()
if old_device:
old_device.close()
del old_device

screen_paint()
except OSError as e:
Expand Down Expand Up @@ -1426,12 +1456,14 @@ def sync(self):
# snek_debug('sync done')

def ping(self):
global snek_lock
# snek_debug('send PING')
snek_device.serial.write(b"\x14")
ret = self.dc4.wait(0.25)
snek_device.serial.write(b"\x14\x0f\x03\x0e")
ret = self.dc4.wait(0.05)
return ret

def wait(self, delay):
return self.dc4.wait(delay)

# Reading text to snek_edit_win instead of snek_repl_win

def add_to(self, window, data):
Expand Down

0 comments on commit 633494e

Please sign in to comment.