mpflash 1.26.3__py3-none-any.whl → 1.26.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mpflash/__init__.py +0 -4
- mpflash/ask_input.py +11 -4
- mpflash/cli_flash.py +28 -29
- mpflash/connected.py +0 -2
- mpflash/db/boards_version.txt +1 -0
- mpflash/db/core.py +0 -1
- mpflash/db/gather_boards.py +67 -17
- mpflash/db/loader.py +15 -2
- mpflash/db/micropython_boards.zip +0 -0
- mpflash/download/__init__.py +5 -9
- mpflash/download/jid.py +38 -44
- mpflash/flash/__init__.py +13 -13
- mpflash/flash/worklist.py +299 -132
- mpflash/logger.py +42 -42
- mpflash/mpremoteboard/__init__.py +10 -8
- mpflash/mpremoteboard/runner.py +1 -0
- {mpflash-1.26.3.dist-info → mpflash-1.26.4.dist-info}/METADATA +32 -4
- {mpflash-1.26.3.dist-info → mpflash-1.26.4.dist-info}/RECORD +21 -20
- {mpflash-1.26.3.dist-info → mpflash-1.26.4.dist-info}/WHEEL +0 -0
- {mpflash-1.26.3.dist-info → mpflash-1.26.4.dist-info}/entry_points.txt +0 -0
- {mpflash-1.26.3.dist-info → mpflash-1.26.4.dist-info}/licenses/LICENSE +0 -0
mpflash/__init__.py
CHANGED
mpflash/ask_input.py
CHANGED
@@ -5,7 +5,7 @@ Note: The prompts can use "{version}" and "{action}" to insert the version and a
|
|
5
5
|
The values are provided from the answers dictionary.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from typing import List, Sequence, Tuple, Union
|
8
|
+
from typing import Dict, List, Sequence, Tuple, Union
|
9
9
|
|
10
10
|
from loguru import logger as log
|
11
11
|
|
@@ -43,7 +43,7 @@ def ask_missing_params(
|
|
43
43
|
action = "download" if isinstance(params, DownloadParams) else "flash"
|
44
44
|
|
45
45
|
questions = []
|
46
|
-
answers:
|
46
|
+
answers: Dict[str, Union[str, List]] = {"action": action}
|
47
47
|
if not multi_select:
|
48
48
|
if not params.serial or "?" in params.serial:
|
49
49
|
questions.append(ask_serialport(multi_select=False, bluetooth=False))
|
@@ -59,7 +59,14 @@ def ask_missing_params(
|
|
59
59
|
if not params.boards or "?" in params.boards:
|
60
60
|
questions.extend(ask_port_board(multi_select=multi_select, action=action))
|
61
61
|
if questions:
|
62
|
-
|
62
|
+
# Store the pre-existing answers before prompting
|
63
|
+
pre_existing_answers = dict(answers)
|
64
|
+
prompted_answers = inquirer.prompt(questions, answers=answers) # type: ignore
|
65
|
+
if not prompted_answers:
|
66
|
+
# input cancelled by user
|
67
|
+
return [] # type: ignore
|
68
|
+
# Merge pre-existing answers with prompted answers
|
69
|
+
answers = {**pre_existing_answers, **prompted_answers}
|
63
70
|
if not answers:
|
64
71
|
# input cancelled by user
|
65
72
|
return [] # type: ignore
|
@@ -226,7 +233,7 @@ def ask_serialport(*, multi_select: bool = False, bluetooth: bool = False):
|
|
226
233
|
# import only when needed to reduce load time
|
227
234
|
import inquirer
|
228
235
|
|
229
|
-
comports = MPRemoteBoard.
|
236
|
+
comports = MPRemoteBoard.connected_comports(bluetooth=bluetooth, description=True) + ["auto"]
|
230
237
|
return inquirer.List(
|
231
238
|
"serial",
|
232
239
|
message="Which serial port do you want to {action} ?",
|
mpflash/cli_flash.py
CHANGED
@@ -11,8 +11,8 @@ from mpflash.cli_group import cli
|
|
11
11
|
from mpflash.cli_list import show_mcus
|
12
12
|
from mpflash.common import BootloaderMethod, FlashParams, filtered_comports
|
13
13
|
from mpflash.errors import MPFlashError
|
14
|
-
from mpflash.flash import
|
15
|
-
from mpflash.flash.worklist import
|
14
|
+
from mpflash.flash import flash_tasks
|
15
|
+
from mpflash.flash.worklist import FlashTaskList, create_worklist
|
16
16
|
from mpflash.mpremoteboard import MPRemoteBoard
|
17
17
|
from mpflash.versions import clean_version
|
18
18
|
|
@@ -193,10 +193,10 @@ def cli_flash_board(**kwargs) -> int:
|
|
193
193
|
raise MPFlashError("Only one version can be flashed at a time")
|
194
194
|
|
195
195
|
params.versions = [clean_version(v) for v in params.versions]
|
196
|
-
|
196
|
+
tasks: FlashTaskList = []
|
197
197
|
|
198
198
|
if len(params.versions) == 1 and len(params.boards) == 1 and params.serial == ["*"]:
|
199
|
-
#
|
199
|
+
# One or more serial ports including the board / variant (auto-detect ports)
|
200
200
|
comports = filtered_comports(
|
201
201
|
ignore=params.ignore,
|
202
202
|
include=params.serial,
|
@@ -205,50 +205,49 @@ def cli_flash_board(**kwargs) -> int:
|
|
205
205
|
board_id = f"{params.boards[0]}-{params.variant}" if params.variant else params.boards[0]
|
206
206
|
log.info(f"Flashing {board_id} {params.versions[0]} to {len(comports)} serial ports")
|
207
207
|
log.info(f"Target ports: {', '.join(comports)}")
|
208
|
-
|
209
|
-
|
208
|
+
tasks = create_worklist(
|
209
|
+
params.versions[0],
|
210
|
+
serial_ports=comports,
|
210
211
|
board_id=board_id,
|
211
|
-
|
212
|
-
custom=params.custom,
|
212
|
+
custom_firmware=params.custom,
|
213
213
|
)
|
214
|
-
# if serial port == auto and there are one or more specified/detected boards
|
215
214
|
elif params.serial == ["*"] and params.boards:
|
215
|
+
# Auto mode on detected boards with optional include/ignore filtering
|
216
216
|
if not all_boards:
|
217
217
|
log.trace("No boards detected yet, scanning for connected boards")
|
218
218
|
_, _, _, all_boards = connected_ports_boards_variants(include=params.ports, ignore=params.ignore)
|
219
|
-
# if variant id provided on the cmdline, treat is as an override
|
220
219
|
if params.variant:
|
221
220
|
for b in all_boards:
|
222
221
|
b.variant = params.variant if (params.variant.lower() not in {"-", "none"}) else ""
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
ignore=params.ignore,
|
222
|
+
tasks = create_worklist(
|
223
|
+
params.versions[0],
|
224
|
+
connected_comports=all_boards,
|
225
|
+
include_ports=params.serial,
|
226
|
+
ignore_ports=params.ignore,
|
229
227
|
)
|
230
|
-
elif params.versions[0] and params.boards
|
231
|
-
#
|
228
|
+
elif params.versions[0] and params.boards and params.serial:
|
229
|
+
# Manual specification of serial ports + board
|
232
230
|
comports = filtered_comports(
|
233
231
|
ignore=params.ignore,
|
234
|
-
include=params.
|
232
|
+
include=params.serial,
|
235
233
|
bluetooth=params.bluetooth,
|
236
234
|
)
|
237
|
-
|
238
|
-
|
235
|
+
tasks = create_worklist(
|
236
|
+
params.versions[0],
|
237
|
+
serial_ports=comports,
|
239
238
|
board_id=params.boards[0],
|
240
|
-
version=params.versions[0],
|
241
239
|
)
|
242
240
|
else:
|
243
|
-
#
|
244
|
-
|
245
|
-
|
246
|
-
|
241
|
+
# Single serial port auto-detection
|
242
|
+
connected_comports = [MPRemoteBoard(params.serial[0])]
|
243
|
+
tasks = create_worklist(
|
244
|
+
params.versions[0],
|
245
|
+
connected_comports=connected_comports,
|
247
246
|
)
|
248
247
|
if not params.custom:
|
249
|
-
jid.
|
250
|
-
if flashed :=
|
251
|
-
|
248
|
+
jid.ensure_firmware_downloaded_tasks(tasks, version=params.versions[0], force=params.force)
|
249
|
+
if flashed := flash_tasks(
|
250
|
+
tasks,
|
252
251
|
params.erase,
|
253
252
|
params.bootloader,
|
254
253
|
flash_mode=params.flash_mode,
|
mpflash/connected.py
CHANGED
@@ -47,8 +47,6 @@ def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False)
|
|
47
47
|
Raises:
|
48
48
|
ConnectionError: If there is an error connecting to a board.
|
49
49
|
"""
|
50
|
-
# conn_mcus = [MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards(bluetooth) if sp not in config.ignore_ports]
|
51
|
-
vid_pid = True
|
52
50
|
comports = filtered_portinfos(
|
53
51
|
ignore=ignore,
|
54
52
|
include=include,
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.27.0-preview
|
mpflash/db/core.py
CHANGED
mpflash/db/gather_boards.py
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
from os import path
|
2
2
|
from pathlib import Path
|
3
|
-
from typing import List
|
3
|
+
from typing import List, Optional, Tuple
|
4
|
+
|
5
|
+
import click
|
6
|
+
from typing_extensions import TypeAlias
|
4
7
|
|
5
8
|
import mpflash.basicgit as git
|
6
9
|
from mpflash.logger import log
|
@@ -8,6 +11,8 @@ from mpflash.mpremoteboard import HERE
|
|
8
11
|
from mpflash.vendor.board_database import Database
|
9
12
|
from mpflash.versions import micropython_versions
|
10
13
|
|
14
|
+
BoardList: TypeAlias = List[Tuple[str, ...]]
|
15
|
+
|
11
16
|
HERE = Path(__file__).parent.resolve()
|
12
17
|
|
13
18
|
|
@@ -47,7 +52,7 @@ def boardlist_from_repo(
|
|
47
52
|
versions: List[str],
|
48
53
|
mpy_dir: Path,
|
49
54
|
):
|
50
|
-
longlist = []
|
55
|
+
longlist: BoardList = []
|
51
56
|
if not mpy_dir.is_dir():
|
52
57
|
log.error(f"Directory {mpy_dir} not found")
|
53
58
|
return longlist
|
@@ -71,38 +76,63 @@ def boardlist_from_repo(
|
|
71
76
|
log.info(f"{git.get_git_describe(mpy_dir)} - {build_nr}")
|
72
77
|
# un-cached database
|
73
78
|
db = Database(mpy_dir)
|
74
|
-
shortlist = list(iter_boards(db, version=version))
|
79
|
+
shortlist: BoardList = list(iter_boards(db, version=version))
|
75
80
|
log.info(f"boards found {len(db.boards.keys())}")
|
76
81
|
log.info(f"boards-variants found {len(shortlist) - len(db.boards.keys())}")
|
77
82
|
longlist.extend(shortlist)
|
78
83
|
return longlist
|
79
84
|
|
80
85
|
|
81
|
-
def create_zip_file(longlist, zip_file: Path):
|
82
|
-
"""Create a ZIP file containing the CSV data.
|
83
|
-
# lazy import
|
84
|
-
import zipfile
|
86
|
+
def create_zip_file(longlist: BoardList, zip_file: Path):
|
87
|
+
"""Create a ZIP file containing the CSV data without external deps.
|
85
88
|
|
86
|
-
|
89
|
+
Uses the standard library csv module to minimize dependencies while
|
90
|
+
preserving identical column ordering to the prior pandas implementation.
|
91
|
+
"""
|
92
|
+
import csv
|
93
|
+
import io
|
94
|
+
import zipfile # lazy import
|
87
95
|
|
88
96
|
csv_filename = "micropython_boards.csv"
|
97
|
+
columns = [
|
98
|
+
"version",
|
99
|
+
"board_id",
|
100
|
+
"board_name",
|
101
|
+
"mcu",
|
102
|
+
"variant",
|
103
|
+
"port",
|
104
|
+
"path",
|
105
|
+
"description",
|
106
|
+
"family",
|
107
|
+
]
|
108
|
+
|
109
|
+
buf = io.StringIO()
|
110
|
+
writer = csv.writer(buf, lineterminator="\n")
|
111
|
+
writer.writerow(columns)
|
112
|
+
# rows already in correct order matching columns
|
113
|
+
for row in longlist:
|
114
|
+
writer.writerow(row)
|
115
|
+
csv_data = buf.getvalue()
|
89
116
|
|
90
|
-
columns = ["version", "board_id", "board_name", "mcu", "variant", "port", "path", "description", "family"]
|
91
|
-
df = pd.DataFrame(longlist, columns=columns)
|
92
|
-
|
93
|
-
# Create the ZIP file and add the CSV data directly without creating an intermediate file
|
94
117
|
with zipfile.ZipFile(zip_file, "w", zipfile.ZIP_DEFLATED) as zipf:
|
95
|
-
# Create a temporary in-memory CSV string
|
96
|
-
csv_data = df.to_csv(index=False)
|
97
|
-
# Write the CSV data directly to the zip file
|
98
118
|
zipf.writestr(csv_filename, csv_data)
|
99
119
|
|
100
120
|
|
121
|
+
def write_version_file(version: str, output_path: Path):
|
122
|
+
version_file = output_path / "boards_version.txt"
|
123
|
+
with version_file.open("w", encoding="utf-8") as vf:
|
124
|
+
vf.write(version + "\n")
|
125
|
+
log.info(f"Wrote version file {version_file}")
|
126
|
+
|
127
|
+
|
101
128
|
def package_repo(mpy_path: Path):
|
102
129
|
mpy_path = mpy_path or Path("../repos/micropython")
|
103
130
|
log.info(f"Packaging Micropython boards from {mpy_path}")
|
104
131
|
mp_versions = micropython_versions(minver="1.18")
|
105
|
-
|
132
|
+
if not mp_versions:
|
133
|
+
log.error("No Micropython versions found")
|
134
|
+
return
|
135
|
+
# checkout
|
106
136
|
longlist = boardlist_from_repo(
|
107
137
|
versions=mp_versions,
|
108
138
|
mpy_dir=mpy_path,
|
@@ -110,9 +140,29 @@ def package_repo(mpy_path: Path):
|
|
110
140
|
log.info(f"Total boards-variants: {len(longlist)}")
|
111
141
|
zip_file = HERE / "micropython_boards.zip"
|
112
142
|
create_zip_file(longlist, zip_file=zip_file)
|
143
|
+
log.info(f"Created {zip_file} with {len(longlist)} entries")
|
144
|
+
boards_version = mp_versions[-1]
|
145
|
+
write_version_file(boards_version, HERE)
|
113
146
|
|
114
147
|
assert zip_file.is_file(), f"Failed to create {zip_file}"
|
115
148
|
|
116
149
|
|
150
|
+
@click.command()
|
151
|
+
@click.option(
|
152
|
+
"--mpy-path",
|
153
|
+
"mpy_path",
|
154
|
+
type=click.Path(path_type=Path),
|
155
|
+
default=None,
|
156
|
+
help="Path to local micropython repo (default: ../repos/micropython).",
|
157
|
+
)
|
158
|
+
def cli(mpy_path: Optional[Path]):
|
159
|
+
"""Package board metadata into a compressed archive.
|
160
|
+
|
161
|
+
Enumerates boards and variants from a Micropython repo, builds CSV, and
|
162
|
+
writes it into a zip archive for fast loading and distribution.
|
163
|
+
"""
|
164
|
+
package_repo(mpy_path if mpy_path else Path("../repos/micropython"))
|
165
|
+
|
166
|
+
|
117
167
|
if __name__ == "__main__":
|
118
|
-
|
168
|
+
cli()
|
mpflash/db/loader.py
CHANGED
@@ -4,7 +4,6 @@ import json
|
|
4
4
|
import re
|
5
5
|
import zipfile
|
6
6
|
from pathlib import Path
|
7
|
-
from turtle import up
|
8
7
|
|
9
8
|
from loguru import logger as log
|
10
9
|
|
@@ -108,8 +107,22 @@ def load_jsonl_to_db(jsonl_path: Path):
|
|
108
107
|
return num_records
|
109
108
|
|
110
109
|
|
110
|
+
def get_boards_version() -> str:
|
111
|
+
version_file = HERE / "boards_version.txt"
|
112
|
+
if version_file.is_file():
|
113
|
+
with version_file.open("r", encoding="utf-8") as vf:
|
114
|
+
version = vf.read().strip()
|
115
|
+
log.debug(f"Boards version from file: {version}")
|
116
|
+
return version
|
117
|
+
log.warning(f"Boards version file not found: {version_file}")
|
118
|
+
return "unknown"
|
119
|
+
|
120
|
+
|
111
121
|
def update_boards():
|
112
|
-
|
122
|
+
# todo: check if update is needed
|
123
|
+
# load board_versions.txt
|
124
|
+
|
125
|
+
boards_version = get_boards_version()
|
113
126
|
try:
|
114
127
|
meta = get_metadata()
|
115
128
|
log.debug(f"Metadata: {meta}")
|
Binary file
|
mpflash/download/__init__.py
CHANGED
@@ -12,16 +12,16 @@ from typing import Dict, List, Optional
|
|
12
12
|
# make sure that jsonlines does not mistake the MicroPython ujson for the CPython ujson
|
13
13
|
import jsonlines
|
14
14
|
from loguru import logger as log
|
15
|
-
from rich.progress import track
|
16
|
-
|
17
15
|
from mpflash.common import PORT_FWTYPES
|
18
16
|
from mpflash.config import config
|
19
|
-
from mpflash.db.core import Session
|
20
|
-
from mpflash.db.models import Firmware, Board
|
21
17
|
from mpflash.downloaded import clean_downloaded_firmwares
|
22
18
|
from mpflash.errors import MPFlashError
|
23
19
|
from mpflash.mpboard_id.alternate import add_renamed_boards
|
24
20
|
from mpflash.versions import clean_version
|
21
|
+
from rich.progress import track
|
22
|
+
|
23
|
+
from mpflash.db.core import Session
|
24
|
+
from mpflash.db.models import Board, Firmware
|
25
25
|
|
26
26
|
from .from_web import fetch_firmware_files, get_boards
|
27
27
|
from .fwinfo import FWInfo
|
@@ -111,11 +111,7 @@ def download_firmwares(
|
|
111
111
|
|
112
112
|
downloaded = 0
|
113
113
|
versions = [] if versions is None else [clean_version(v) for v in versions]
|
114
|
-
|
115
|
-
# remove the known variant suffixes from the boards
|
116
|
-
# TODO: IS THIS REALLY NEEDED ?
|
117
|
-
# boards = [strip_variant(b) for b in boards]
|
118
|
-
|
114
|
+
|
119
115
|
# handle downloading firmware for renamed boards
|
120
116
|
boards = add_renamed_boards(boards)
|
121
117
|
|
mpflash/download/jid.py
CHANGED
@@ -1,56 +1,50 @@
|
|
1
1
|
# Just In-time Download of firmware if not already available
|
2
|
+
import warnings
|
3
|
+
|
2
4
|
from loguru import logger as log
|
3
5
|
|
4
|
-
from mpflash.common import Params
|
5
6
|
from mpflash.download import download
|
6
7
|
from mpflash.downloaded import find_downloaded_firmware
|
7
8
|
from mpflash.errors import MPFlashError
|
8
|
-
from mpflash.flash.worklist import
|
9
|
+
from mpflash.flash.worklist import FlashTaskList
|
9
10
|
from mpflash.mpboard_id.alternate import alternate_board_names
|
10
11
|
|
11
12
|
|
12
|
-
def
|
13
|
-
"""
|
14
|
-
Ensure all firmware in the worklist is downloaded for the given version.
|
15
|
-
|
16
|
-
Iterates over the worklist, downloads missing firmware, and updates the worklist
|
17
|
-
with the downloaded firmware.
|
13
|
+
def ensure_firmware_downloaded_tasks(tasks: FlashTaskList, version: str, force: bool) -> None:
|
14
|
+
"""Ensure firmware present for each FlashTask, updating in-place.
|
18
15
|
|
19
|
-
|
16
|
+
Mirrors ensure_firmware_downloaded logic but works directly on FlashTaskList.
|
20
17
|
"""
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
18
|
+
updated: FlashTaskList = []
|
19
|
+
for task in tasks:
|
20
|
+
mcu = task.board
|
21
|
+
fw = task.firmware
|
22
|
+
if not force and fw:
|
23
|
+
updated.append(task)
|
24
|
+
continue
|
25
|
+
# find already downloaded firmware unless forcing
|
26
|
+
if force or not fw:
|
27
|
+
found = (
|
28
|
+
find_downloaded_firmware(
|
29
|
+
board_id=f"{mcu.board}-{mcu.variant}" if mcu.variant else mcu.board,
|
30
|
+
version=version,
|
31
|
+
port=mcu.port,
|
32
|
+
)
|
33
|
+
if not force
|
34
|
+
else []
|
36
35
|
)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
worklist.clear()
|
54
|
-
worklist.extend(newlist)
|
55
|
-
|
56
|
-
pass
|
36
|
+
if not found:
|
37
|
+
log.info(f"Downloading {version} firmware for {mcu.board} on {mcu.serialport}.")
|
38
|
+
download(ports=[mcu.port], boards=alternate_board_names(mcu.board, mcu.port), versions=[version], force=True, clean=True)
|
39
|
+
found = find_downloaded_firmware(
|
40
|
+
board_id=f"{mcu.board}-{mcu.variant}" if mcu.variant else mcu.board,
|
41
|
+
version=version,
|
42
|
+
port=mcu.port,
|
43
|
+
)
|
44
|
+
if not found:
|
45
|
+
raise MPFlashError(f"Failed to download {version} firmware for {mcu.board} on {mcu.serialport}.")
|
46
|
+
# choose last/newest
|
47
|
+
task.firmware = found[-1]
|
48
|
+
updated.append(task)
|
49
|
+
tasks.clear()
|
50
|
+
tasks.extend(updated)
|
mpflash/flash/__init__.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
from pathlib import Path
|
2
2
|
|
3
3
|
from loguru import logger as log
|
4
|
-
|
5
|
-
from mpflash.bootloader.activate import enter_bootloader
|
6
4
|
from mpflash.common import PORT_FWTYPES, UF2_PORTS, BootloaderMethod
|
7
5
|
from mpflash.config import config
|
8
6
|
from mpflash.errors import MPFlashError
|
@@ -10,28 +8,29 @@ from mpflash.errors import MPFlashError
|
|
10
8
|
from .esp import flash_esp
|
11
9
|
from .stm32 import flash_stm32
|
12
10
|
from .uf2 import flash_uf2
|
13
|
-
from .worklist import
|
11
|
+
from .worklist import FlashTaskList
|
14
12
|
|
15
13
|
# #########################################################################################################
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
|
16
|
+
def flash_tasks(
|
17
|
+
tasks: FlashTaskList,
|
19
18
|
erase: bool,
|
20
19
|
bootloader: BootloaderMethod,
|
21
|
-
**kwargs
|
22
|
-
):
|
23
|
-
"""Flash a list of
|
20
|
+
**kwargs,
|
21
|
+
):
|
22
|
+
"""Flash a list of FlashTask items directly."""
|
24
23
|
flashed = []
|
25
|
-
for
|
24
|
+
for task in tasks:
|
25
|
+
mcu = task.board
|
26
|
+
fw_info = task.firmware
|
26
27
|
if not fw_info:
|
27
28
|
log.error(f"Firmware not found for {mcu.board} on {mcu.serialport}, skipping")
|
28
29
|
continue
|
29
|
-
|
30
30
|
fw_file = config.firmware_folder / fw_info.firmware_file
|
31
31
|
if not fw_file.exists():
|
32
32
|
log.error(f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}")
|
33
33
|
continue
|
34
|
-
|
35
34
|
log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info.version}")
|
36
35
|
try:
|
37
36
|
updated = flash_mcu(mcu, fw_file=fw_file, erase=erase, bootloader=bootloader, **kwargs)
|
@@ -40,14 +39,13 @@ def flash_list(
|
|
40
39
|
continue
|
41
40
|
if updated:
|
42
41
|
if fw_info.custom:
|
43
|
-
# Add / Update board_info.toml with the custom_id and Description
|
44
42
|
mcu.get_board_info_toml()
|
45
43
|
if fw_info.description:
|
46
44
|
mcu.toml["description"] = fw_info.description
|
45
|
+
mcu.toml.setdefault("mpflash", {})
|
47
46
|
mcu.toml["mpflash"]["board_id"] = fw_info.board_id
|
48
47
|
mcu.toml["mpflash"]["custom_id"] = fw_info.custom_id
|
49
48
|
mcu.set_board_info_toml()
|
50
|
-
|
51
49
|
flashed.append(updated)
|
52
50
|
else:
|
53
51
|
log.error(f"Failed to flash {mcu.board} on {mcu.serialport}")
|
@@ -63,6 +61,8 @@ def flash_mcu(
|
|
63
61
|
**kwargs
|
64
62
|
):
|
65
63
|
"""Flash a single MCU with the specified firmware."""
|
64
|
+
from mpflash.bootloader.activate import enter_bootloader
|
65
|
+
|
66
66
|
updated = None
|
67
67
|
try:
|
68
68
|
if mcu.port in UF2_PORTS and fw_file.suffix == ".uf2":
|