serialhdl: Use send_with_response() to query identify data
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
461ed4cb80
commit
ebb375fee9
|
@ -29,10 +29,9 @@ class SerialReader:
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
self.background_thread = None
|
self.background_thread = None
|
||||||
# Message handlers
|
# Message handlers
|
||||||
handlers = {
|
self.handlers = {}
|
||||||
'#unknown': self.handle_unknown, '#output': self.handle_output,
|
self.register_response(self._handle_unknown_init, '#unknown')
|
||||||
}
|
self.register_response(self.handle_output, '#output')
|
||||||
self.handlers = { (k, None): v for k, v in handlers.items() }
|
|
||||||
def _bg_thread(self):
|
def _bg_thread(self):
|
||||||
response = self.ffi_main.new('struct pull_queue_message *')
|
response = self.ffi_main.new('struct pull_queue_message *')
|
||||||
while 1:
|
while 1:
|
||||||
|
@ -50,6 +49,21 @@ class SerialReader:
|
||||||
hdl(params)
|
hdl(params)
|
||||||
except:
|
except:
|
||||||
logging.exception("Exception in serial callback")
|
logging.exception("Exception in serial callback")
|
||||||
|
def _get_identify_data(self, timeout):
|
||||||
|
# Query the "data dictionary" from the micro-controller
|
||||||
|
identify_data = ""
|
||||||
|
identify_cmd = self.lookup_command("identify offset=%u count=%c")
|
||||||
|
while 1:
|
||||||
|
params = identify_cmd.send_with_response([len(identify_data), 40],
|
||||||
|
'identify_response')
|
||||||
|
if params['offset'] == len(identify_data):
|
||||||
|
msgdata = params['data']
|
||||||
|
if not msgdata:
|
||||||
|
# Done
|
||||||
|
return identify_data
|
||||||
|
identify_data += msgdata
|
||||||
|
if self.reactor.monotonic() > timeout:
|
||||||
|
raise error("Timeout during identify")
|
||||||
def connect(self):
|
def connect(self):
|
||||||
# Initial connection
|
# Initial connection
|
||||||
logging.info("Starting serial connect")
|
logging.info("Starting serial connect")
|
||||||
|
@ -72,10 +86,10 @@ class SerialReader:
|
||||||
self.background_thread = threading.Thread(target=self._bg_thread)
|
self.background_thread = threading.Thread(target=self._bg_thread)
|
||||||
self.background_thread.start()
|
self.background_thread.start()
|
||||||
# Obtain and load the data dictionary from the firmware
|
# Obtain and load the data dictionary from the firmware
|
||||||
sbs = SerialBootStrap(self)
|
try:
|
||||||
identify_data = sbs.get_identify_data(starttime + 5.)
|
identify_data = self._get_identify_data(starttime + 5.)
|
||||||
if identify_data is None:
|
except error as e:
|
||||||
logging.warn("Timeout on serial connect")
|
logging.exception("Timeout on serial connect")
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
|
@ -165,6 +179,9 @@ class SerialReader:
|
||||||
i, msg.receive_time, msg.sent_time, msg.len, ', '.join(cmds)))
|
i, msg.receive_time, msg.sent_time, msg.len, ', '.join(cmds)))
|
||||||
return '\n'.join(out)
|
return '\n'.join(out)
|
||||||
# Default message handlers
|
# Default message handlers
|
||||||
|
def _handle_unknown_init(self, params):
|
||||||
|
logging.debug("Unknown message %d (len %d) while identifying",
|
||||||
|
params['#msgid'], len(params['#msg']))
|
||||||
def handle_unknown(self, params):
|
def handle_unknown(self, params):
|
||||||
logging.warn("Unknown message type %d: %s",
|
logging.warn("Unknown message type %d: %s",
|
||||||
params['#msgid'], repr(params['#msg']))
|
params['#msgid'], repr(params['#msg']))
|
||||||
|
@ -233,46 +250,6 @@ class SerialRetryCommand:
|
||||||
self.unregister()
|
self.unregister()
|
||||||
return self.response
|
return self.response
|
||||||
|
|
||||||
# Code to start communication and download message type dictionary
|
|
||||||
class SerialBootStrap:
|
|
||||||
RETRY_TIME = 0.500
|
|
||||||
def __init__(self, serial):
|
|
||||||
self.serial = serial
|
|
||||||
self.identify_data = ""
|
|
||||||
self.identify_cmd = self.serial.lookup_command(
|
|
||||||
"identify offset=%u count=%c")
|
|
||||||
self.is_done = False
|
|
||||||
self.serial.register_response(self.handle_identify, 'identify_response')
|
|
||||||
self.serial.register_response(self.handle_unknown, '#unknown')
|
|
||||||
self.send_timer = self.serial.reactor.register_timer(
|
|
||||||
self.send_event, self.serial.reactor.NOW)
|
|
||||||
def get_identify_data(self, timeout):
|
|
||||||
eventtime = self.serial.reactor.monotonic()
|
|
||||||
while not self.is_done and eventtime <= timeout:
|
|
||||||
eventtime = self.serial.reactor.pause(eventtime + 0.05)
|
|
||||||
self.serial.unregister_response('identify_response')
|
|
||||||
self.serial.reactor.unregister_timer(self.send_timer)
|
|
||||||
if not self.is_done:
|
|
||||||
return None
|
|
||||||
return self.identify_data
|
|
||||||
def handle_identify(self, params):
|
|
||||||
if self.is_done or params['offset'] != len(self.identify_data):
|
|
||||||
return
|
|
||||||
msgdata = params['data']
|
|
||||||
if not msgdata:
|
|
||||||
self.is_done = True
|
|
||||||
return
|
|
||||||
self.identify_data += msgdata
|
|
||||||
self.identify_cmd.send([len(self.identify_data), 40])
|
|
||||||
def send_event(self, eventtime):
|
|
||||||
if self.is_done:
|
|
||||||
return self.serial.reactor.NEVER
|
|
||||||
self.identify_cmd.send([len(self.identify_data), 40])
|
|
||||||
return eventtime + self.RETRY_TIME
|
|
||||||
def handle_unknown(self, params):
|
|
||||||
logging.debug("Unknown message %d (len %d) while identifying",
|
|
||||||
params['#msgid'], len(params['#msg']))
|
|
||||||
|
|
||||||
# Attempt to place an AVR stk500v2 style programmer into normal mode
|
# Attempt to place an AVR stk500v2 style programmer into normal mode
|
||||||
def stk500v2_leave(ser, reactor):
|
def stk500v2_leave(ser, reactor):
|
||||||
logging.debug("Starting stk500v2 leave programmer sequence")
|
logging.debug("Starting stk500v2 leave programmer sequence")
|
||||||
|
|
Loading…
Reference in New Issue