mpflash 1.25.0.post1__py3-none-any.whl → 1.25.0rc1__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.
Files changed (50) hide show
  1. mpflash/add_firmware.py +43 -16
  2. mpflash/ask_input.py +4 -3
  3. mpflash/basicgit.py +1 -1
  4. mpflash/bootloader/manual.py +1 -1
  5. mpflash/cli_download.py +8 -5
  6. mpflash/cli_flash.py +17 -33
  7. mpflash/cli_group.py +3 -0
  8. mpflash/cli_list.py +2 -2
  9. mpflash/cli_main.py +4 -0
  10. mpflash/common.py +1 -36
  11. mpflash/config.py +21 -0
  12. mpflash/db/__init__.py +2 -0
  13. mpflash/db/core.py +56 -0
  14. mpflash/db/gather_boards.py +112 -0
  15. mpflash/db/loader.py +120 -0
  16. mpflash/db/meta.py +78 -0
  17. mpflash/db/micropython_boards.zip +0 -0
  18. mpflash/db/models.py +93 -0
  19. mpflash/db/tools.py +27 -0
  20. mpflash/download/__init__.py +46 -64
  21. mpflash/download/from_web.py +26 -36
  22. mpflash/download/fwinfo.py +41 -0
  23. mpflash/download/jid.py +53 -0
  24. mpflash/downloaded.py +79 -93
  25. mpflash/flash/__init__.py +7 -3
  26. mpflash/flash/esp.py +2 -1
  27. mpflash/flash/worklist.py +16 -28
  28. mpflash/list.py +3 -3
  29. mpflash/logger.py +2 -2
  30. mpflash/mpboard_id/__init__.py +3 -9
  31. mpflash/mpboard_id/alternate.py +56 -0
  32. mpflash/mpboard_id/board_id.py +11 -94
  33. mpflash/mpboard_id/known.py +44 -56
  34. mpflash/mpboard_id/resolve.py +19 -0
  35. mpflash/mpremoteboard/__init__.py +1 -1
  36. mpflash/mpremoteboard/mpy_fw_info.py +1 -0
  37. mpflash/mpremoteboard/runner.py +5 -2
  38. mpflash/vendor/pydfu.py +4 -5
  39. mpflash/versions.py +3 -0
  40. {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/METADATA +2 -2
  41. mpflash-1.25.0rc1.dist-info/RECORD +69 -0
  42. mpflash/db/boards.py +0 -63
  43. mpflash/db/downloads.py +0 -87
  44. mpflash/mpboard_id/add_boards.py +0 -260
  45. mpflash/mpboard_id/board.py +0 -40
  46. mpflash/mpboard_id/store.py +0 -47
  47. mpflash-1.25.0.post1.dist-info/RECORD +0 -62
  48. {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/LICENSE +0 -0
  49. {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/WHEEL +0 -0
  50. {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/entry_points.txt +0 -0
@@ -1,260 +0,0 @@
1
- """
2
- Collects board name and description information from MicroPython and writes it to JSON and CSV files.
3
- """
4
-
5
- import re
6
- from pathlib import Path
7
- from typing import List, Optional
8
-
9
- import inquirer
10
- import rich
11
- import rich.table
12
- from rich.console import Console
13
- from rich.progress import track
14
-
15
- import mpflash.basicgit as git
16
- from mpflash.logger import log
17
- from mpflash.mpboard_id import Board
18
- from mpflash.mpboard_id.store import write_boardinfo_json
19
- from mpflash.versions import get_preview_mp_version, micropython_versions
20
-
21
- # look for all mpconfigboard.h files and extract the board name
22
- # from the #define MICROPY_HW_BOARD_NAME "PYBD_SF6"
23
- # and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
24
- RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
25
- RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\s+\"(.+)\"")
26
- # find boards and variants in the mpconfigboard*.cmake files
27
- RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
28
- RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
29
- # TODO: normal make files
30
-
31
-
32
- def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None) -> List[Board]:
33
- """Collects board name and decriptions from mpconfigboard.h files.
34
-
35
- Args:
36
- mpy_path (Path): The path to the MicroPython repository.
37
- version (str): The version of MicroPython.
38
-
39
- Returns:
40
- List[Board]: A list of Board objects containing the board information.
41
- """
42
- if not mpy_path.exists() or not mpy_path.is_dir():
43
- raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
44
- family = family or "micropython"
45
- version = version or git.get_local_tag() # type: ignore
46
- if not version:
47
- raise ValueError("No version provided and no local tag found.")
48
- elif version in ["main", "master"]:
49
- version = get_preview_mp_version()
50
-
51
- board_list: List[Board] = []
52
- # look in mpconfigboard.h files
53
- board_list = boards_from_cmake(mpy_path, version, family)
54
-
55
- # look for boards in the .cmake files
56
- board_list.extend(boards_from_headers(mpy_path, version, family))
57
-
58
- # TODO:? look for variants in the board.json files
59
-
60
- return board_list
61
-
62
-
63
- def boards_from_cmake(mpy_path: Path, version: str, family: str):
64
- """Get boards from the mpconfigboard.cmake files to the board_list."""
65
- board_list = []
66
- for path in mpy_path.glob("ports/**/mpconfigboard*.cmake"):
67
- board = path.parent.name
68
- port = path.parent.parent.parent.name
69
- with open(path, "r") as f:
70
- board_name = mcu_name = "-"
71
- for line in f:
72
- line = line.strip()
73
- if match := RE_CMAKE_MICROPY_HW_BOARD_NAME.match(line):
74
- description = match["variant"]
75
- board_list.append(
76
- Board(
77
- board_id=board,
78
- port=port,
79
- board_name=board_name,
80
- mcu_name=mcu_name,
81
- description=description,
82
- path=path.relative_to(mpy_path),
83
- version=version,
84
- family=family,
85
- )
86
- )
87
- elif match := RE_CMAKE_MICROPY_HW_MCU_NAME.match(line):
88
- description = match["variant"]
89
- board_list.append(
90
- Board(
91
- board_id=board,
92
- port=port,
93
- board_name=board_name,
94
- mcu_name=mcu_name,
95
- description=description,
96
- path=path.relative_to(mpy_path),
97
- version=version,
98
- family=family,
99
- )
100
- )
101
- return board_list
102
-
103
-
104
- def boards_from_headers(mpy_path: Path, version: str, family: str):
105
- """Get boards from the mpconfigboard.h files to the board_list."""
106
- board_list = []
107
- for path in mpy_path.glob("ports/**/mpconfigboard.h"):
108
- board = path.parent.name
109
- port = path.parent.parent.parent.name
110
- with open(path, "r") as f:
111
- board_name = mcu_name = "-"
112
- found = 0
113
- for line in f:
114
- if match := RE_H_MICROPY_HW_BOARD_NAME.match(line):
115
- board_name = match[1]
116
- found += 1
117
- elif match := RE_H_MICROPY_HW_MCU_NAME.match(line):
118
- mcu_name = match[1]
119
- found += 1
120
- if found == 2:
121
- description = f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
122
- board_list.append(
123
- Board(
124
- board_id=board,
125
- port=port,
126
- board_name=board_name,
127
- mcu_name=mcu_name,
128
- description=description,
129
- path=path.relative_to(mpy_path),
130
- version=version,
131
- family=family,
132
- )
133
- )
134
- found = 0
135
- if found == 1:
136
- description = board_name
137
- board_list.append(
138
- Board(
139
- board_id=board,
140
- port=port,
141
- board_name=board_name,
142
- mcu_name=mcu_name,
143
- description=description,
144
- path=path.relative_to(mpy_path),
145
- version=version,
146
- family=family,
147
- )
148
- )
149
- return board_list
150
-
151
-
152
- def boards_for_versions(versions: List[str], mpy_path: Path):
153
- """Gets the list of boards for multiple versions of MicroPython.
154
-
155
- Args:
156
- versions (List[str]): The list of MicroPython versions.
157
- mpy_path (Path): The path to the MicroPython repository.
158
-
159
- Returns:
160
- List[Board]: The list of Board objects.
161
- """
162
- board_list: List[Board] = []
163
- # first fetch all tags from the repository
164
- git.fetch(mpy_path)
165
- for version in track(versions, description="Searching MicroPython versions"):
166
- if git.checkout_tag(tag=version, repo=mpy_path):
167
- new_ones = boards_from_repo(mpy_path, version, family="micropython")
168
- print(f"Found {len(new_ones)} board definitions for {version}.")
169
- board_list += new_ones
170
- else:
171
- print(f"Could not checkout version {version}.")
172
-
173
- # sort the board_list by description and board
174
- print("Total number of boards found:", len(board_list))
175
-
176
- board_list = unique_boards(board_list)
177
- print("Unique board descriptions found:", len(board_list))
178
- return board_list
179
-
180
-
181
- def unique_boards(board_list: List[Board], *, key_version: bool = True):
182
- """Remove duplicate boards by 'BOARD_ID description' from the list."""
183
- seen = set()
184
- result = []
185
- for x in board_list:
186
- if key_version:
187
- key = f"{x.board_id}|{x.version}|{x.description}"
188
- else:
189
- key = f"{x.board_id}|{x.description}"
190
- if key not in seen:
191
- result.append(x)
192
- seen.add(key)
193
- result.sort(key=lambda x: x.description.lower())
194
- return result
195
-
196
-
197
- def make_table(board_list: List[Board]) -> rich.table.Table:
198
- """Creates a rich table with board information."""
199
- is_wide = True
200
-
201
- table = rich.table.Table(title="MicroPython Board Information")
202
- table.add_column("Port", justify="left", style="magenta")
203
- table.add_column("BOARD_ID", justify="left", style="green")
204
- table.add_column("Variant(s)", justify="left", style="blue")
205
- table.add_column("Description", justify="left", style="cyan")
206
- table.add_column("Board Name", justify="left", style="blue")
207
- if is_wide:
208
- table.add_column("MCU Name", justify="left", style="blue")
209
- table.add_column("Detection", justify="left", style="yellow")
210
- table.add_column("Version", justify="left", style="blue")
211
- if is_wide:
212
- table.add_column("Family", justify="left", style="blue")
213
-
214
- for board in board_list:
215
- row = [board.port, board.board_id, board.variant, board.description, board.board_name]
216
- if is_wide:
217
- row.append(board.mcu_name)
218
- row.extend((str(Path(board.path).suffix), board.version))
219
- if is_wide:
220
- row.append(board.family)
221
- table.add_row(*row)
222
-
223
- return table
224
-
225
-
226
- def ask_mpy_path():
227
- """Ask the user for the path to the MicroPython repository."""
228
- questions = [
229
- inquirer.Text(
230
- "mpy_path",
231
- message="Enter the path to the MicroPython repository",
232
- default="./repos/micropython",
233
- )
234
- ]
235
- if answers := inquirer.prompt(questions):
236
- return Path(answers["mpy_path"])
237
- else:
238
- raise ValueError("No path provided.")
239
-
240
-
241
- def main():
242
- """Main function to collect and write board information."""
243
-
244
- console = Console()
245
-
246
- mpy_path = ask_mpy_path()
247
- versions = micropython_versions(minver="v1.10") + ["master"]
248
- board_list = boards_for_versions(versions, mpy_path)
249
-
250
- here = Path(__file__).parent
251
- log.info(write_boardinfo_json(board_list, folder=here))
252
- # write_files(board_list, folder=CONFIG.board_path)
253
-
254
- # table of when the board was added
255
- table = make_table(unique_boards(board_list, key_version=False))
256
- console.print(table)
257
-
258
-
259
- if __name__ == "__main__":
260
- main()
@@ -1,40 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from pathlib import Path
3
- from typing import Union
4
-
5
-
6
- # - source : get_boardnames.py
7
- @dataclass
8
- class Board:
9
- """
10
- MicroPython Board definitions, parsed from the make and header files
11
- """
12
-
13
- port: str # micropython port
14
- board_id: str # BOARD_ID (Foldername) as used in the make files
15
- board_name: str # Short board description
16
- description: str # Long board description
17
- path: Union[Path, str]
18
- version: str = field(default="") # version of MicroPython""
19
- # versions: List[str] = field(default=[]) # version of MicroPython""
20
- family: str = field(default="micropython")
21
- mcu_name: str = field(default="")
22
- cpu: str = field(default="")
23
- variant: str = field(default="")
24
- mcu: str = field(default="")
25
-
26
- def __post_init__(self):
27
- if not self.cpu:
28
- if " with " in self.description:
29
- self.cpu = self.description.rsplit(" with ")[-1]
30
- else:
31
- self.cpu = self.port
32
-
33
- @staticmethod
34
- def from_dict(data: dict) -> "Board":
35
- valid_keys = {field.name for field in Board.__dataclass_fields__.values()}
36
- filtered_data = {k: v for k, v in data.items() if k in valid_keys}
37
- return Board(**filtered_data)
38
-
39
- def to_dict(self) -> dict:
40
- return self.__dict__
@@ -1,47 +0,0 @@
1
- import functools
2
- import zipfile
3
- from pathlib import Path
4
- from typing import Final, List, Optional
5
- from mpflash.logger import log
6
-
7
- import jsons
8
-
9
- from mpflash.mpboard_id.board import Board
10
-
11
- ###############################################################################################
12
- HERE: Final = Path(__file__).parent
13
- ###############################################################################################
14
-
15
-
16
- def write_boardinfo_json(board_list: List[Board], *, folder: Optional[Path] = None):
17
- """Writes the board information to a JSON file.
18
-
19
- Args:
20
- board_list (List[Board]): The list of Board objects.
21
- folder (Path): The folder where the compressed JSON file will be saved.
22
- """
23
-
24
- if not folder:
25
- folder = HERE
26
- # create a zip file with the json file
27
- with zipfile.ZipFile(folder / "board_info.zip", "w", compression=zipfile.ZIP_DEFLATED) as zipf:
28
- # write the list to json file inside the zip
29
- with zipf.open("board_info.json", "w") as fp:
30
- fp.write(jsons.dumps(board_list, jdkwargs={"indent": 4}).encode())
31
-
32
-
33
- @functools.lru_cache(maxsize=20)
34
- def read_known_boardinfo(board_info: Optional[Path] = None) -> List[Board]:
35
- """Reads the board information from a JSON file in a zip file."""
36
- log.warning("read_known_boardinfo() is deprecated")
37
-
38
- if not board_info:
39
- board_info = HERE / "board_info.zip"
40
- if not board_info.exists():
41
- raise FileNotFoundError(f"Board info file not found: {board_info}")
42
-
43
- with zipfile.ZipFile(board_info, "r") as zf:
44
- with zf.open("board_info.json", "r") as file:
45
- info = jsons.loads(file.read().decode(encoding="utf-8"), List[Board])
46
-
47
- return info
@@ -1,62 +0,0 @@
1
- mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mpflash/add_firmware.py,sha256=1h0HsA-EVi3HXLmoEvzwY_a-GuWYzPwulTYHHBB8THg,3428
3
- mpflash/ask_input.py,sha256=piwMuW7QlYsIvDdJFN1lVCkCGsmsSyyMaUOtvf_S330,8885
4
- mpflash/basicgit.py,sha256=AGqFZeEHjb_o7QtZyJ_M9aOXHN-JEGvUi6W01fpOGzc,9676
5
- mpflash/bootloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- mpflash/bootloader/activate.py,sha256=orQOw4XTkXVZI-rMInRb0T5Wp3qA_BlzbJUA2gyBToU,2361
7
- mpflash/bootloader/detect.py,sha256=OagP2QVWeLLWkZt2paqEF6r4_x3QDcBGNCPOWfMy9NQ,2686
8
- mpflash/bootloader/manual.py,sha256=C3PVLW3lwz66zG2mOekAJdwXD8PZcIyI3VuLEkusMpI,3168
9
- mpflash/bootloader/micropython.py,sha256=v_kZkvg0uWZDbMrT78gmiYHbD83QLdnrctvEClI8iRg,529
10
- mpflash/bootloader/touch1200.py,sha256=VND7_YniS9Vx6WEaAxjI72RZZ6WBOwmBTsKJkbuaAHk,1105
11
- mpflash/cli_download.py,sha256=6p83u0Iqyq-V6zS_zQbngSgnCnE0thNPR02r_12_d_Y,3660
12
- mpflash/cli_flash.py,sha256=6ZOHChF1cUyQEDzUpgJKko8EX__55Ol-fQkZNfTJpB8,8337
13
- mpflash/cli_group.py,sha256=_Wj4EvRkmPri6wyJWT8cQ0WRMwrj9xtCDLaxFJs7ssM,2617
14
- mpflash/cli_list.py,sha256=U4lrlE7O6o1BamHD0K_cJhuINanKNgXkg-WTU5RetF4,2354
15
- mpflash/cli_main.py,sha256=aVlsA-ZHBKJyuGwSCbpO2Ky0X52wPeOOGumvuPPTFzQ,1136
16
- mpflash/common.py,sha256=1mEsilJd3HpL7wFPsJ0EScYoJj7JqGFWDjSFEKJdjeU,7488
17
- mpflash/config.py,sha256=GMuqhrof3lkG7x_CxitYRkm4mxHEYZ_uPFNO3QxSJCY,2166
18
- mpflash/connected.py,sha256=oxZdk1o-AfNPhJsSxr3KrMH_gdYfrjqc_IpT6J8Ng9k,3496
19
- mpflash/db/boards.py,sha256=KvpJ45oPwoxuXCzNpAPIyMOiXOpO72LBJowQ4QBJPiU,1960
20
- mpflash/db/downloads.py,sha256=sHJzKLf5cYFftIcweoBfCqMY0MPJMmFYVRT7mprspvU,2975
21
- mpflash/download/__init__.py,sha256=kI9zYSjFUO2vVbRofJmQw44ftlM5r1HnjmkdZenzo2c,8451
22
- mpflash/download/from_web.py,sha256=ddUd7MZJj19e_nR9Iw79v3UuCPwvkWwQtuBEyu-XsbY,7860
23
- mpflash/downloaded.py,sha256=kfUt07vDARZYw64TToXLxA-UlP7zFTGRjnBzIEDL5cU,4163
24
- mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
25
- mpflash/flash/__init__.py,sha256=V--YRwDGtCCLVfCe9p9SGV1Cbi0FNd9zenKlIb-HFw0,2820
26
- mpflash/flash/esp.py,sha256=N71fPMYhYexEF3YeJGJ74B3GtceXa-FdGqiBpa2qboI,3225
27
- mpflash/flash/stm32.py,sha256=dqp9BZ4Vr-6GlQcF12TSmRf-5TXkov9qvCpMgeUJc7Y,574
28
- mpflash/flash/stm32_dfu.py,sha256=W-3JsRQyf3DduoIRXDmGZ35RogqtjQgcJnk-GOtQoLE,3090
29
- mpflash/flash/uf2/__init__.py,sha256=haL84hP2p1ZjKF6dXJJHAB_NTf7jT91MuZvmvg9SpIA,3617
30
- mpflash/flash/uf2/boardid.py,sha256=U5wGM8VA3wEpUxQCMtuXpMZZomdVH8J_Zd5_GekUMuU,423
31
- mpflash/flash/uf2/linux.py,sha256=uTgqyS7C7xfQ25RrTcSUkt-m2u2Ks_o7bPLzIecPoC8,4355
32
- mpflash/flash/uf2/macos.py,sha256=JTaIpqnR_0k4oSEvzs9amhmK-PMxUJyZLnZ_wZwxa-0,1228
33
- mpflash/flash/uf2/uf2disk.py,sha256=4_P2l-kedM7VSliA2u706LQLxvu3xWSod1-lj-xjZis,298
34
- mpflash/flash/uf2/windows.py,sha256=S---sVjVrC00ZcnpOewtJIBfSCj2cr7FGQwEm_ZEDnY,1334
35
- mpflash/flash/worklist.py,sha256=eOD7BigUEshwcc5p7SaSeegpSpIOX1zE_6HuOzssrqM,6083
36
- mpflash/list.py,sha256=AjsVTWWTcfUhoT2lYJf2KvcOgMen9MgXY6fDYJvd0Mc,4014
37
- mpflash/logger.py,sha256=D6S-KDhXTLl7bYMKfu71iVO1YlpGSd0BcHvkVFOCW5c,1080
38
- mpflash/mpboard_id/__init__.py,sha256=i-HxDi4UPvQu2zFhWK5HENr_HmTdsnaqkLfNyxjOelg,515
39
- mpflash/mpboard_id/add_boards.py,sha256=XCSyZC9v-B5gzW4dIWdqQVIiE8JviKx0GpyGEQ64dm8,9949
40
- mpflash/mpboard_id/board.py,sha256=hzP_SNyigjRQsP3FmTCvuCDtPPalfkL5IfjrnATlVS0,1367
41
- mpflash/mpboard_id/board_id.py,sha256=mJqVW_D8uHnuON7xpKBRRs2e3ExQGNYC2bSA2ItZBKY,5439
42
- mpflash/mpboard_id/board_info.json,sha256=A3ZIt38KvAy2NMB5srHorSBd3Q3wOZIXufWiIs3XLrs,1019745
43
- mpflash/mpboard_id/board_info.zip,sha256=-2bnQGRsIQuJUfz-7_-GQ8pMWJ1evhCez6yfjhXocNw,23213
44
- mpflash/mpboard_id/known.py,sha256=ySTOVDFjqhoeVcGtJcpaY6Cy2blTbLovD5z-IsdZhco,3769
45
- mpflash/mpboard_id/store.py,sha256=UR5nWwywqSPY_2DBP2w8td3b7N6iS-B5rMcyh-s2JOQ,1750
46
- mpflash/mpremoteboard/__init__.py,sha256=jj4FVK237BmQ1-N4ANePWEJFY7yyhbb0XvJx8n00vuc,11993
47
- mpflash/mpremoteboard/mpy_fw_info.py,sha256=xhEjifU7pAUpey5T23k6x_1bhuS2XcVbSM21ZynWDdM,5148
48
- mpflash/mpremoteboard/runner.py,sha256=-PgzAeBGbyXaAUlwyiw4mcINsP2U1XRRjP1_QdBrxpg,4786
49
- mpflash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- mpflash/vendor/board_database.py,sha256=Cb8fEhJaZ2siMkLPW5rPwV9yzBsTtKGOqWUd9TxNgFM,8763
51
- mpflash/vendor/click_aliases.py,sha256=adLhqLxNpJEPjSCIRSTkR-QzSgavGFKT0cwRbjxpzRU,5395
52
- mpflash/vendor/dfu.py,sha256=6rqGCBS8mTxxaLtkdzJ8O6nc74kFk8jrkmKvxw-x-u8,5693
53
- mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt,sha256=Zkc2iTNbib2NCMwtLjMEz0vFCPglgvaw6Mj7QiWldpQ,1484
54
- mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2,sha256=QuPMppqHMVOt3vDVU0bikHRLsTiDRQYNUcGQ_OLRFGI,28160
55
- mpflash/vendor/pydfu.py,sha256=uD0esm1iPHap7T93M_fli1LlXwn8RxKDFRnt8inxJu8,20389
56
- mpflash/vendor/readme.md,sha256=BQ7Uxf8joeYMjTUuSLLBG49ob6a9MgFPIEwuc72-Mfw,415
57
- mpflash/versions.py,sha256=zDAUEMae0hvB8CFmVnf_VWtnVIpAiMGXKpvk2FgnWcg,4878
58
- mpflash-1.25.0.post1.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
59
- mpflash-1.25.0.post1.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
60
- mpflash-1.25.0.post1.dist-info/METADATA,sha256=JvqTGcAdnDOMzvMK3JVqNqE8OKtBcV986kDTdtTG-KY,23936
61
- mpflash-1.25.0.post1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
62
- mpflash-1.25.0.post1.dist-info/RECORD,,