micropython-stubber 1.17.5__py3-none-any.whl → 1.19.0__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.
- {micropython_stubber-1.17.5.dist-info → micropython_stubber-1.19.0.dist-info}/METADATA +7 -6
- {micropython_stubber-1.17.5.dist-info → micropython_stubber-1.19.0.dist-info}/RECORD +71 -52
- mpflash/README.md +22 -3
- mpflash/libusb_flash.ipynb +203 -0
- mpflash/mpflash/ask_input.py +234 -0
- mpflash/mpflash/cli_download.py +107 -0
- mpflash/mpflash/cli_flash.py +165 -0
- mpflash/mpflash/cli_group.py +41 -8
- mpflash/mpflash/cli_list.py +41 -0
- mpflash/mpflash/cli_main.py +13 -8
- mpflash/mpflash/common.py +33 -122
- mpflash/mpflash/config.py +9 -0
- mpflash/mpflash/{downloader.py → download.py} +112 -120
- mpflash/mpflash/downloaded.py +108 -0
- mpflash/mpflash/errors.py +5 -0
- mpflash/mpflash/flash.py +69 -0
- mpflash/mpflash/flash_esp.py +17 -23
- mpflash/mpflash/flash_stm32.py +16 -113
- mpflash/mpflash/flash_stm32_cube.py +111 -0
- mpflash/mpflash/flash_stm32_dfu.py +101 -0
- mpflash/mpflash/flash_uf2.py +8 -8
- mpflash/mpflash/flash_uf2_linux.py +25 -12
- mpflash/mpflash/flash_uf2_windows.py +24 -12
- mpflash/mpflash/list.py +34 -37
- mpflash/mpflash/logger.py +12 -13
- mpflash/mpflash/mpboard_id/__init__.py +96 -0
- mpflash/mpflash/mpboard_id/board_id.py +63 -0
- mpflash/mpflash/mpboard_id/board_info.csv +2213 -0
- mpflash/mpflash/mpboard_id/board_info.json +19910 -0
- mpflash/mpflash/mpremoteboard/__init__.py +208 -0
- mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -0
- {stubber/bulk → mpflash/mpflash/mpremoteboard}/runner.py +22 -5
- mpflash/mpflash/vendor/dfu.py +164 -0
- mpflash/mpflash/vendor/pydfu.py +605 -0
- mpflash/mpflash/vendor/readme.md +3 -0
- mpflash/mpflash/vendor/versions.py +113 -0
- mpflash/mpflash/worklist.py +147 -0
- mpflash/poetry.lock +411 -595
- mpflash/pyproject.toml +24 -8
- mpflash/stm32_udev_rules.md +63 -0
- stubber/__init__.py +1 -1
- stubber/basicgit.py +1 -0
- stubber/board/createstubs.py +10 -4
- stubber/board/createstubs_db.py +11 -5
- stubber/board/createstubs_db_min.py +61 -58
- stubber/board/createstubs_db_mpy.mpy +0 -0
- stubber/board/createstubs_mem.py +11 -5
- stubber/board/createstubs_mem_min.py +56 -53
- stubber/board/createstubs_mem_mpy.mpy +0 -0
- stubber/board/createstubs_min.py +54 -51
- stubber/board/createstubs_mpy.mpy +0 -0
- stubber/bulk/mcu_stubber.py +9 -5
- stubber/codemod/_partials/db_main.py +14 -25
- stubber/codemod/_partials/lvgl_main.py +2 -2
- stubber/codemod/board.py +10 -3
- stubber/commands/clone_cmd.py +7 -7
- stubber/commands/config_cmd.py +3 -0
- stubber/freeze/get_frozen.py +0 -2
- stubber/publish/candidates.py +1 -1
- stubber/publish/package.py +1 -1
- stubber/publish/pathnames.py +1 -1
- stubber/publish/stubpackage.py +1 -0
- stubber/rst/lookup.py +1 -1
- stubber/tools/manifestfile.py +5 -3
- stubber/utils/config.py +26 -36
- stubber/utils/repos.py +2 -2
- stubber/utils/versions.py +1 -0
- mpflash/mpflash/flasher.py +0 -287
- stubber/bulk/board_id.py +0 -40
- stubber/bulk/mpremoteboard.py +0 -141
- {micropython_stubber-1.17.5.dist-info → micropython_stubber-1.19.0.dist-info}/LICENSE +0 -0
- {micropython_stubber-1.17.5.dist-info → micropython_stubber-1.19.0.dist-info}/WHEEL +0 -0
- {micropython_stubber-1.17.5.dist-info → micropython_stubber-1.19.0.dist-info}/entry_points.txt +0 -0
- /mpflash/mpflash/{uf2_boardid.py → flash_uf2_boardid.py} +0 -0
stubber/commands/clone_cmd.py
CHANGED
@@ -31,16 +31,16 @@ def cli_clone(path: Union[str, Path], stubs: bool = False):
|
|
31
31
|
dest_path = Path(path)
|
32
32
|
if not dest_path.exists():
|
33
33
|
os.mkdir(dest_path)
|
34
|
-
|
35
|
-
|
34
|
+
if dest_path == CONFIG.repo_path:
|
35
|
+
# same as default
|
36
|
+
mpy_path = CONFIG.mpy_path
|
37
|
+
mpy_lib_path = CONFIG.mpy_lib_path
|
38
|
+
mpy_stubs_path = CONFIG.mpy_stubs_path
|
39
|
+
else:
|
40
|
+
# repos are relative to provided path
|
36
41
|
mpy_path = dest_path / "micropython"
|
37
42
|
mpy_lib_path = dest_path / "micropython-lib"
|
38
43
|
mpy_stubs_path = dest_path / "micropython-stubs"
|
39
|
-
else:
|
40
|
-
mpy_path = CONFIG.mpy_path
|
41
|
-
mpy_lib_path = CONFIG.mpy_lib_path
|
42
|
-
|
43
|
-
mpy_stubs_path = CONFIG.stub_path.parent
|
44
44
|
|
45
45
|
repos: List[Tuple[Path, str, str]] = [
|
46
46
|
(mpy_path, "https://github.com/micropython/micropython.git", "master"),
|
stubber/commands/config_cmd.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
"""Show the current configuration"""
|
2
|
+
|
2
3
|
# pragma: no cover
|
3
4
|
|
4
5
|
from loguru import logger as log
|
6
|
+
|
5
7
|
from stubber.utils.config import CONFIG
|
6
8
|
|
7
9
|
from .cli import stubber_cli
|
@@ -20,6 +22,7 @@ def cli_config():
|
|
20
22
|
log.info(f"CONFIG.repo_path {CONFIG.repo_path}")
|
21
23
|
log.info(f"CONFIG.mpy_path {CONFIG.mpy_path}")
|
22
24
|
log.info(f"CONFIG.mpy_lib_path {CONFIG.mpy_lib_path}")
|
25
|
+
log.info(f"CONFIG.mpy_stubs_path {CONFIG.mpy_stubs_path}")
|
23
26
|
|
24
27
|
log.info(f"CONFIG.stub_path {CONFIG.stub_path}")
|
25
28
|
log.info(f"CONFIG.publish_path {CONFIG.publish_path}")
|
stubber/freeze/get_frozen.py
CHANGED
@@ -25,9 +25,7 @@ from typing import List, Optional
|
|
25
25
|
from loguru import logger as log
|
26
26
|
from packaging.version import Version
|
27
27
|
|
28
|
-
import stubber.basicgit as git
|
29
28
|
from stubber import utils
|
30
|
-
from stubber.codemod.add_comment import AddComment
|
31
29
|
from stubber.freeze.freeze_folder import freeze_folders # Micropython < v1.12
|
32
30
|
from stubber.freeze.freeze_manifest_2 import freeze_one_manifest_2
|
33
31
|
from stubber.utils.config import CONFIG
|
stubber/publish/candidates.py
CHANGED
@@ -236,7 +236,7 @@ def board_candidates(
|
|
236
236
|
else:
|
237
237
|
r = git.checkout_tag(repo=mpy_path, tag=version)
|
238
238
|
if not r:
|
239
|
-
log.warning(f"Incorrect version or did you run `stubber clone` to get the micropython repo?")
|
239
|
+
log.warning(f"Incorrect version: {version} or did you forget to run `stubber clone` to get the micropython repo?")
|
240
240
|
return []
|
241
241
|
ports = list_micropython_ports(family=family, mpy_path=mpy_path)
|
242
242
|
for port in ports:
|
stubber/publish/package.py
CHANGED
stubber/publish/pathnames.py
CHANGED
stubber/publish/stubpackage.py
CHANGED
stubber/rst/lookup.py
CHANGED
stubber/tools/manifestfile.py
CHANGED
@@ -26,10 +26,10 @@
|
|
26
26
|
# THE SOFTWARE.
|
27
27
|
|
28
28
|
from __future__ import print_function
|
29
|
+
|
29
30
|
import contextlib
|
30
31
|
import os
|
31
32
|
import sys
|
32
|
-
import glob
|
33
33
|
import tempfile
|
34
34
|
from collections import namedtuple
|
35
35
|
|
@@ -270,7 +270,9 @@ class ManifestFile:
|
|
270
270
|
raise ManifestFileError("Expected .py file")
|
271
271
|
kind = KIND_COMPILE_AS_MPY
|
272
272
|
|
273
|
-
self._manifest_files.append(
|
273
|
+
self._manifest_files.append(
|
274
|
+
ManifestOutput(FILE_TYPE_LOCAL, full_path, target_path, timestamp, kind, self._metadata[-1], opt)
|
275
|
+
)
|
274
276
|
|
275
277
|
def _search(self, base_path, package_path, files, exts, kind, opt=None, strict=False):
|
276
278
|
base_path = self._resolve_path(base_path)
|
@@ -411,7 +413,7 @@ class ManifestFile:
|
|
411
413
|
|
412
414
|
for lib_dir in lib_dirs:
|
413
415
|
# Search for {lib_dir}/**/{name}/manifest.py.
|
414
|
-
for root,
|
416
|
+
for root, _, filenames in os.walk(os.path.join(self._path_vars["MPY_LIB_DIR"], lib_dir)):
|
415
417
|
if os.path.basename(root) == name and "manifest.py" in filenames:
|
416
418
|
self.include(root, is_require=True, **kwargs)
|
417
419
|
return
|
stubber/utils/config.py
CHANGED
@@ -15,43 +15,25 @@ from .typed_config_toml import TomlConfigSource
|
|
15
15
|
@section("micropython-stubber")
|
16
16
|
class StubberConfig(Config):
|
17
17
|
"stubber configuration class"
|
18
|
-
stub_path = key(key_name="stub-path", cast=Path, required=False, default=Path("./stubs"))
|
19
|
-
"a Path to the stubs directory"
|
20
18
|
# relative to stubs folder
|
21
|
-
fallback_path = key(key_name="fallback-path", cast=Path, required=False, default=Path("typings/fallback"))
|
19
|
+
fallback_path: Path = key(key_name="fallback-path", cast=Path, required=False, default=Path("typings/fallback"))
|
22
20
|
"a Path to the fallback stubs directory"
|
23
21
|
|
24
22
|
# ------------------------------------------------------------------------------------------
|
25
23
|
# micropython and micropython-lib are relative to ./repo folder
|
26
|
-
repo_path = key(key_name="repo-path", cast=Path, required=False, default=Path("./repos"))
|
24
|
+
repo_path: Path = key(key_name="repo-path", cast=Path, required=False, default=Path("./repos"))
|
27
25
|
"a Path to the repo directory"
|
28
26
|
|
29
|
-
mpy_path = key(key_name="mpy-path", cast=Path, required=False, default=Path("micropython"))
|
27
|
+
mpy_path: Path = key(key_name="mpy-path", cast=Path, required=False, default=Path("micropython"))
|
30
28
|
"a Path to the micropython folder in the repos directory"
|
31
29
|
|
32
|
-
mpy_lib_path = key(key_name="mpy-lib-path", cast=Path, required=False, default=Path("micropython-lib"))
|
30
|
+
mpy_lib_path: Path = key(key_name="mpy-lib-path", cast=Path, required=False, default=Path("micropython-lib"))
|
33
31
|
"a Path to the micropython-lib folder in the repos directory"
|
34
32
|
|
35
|
-
|
36
|
-
|
33
|
+
mpy_stubs_path: Path = key(key_name="mpy-stubs-path", cast=Path, required=False, default=Path("micropython-stubs"))
|
34
|
+
"a Path to the micropython-stubs folder in the repos directory (or current directory)"
|
37
35
|
|
38
|
-
|
39
|
-
key_name="publish-path",
|
40
|
-
cast=Path,
|
41
|
-
required=False,
|
42
|
-
default=Path("./repos/micropython-stubs/publish"),
|
43
|
-
)
|
44
|
-
"A Path to the folder where all stub publication artifacts are stored"
|
45
|
-
|
46
|
-
template_path = key(
|
47
|
-
key_name="template-path",
|
48
|
-
cast=Path,
|
49
|
-
required=False,
|
50
|
-
default=Path("./repos/micropython-stubs/publish/template"),
|
51
|
-
)
|
52
|
-
"a Path to the publication folder that has the template files"
|
53
|
-
|
54
|
-
stable_version = key(key_name="stable-version", cast=str, required=False, default="1.20.0")
|
36
|
+
stable_version: str = key(key_name="stable-version", cast=str, required=False, default="1.20.0")
|
55
37
|
|
56
38
|
"last published stable"
|
57
39
|
|
@@ -66,25 +48,33 @@ class StubberConfig(Config):
|
|
66
48
|
BLOCKED_PORTS = ["minimal", "bare-arm"]
|
67
49
|
"ports that should be ignored as a source of stubs"
|
68
50
|
|
69
|
-
|
70
|
-
|
71
|
-
|
51
|
+
@property
|
52
|
+
def stub_path(self) -> Path:
|
53
|
+
"return the stubs path in the microypthon-stubs repo"
|
54
|
+
return self.mpy_stubs_path / "stubs"
|
55
|
+
|
56
|
+
@property
|
57
|
+
def publish_path(self) -> Path:
|
58
|
+
"return the stubs path in the microypthon-stubs repo"
|
59
|
+
return self.mpy_stubs_path / "publish"
|
72
60
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# self.ALL_VERSIONS = ["1.17", "1.18", "1.19", "1.19.1"]
|
78
|
-
# self.STABLE_VERSION = self.ALL_VERSIONS[-1]
|
61
|
+
@property
|
62
|
+
def template_path(self) -> Path:
|
63
|
+
"return the stubs path in the microypthon-stubs repo"
|
64
|
+
return self.mpy_stubs_path / "publish" / "template"
|
79
65
|
|
80
66
|
def post_read_hook(self) -> dict:
|
81
67
|
config_updates = {}
|
82
68
|
# relative to stubs
|
83
|
-
config_updates.update(fallback_path=self.stub_path / self.fallback_path)
|
69
|
+
# config_updates.update(fallback_path=self.stub_path / self.fallback_path)
|
84
70
|
|
85
71
|
# relative to repo path
|
86
72
|
config_updates.update(mpy_path=self.repo_path / self.mpy_path)
|
87
73
|
config_updates.update(mpy_lib_path=self.repo_path / self.mpy_lib_path)
|
74
|
+
if self.mpy_stubs_path.is_absolute() or self.mpy_stubs_path == Path("."):
|
75
|
+
config_updates.update(mpy_stubs_path=self.mpy_stubs_path)
|
76
|
+
else:
|
77
|
+
config_updates.update(mpy_stubs_path=self.repo_path / self.mpy_stubs_path)
|
88
78
|
# read the versions from the git tags
|
89
79
|
all_versions = []
|
90
80
|
try:
|
@@ -107,7 +97,7 @@ def readconfig(filename: str = "pyproject.toml", prefix: str = "tool.", must_exi
|
|
107
97
|
while not (path / filename).exists():
|
108
98
|
path = path.parent
|
109
99
|
if path == path.parent:
|
110
|
-
log.
|
100
|
+
log.trace(f"Could not find config file: {filename}")
|
111
101
|
use_toml = False
|
112
102
|
break
|
113
103
|
|
stubber/utils/repos.py
CHANGED
@@ -107,9 +107,9 @@ def fetch_repos(tag: str, mpy_path: Path, mpy_lib_path: Path):
|
|
107
107
|
git.fetch(mpy_path)
|
108
108
|
git.fetch(mpy_lib_path)
|
109
109
|
try:
|
110
|
-
git.fetch(CONFIG.
|
110
|
+
git.fetch(CONFIG.mpy_stubs_path)
|
111
111
|
except Exception:
|
112
|
-
log.trace("no stubs repo found : {CONFIG.
|
112
|
+
log.trace("no stubs repo found : {CONFIG.mpy_stubs_path}")
|
113
113
|
|
114
114
|
if not tag:
|
115
115
|
tag = V_PREVIEW
|
stubber/utils/versions.py
CHANGED
mpflash/mpflash/flasher.py
DELETED
@@ -1,287 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from typing import List, Optional, Tuple
|
3
|
-
|
4
|
-
import jsonlines
|
5
|
-
import rich_click as click
|
6
|
-
from loguru import logger as log
|
7
|
-
|
8
|
-
# TODO: - refactor so that we do not need the entire stubber package
|
9
|
-
from stubber.bulk.mpremoteboard import MPRemoteBoard
|
10
|
-
|
11
|
-
from .cli_group import cli
|
12
|
-
from .common import DEFAULT_FW_PATH, FWInfo, clean_version
|
13
|
-
from .config import config
|
14
|
-
from .flash_esp import flash_esp
|
15
|
-
from .flash_stm32 import flash_stm32
|
16
|
-
from .flash_uf2 import flash_uf2
|
17
|
-
from .list import show_boards
|
18
|
-
|
19
|
-
# #########################################################################################################
|
20
|
-
|
21
|
-
|
22
|
-
def load_firmwares(fw_folder: Path) -> List[FWInfo]:
|
23
|
-
"""Load a list of available firmwares from the jsonl file"""
|
24
|
-
firmwares: List[FWInfo] = []
|
25
|
-
try:
|
26
|
-
with jsonlines.open(fw_folder / "firmware.jsonl") as reader:
|
27
|
-
firmwares.extend(iter(reader))
|
28
|
-
except FileNotFoundError:
|
29
|
-
log.error(f"No firmware.jsonl found in {fw_folder}")
|
30
|
-
# sort by filename
|
31
|
-
firmwares.sort(key=lambda x: x["filename"])
|
32
|
-
return firmwares
|
33
|
-
|
34
|
-
|
35
|
-
def find_firmware(
|
36
|
-
*,
|
37
|
-
board: str,
|
38
|
-
version: str = "",
|
39
|
-
port: str = "",
|
40
|
-
preview: bool = False,
|
41
|
-
variants: bool = False,
|
42
|
-
fw_folder: Optional[Path] = None,
|
43
|
-
trie: int = 1,
|
44
|
-
):
|
45
|
-
# TODO : better path handling
|
46
|
-
fw_folder = fw_folder or DEFAULT_FW_PATH
|
47
|
-
# Use the information in firmwares.jsonl to find the firmware file
|
48
|
-
fw_list = load_firmwares(fw_folder)
|
49
|
-
|
50
|
-
if not fw_list:
|
51
|
-
log.error(f"No firmware files found. Please download the firmware first.")
|
52
|
-
return []
|
53
|
-
# filter by version
|
54
|
-
version = clean_version(version, drop_v=True)
|
55
|
-
if preview or "preview" in version:
|
56
|
-
# never get a preview for an older version
|
57
|
-
fw_list = [fw for fw in fw_list if fw["preview"]]
|
58
|
-
else:
|
59
|
-
fw_list = [fw for fw in fw_list if fw["version"] == version]
|
60
|
-
|
61
|
-
# filter by port
|
62
|
-
if port:
|
63
|
-
fw_list = [fw for fw in fw_list if fw["port"] == port]
|
64
|
-
|
65
|
-
if board:
|
66
|
-
if variants:
|
67
|
-
fw_list = [fw for fw in fw_list if fw["board"] == board]
|
68
|
-
else:
|
69
|
-
# the variant should match exactly the board name
|
70
|
-
fw_list = [fw for fw in fw_list if fw["variant"] == board]
|
71
|
-
|
72
|
-
if not fw_list and trie < 2:
|
73
|
-
board_id = board.replace("_", "-")
|
74
|
-
# ESP board naming conventions have changed by adding a PORT refix
|
75
|
-
if port.startswith("esp") and not board_id.startswith(port.upper()):
|
76
|
-
board_id = f"{port.upper()}_{board_id}"
|
77
|
-
# RP2 board naming conventions have changed by adding a _RPIprefix
|
78
|
-
if port == "rp2" and not board_id.startswith("RPI_"):
|
79
|
-
board_id = f"RPI_{board_id}"
|
80
|
-
|
81
|
-
log.warning(f"Trying to find a firmware for the board {board_id}")
|
82
|
-
fw_list = find_firmware(
|
83
|
-
fw_folder=fw_folder,
|
84
|
-
board=board_id,
|
85
|
-
version=version,
|
86
|
-
port=port,
|
87
|
-
preview=preview,
|
88
|
-
trie=trie + 1,
|
89
|
-
)
|
90
|
-
# hope we have a match now for the board
|
91
|
-
# sort by filename
|
92
|
-
fw_list.sort(key=lambda x: x["filename"])
|
93
|
-
return fw_list
|
94
|
-
|
95
|
-
|
96
|
-
# #########################################################################################################
|
97
|
-
#
|
98
|
-
# #########################################################################################################
|
99
|
-
WorkList = List[Tuple[MPRemoteBoard, FWInfo]]
|
100
|
-
|
101
|
-
|
102
|
-
def auto_update(conn_boards: List[MPRemoteBoard], target_version: str, fw_folder: Path):
|
103
|
-
"""Builds a list of boards to update based on the connected boards and the firmware available"""
|
104
|
-
wl: WorkList = []
|
105
|
-
for mcu in conn_boards:
|
106
|
-
if mcu.family != "micropython":
|
107
|
-
log.warning(
|
108
|
-
f"Skipping {mcu.board} on {mcu.serialport} as it is not a micropython board"
|
109
|
-
)
|
110
|
-
continue
|
111
|
-
board_firmwares = find_firmware(
|
112
|
-
fw_folder=fw_folder,
|
113
|
-
board=mcu.board,
|
114
|
-
version=target_version,
|
115
|
-
port=mcu.port,
|
116
|
-
preview="preview" in target_version,
|
117
|
-
)
|
118
|
-
|
119
|
-
if not board_firmwares:
|
120
|
-
log.error(
|
121
|
-
f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}."
|
122
|
-
)
|
123
|
-
continue
|
124
|
-
if len(board_firmwares) > 1:
|
125
|
-
log.debug(
|
126
|
-
f"Multiple {target_version} firmwares found for {mcu.board} on {mcu.serialport}."
|
127
|
-
)
|
128
|
-
# just use the last firmware
|
129
|
-
fw_info = board_firmwares[-1]
|
130
|
-
log.info(
|
131
|
-
f"Found {target_version} firmware {fw_info['filename']} for {mcu.board} on {mcu.serialport}."
|
132
|
-
)
|
133
|
-
wl.append((mcu, fw_info))
|
134
|
-
return wl
|
135
|
-
|
136
|
-
|
137
|
-
# #########################################################################################################
|
138
|
-
# CLI
|
139
|
-
# #########################################################################################################
|
140
|
-
|
141
|
-
|
142
|
-
@cli.command(
|
143
|
-
"flash",
|
144
|
-
short_help="Flash one or all connected MicroPython boards with a specific firmware and version.",
|
145
|
-
)
|
146
|
-
@click.option(
|
147
|
-
"--firmware",
|
148
|
-
"-f",
|
149
|
-
"fw_folder",
|
150
|
-
type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
|
151
|
-
default="./firmware",
|
152
|
-
show_default=True,
|
153
|
-
help="The folder to retrieve the firmware from.",
|
154
|
-
)
|
155
|
-
@click.option(
|
156
|
-
"--version",
|
157
|
-
"-v",
|
158
|
-
"target_version",
|
159
|
-
default="stable",
|
160
|
-
show_default=True,
|
161
|
-
help="The version of MicroPython to flash.",
|
162
|
-
metavar="SEMVER, stable or preview",
|
163
|
-
)
|
164
|
-
@click.option(
|
165
|
-
"--serial",
|
166
|
-
"--serial-port",
|
167
|
-
"-s",
|
168
|
-
"serial_port",
|
169
|
-
default="auto",
|
170
|
-
show_default=True,
|
171
|
-
help="Which serial port(s) to flash",
|
172
|
-
metavar="SERIAL_PORT",
|
173
|
-
)
|
174
|
-
@click.option(
|
175
|
-
"--port",
|
176
|
-
"-p",
|
177
|
-
"port",
|
178
|
-
help="The MicroPython port to flash",
|
179
|
-
metavar="PORT",
|
180
|
-
default="",
|
181
|
-
)
|
182
|
-
@click.option(
|
183
|
-
"--board",
|
184
|
-
"-b",
|
185
|
-
"board",
|
186
|
-
help="The MicroPython board ID to flash. if not specified will try to read the BOARD_ID from the connected MCU.",
|
187
|
-
metavar="BOARD_ID",
|
188
|
-
default="",
|
189
|
-
)
|
190
|
-
@click.option(
|
191
|
-
"--erase/--no-erase",
|
192
|
-
default=True,
|
193
|
-
show_default=True,
|
194
|
-
help="""Erase flash before writing new firmware.""",
|
195
|
-
)
|
196
|
-
@click.option(
|
197
|
-
"--preview/--no-preview",
|
198
|
-
default=False,
|
199
|
-
show_default=True,
|
200
|
-
help="""Include preview versions in the download list.""",
|
201
|
-
)
|
202
|
-
def flash_board(
|
203
|
-
target_version: str,
|
204
|
-
fw_folder: Path,
|
205
|
-
serial_port: Optional[str] = None,
|
206
|
-
board: Optional[str] = None,
|
207
|
-
port: Optional[str] = None,
|
208
|
-
variant: Optional[str] = None,
|
209
|
-
erase: bool = False,
|
210
|
-
preview: bool = False,
|
211
|
-
):
|
212
|
-
todo: WorkList = []
|
213
|
-
target_version = clean_version(target_version)
|
214
|
-
# Update all micropython boards to the latest version
|
215
|
-
if target_version and port and board and serial_port:
|
216
|
-
mcu = MPRemoteBoard(serial_port)
|
217
|
-
mcu.port = port
|
218
|
-
mcu.cpu = port if port.startswith("esp") else ""
|
219
|
-
mcu.board = board
|
220
|
-
firmwares = find_firmware(
|
221
|
-
fw_folder=fw_folder,
|
222
|
-
board=board,
|
223
|
-
version=target_version,
|
224
|
-
port=port,
|
225
|
-
preview=preview or "preview" in target_version,
|
226
|
-
)
|
227
|
-
if not firmwares:
|
228
|
-
log.error(f"No firmware found for {port} {board} version {target_version}")
|
229
|
-
return
|
230
|
-
# use the most recent matching firmware
|
231
|
-
todo = [(mcu, firmwares[-1])]
|
232
|
-
elif serial_port:
|
233
|
-
if serial_port == "auto":
|
234
|
-
# update all connected boards
|
235
|
-
conn_boards = [
|
236
|
-
MPRemoteBoard(sp)
|
237
|
-
for sp in MPRemoteBoard.connected_boards()
|
238
|
-
if sp not in config.ignore_ports
|
239
|
-
]
|
240
|
-
else:
|
241
|
-
# just this serial port
|
242
|
-
conn_boards = [MPRemoteBoard(serial_port)]
|
243
|
-
show_boards(conn_boards)
|
244
|
-
todo = auto_update(conn_boards, target_version, fw_folder)
|
245
|
-
|
246
|
-
flashed = []
|
247
|
-
for mcu, fw_info in todo:
|
248
|
-
fw_file = fw_folder / fw_info["filename"] # type: ignore
|
249
|
-
if not fw_file.exists():
|
250
|
-
log.error(
|
251
|
-
f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}"
|
252
|
-
)
|
253
|
-
continue
|
254
|
-
log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info['version']}")
|
255
|
-
|
256
|
-
updated = None
|
257
|
-
# try:
|
258
|
-
if mcu.port in ["samd", "rp2"]:
|
259
|
-
updated = flash_uf2(mcu, fw_file=fw_file, erase=erase)
|
260
|
-
elif mcu.port in ["esp32", "esp8266"]:
|
261
|
-
updated = flash_esp(mcu, fw_file=fw_file, erase=erase)
|
262
|
-
elif mcu.port in ["stm32"]:
|
263
|
-
updated = flash_stm32(mcu, fw_file=fw_file, erase=erase)
|
264
|
-
|
265
|
-
if updated:
|
266
|
-
flashed.append(updated)
|
267
|
-
else:
|
268
|
-
log.error(f"Failed to flash {mcu.board} on {mcu.serialport}")
|
269
|
-
|
270
|
-
if flashed:
|
271
|
-
log.info(f"Flashed {len(flashed)} boards")
|
272
|
-
conn_boards = [
|
273
|
-
MPRemoteBoard(sp)
|
274
|
-
for sp in MPRemoteBoard.connected_boards()
|
275
|
-
if sp not in config.ignore_ports
|
276
|
-
]
|
277
|
-
show_boards(conn_boards, title="Connected boards after flashing")
|
278
|
-
|
279
|
-
|
280
|
-
# TODO:
|
281
|
-
# flash from some sort of queue to allow different images to be flashed to the same board
|
282
|
-
# - flash variant 1
|
283
|
-
# - stub variant 1
|
284
|
-
# - flash variant 2
|
285
|
-
# - stub variant 2
|
286
|
-
#
|
287
|
-
# JIT download / download any missing firmwares based on the detected boards
|
stubber/bulk/board_id.py
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Translate board description to board designator
|
3
|
-
"""
|
4
|
-
|
5
|
-
from pathlib import Path
|
6
|
-
from typing import Optional
|
7
|
-
|
8
|
-
###############################################################################################
|
9
|
-
# TODO : make this a bit nicer
|
10
|
-
HERE = Path(__file__).parent
|
11
|
-
###############################################################################################
|
12
|
-
|
13
|
-
|
14
|
-
def find_board_designator(descr: str, short_descr: str, board_info: Optional[Path] = None) -> Optional[str]:
|
15
|
-
"""
|
16
|
-
Find the miropython BOARD designator based on the description in the firmware
|
17
|
-
using the pre-built board_info.csv file
|
18
|
-
"""
|
19
|
-
if not board_info:
|
20
|
-
board_info = HERE / "../data/board_info.csv"
|
21
|
-
if not board_info.exists():
|
22
|
-
raise FileNotFoundError(f"Board info file not found: {board_info}")
|
23
|
-
|
24
|
-
short_hit = ""
|
25
|
-
with open(board_info, "r") as file:
|
26
|
-
while 1:
|
27
|
-
line = file.readline()
|
28
|
-
if not line:
|
29
|
-
break
|
30
|
-
descr_, board_ = line.split(",")[0].strip(), line.split(",")[1].strip()
|
31
|
-
if descr_ == descr:
|
32
|
-
return board_
|
33
|
-
if short_descr and descr_ == short_descr:
|
34
|
-
if "with" in short_descr:
|
35
|
-
# Good enough - no need to trawl the entire file
|
36
|
-
# info["board"] = board_
|
37
|
-
return board_
|
38
|
-
# good enough if not found in the rest of the file (but slow)
|
39
|
-
short_hit = board_
|
40
|
-
return short_hit or None
|