From 30a2a3eec2c54407cfa1d7c00d8a3a4e2440c6d0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 19 Oct 2024 09:45:49 +0900 Subject: [PATCH] support loading AM32 amj files --- dronecan_gui_tool/widgets/file_server.py | 22 +++++++++++++++++++- dronecan_gui_tool/widgets/node_properties.py | 2 +- setup.py | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/dronecan_gui_tool/widgets/file_server.py b/dronecan_gui_tool/widgets/file_server.py index 441ed15..8353a77 100644 --- a/dronecan_gui_tool/widgets/file_server.py +++ b/dronecan_gui_tool/widgets/file_server.py @@ -95,6 +95,19 @@ def update_hit_count(self, _path, hit_count): def reset_hit_counts(self): self._hit_count_label.setText('0') +def hex2bin(heximage): + ''' + Convert an Intel HEX format bytes array to binary format + ''' + import intelhex + import io + + hex_stream = io.StringIO(heximage.decode('utf-8')) + bin_stream = io.BytesIO() + intelhex.hex2bin(hex_stream, bin_stream) + bin_stream.seek(0) + return bin_stream.read() + class FileServerJson(dronecan.app.file_server.FileServer): def __init__(self, node): super(FileServerJson, self).__init__(node) @@ -115,7 +128,14 @@ def _load_image(self, path): if not 'image' in j: print("Missing image in %s" % path) return None - return bytearray(zlib.decompress(base64.b64decode(j['image']))) + return bytearray(zlib.decompress(base64.b64decode(j['image'].encode('utf-8')))) + if path.lower().endswith('.amj'): + # load JSON image as hex image + j = json.load(open(path,'r')) + if not 'hex' in j: + print("Missing hex image in %s" % path) + return None + return hex2bin(base64.b64decode(j['hex'])) return open(path,'rb').read() def _check_path_change(self, path): diff --git a/dronecan_gui_tool/widgets/node_properties.py b/dronecan_gui_tool/widgets/node_properties.py index 76a9fef..58a8dfe 100644 --- a/dronecan_gui_tool/widgets/node_properties.py +++ b/dronecan_gui_tool/widgets/node_properties.py @@ -246,7 +246,7 @@ def _do_firmware_update(self): # Requesting the firmware path fw_file = QFileDialog().getOpenFileName(self, 'Select firmware file', '', - 'Binary images (*.bin);;ArduPilot Firmware (*.apj);;PX4 Firmware (*.px4);;All files (*.*)') + 'Binary images (*.bin);;ArduPilot Firmware (*.apj);;AM32 Firmware (*.amj);;PX4 Firmware (*.px4);;All files (*.*)') if not fw_file[0]: self.window().show_message('Cancelled') return diff --git a/setup.py b/setup.py index e83f169..45cd4f6 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,8 @@ 'pygments', 'qtpy', 'pyqtgraph', - 'qtwidgets' + 'qtwidgets', + 'intelhex' ], # We can't use "scripts" here, because generated shims don't work with multiprocessing pickler. entry_points={