Skip to content

Commit

Permalink
API: Update firmware endpoint (#1061)
Browse files Browse the repository at this point in the history
* no homing on boot

* adds lpc21isp tool to compute/scripts

* adds endpoint update_firmware, which flashes HEX file with lpc21isp

* open serialport before resetting and waiting for ACK

* driver connect/disconnect actually open/close port; adds driver property port() to retrive portname

* only connect if not already connected; moves opentrons import to top of file
  • Loading branch information
andySigler committed Mar 19, 2018
1 parent 34cbef2 commit ebe78a5
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 1 deletion.
13 changes: 13 additions & 0 deletions api/opentrons/drivers/smoothie_drivers/driver_3_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,21 @@ def connect(self):
self._setup()

def disconnect(self):
if self._connection:
self._connection.close()
self.simulating = True

def is_connected(self):
if not self._connection:
return False
return self._connection.is_open

@property
def port(self):
if not self._connection:
return None
return self._connection.port

def get_fw_version(self):
version = 'Virtual Smoothie'
if not self.simulating:
Expand Down
2 changes: 1 addition & 1 deletion api/opentrons/robot/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ def get_serial_ports_list(self):
def is_connected(self):
if not self._driver:
return False
return not self._driver.simulating
return self._driver.is_connected()

def is_simulating(self):
if not self._driver:
Expand Down
71 changes: 71 additions & 0 deletions api/opentrons/server/endpoints/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import asyncio
from aiohttp import web

from opentrons import robot

log = logging.getLogger(__name__)


Expand All @@ -20,6 +22,39 @@ async def _install(filename, loop):
return res


async def _update_firmware(filename, loop):
# ensure there is a reference to the port
if not robot.is_connected():
robot.connect()

# get port name
port = str(robot._driver.port)
# set smoothieware into programming mode
robot._driver._smoothie_programming_mode()
# close the port so other application can access it
robot._driver._connection.close()

# run lpc21isp, THIS WILL TAKE AROUND 1 MINUTE TO COMPLETE
update_cmd = 'lpc21isp -wipe -donotstart {0} {1} {2} 12000'.format(
filename, port, robot.config.serial_speed)
proc = await asyncio.create_subprocess_shell(
update_cmd,
stdout=asyncio.subprocess.PIPE,
loop=loop)
rd = await proc.stdout.read()
res = rd.decode().strip()
await proc.wait()

# re-open the port
robot._driver._connection.open()
# reset smoothieware
robot._driver._smoothie_reset()
# run setup gcodes
robot._driver._setup()

return res


async def install_api(request):
"""
This handler accepts a POST request with Content-Type: multipart/form-data
Expand Down Expand Up @@ -53,3 +88,39 @@ async def install_api(request):
type(e), data, e.__traceback__)},
status=500)
return res


async def update_firmware(request):
"""
This handler accepts a POST request with Content-Type: multipart/form-data
and a file field in the body named "hex". The file should be a valid HEX
image to be flashed to the LPC1769. The received file is flashed using
lpc21isp, and then deleted and a success code is returned.
"""
log.debug('Update Firmware request received')
data = await request.post()
try:
filename = data['hex'].filename
log.info('Flashing image "{}", this will take about 1 minute'.format(
filename))
content = data['hex'].file.read()

with open(filename, 'wb') as wf:
wf.write(content)

msg = await _update_firmware(filename, request.loop)
log.debug('Firmware Update complete')
try:
os.remove(filename)
except OSError:
pass
log.debug("Result: {}".format(msg))
res = web.json_response({
'message': msg,
'filename': filename})
except Exception as e:
res = web.json_response(
{'error': 'Exception {} raised by update of {}. Trace: {}'.format(
type(e), data, e.__traceback__)},
status=500)
return res
2 changes: 2 additions & 0 deletions api/opentrons/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def init(loop=None):
server.app.router.add_post('/lights/on', control.turn_on_rail_lights)
server.app.router.add_post('/lights/off', control.turn_off_rail_lights)
server.app.router.add_post('/server/update', update.install_api)
server.app.router.add_post(
'/server/update_firmware', update.update_firmware)
server.app.router.add_post('/server/restart', control.restart)
server.app.router.add_get('/calibration/deck', dc_endp.start)
server.app.router.add_post('/calibration/deck', dc_endp.dispatch)
Expand Down
Binary file added compute/scripts/lpc21isp
Binary file not shown.

0 comments on commit ebe78a5

Please sign in to comment.