mpflash 1.24.5__py3-none-any.whl → 1.24.7__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/basicgit.py +22 -2
- mpflash/bootloader/activate.py +1 -1
- mpflash/common.py +4 -13
- mpflash/downloaded.py +10 -2
- mpflash/flash/esp.py +1 -1
- mpflash/flash/uf2/__init__.py +18 -2
- mpflash/mpboard_id/add_boards.py +29 -15
- mpflash/mpboard_id/board.py +2 -2
- mpflash/mpboard_id/board_id.py +7 -5
- mpflash/mpboard_id/board_info.zip +0 -0
- mpflash/mpremoteboard/__init__.py +13 -8
- mpflash/vendor/board_database.py +185 -0
- mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt +21 -0
- mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2 +0 -0
- mpflash/vendor/readme.md +12 -1
- mpflash/versions.py +16 -32
- {mpflash-1.24.5.dist-info → mpflash-1.24.7.dist-info}/METADATA +7 -5
- {mpflash-1.24.5.dist-info → mpflash-1.24.7.dist-info}/RECORD +21 -18
- {mpflash-1.24.5.dist-info → mpflash-1.24.7.dist-info}/WHEEL +1 -1
- {mpflash-1.24.5.dist-info → mpflash-1.24.7.dist-info}/LICENSE +0 -0
- {mpflash-1.24.5.dist-info → mpflash-1.24.7.dist-info}/entry_points.txt +0 -0
mpflash/basicgit.py
CHANGED
@@ -136,6 +136,9 @@ def get_local_tags(repo: Optional[Path] = None, minver: Optional[str] = None) ->
|
|
136
136
|
return sorted(tags)
|
137
137
|
|
138
138
|
|
139
|
+
from github.GithubException import BadCredentialsException
|
140
|
+
|
141
|
+
|
139
142
|
@cachetools.func.ttl_cache(maxsize=16, ttl=60) # 60 seconds
|
140
143
|
def get_tags(repo: str, minver: Optional[str] = None) -> List[str]:
|
141
144
|
"""
|
@@ -176,7 +179,7 @@ def checkout_tag(tag: str, repo: Optional[Union[str, Path]] = None) -> bool:
|
|
176
179
|
return True
|
177
180
|
|
178
181
|
|
179
|
-
def sync_submodules(repo:
|
182
|
+
def sync_submodules(repo: Union[Path, str]) -> bool:
|
180
183
|
"""
|
181
184
|
make sure any submodules are in sync
|
182
185
|
"""
|
@@ -191,9 +194,26 @@ def sync_submodules(repo: Optional[Union[Path, str]] = None) -> bool:
|
|
191
194
|
log.debug(result.stderr)
|
192
195
|
else:
|
193
196
|
return False
|
197
|
+
checkout_arduino_lib(Path(repo))
|
194
198
|
return True
|
195
199
|
|
196
200
|
|
201
|
+
def checkout_arduino_lib(mpy_path: Path):
|
202
|
+
"""
|
203
|
+
Checkout the arduino-lib submodule repo if it exists
|
204
|
+
|
205
|
+
This is needed as some of the arduino boards freeze modules originationg from the arduino-lib
|
206
|
+
"""
|
207
|
+
# arduino_lib_path = mpy_path / "lib/arduino-lib"
|
208
|
+
if (mpy_path / "lib/arduino-lib").exists():
|
209
|
+
cmd = ["git", "submodule", "update", "--init", "lib/arduino-lib"]
|
210
|
+
try:
|
211
|
+
result = subprocess.run(cmd, cwd=mpy_path, check=True)
|
212
|
+
log.info(f"checkout arduino-lib: {result.returncode}")
|
213
|
+
except subprocess.CalledProcessError as e:
|
214
|
+
log.warning("Could not check out arduino-lib, error: ", e)
|
215
|
+
|
216
|
+
|
197
217
|
def checkout_commit(commit_hash: str, repo: Optional[Union[Path, str]] = None) -> bool:
|
198
218
|
"""
|
199
219
|
Checkout a specific commit
|
@@ -242,7 +262,7 @@ def switch_branch(branch: str, repo: Optional[Union[Path, str]] = None) -> bool:
|
|
242
262
|
|
243
263
|
def fetch(repo: Union[Path, str]) -> bool:
|
244
264
|
"""
|
245
|
-
fetches a repo
|
265
|
+
fetches a repo and all tags
|
246
266
|
repo should be in the form of : path/.git
|
247
267
|
repo = '../micropython/.git'
|
248
268
|
returns True on success
|
mpflash/bootloader/activate.py
CHANGED
@@ -12,7 +12,7 @@ from .touch1200 import enter_bootloader_touch_1200bps
|
|
12
12
|
|
13
13
|
BL_OPTIONS = {
|
14
14
|
"stm32": [BootloaderMethod.TOUCH_1200, BootloaderMethod.MPY, BootloaderMethod.MANUAL],
|
15
|
-
"rp2": [BootloaderMethod.
|
15
|
+
"rp2": [BootloaderMethod.MPY, BootloaderMethod.TOUCH_1200, BootloaderMethod.MANUAL],
|
16
16
|
"samd": [BootloaderMethod.TOUCH_1200, BootloaderMethod.MPY, BootloaderMethod.MANUAL],
|
17
17
|
"esp32": [BootloaderMethod.NONE],
|
18
18
|
"esp8266": [BootloaderMethod.NONE],
|
mpflash/common.py
CHANGED
@@ -7,10 +7,11 @@ from enum import Enum
|
|
7
7
|
from pathlib import Path
|
8
8
|
from typing import List, Optional, Union
|
9
9
|
|
10
|
-
from github import Auth, Github
|
11
10
|
from serial.tools import list_ports
|
12
11
|
from serial.tools.list_ports_common import ListPortInfo
|
13
12
|
|
13
|
+
from mpflash.basicgit import GH_CLIENT as GH_CLIENT
|
14
|
+
|
14
15
|
from .logger import log
|
15
16
|
|
16
17
|
# from mpflash.mpremoteboard import MPRemoteBoard
|
@@ -27,17 +28,6 @@ PORT_FWTYPES = {
|
|
27
28
|
"renesas-ra": [".hex"],
|
28
29
|
}
|
29
30
|
|
30
|
-
# Token with no permissions to avoid throttling
|
31
|
-
# https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
|
32
|
-
PAT_NO_ACCESS = (
|
33
|
-
"github_pat_"
|
34
|
-
+ "11AAHPVFQ0G4NTaQ73Bw5J"
|
35
|
-
+ "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
|
36
|
-
)
|
37
|
-
|
38
|
-
PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
|
39
|
-
GH_CLIENT = Github(auth=Auth.Token(PAT))
|
40
|
-
|
41
31
|
|
42
32
|
@dataclass
|
43
33
|
class FWInfo:
|
@@ -150,9 +140,10 @@ def filtered_comports(
|
|
150
140
|
comports = [
|
151
141
|
p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)
|
152
142
|
]
|
153
|
-
|
143
|
+
|
154
144
|
if False:
|
155
145
|
import jsons
|
146
|
+
|
156
147
|
print(jsons.dumps(comports).replace('{"description":', '\n{"description":'))
|
157
148
|
|
158
149
|
if platform.system() == "Linux":
|
mpflash/downloaded.py
CHANGED
@@ -14,11 +14,15 @@ from .config import config
|
|
14
14
|
def downloaded_firmwares(fw_folder: Path) -> List[FWInfo]:
|
15
15
|
"""Load a list of locally downloaded firmwares from the jsonl file"""
|
16
16
|
firmwares: List[FWInfo] = []
|
17
|
+
log.debug(f"Reading {fw_folder / 'firmware.jsonl' }")
|
17
18
|
try:
|
18
19
|
with jsonlines.open(fw_folder / "firmware.jsonl") as reader:
|
19
20
|
firmwares = [FWInfo.from_dict(item) for item in reader]
|
20
21
|
except FileNotFoundError:
|
21
22
|
log.error(f"No firmware.jsonl found in {fw_folder}")
|
23
|
+
except jsonlines.InvalidLineError as e:
|
24
|
+
log.error(f"Invalid firmware.jsonl found in {fw_folder} : {e}")
|
25
|
+
|
22
26
|
# sort by filename
|
23
27
|
firmwares.sort(key=lambda x: x.filename)
|
24
28
|
return firmwares
|
@@ -109,7 +113,11 @@ def filter_downloaded_fwlist(
|
|
109
113
|
log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
|
110
114
|
# filter by port
|
111
115
|
if port:
|
112
|
-
fw_list = [
|
116
|
+
fw_list = [
|
117
|
+
fw
|
118
|
+
for fw in fw_list
|
119
|
+
if fw.port == port and Path(fw.firmware).suffix in PORT_FWTYPES[port]
|
120
|
+
]
|
113
121
|
log.trace(f"Filtering firmware for {port} : {len(fw_list)} found.")
|
114
122
|
|
115
123
|
if board_id:
|
@@ -120,7 +128,7 @@ def filter_downloaded_fwlist(
|
|
120
128
|
# the firmware variant should match exactly the board_id
|
121
129
|
fw_list = [fw for fw in fw_list if fw.variant == board_id]
|
122
130
|
log.trace(f"Filtering firmware for {board_id} : {len(fw_list)} found.")
|
123
|
-
|
131
|
+
|
124
132
|
if selector and port in selector:
|
125
133
|
fw_list = [fw for fw in fw_list if fw.filename.endswith(selector[port])]
|
126
134
|
return fw_list
|
mpflash/flash/esp.py
CHANGED
@@ -15,7 +15,7 @@ from mpflash.mpremoteboard import MPRemoteBoard
|
|
15
15
|
|
16
16
|
|
17
17
|
def flash_esp(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool = True) -> Optional[MPRemoteBoard]:
|
18
|
-
if mcu.port not in ["esp32", "esp8266"] or mcu.board
|
18
|
+
if mcu.port not in ["esp32", "esp8266"] or mcu.board.startswith("ARDUINO_"):
|
19
19
|
log.error(f"esptool not supported for {mcu.port} {mcu.board} on {mcu.serialport}")
|
20
20
|
return None
|
21
21
|
|
mpflash/flash/uf2/__init__.py
CHANGED
@@ -5,6 +5,7 @@ Flash SAMD and RP2 via UF2
|
|
5
5
|
import shutil
|
6
6
|
import sys
|
7
7
|
from pathlib import Path
|
8
|
+
import time
|
8
9
|
from typing import Optional
|
9
10
|
|
10
11
|
import tenacity
|
@@ -38,7 +39,21 @@ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemo
|
|
38
39
|
log.error(f"UF2 not supported on {mcu.board} on {mcu.serialport}")
|
39
40
|
return None
|
40
41
|
if erase:
|
41
|
-
|
42
|
+
if mcu.port == "rp2":
|
43
|
+
rp2_erase =Path(__file__).parent.joinpath("../../vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2").resolve()
|
44
|
+
log.info(f"Erasing {mcu.port} with {rp2_erase.name}")
|
45
|
+
# optimistic
|
46
|
+
destination = waitfor_uf2(board_id=mcu.port.upper())
|
47
|
+
if not destination :
|
48
|
+
log.error("Board is not in bootloader mode")
|
49
|
+
return None
|
50
|
+
copy_firmware_to_uf2(rp2_erase, destination)
|
51
|
+
if sys.platform in ["linux"]:
|
52
|
+
dismount_uf2_linux()
|
53
|
+
# allow for MCU restart after erase
|
54
|
+
time.sleep(0.5)
|
55
|
+
else:
|
56
|
+
log.warning(f"Erase not (yet) supported on .UF2, for port {mcu.port}, skipping erase.")
|
42
57
|
|
43
58
|
destination = waitfor_uf2(board_id=mcu.port.upper())
|
44
59
|
|
@@ -84,5 +99,6 @@ def copy_firmware_to_uf2(fw_file: Path, destination: Path):
|
|
84
99
|
Copy the firmware file to the destination,
|
85
100
|
Retry 3 times with 1s delay
|
86
101
|
"""
|
87
|
-
log.
|
102
|
+
log.trace(f"Firmware: {fw_file}")
|
103
|
+
log.info(f"Copying {fw_file.name} to {destination}.")
|
88
104
|
return shutil.copy(fw_file, destination)
|
mpflash/mpboard_id/add_boards.py
CHANGED
@@ -16,16 +16,18 @@ import mpflash.basicgit as git
|
|
16
16
|
from mpflash.logger import log
|
17
17
|
from mpflash.mpboard_id import Board
|
18
18
|
from mpflash.mpboard_id.store import write_boardinfo_json
|
19
|
-
from mpflash.versions import
|
19
|
+
from mpflash.versions import (get_preview_mp_version, get_stable_mp_version,
|
20
|
+
micropython_versions)
|
20
21
|
|
21
22
|
# look for all mpconfigboard.h files and extract the board name
|
22
23
|
# from the #define MICROPY_HW_BOARD_NAME "PYBD_SF6"
|
23
24
|
# and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
|
24
25
|
RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
|
25
26
|
RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\s+\"(.+)\"")
|
26
|
-
# find in the mpconfigboard
|
27
|
-
|
28
|
-
|
27
|
+
# find boards and variants in the mpconfigboard*.cmake files
|
28
|
+
RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(
|
29
|
+
r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\""
|
30
|
+
)
|
29
31
|
RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
|
30
32
|
# TODO: normal make files
|
31
33
|
|
@@ -42,20 +44,21 @@ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None)
|
|
42
44
|
"""
|
43
45
|
if not mpy_path.exists() or not mpy_path.is_dir():
|
44
46
|
raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
|
45
|
-
|
46
|
-
|
47
|
-
if not version:
|
48
|
-
version = git.get_local_tag() # type: ignore
|
47
|
+
family = family or "micropython"
|
48
|
+
version = version or git.get_local_tag() # type: ignore
|
49
49
|
if not version:
|
50
50
|
raise ValueError("No version provided and no local tag found.")
|
51
|
+
elif version in ["main", "master"]:
|
52
|
+
version = get_preview_mp_version()
|
51
53
|
|
52
54
|
board_list: List[Board] = []
|
53
55
|
# look in mpconfigboard.h files
|
54
56
|
board_list = boards_from_cmake(mpy_path, version, family)
|
55
57
|
|
56
|
-
# look for
|
58
|
+
# look for boards in the .cmake files
|
57
59
|
board_list.extend(boards_from_headers(mpy_path, version, family))
|
58
|
-
|
60
|
+
|
61
|
+
# TODO:? look for variants in the board.json files
|
59
62
|
|
60
63
|
return board_list
|
61
64
|
|
@@ -63,7 +66,7 @@ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None)
|
|
63
66
|
def boards_from_cmake(mpy_path: Path, version: str, family: str):
|
64
67
|
"""Get boards from the mpconfigboard.cmake files to the board_list."""
|
65
68
|
board_list = []
|
66
|
-
for path in mpy_path.glob("ports/**/mpconfigboard
|
69
|
+
for path in mpy_path.glob("ports/**/mpconfigboard*.cmake"):
|
67
70
|
board = path.parent.name
|
68
71
|
port = path.parent.parent.parent.name
|
69
72
|
with open(path, "r") as f:
|
@@ -118,7 +121,9 @@ def boards_from_headers(mpy_path: Path, version: str, family: str):
|
|
118
121
|
mcu_name = match[1]
|
119
122
|
found += 1
|
120
123
|
if found == 2:
|
121
|
-
description =
|
124
|
+
description = (
|
125
|
+
f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
|
126
|
+
)
|
122
127
|
board_list.append(
|
123
128
|
Board(
|
124
129
|
board_id=board,
|
@@ -160,6 +165,8 @@ def boards_for_versions(versions: List[str], mpy_path: Path):
|
|
160
165
|
List[Board]: The list of Board objects.
|
161
166
|
"""
|
162
167
|
board_list: List[Board] = []
|
168
|
+
# first fetch all tags from the repository
|
169
|
+
git.fetch(mpy_path)
|
163
170
|
for version in track(versions, description="Searching MicroPython versions"):
|
164
171
|
if git.checkout_tag(tag=version, repo=mpy_path):
|
165
172
|
new_ones = boards_from_repo(mpy_path, version, family="micropython")
|
@@ -197,9 +204,10 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
|
|
197
204
|
is_wide = True
|
198
205
|
|
199
206
|
table = rich.table.Table(title="MicroPython Board Information")
|
207
|
+
table.add_column("Port", justify="left", style="magenta")
|
200
208
|
table.add_column("BOARD_ID", justify="left", style="green")
|
209
|
+
table.add_column("Variant(s)", justify="left", style="blue")
|
201
210
|
table.add_column("Description", justify="left", style="cyan")
|
202
|
-
table.add_column("Port", justify="left", style="magenta")
|
203
211
|
table.add_column("Board Name", justify="left", style="blue")
|
204
212
|
if is_wide:
|
205
213
|
table.add_column("MCU Name", justify="left", style="blue")
|
@@ -209,7 +217,7 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
|
|
209
217
|
table.add_column("Family", justify="left", style="blue")
|
210
218
|
|
211
219
|
for board in board_list:
|
212
|
-
row = [board.board_id, board.
|
220
|
+
row = [board.port, board.board_id, board.variant, board.description, board.board_name]
|
213
221
|
if is_wide:
|
214
222
|
row.append(board.mcu_name)
|
215
223
|
row.extend((str(Path(board.path).suffix), board.version))
|
@@ -222,7 +230,13 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
|
|
222
230
|
|
223
231
|
def ask_mpy_path():
|
224
232
|
"""Ask the user for the path to the MicroPython repository."""
|
225
|
-
questions = [
|
233
|
+
questions = [
|
234
|
+
inquirer.Text(
|
235
|
+
"mpy_path",
|
236
|
+
message="Enter the path to the MicroPython repository",
|
237
|
+
default="./repos/micropython",
|
238
|
+
)
|
239
|
+
]
|
226
240
|
if answers := inquirer.prompt(questions):
|
227
241
|
return Path(answers["mpy_path"])
|
228
242
|
else:
|
mpflash/mpboard_id/board.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from dataclasses import dataclass, field
|
2
2
|
from pathlib import Path
|
3
|
-
from typing import
|
3
|
+
from typing import Union
|
4
4
|
|
5
5
|
|
6
6
|
# - source : get_boardnames.py
|
@@ -20,7 +20,7 @@ class Board:
|
|
20
20
|
family: str = field(default="micropython")
|
21
21
|
mcu_name: str = field(default="")
|
22
22
|
cpu: str = field(default="")
|
23
|
-
|
23
|
+
variant: str = field(default="")
|
24
24
|
|
25
25
|
def __post_init__(self):
|
26
26
|
if not self.cpu:
|
mpflash/mpboard_id/board_id.py
CHANGED
@@ -9,7 +9,7 @@ from typing import Optional
|
|
9
9
|
from mpflash.errors import MPFlashError
|
10
10
|
from mpflash.logger import log
|
11
11
|
from mpflash.mpboard_id.store import read_known_boardinfo
|
12
|
-
from mpflash.versions import clean_version, get_stable_mp_version
|
12
|
+
from mpflash.versions import clean_version, get_preview_mp_version, get_stable_mp_version
|
13
13
|
|
14
14
|
|
15
15
|
def find_board_id_by_description(
|
@@ -64,13 +64,15 @@ def _find_board_id_by_description(
|
|
64
64
|
short_descr = descr.split(" with ")[0]
|
65
65
|
if version:
|
66
66
|
# filter for matching version
|
67
|
-
if version in ("
|
68
|
-
# match last stable
|
67
|
+
if version in ("stable"):
|
69
68
|
version = get_stable_mp_version()
|
69
|
+
if version in ("preview", "master"):
|
70
|
+
version = get_preview_mp_version()
|
70
71
|
known_versions = sorted({b.version for b in candidate_boards})
|
71
72
|
if version not in known_versions:
|
72
|
-
log.trace(
|
73
|
-
version
|
73
|
+
log.trace(known_versions)
|
74
|
+
log.debug(f"Version {version} not found in board info, using latest stable version {get_stable_mp_version()}")
|
75
|
+
version = ".".join(get_stable_mp_version().split(".")[:2]) # take only major.minor
|
74
76
|
if version_matches := [b for b in candidate_boards if b.version.startswith(version)]:
|
75
77
|
candidate_boards = version_matches
|
76
78
|
else:
|
Binary file
|
@@ -55,7 +55,7 @@ class MPRemoteBoard:
|
|
55
55
|
self.arch = ""
|
56
56
|
self.mpy = ""
|
57
57
|
self.build = ""
|
58
|
-
self.location = location
|
58
|
+
self.location = location # USB location
|
59
59
|
self.toml = {}
|
60
60
|
if update:
|
61
61
|
self.get_mcu_info()
|
@@ -97,7 +97,9 @@ class MPRemoteBoard:
|
|
97
97
|
|
98
98
|
if sys.platform == "win32":
|
99
99
|
# Windows sort of comports by number - but fallback to device name
|
100
|
-
return sorted(
|
100
|
+
return sorted(
|
101
|
+
output, key=lambda x: int(x.split()[0][3:]) if x.split()[0][3:].isdigit() else x
|
102
|
+
)
|
101
103
|
# sort by device name
|
102
104
|
return sorted(output)
|
103
105
|
|
@@ -116,9 +118,10 @@ class MPRemoteBoard:
|
|
116
118
|
["run", str(HERE / "mpy_fw_info.py")],
|
117
119
|
no_info=True,
|
118
120
|
timeout=timeout,
|
119
|
-
resume=
|
121
|
+
resume=False, # Avoid restarts
|
120
122
|
)
|
121
|
-
if rc
|
123
|
+
if rc:
|
124
|
+
log.debug(f"rc: {rc}, result: {result}")
|
122
125
|
raise ConnectionError(f"Failed to get mcu_info for {self.serialport}")
|
123
126
|
# Ok we have the info, now parse it
|
124
127
|
raw_info = result[0].strip()
|
@@ -134,7 +137,9 @@ class MPRemoteBoard:
|
|
134
137
|
self.description = descr = info["board"]
|
135
138
|
pos = descr.rfind(" with")
|
136
139
|
short_descr = descr[:pos].strip() if pos != -1 else ""
|
137
|
-
if board_name := find_board_id_by_description(
|
140
|
+
if board_name := find_board_id_by_description(
|
141
|
+
descr, short_descr, version=self.version
|
142
|
+
):
|
138
143
|
self.board = board_name
|
139
144
|
else:
|
140
145
|
self.board = "UNKNOWN_BOARD"
|
@@ -174,7 +179,7 @@ class MPRemoteBoard:
|
|
174
179
|
except Exception as e:
|
175
180
|
log.error(f"Failed to parse board_info.toml: {e}")
|
176
181
|
else:
|
177
|
-
log.trace(f"
|
182
|
+
log.trace(f"Did not find a board_info.toml: {result}")
|
178
183
|
|
179
184
|
def disconnect(self) -> bool:
|
180
185
|
"""
|
@@ -202,7 +207,7 @@ class MPRemoteBoard:
|
|
202
207
|
log_errors: bool = True,
|
203
208
|
no_info: bool = False,
|
204
209
|
timeout: int = 60,
|
205
|
-
resume: bool =
|
210
|
+
resume: Optional[bool] = None,
|
206
211
|
**kwargs,
|
207
212
|
):
|
208
213
|
"""
|
@@ -223,7 +228,7 @@ class MPRemoteBoard:
|
|
223
228
|
if self.serialport:
|
224
229
|
prefix += ["connect", self.serialport]
|
225
230
|
# if connected add resume to keep state between commands
|
226
|
-
if self.connected or resume:
|
231
|
+
if (resume != False) and self.connected or resume:
|
227
232
|
prefix += ["resume"]
|
228
233
|
cmd = prefix + cmd
|
229
234
|
log.debug(" ".join(cmd))
|
@@ -0,0 +1,185 @@
|
|
1
|
+
"""
|
2
|
+
The micropython git repo contains many 'board.json' files.
|
3
|
+
|
4
|
+
This is an example:
|
5
|
+
ports/stm32/boards/PYBV11/board.json
|
6
|
+
|
7
|
+
{
|
8
|
+
"deploy": [
|
9
|
+
"../PYBV10/deploy.md"
|
10
|
+
],
|
11
|
+
"docs": "",
|
12
|
+
"features": [],
|
13
|
+
"images": [
|
14
|
+
"PYBv1_1.jpg",
|
15
|
+
"PYBv1_1-C.jpg",
|
16
|
+
"PYBv1_1-E.jpg"
|
17
|
+
],
|
18
|
+
"mcu": "stm32f4",
|
19
|
+
"product": "Pyboard v1.1",
|
20
|
+
"thumbnail": "",
|
21
|
+
"url": "https://store.micropython.org/product/PYBv1.1",
|
22
|
+
"variants": {
|
23
|
+
"DP": "Double-precision float",
|
24
|
+
"DP_THREAD": "Double precision float + Threads",
|
25
|
+
"NETWORK": "Wiznet 5200 Driver",
|
26
|
+
"THREAD": "Threading"
|
27
|
+
},
|
28
|
+
"vendor": "George Robotics"
|
29
|
+
}
|
30
|
+
|
31
|
+
This module implements `class Database` which reads all 'board.json' files and
|
32
|
+
provides a way to browse it's data.
|
33
|
+
"""
|
34
|
+
|
35
|
+
from __future__ import annotations
|
36
|
+
|
37
|
+
import json
|
38
|
+
from dataclasses import dataclass, field
|
39
|
+
from glob import glob
|
40
|
+
from pathlib import Path
|
41
|
+
|
42
|
+
|
43
|
+
@dataclass(order=True)
|
44
|
+
class Variant:
|
45
|
+
name: str
|
46
|
+
"""
|
47
|
+
Example: "DP_THREAD"
|
48
|
+
"""
|
49
|
+
text: str
|
50
|
+
"""
|
51
|
+
Example: "Double precision float + Threads"
|
52
|
+
"""
|
53
|
+
board: Board = field(repr=False)
|
54
|
+
|
55
|
+
|
56
|
+
@dataclass(order=True)
|
57
|
+
class Board:
|
58
|
+
name: str
|
59
|
+
"""
|
60
|
+
Example: "PYBV11"
|
61
|
+
"""
|
62
|
+
variants: list[Variant]
|
63
|
+
"""
|
64
|
+
List of variants available for this board.
|
65
|
+
Variants are sorted. May be an empty list if no variants are available.
|
66
|
+
Example key: "DP_THREAD"
|
67
|
+
"""
|
68
|
+
url: str
|
69
|
+
"""
|
70
|
+
Primary URL to link to this board.
|
71
|
+
"""
|
72
|
+
mcu: str
|
73
|
+
"""
|
74
|
+
Example: "stm32f4"
|
75
|
+
"""
|
76
|
+
product: str
|
77
|
+
"""
|
78
|
+
Example: "Pyboard v1.1"
|
79
|
+
"""
|
80
|
+
vendor: str
|
81
|
+
"""
|
82
|
+
Example: "George Robotics"
|
83
|
+
"""
|
84
|
+
images: list[str]
|
85
|
+
"""
|
86
|
+
Images of this board, stored in the micropython-media repository.
|
87
|
+
Example: ["PYBv1_1.jpg", "PYBv1_1-C.jpg", "PYBv1_1-E.jpg"]
|
88
|
+
"""
|
89
|
+
deploy: list[str]
|
90
|
+
"""
|
91
|
+
Files that explain how to deploy for this board:
|
92
|
+
Example: ["../PYBV10/deploy.md"]
|
93
|
+
"""
|
94
|
+
port: Port | None = field(default=None, compare=False)
|
95
|
+
|
96
|
+
@staticmethod
|
97
|
+
def factory(filename_json: Path) -> Board:
|
98
|
+
with filename_json.open() as f:
|
99
|
+
board_json = json.load(f)
|
100
|
+
|
101
|
+
board = Board(
|
102
|
+
name=filename_json.parent.name,
|
103
|
+
variants=[],
|
104
|
+
url=board_json["url"],
|
105
|
+
mcu=board_json["mcu"],
|
106
|
+
product=board_json["product"],
|
107
|
+
vendor=board_json["vendor"],
|
108
|
+
images=board_json["images"],
|
109
|
+
deploy=board_json["deploy"],
|
110
|
+
)
|
111
|
+
board.variants.extend(
|
112
|
+
sorted([Variant(*v, board) for v in board_json.get("variants", {}).items()]) # type: ignore
|
113
|
+
)
|
114
|
+
return board
|
115
|
+
|
116
|
+
|
117
|
+
@dataclass(order=True)
|
118
|
+
class Port:
|
119
|
+
name: str
|
120
|
+
"""
|
121
|
+
Example: "stm32"
|
122
|
+
"""
|
123
|
+
boards: dict[str, Board] = field(default_factory=dict, repr=False)
|
124
|
+
"""
|
125
|
+
Example key: "PYBV11"
|
126
|
+
"""
|
127
|
+
|
128
|
+
|
129
|
+
@dataclass
|
130
|
+
class Database:
|
131
|
+
"""
|
132
|
+
This database contains all information retrieved from all 'board.json' files.
|
133
|
+
"""
|
134
|
+
|
135
|
+
mpy_root_directory: Path = field(repr=False)
|
136
|
+
port_filter: str = field(default="", repr=False)
|
137
|
+
|
138
|
+
ports: dict[str, Port] = field(default_factory=dict)
|
139
|
+
boards: dict[str, Board] = field(default_factory=dict)
|
140
|
+
|
141
|
+
def __post_init__(self) -> None:
|
142
|
+
mpy_dir = self.mpy_root_directory
|
143
|
+
# Take care to avoid using Path.glob! Performance was 15x slower.
|
144
|
+
for p in glob(f"{mpy_dir}/ports/**/boards/**/board.json"):
|
145
|
+
filename_json = Path(p)
|
146
|
+
port_name = filename_json.parent.parent.parent.name
|
147
|
+
if self.port_filter and self.port_filter != port_name:
|
148
|
+
continue
|
149
|
+
|
150
|
+
# Create a port
|
151
|
+
port = self.ports.get(port_name, None)
|
152
|
+
if port is None:
|
153
|
+
port = Port(port_name)
|
154
|
+
self.ports[port_name] = port
|
155
|
+
|
156
|
+
# Load board.json and attach it to the board
|
157
|
+
board = Board.factory(filename_json)
|
158
|
+
board.port = port
|
159
|
+
|
160
|
+
port.boards[board.name] = board
|
161
|
+
self.boards[board.name] = board
|
162
|
+
|
163
|
+
# Add 'special' ports, that don't have boards
|
164
|
+
# TODO(mst) Tidy up later (variant descriptions etc)
|
165
|
+
for special_port_name in ["unix", "webassembly", "windows"]:
|
166
|
+
if self.port_filter and self.port_filter != special_port_name:
|
167
|
+
continue
|
168
|
+
path = Path(mpy_dir, "ports", special_port_name)
|
169
|
+
variant_names = [var.name for var in path.glob("variants/*") if var.is_dir()]
|
170
|
+
board = Board(
|
171
|
+
special_port_name,
|
172
|
+
[],
|
173
|
+
f"https://github.com/micropython/micropython/blob/master/ports/{special_port_name}/README.md",
|
174
|
+
"",
|
175
|
+
"",
|
176
|
+
"",
|
177
|
+
[],
|
178
|
+
[],
|
179
|
+
)
|
180
|
+
board.variants = [Variant(v, "", board) for v in variant_names]
|
181
|
+
port = Port(special_port_name, {special_port_name: board})
|
182
|
+
board.port = port
|
183
|
+
|
184
|
+
self.ports[special_port_name] = port
|
185
|
+
self.boards[board.name] = board
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright 2024 Phil Howard
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
4
|
+
following conditions are met:
|
5
|
+
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
7
|
+
disclaimer.
|
8
|
+
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
10
|
+
disclaimer in the documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
16
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
18
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
19
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
20
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
21
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Binary file
|
mpflash/vendor/readme.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
1
|
These modules are vendored from the following repositories:
|
2
2
|
|
3
|
-
micropython/micropython
|
3
|
+
- https://github.com/micropython/micropython (MIT)
|
4
|
+
- dfu.py
|
5
|
+
- pydfy.py
|
6
|
+
|
7
|
+
- https://github.com/mattytrentini/mpbuild (MIT)
|
8
|
+
- board_database.py
|
9
|
+
|
10
|
+
- https://github.com/click-contrib/click-aliases (Public Domain)
|
11
|
+
- click_aliases.py (Robbin Bonthond)
|
12
|
+
|
13
|
+
- https://github.com/Gadgetoid/pico-universal-flash-nuke
|
14
|
+
- universal_flash_nuke.uf2
|
mpflash/versions.py
CHANGED
@@ -81,34 +81,16 @@ def micropython_versions(minver: str = "v1.20", reverse: bool = False, cache_it=
|
|
81
81
|
try:
|
82
82
|
gh_client = GH_CLIENT
|
83
83
|
repo = gh_client.get_repo("micropython/micropython")
|
84
|
-
|
84
|
+
tags = [tag.name for tag in repo.get_tags() if parse(tag.name) >= parse(minver)]
|
85
|
+
versions = [v for v in tags if not v.endswith(V_PREVIEW)]
|
85
86
|
# Only keep the last preview
|
86
|
-
|
87
|
+
preview = sorted([v for v in tags if v.endswith(V_PREVIEW)], reverse=True)[0]
|
88
|
+
versions.append(preview)
|
87
89
|
except Exception as e:
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
"v1.22.0",
|
93
|
-
"v1.21.1",
|
94
|
-
"v1.21.0",
|
95
|
-
"v1.20.0",
|
96
|
-
"v1.19.1",
|
97
|
-
"v1.19",
|
98
|
-
"v1.18",
|
99
|
-
"v1.17",
|
100
|
-
"v1.16",
|
101
|
-
"v1.15",
|
102
|
-
"v1.14",
|
103
|
-
"v1.13",
|
104
|
-
"v1.12",
|
105
|
-
"v1.11",
|
106
|
-
"v1.10",
|
107
|
-
]
|
108
|
-
cache_it = False
|
109
|
-
versions = [v for v in versions if parse(v) >= parse(minver)]
|
110
|
-
# remove all but the most recent (preview) version
|
111
|
-
versions = versions[:1] + [v for v in versions if "preview" not in v]
|
90
|
+
log.error(e)
|
91
|
+
versions = []
|
92
|
+
# returns - but does not cache
|
93
|
+
raise NoCacheCondition(function_value=versions)
|
112
94
|
# remove any duplicates and sort
|
113
95
|
versions = sorted(list(set(versions)), reverse=reverse, key=lambda s: (not is_version(s), s))
|
114
96
|
if cache_it:
|
@@ -117,16 +99,18 @@ def micropython_versions(minver: str = "v1.20", reverse: bool = False, cache_it=
|
|
117
99
|
raise NoCacheCondition(function_value=versions)
|
118
100
|
|
119
101
|
|
120
|
-
def get_stable_mp_version() -> str:
|
102
|
+
def get_stable_mp_version(cache_it=True) -> str:
|
121
103
|
# read the versions from the git tags
|
122
|
-
all_versions = micropython_versions(minver=OLDEST_VERSION)
|
123
|
-
|
104
|
+
all_versions = micropython_versions(minver=OLDEST_VERSION, cache_it=cache_it)
|
105
|
+
versions = [v for v in all_versions if not v.endswith(V_PREVIEW)]
|
106
|
+
return versions[-1] if versions else ""
|
124
107
|
|
125
108
|
|
126
|
-
def get_preview_mp_version() -> str:
|
109
|
+
def get_preview_mp_version(cache_it=True) -> str:
|
127
110
|
# read the versions from the git tags
|
128
|
-
all_versions = micropython_versions(minver=OLDEST_VERSION)
|
129
|
-
|
111
|
+
all_versions = micropython_versions(minver=OLDEST_VERSION, cache_it=cache_it)
|
112
|
+
versions = [v for v in all_versions if v.endswith(V_PREVIEW)]
|
113
|
+
return versions[0] if versions else ""
|
130
114
|
|
131
115
|
|
132
116
|
# Do not cache , same path will have different versions checked out
|
@@ -1,19 +1,19 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: mpflash
|
3
|
-
Version: 1.24.
|
3
|
+
Version: 1.24.7
|
4
4
|
Summary: Flash and download tool for MicroPython firmwares
|
5
|
-
Home-page: https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md
|
6
5
|
License: MIT
|
7
6
|
Keywords: MicroPython,firmware,flash,download,UF2,esptool
|
8
7
|
Author: Jos Verlinde
|
9
8
|
Author-email: jos_verlinde@hotmail.com
|
10
|
-
Requires-Python: >=3.
|
9
|
+
Requires-Python: >=3.9,<4.0
|
11
10
|
Classifier: License :: OSI Approved :: MIT License
|
12
11
|
Classifier: Programming Language :: Python :: 3
|
13
12
|
Classifier: Programming Language :: Python :: 3.9
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
17
17
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
18
18
|
Classifier: Programming Language :: Python :: Implementation :: MicroPython
|
19
19
|
Classifier: Topic :: Software Development :: Build Tools
|
@@ -29,14 +29,16 @@ Requires-Dist: jsons (>=1.6.3,<2.0.0)
|
|
29
29
|
Requires-Dist: libusb (>=1.0.27,<2.0.0) ; sys_platform == "win32"
|
30
30
|
Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
31
31
|
Requires-Dist: mpremote (>=1.22.0,<2.0.0)
|
32
|
-
Requires-Dist: packaging (
|
32
|
+
Requires-Dist: packaging (>=24.2,<25.0)
|
33
33
|
Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
|
34
|
+
Requires-Dist: poetry (>=2.0.1,<3.0.0)
|
34
35
|
Requires-Dist: psutil (>=5.9.8,<6.0.0)
|
35
36
|
Requires-Dist: pygithub (>=2.1.1,<3.0.0)
|
36
37
|
Requires-Dist: pyusb (>=1.2.1,<2.0.0)
|
37
38
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
38
39
|
Requires-Dist: rich-click (>=1.8.1,<2.0.0)
|
39
40
|
Requires-Dist: tenacity (==8.2.3)
|
41
|
+
Project-URL: Homepage, https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md
|
40
42
|
Project-URL: Repository, https://github.com/Josverl/micropython-stubber
|
41
43
|
Description-Content-Type: text/markdown
|
42
44
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
mpflash/add_firmware.py,sha256=1h0HsA-EVi3HXLmoEvzwY_a-GuWYzPwulTYHHBB8THg,3428
|
3
3
|
mpflash/ask_input.py,sha256=RJHGGrhYniSu-bdoKnKptE3DtpiCREJGRTZmFazvG-E,8946
|
4
|
-
mpflash/basicgit.py,sha256=
|
4
|
+
mpflash/basicgit.py,sha256=NO27JTPUsnMWQ2bKI_zsIFsFTfCZO3QKbvQ23kIehxU,10734
|
5
5
|
mpflash/bootloader/__init__.py,sha256=Qy3E6tETPnzMga9LgD5UgOvJ0zZIBEqhtEVb4v8CTWQ,107
|
6
|
-
mpflash/bootloader/activate.py,sha256=
|
6
|
+
mpflash/bootloader/activate.py,sha256=orQOw4XTkXVZI-rMInRb0T5Wp3qA_BlzbJUA2gyBToU,2361
|
7
7
|
mpflash/bootloader/detect.py,sha256=fBrILi7-ICRaregqms3PYqwiQVAJC0rXVhpyzDkoPQI,2690
|
8
8
|
mpflash/bootloader/manual.py,sha256=2IfxrTFRso78FezVMTOrXMEojamFDDTXrAM9g1SbjNA,3170
|
9
9
|
mpflash/bootloader/micropython.py,sha256=v_kZkvg0uWZDbMrT78gmiYHbD83QLdnrctvEClI8iRg,529
|
@@ -13,17 +13,17 @@ mpflash/cli_flash.py,sha256=pVqEsDocDT3KmIMTpXdym-ZlzThLSIp6oVtYib65dys,7595
|
|
13
13
|
mpflash/cli_group.py,sha256=VWwYHiPVV19sQEr5lL8LlcPyZ-A6Gs79eMDJy8LLt90,2615
|
14
14
|
mpflash/cli_list.py,sha256=ja21AZ4yghGTtOHkEtV1EOmT6EYxOiU2gzJc-mZaDto,2427
|
15
15
|
mpflash/cli_main.py,sha256=5EkvzsqOUDXvNaW814oSUcPWeNhnwh78Sg0MteDv_fk,1133
|
16
|
-
mpflash/common.py,sha256=
|
16
|
+
mpflash/common.py,sha256=umTouKs5Wb7Q2zOaaoO9nqmlpHIaiDBRIGYIkZMBVO8,7558
|
17
17
|
mpflash/config.py,sha256=tdpvAvAlpco1GfeG2evn5tAKYluLEanqwrrvkir7QcQ,1073
|
18
18
|
mpflash/connected.py,sha256=woYhuXoWpfzRMDUpBLVQZbVTGtMsKWNd5z1rsR1ELXA,3578
|
19
19
|
mpflash/download.py,sha256=wE4uBSFFMAKOBH4jwHweL0wVYh4vi74t1673ku_IeoA,14305
|
20
|
-
mpflash/downloaded.py,sha256=
|
20
|
+
mpflash/downloaded.py,sha256=nxTWU4lvhcthqvVmzpYHnXCnjD8wJv0KFq2KtaoTO1A,5160
|
21
21
|
mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
|
22
22
|
mpflash/flash/__init__.py,sha256=g4Fp8MiquaDZXIvRJwYRkkll1MMyRud7x6qmwCk9Lgo,2096
|
23
|
-
mpflash/flash/esp.py,sha256=
|
23
|
+
mpflash/flash/esp.py,sha256=CRF8sfIyuDZoYC1luBy92zLm6Qz3dnBBWjuJ3A4_crE,2284
|
24
24
|
mpflash/flash/stm32.py,sha256=dqp9BZ4Vr-6GlQcF12TSmRf-5TXkov9qvCpMgeUJc7Y,574
|
25
25
|
mpflash/flash/stm32_dfu.py,sha256=W-3JsRQyf3DduoIRXDmGZ35RogqtjQgcJnk-GOtQoLE,3090
|
26
|
-
mpflash/flash/uf2/__init__.py,sha256=
|
26
|
+
mpflash/flash/uf2/__init__.py,sha256=haL84hP2p1ZjKF6dXJJHAB_NTf7jT91MuZvmvg9SpIA,3617
|
27
27
|
mpflash/flash/uf2/boardid.py,sha256=U5wGM8VA3wEpUxQCMtuXpMZZomdVH8J_Zd5_GekUMuU,423
|
28
28
|
mpflash/flash/uf2/linux.py,sha256=UgoF_GhJdxA2NvfcFNV69YuDg3v4ueLM0epsDzmfKK0,4440
|
29
29
|
mpflash/flash/uf2/macos.py,sha256=TGGijlnMJy3RDhdPS3WsPOE2lWFOQbqC3xn4cxLu8GA,1229
|
@@ -33,21 +33,24 @@ mpflash/flash/worklist.py,sha256=owS3xJbWC-SzbK9z6jQER0Kat3OIV09IxnV-f-tjGlY,599
|
|
33
33
|
mpflash/list.py,sha256=lP_S5xbC0Men9HsXcIxOsP0bFRlCYh5CynMLFJx8cEE,3607
|
34
34
|
mpflash/logger.py,sha256=dI_H_a7EOdQJyvoeRHQuYeZuTKYVUS3DUPTLhE9rkdM,1098
|
35
35
|
mpflash/mpboard_id/__init__.py,sha256=b9PJiKFqmfyYgfi0-pbWGp2mrljdgvO6DNy0ABS8izU,3898
|
36
|
-
mpflash/mpboard_id/add_boards.py,sha256=
|
37
|
-
mpflash/mpboard_id/board.py,sha256=
|
38
|
-
mpflash/mpboard_id/board_id.py,sha256=
|
39
|
-
mpflash/mpboard_id/board_info.zip,sha256=
|
36
|
+
mpflash/mpboard_id/add_boards.py,sha256=xBC9DULWq6nR1Nui2Z7tiLHxC0QohPXgJOYvSgrGwEM,10063
|
37
|
+
mpflash/mpboard_id/board.py,sha256=JKb4T67HmK7widW-4c1PgilvywMbZYToLk9Fyokm-6Q,1163
|
38
|
+
mpflash/mpboard_id/board_id.py,sha256=A2os0LU7-i_0JuEcMc1PbLt79TiAq16qRl7fv5uzsA8,3374
|
39
|
+
mpflash/mpboard_id/board_info.zip,sha256=0rQkVLOBRg5dwvkLmJtRdCXwKiA9arkWYVH7N8dYuNw,21720
|
40
40
|
mpflash/mpboard_id/store.py,sha256=n85vnUAxGKv1C23wkm22ZFAFGK6AZZiCFvc1lGJJjis,1703
|
41
|
-
mpflash/mpremoteboard/__init__.py,sha256=
|
41
|
+
mpflash/mpremoteboard/__init__.py,sha256=Vydc7jZai32lrGTUjwylZT9U8yulsgLIk39mnuI_k9I,9666
|
42
42
|
mpflash/mpremoteboard/mpy_fw_info.py,sha256=eRjhqN7MpmYE9TiS4iukquZZs3QE_lD5zv_vOPSjNrk,4821
|
43
43
|
mpflash/mpremoteboard/runner.py,sha256=-PgzAeBGbyXaAUlwyiw4mcINsP2U1XRRjP1_QdBrxpg,4786
|
44
|
+
mpflash/vendor/board_database.py,sha256=QE3oXj96oTAsx94gNfHMYWu_RgBTHW1v9Wp5dq_Dt-Q,5253
|
44
45
|
mpflash/vendor/click_aliases.py,sha256=c853EHSlkE2DvFqeFvFpwXKuJj3_jsXDP7iotVOKaAw,3156
|
45
46
|
mpflash/vendor/dfu.py,sha256=ZXMcE6aH4-43Wh4tbQT4U-q-BU3RUiL3JAxmP_QAK2s,5755
|
47
|
+
mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt,sha256=Zkc2iTNbib2NCMwtLjMEz0vFCPglgvaw6Mj7QiWldpQ,1484
|
48
|
+
mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2,sha256=QuPMppqHMVOt3vDVU0bikHRLsTiDRQYNUcGQ_OLRFGI,28160
|
46
49
|
mpflash/vendor/pydfu.py,sha256=_MdBRo1EeNeKDqFPSTB5tNL1jGSBJgsVeVjE5e7Pb8s,20542
|
47
|
-
mpflash/vendor/readme.md,sha256=
|
48
|
-
mpflash/versions.py,sha256=
|
49
|
-
mpflash-1.24.
|
50
|
-
mpflash-1.24.
|
51
|
-
mpflash-1.24.
|
52
|
-
mpflash-1.24.
|
53
|
-
mpflash-1.24.
|
50
|
+
mpflash/vendor/readme.md,sha256=BQ7Uxf8joeYMjTUuSLLBG49ob6a9MgFPIEwuc72-Mfw,415
|
51
|
+
mpflash/versions.py,sha256=qGkE2LTzQ1QDyHc9-wzsHsRrN7PWK69xt0Vq3EVojms,4452
|
52
|
+
mpflash-1.24.7.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
|
53
|
+
mpflash-1.24.7.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
|
54
|
+
mpflash-1.24.7.dist-info/METADATA,sha256=kkeoaVrJt6i62yFsvXWdczncaJ3bz3055X05Ijt6z-g,17757
|
55
|
+
mpflash-1.24.7.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
56
|
+
mpflash-1.24.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|