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
mpflash/mpflash/list.py
CHANGED
@@ -1,75 +1,72 @@
|
|
1
|
-
import json
|
2
1
|
from typing import List
|
3
2
|
|
4
|
-
import rich_click as click
|
5
3
|
from rich import print
|
6
4
|
from rich.progress import track
|
7
5
|
from rich.table import Table
|
8
6
|
|
9
|
-
|
10
|
-
from stubber.bulk.mpremoteboard import MPRemoteBoard
|
7
|
+
from mpflash.mpremoteboard import MPRemoteBoard
|
11
8
|
|
12
|
-
from .cli_group import cli
|
13
9
|
from .config import config
|
10
|
+
from .logger import console
|
14
11
|
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"-j",
|
20
|
-
"as_json",
|
21
|
-
is_flag=True,
|
22
|
-
default=False,
|
23
|
-
show_default=True,
|
24
|
-
help="""Output in json format""",
|
25
|
-
)
|
26
|
-
def list_boards(as_json: bool):
|
27
|
-
conn_boards = [
|
28
|
-
MPRemoteBoard(sp)
|
29
|
-
for sp in MPRemoteBoard.connected_boards()
|
30
|
-
if sp not in config.ignore_ports
|
31
|
-
]
|
13
|
+
def list_mcus(bluetooth: bool = False):
|
14
|
+
"""
|
15
|
+
Retrieves information about connected microcontroller boards.
|
32
16
|
|
33
|
-
|
17
|
+
Returns:
|
18
|
+
List[MPRemoteBoard]: A list of MPRemoteBoard instances with board information.
|
19
|
+
Raises:
|
20
|
+
ConnectionError: If there is an error connecting to a board.
|
21
|
+
"""
|
22
|
+
conn_mcus = [MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards(bluetooth) if sp not in config.ignore_ports]
|
23
|
+
|
24
|
+
for mcu in track(conn_mcus, description="Getting board info", transient=True, update_period=0.1):
|
34
25
|
try:
|
35
26
|
mcu.get_mcu_info()
|
36
27
|
except ConnectionError as e:
|
37
28
|
print(f"Error: {e}")
|
38
29
|
continue
|
39
|
-
|
40
|
-
print(json.dumps([mcu.__dict__ for mcu in conn_boards], indent=4))
|
41
|
-
else:
|
42
|
-
show_boards(conn_boards, refresh=False)
|
30
|
+
return conn_mcus
|
43
31
|
|
44
32
|
|
45
|
-
def
|
46
|
-
|
33
|
+
def show_mcus(
|
34
|
+
conn_mcus: List[MPRemoteBoard],
|
47
35
|
title: str = "Connected boards",
|
48
36
|
refresh: bool = True,
|
49
|
-
):
|
37
|
+
): # sourcery skip: extract-duplicate-method
|
50
38
|
"""Show the list of connected boards in a nice table"""
|
51
|
-
table = Table(
|
52
|
-
|
39
|
+
table = Table(
|
40
|
+
title=title,
|
41
|
+
title_style="bold",
|
42
|
+
header_style="bold blue",
|
43
|
+
collapse_padding=True,
|
44
|
+
width=110,
|
45
|
+
row_styles=["blue", "yellow"],
|
46
|
+
)
|
47
|
+
table.add_column("Serial", overflow="fold")
|
53
48
|
table.add_column("Family")
|
54
49
|
table.add_column("Port")
|
55
|
-
table.add_column("Board")
|
50
|
+
table.add_column("Board", overflow="fold")
|
51
|
+
# table.add_column("Variant") # TODO: add variant
|
56
52
|
table.add_column("CPU")
|
57
53
|
table.add_column("Version")
|
58
|
-
table.add_column("build")
|
54
|
+
table.add_column("build", justify="right")
|
59
55
|
|
60
|
-
for mcu in track(
|
56
|
+
for mcu in track(conn_mcus, description="Updating board info", transient=True, update_period=0.1):
|
61
57
|
if refresh:
|
62
58
|
try:
|
63
59
|
mcu.get_mcu_info()
|
64
60
|
except ConnectionError:
|
65
61
|
continue
|
66
62
|
table.add_row(
|
67
|
-
mcu.serialport,
|
63
|
+
mcu.serialport.replace("/dev/", ""),
|
68
64
|
mcu.family,
|
69
65
|
mcu.port,
|
70
|
-
mcu.board,
|
66
|
+
f"{mcu.board}\n{mcu.description}".strip(),
|
67
|
+
# mcu.variant,
|
71
68
|
mcu.cpu,
|
72
69
|
mcu.version,
|
73
70
|
mcu.build,
|
74
71
|
)
|
75
|
-
print(table)
|
72
|
+
console.print(table)
|
mpflash/mpflash/logger.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
"""Logging."""
|
2
2
|
|
3
3
|
from loguru import logger as log
|
4
4
|
from rich.console import Console
|
5
5
|
|
6
|
+
from .config import config
|
7
|
+
|
6
8
|
console = Console()
|
7
9
|
|
8
10
|
|
9
11
|
def _log_formatter(record: dict) -> str:
|
10
|
-
"""Log message formatter"""
|
12
|
+
"""Log message formatter to combine loguru and rich formatting."""
|
11
13
|
color_map = {
|
12
14
|
"TRACE": "dim blue",
|
13
15
|
"DEBUG": "cyan",
|
@@ -19,8 +21,7 @@ def _log_formatter(record: dict) -> str:
|
|
19
21
|
}
|
20
22
|
lvl_color = color_map.get(record["level"].name, "cyan")
|
21
23
|
return (
|
22
|
-
"[not bold green]{time:HH:mm:ss}[/not bold green] | {level.icon}"
|
23
|
-
+ f" - [{lvl_color}]{{message}}[/{lvl_color}]"
|
24
|
+
"[not bold green]{time:HH:mm:ss}[/not bold green] | {level.icon} " + f"[{lvl_color}]{{message}}[/{lvl_color}]"
|
24
25
|
)
|
25
26
|
|
26
27
|
|
@@ -30,13 +31,11 @@ def set_loglevel(loglevel: str):
|
|
30
31
|
log.remove()
|
31
32
|
except ValueError:
|
32
33
|
pass
|
33
|
-
log.add(
|
34
|
-
|
35
|
-
)
|
34
|
+
log.add(console.print, level=loglevel.upper(), colorize=False, format=_log_formatter) # type: ignore
|
35
|
+
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# )
|
37
|
+
def make_quiet():
|
38
|
+
"""Make the logger quiet"""
|
39
|
+
config.quiet = True
|
40
|
+
console.quiet = True
|
41
|
+
set_loglevel("CRITICAL")
|
@@ -0,0 +1,96 @@
|
|
1
|
+
"""
|
2
|
+
Access to the micropython port and board information that is stored in the board_info.json file
|
3
|
+
that is included in the module.
|
4
|
+
|
5
|
+
"""
|
6
|
+
|
7
|
+
import json
|
8
|
+
from functools import lru_cache
|
9
|
+
from pathlib import Path
|
10
|
+
from typing import List, Optional, Tuple, TypedDict, Union
|
11
|
+
|
12
|
+
from mpflash.errors import MPFlashError
|
13
|
+
from mpflash.common import PORT_FWTYPES
|
14
|
+
from mpflash.vendor.versions import clean_version
|
15
|
+
|
16
|
+
|
17
|
+
# Board based on the dataclass Board but changed to TypedDict
|
18
|
+
# - source : get_boardnames.py
|
19
|
+
class Board(TypedDict):
|
20
|
+
"""MicroPython Board definition"""
|
21
|
+
|
22
|
+
description: str
|
23
|
+
port: str
|
24
|
+
board: str
|
25
|
+
board_name: str
|
26
|
+
mcu_name: str
|
27
|
+
path: Union[Path, str]
|
28
|
+
version: str
|
29
|
+
cpu: str
|
30
|
+
|
31
|
+
|
32
|
+
@lru_cache(maxsize=None)
|
33
|
+
def read_stored_boardinfo() -> List[Board]:
|
34
|
+
"""Reads the board_info.json file and returns the data as a list of Board objects"""
|
35
|
+
with open(Path(__file__).parent / "board_info.json", "r") as file:
|
36
|
+
return json.load(file)
|
37
|
+
|
38
|
+
|
39
|
+
def local_mp_ports() -> List[str]:
|
40
|
+
# TODO: Filter for Version
|
41
|
+
mp_boards = read_stored_boardinfo()
|
42
|
+
# select the unique ports from info
|
43
|
+
ports = set({board["port"] for board in mp_boards if board["port"] in PORT_FWTYPES.keys()})
|
44
|
+
return sorted(list(ports))
|
45
|
+
|
46
|
+
|
47
|
+
def get_stored_boards_for_port(port: str, versions: Optional[List[str]] = None):
|
48
|
+
"""
|
49
|
+
Returns a list of boards for the given port and version(s)
|
50
|
+
|
51
|
+
port : str : The Micropython port to filter for
|
52
|
+
versions : List[str] : The Micropython versions to filter for (actual versions required)"""
|
53
|
+
mp_boards = read_stored_boardinfo()
|
54
|
+
|
55
|
+
# filter for 'preview' as they are not in the board_info.json
|
56
|
+
# instead use stable version
|
57
|
+
versions = versions or []
|
58
|
+
if "preview" in versions:
|
59
|
+
versions.remove("preview")
|
60
|
+
versions.append("stable")
|
61
|
+
if versions:
|
62
|
+
# make sure of the v prefix
|
63
|
+
versions = [clean_version(v) for v in versions]
|
64
|
+
# filter for the version(s)
|
65
|
+
mp_boards = [board for board in mp_boards if board["version"] in versions]
|
66
|
+
# filter for the port
|
67
|
+
mp_boards = [board for board in mp_boards if board["port"] == port]
|
68
|
+
return mp_boards
|
69
|
+
|
70
|
+
|
71
|
+
def known_stored_boards(port: str, versions: Optional[List[str]] = None) -> List[Tuple[str, str]]:
|
72
|
+
"""
|
73
|
+
Returns a list of tuples with the description and board name for the given port and version
|
74
|
+
|
75
|
+
port : str : The Micropython port to filter for
|
76
|
+
versions : List[str] : The Micropython versions to filter for (actual versions required)
|
77
|
+
"""
|
78
|
+
mp_boards = get_stored_boards_for_port(port, versions)
|
79
|
+
|
80
|
+
boards = set({(f'{board["version"]} {board["description"]}', board["board"]) for board in mp_boards})
|
81
|
+
return sorted(list(boards))
|
82
|
+
|
83
|
+
|
84
|
+
@lru_cache(maxsize=20)
|
85
|
+
def find_stored_board(board_id: str) -> Board:
|
86
|
+
"""Find the board for the given board_ID or 'board description' and return the board info as a Board object"""
|
87
|
+
info = read_stored_boardinfo()
|
88
|
+
for board_info in info:
|
89
|
+
if board_id in (board_info["board"], board_info["description"]):
|
90
|
+
if "cpu" not in board_info or not board_info["cpu"]:
|
91
|
+
if " with " in board_info["description"]:
|
92
|
+
board_info["cpu"] = board_info["description"].split(" with ")[-1]
|
93
|
+
else:
|
94
|
+
board_info["cpu"] = board_info["port"]
|
95
|
+
return board_info
|
96
|
+
raise MPFlashError(f"Board {board_id} not found")
|
@@ -0,0 +1,63 @@
|
|
1
|
+
"""
|
2
|
+
Translate board description to board designator
|
3
|
+
"""
|
4
|
+
|
5
|
+
import functools
|
6
|
+
import json
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Optional
|
9
|
+
|
10
|
+
from mpflash.errors import MPFlashError
|
11
|
+
from mpflash.vendor.versions import clean_version
|
12
|
+
|
13
|
+
###############################################################################################
|
14
|
+
HERE = Path(__file__).parent
|
15
|
+
###############################################################################################
|
16
|
+
|
17
|
+
|
18
|
+
def find_board_id(
|
19
|
+
descr: str, short_descr: str, board_info: Optional[Path] = None, version: str = "stable"
|
20
|
+
) -> Optional[str]:
|
21
|
+
# TODO: use the json file instead of the csv and get the cpu
|
22
|
+
boards = find_board_by_description(
|
23
|
+
descr=descr,
|
24
|
+
short_descr=short_descr,
|
25
|
+
board_info=board_info,
|
26
|
+
version=clean_version(version),
|
27
|
+
)
|
28
|
+
return boards[-1]["board"]
|
29
|
+
|
30
|
+
|
31
|
+
@functools.lru_cache(maxsize=20)
|
32
|
+
def find_board_by_description(*, descr: str, short_descr: str, version="v1.21.0", board_info: Optional[Path] = None):
|
33
|
+
"""
|
34
|
+
Find the MicroPython BOARD designator based on the description in the firmware
|
35
|
+
using the pre-built board_info.json file
|
36
|
+
"""
|
37
|
+
if not board_info:
|
38
|
+
board_info = HERE / "board_info.json"
|
39
|
+
if not board_info.exists():
|
40
|
+
raise FileNotFoundError(f"Board info file not found: {board_info}")
|
41
|
+
|
42
|
+
info = _read_board_info(board_info)
|
43
|
+
|
44
|
+
# filter for matching version
|
45
|
+
if version == "preview":
|
46
|
+
# TODO: match last stable
|
47
|
+
version = "v1.22.2"
|
48
|
+
version_matches = [b for b in info if b["version"].startswith(version)]
|
49
|
+
if not version_matches:
|
50
|
+
raise MPFlashError(f"No board info found for version {version}")
|
51
|
+
matches = [b for b in version_matches if b["description"] == descr]
|
52
|
+
if not matches and short_descr:
|
53
|
+
matches = [b for b in version_matches if b["description"] == short_descr]
|
54
|
+
if not matches:
|
55
|
+
raise MPFlashError(f"No board info found for description {descr}")
|
56
|
+
return sorted(matches, key=lambda x: x["version"])
|
57
|
+
|
58
|
+
|
59
|
+
@functools.lru_cache(maxsize=20)
|
60
|
+
def _read_board_info(board_info):
|
61
|
+
with open(board_info, "r") as file:
|
62
|
+
info = json.load(file)
|
63
|
+
return info
|