--usb flag to edit-config direct off the board
This commit is contained in:
parent
70d3ce8be0
commit
0378269a00
11
README.md
11
README.md
@ -24,12 +24,17 @@ currently the expectation is that you can run it yourself before invoking these
|
|||||||
% pip install -Ur requirements/requirements-dev.txt
|
% pip install -Ur requirements/requirements-dev.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
In all cases, online help can be retrieved by providing the `-h` or ``--help`` flags to the below programs.
|
||||||
|
|
||||||
## Config Editor
|
## Config Editor
|
||||||
|
|
||||||
[](https://asciinema.org/a/67hELtUNkKCit4dFwYeAUa2fo)
|
[](https://asciinema.org/a/67hELtUNkKCit4dFwYeAUa2fo)
|
||||||
|
|
||||||
A terminal UI config editor, capable of viewing and editing existing configurations, can be launched via
|
A terminal UI config editor, capable of viewing and editing existing configurations, can be launched via
|
||||||
**edit-config**. It supports navigation both via the keyboard or the mouse.
|
**edit-config**. It supports navigation both via the keyboard or the mouse, and can either view and edit a binary file
|
||||||
|
made via `picotool`, or view the configuration directly on the board in BOOTSEL mode over USB (editing coming soon).
|
||||||
|
|
||||||
Simple usage:
|
Simple usage:
|
||||||
|
|
||||||
@ -46,10 +51,6 @@ Simple usage:
|
|||||||
|
|
||||||
A quick demonstration of the editor is available [on asciinema.org](https://asciinema.org/a/67hELtUNkKCit4dFwYeAUa2fo).
|
A quick demonstration of the editor is available [on asciinema.org](https://asciinema.org/a/67hELtUNkKCit4dFwYeAUa2fo).
|
||||||
|
|
||||||
## Tools
|
|
||||||
|
|
||||||
In all cases, online help can be retrieved by providing the `-h` or ``--help`` flags to the below programs.
|
|
||||||
|
|
||||||
### concatenate
|
### concatenate
|
||||||
|
|
||||||
**concatenate** combines a GP2040-CE firmware .bin file (such as from a fresh build) and a GP2040-CE board's storage
|
**concatenate** combines a GP2040-CE firmware .bin file (such as from a fresh build) and a GP2040-CE board's storage
|
||||||
|
@ -17,7 +17,8 @@ from textual.widgets.tree import TreeNode
|
|||||||
|
|
||||||
from gp2040ce_bintools import core_parser, handler
|
from gp2040ce_bintools import core_parser, handler
|
||||||
from gp2040ce_bintools.builder import write_new_config_to_filename
|
from gp2040ce_bintools.builder import write_new_config_to_filename
|
||||||
from gp2040ce_bintools.storage import get_config_from_file
|
from gp2040ce_bintools.pico import get_bootsel_endpoints, read
|
||||||
|
from gp2040ce_bintools.storage import STORAGE_MEMORY_ADDRESS, STORAGE_SIZE, get_config, get_config_from_file
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -130,8 +131,19 @@ class ConfigEditor(App):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize config."""
|
"""Initialize config."""
|
||||||
self.config_filename = kwargs.pop('config_filename')
|
self.config_filename = kwargs.pop('config_filename', None)
|
||||||
self.whole_board = kwargs.pop('whole_board', False)
|
self.whole_board = kwargs.pop('whole_board', False)
|
||||||
|
usb = kwargs.pop('usb', False)
|
||||||
|
# load the config
|
||||||
|
if usb:
|
||||||
|
endpoint_out, endpoint_in = get_bootsel_endpoints()
|
||||||
|
storage = read(endpoint_out, endpoint_in, STORAGE_MEMORY_ADDRESS, STORAGE_SIZE)
|
||||||
|
self.config = get_config(bytes(storage))
|
||||||
|
self.source_name = (f"DEVICE ID {hex(endpoint_out.device.idVendor)}:{hex(endpoint_out.device.idProduct)} "
|
||||||
|
f"on bus {endpoint_out.device.bus} address {endpoint_out.device.address}")
|
||||||
|
else:
|
||||||
|
self.config = get_config_from_file(self.config_filename, whole_board=self.whole_board)
|
||||||
|
self.source_name = self.config_filename
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# disable normal logging and enable console logging if we're not headless
|
# disable normal logging and enable console logging if we're not headless
|
||||||
@ -149,11 +161,10 @@ class ConfigEditor(App):
|
|||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
"""Load the configuration object into the tree view."""
|
"""Load the configuration object into the tree view."""
|
||||||
self.config = get_config_from_file(self.config_filename, whole_board=self.whole_board)
|
|
||||||
tree = self.query_one(Tree)
|
tree = self.query_one(Tree)
|
||||||
|
|
||||||
tree.root.data = (None, self.config.DESCRIPTOR, self.config)
|
tree.root.data = (None, self.config.DESCRIPTOR, self.config)
|
||||||
tree.root.set_label(self.config_filename)
|
tree.root.set_label(self.source_name)
|
||||||
missing_fields = [f for f in self.config.DESCRIPTOR.fields
|
missing_fields = [f for f in self.config.DESCRIPTOR.fields
|
||||||
if f not in [fp for fp, vp in self.config.ListFields()]]
|
if f not in [fp for fp, vp in self.config.ListFields()]]
|
||||||
for field_descriptor, field_value in sorted(self.config.ListFields(), key=lambda f: f[0].name):
|
for field_descriptor, field_value in sorted(self.config.ListFields(), key=lambda f: f[0].name):
|
||||||
@ -200,6 +211,9 @@ class ConfigEditor(App):
|
|||||||
|
|
||||||
def action_save(self) -> None:
|
def action_save(self) -> None:
|
||||||
"""Save the configuration."""
|
"""Save the configuration."""
|
||||||
|
if not self.config_filename:
|
||||||
|
raise NotImplementedError("saving to USB is not yet implemented!")
|
||||||
|
|
||||||
write_new_config_to_filename(self.config, self.config_filename, inject=self.whole_board)
|
write_new_config_to_filename(self.config, self.config_filename, inject=self.whole_board)
|
||||||
self.push_screen(MessageScreen(f"Configuration saved to {self.config_filename}."))
|
self.push_screen(MessageScreen(f"Configuration saved to {self.config_filename}."))
|
||||||
|
|
||||||
@ -339,9 +353,16 @@ def edit_config():
|
|||||||
description="Utilize a GUI to view and alter the contents of a GP2040-CE configuration.",
|
description="Utilize a GUI to view and alter the contents of a GP2040-CE configuration.",
|
||||||
parents=[core_parser],
|
parents=[core_parser],
|
||||||
)
|
)
|
||||||
parser.add_argument('--whole-board', action='store_true', help="indicate the binary file is a whole board dump")
|
group = parser.add_mutually_exclusive_group(required=True)
|
||||||
parser.add_argument('filename', help=".bin file of a GP2040-CE board's config + footer or entire storage section, "
|
group.add_argument('--usb', action='store_true', help="retrieve the config from a Pico board connected over USB "
|
||||||
|
"and in BOOTSEL mode")
|
||||||
|
group.add_argument('--filename', help=".bin file of a GP2040-CE board's config + footer or entire storage section, "
|
||||||
"or of a GP2040-CE's whole board dump if --whole-board is specified")
|
"or of a GP2040-CE's whole board dump if --whole-board is specified")
|
||||||
|
parser.add_argument('--whole-board', action='store_true', help="indicate the binary file is a whole board dump")
|
||||||
args, _ = parser.parse_known_args()
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
|
if args.usb:
|
||||||
|
app = ConfigEditor(usb=True)
|
||||||
|
else:
|
||||||
app = ConfigEditor(config_filename=args.filename, whole_board=args.whole_board)
|
app = ConfigEditor(config_filename=args.filename, whole_board=args.whole_board)
|
||||||
app.run()
|
app.run()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user