mpflash 0.9.1.post2__py3-none-any.whl → 1.0.1__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/cli_download.py CHANGED
@@ -58,7 +58,7 @@ from .download import download
58
58
  default=["*"],
59
59
  show_default=True,
60
60
  multiple=True,
61
- help="Which serial port(s) to flash",
61
+ help="Which serial port(s) (or globs) to flash",
62
62
  metavar="SERIALPORT",
63
63
  )
64
64
  @click.option(
mpflash/cli_flash.py CHANGED
@@ -4,22 +4,19 @@ from typing import List
4
4
  import rich_click as click
5
5
  from loguru import logger as log
6
6
 
7
- from mpflash.common import BootloaderMethod
7
+ from mpflash.ask_input import ask_missing_params
8
+ from mpflash.cli_download import connected_ports_boards
9
+ from mpflash.cli_group import cli
10
+ from mpflash.cli_list import show_mcus
11
+ from mpflash.common import BootloaderMethod, FlashParams, Params
12
+ from mpflash.config import config
8
13
  from mpflash.errors import MPFlashError
14
+ from mpflash.flash import flash_list
15
+ from mpflash.flash.worklist import WorkList, full_auto_worklist, manual_worklist, single_auto_worklist
9
16
  from mpflash.mpboard_id import find_known_board
10
17
  from mpflash.mpremoteboard import MPRemoteBoard
11
18
  from mpflash.versions import clean_version
12
19
 
13
- from .ask_input import ask_missing_params
14
- from .cli_download import connected_ports_boards
15
- from .cli_group import cli
16
- from .cli_list import show_mcus
17
- from .common import FlashParams
18
- from .config import config
19
- from .flash import flash_list
20
- from .flash.worklist import (WorkList, full_auto_worklist, manual_worklist,
21
- single_auto_worklist)
22
-
23
20
  # #########################################################################################################
24
21
  # CLI
25
22
  # #########################################################################################################
@@ -56,7 +53,7 @@ from .flash.worklist import (WorkList, full_auto_worklist, manual_worklist,
56
53
  default=["*"],
57
54
  multiple=True,
58
55
  show_default=True,
59
- help="Which serial port(s) to flash",
56
+ help="Which serial port(s) (or globs) to flash",
60
57
  metavar="SERIALPORT",
61
58
  )
62
59
  @click.option(
@@ -122,7 +119,7 @@ def cli_flash_board(**kwargs) -> int:
122
119
  params = FlashParams(**kwargs)
123
120
  params.versions = list(params.versions)
124
121
  params.ports = list(params.ports)
125
- params.boards = list(params.boards)
122
+ params.boards = list(params.boards)
126
123
  params.serial = list(params.serial)
127
124
  params.ignore = list(params.ignore)
128
125
  params.bootloader = BootloaderMethod(params.bootloader)
@@ -203,7 +200,7 @@ def cli_flash_board(**kwargs) -> int:
203
200
  return 1
204
201
 
205
202
 
206
- def resolve_board_ids(params):
203
+ def resolve_board_ids(params: Params):
207
204
  """Resolve board descriptions to board_id, and remove empty strings from list of boards"""
208
205
  for board_id in params.boards:
209
206
  if board_id == "":
mpflash/cli_list.py CHANGED
@@ -32,14 +32,14 @@ from .logger import make_quiet
32
32
  default=["*"],
33
33
  multiple=True,
34
34
  show_default=True,
35
- help="Which serial port(s) to list. ",
35
+ help="Serial port(s) (or globs) to list. ",
36
36
  metavar="SERIALPORT",
37
37
  )
38
38
  @click.option(
39
39
  "--ignore",
40
40
  "-i",
41
41
  is_eager=True,
42
- help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
42
+ help="Serial port(s) (or globs) to ignore. Defaults to MPFLASH_IGNORE.",
43
43
  multiple=True,
44
44
  default=[],
45
45
  envvar="MPFLASH_IGNORE",
@@ -73,7 +73,13 @@ def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json
73
73
  # TODO? Ask user to select a serialport if [?] is given ?
74
74
 
75
75
  conn_mcus = list_mcus(ignore=ignore, include=serial, bluetooth=bluetooth)
76
+ # ignore boards that have the [micropython-stubber] ignore flag set
77
+ conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
76
78
  if as_json:
79
+ # remove the path and firmware attibutes from the json output as they are always empty
80
+ for mcu in conn_mcus:
81
+ del mcu.path
82
+ del mcu.firmware
77
83
  print(json.dumps([mcu.__dict__ for mcu in conn_mcus], indent=4))
78
84
  progress = False
79
85
  if progress:
mpflash/common.py CHANGED
@@ -29,7 +29,9 @@ PORT_FWTYPES = {
29
29
  # Token with no permissions to avoid throttling
30
30
  # 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
31
31
  PAT_NO_ACCESS = (
32
- "github_pat" + "_11AAHPVFQ0qAkDnSUaMKSp" + "_ZkDl5NRRwBsUN6EYg9ahp1Dvj4FDDONnXVgimxC2EtpY7Q7BUKBoQ0Jq72X"
32
+ "github_pat"
33
+ + "_11AAHPVFQ0qAkDnSUaMKSp"
34
+ + "_ZkDl5NRRwBsUN6EYg9ahp1Dvj4FDDONnXVgimxC2EtpY7Q7BUKBoQ0Jq72X"
33
35
  )
34
36
  PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
35
37
  GH_CLIENT = Github(auth=Auth.Token(PAT))
@@ -99,7 +101,6 @@ class BootloaderMethod(Enum):
99
101
  NONE = "none"
100
102
 
101
103
 
102
-
103
104
  @dataclass
104
105
  class FlashParams(Params):
105
106
  """Parameters for flashing a board"""
@@ -122,7 +123,8 @@ def filtered_comports(
122
123
  bluetooth: bool = False,
123
124
  ) -> List[ListPortInfo]: # sourcery skip: assign-if-exp
124
125
  """
125
- Get a list of filtered comports.
126
+ Get a list of filtered comports using the include and ignore lists.
127
+ both can be globs (e.g. COM*) or exact port names (e.g. COM1)
126
128
  """
127
129
  if not ignore:
128
130
  ignore = []
@@ -135,13 +137,20 @@ def filtered_comports(
135
137
 
136
138
  # remove ports that are to be ignored
137
139
  log.trace(f"{include=}, {ignore=}, {bluetooth=}")
138
- comports = [p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)]
140
+ # use p.location to filter out the bogus ports on newer Linux kernels
141
+ comports = [
142
+ p
143
+ for p in list_ports.comports()
144
+ if p.location and not any(fnmatch.fnmatch(p.device, i) for i in ignore)
145
+ ]
139
146
  log.trace(f"comports: {[p.device for p in comports]}")
140
147
  # remove bluetooth ports
141
148
 
142
149
  if include != ["*"]:
143
150
  # if there are explicit ports to include, add them to the list
144
- explicit = [p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)]
151
+ explicit = [
152
+ p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)
153
+ ]
145
154
  log.trace(f"explicit: {[p.device for p in explicit]}")
146
155
  if ignore == []:
147
156
  # if nothing to ignore, just use the explicit list as a sinple sane default
@@ -160,6 +169,9 @@ def filtered_comports(
160
169
  # sort
161
170
  if sys.platform == "win32":
162
171
  # Windows sort of comports by number - but fallback to device name
163
- return sorted(comports, key=lambda x: int(x.device.split()[0][3:]) if x.device.split()[0][3:].isdigit() else x)
172
+ return sorted(
173
+ comports,
174
+ key=lambda x: int(x.device.split()[0][3:]) if x.device.split()[0][3:].isdigit() else x,
175
+ )
164
176
  # sort by device name
165
177
  return sorted(comports, key=lambda x: x.device)
mpflash/connected.py CHANGED
@@ -4,10 +4,9 @@ from rich import print
4
4
  from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
5
5
  from rich.table import Column
6
6
 
7
+ from mpflash.common import filtered_comports
7
8
  from mpflash.mpremoteboard import MPRemoteBoard
8
9
 
9
- from .common import filtered_comports
10
-
11
10
 
12
11
  def connected_ports_boards(*, include: List[str], ignore: List[str]) -> Tuple[List[str], List[str], List[MPRemoteBoard]]:
13
12
  """
@@ -32,7 +31,7 @@ rp_text = TextColumn("{task.description} {task.fields[device]}", table_column=Co
32
31
  rp_bar = BarColumn(bar_width=None, table_column=Column())
33
32
 
34
33
 
35
- def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False):
34
+ def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False) -> List[MPRemoteBoard]:
36
35
  """
37
36
  Retrieves information about connected microcontroller boards.
38
37
 
mpflash/list.py CHANGED
@@ -38,11 +38,25 @@ def mcu_table(
38
38
  - Serial Yes Yes
39
39
  - Family abbrv. Yes
40
40
  - Port - yes
41
- - Board Yes Yes BOARD_ID and Description
41
+ - Board Yes Yes BOARD_ID and Description, and the description from board_info.toml
42
42
  - CPU - Yes
43
43
  - Version Yes Yes
44
44
  - Build * * only if any of the mcus have a build
45
+ - Location - - only if --usb is given
45
46
  """
47
+ # refresh if requested
48
+ if refresh:
49
+ for mcu in track(
50
+ conn_mcus,
51
+ description="Updating board info",
52
+ transient=True,
53
+ show_speed=False,
54
+ refresh_per_second=1,
55
+ ):
56
+ try:
57
+ mcu.get_mcu_info()
58
+ except ConnectionError:
59
+ continue
46
60
  table = Table(
47
61
  title=title,
48
62
  title_style="magenta",
@@ -50,6 +64,7 @@ def mcu_table(
50
64
  collapse_padding=True,
51
65
  padding=(0, 0),
52
66
  )
67
+ # Build the table
53
68
  # check if the terminal is wide enough to show all columns or if we need to collapse some
54
69
  is_wide = console.width > 99
55
70
  needs_build = any(mcu.build for mcu in conn_mcus)
@@ -67,19 +82,11 @@ def mcu_table(
67
82
  table.add_column("Build" if is_wide else "Bld", justify="right")
68
83
  if config.usb:
69
84
  table.add_column("Location", overflow="fold", max_width=40)
70
- for mcu in track(
71
- conn_mcus,
72
- description="Updating board info",
73
- transient=True,
74
- show_speed=False,
75
- refresh_per_second=1,
76
- ):
77
- if refresh:
78
- try:
79
- mcu.get_mcu_info()
80
- except ConnectionError:
81
- continue
85
+ # fill the table with the data
86
+ for mcu in conn_mcus:
82
87
  description = f"[italic bright_cyan]{mcu.description}" if mcu.description else ""
88
+ if "description" in mcu.toml:
89
+ description += f"\n[italic bright_green]{mcu.toml['description']}"
83
90
  row = [
84
91
  mcu.serialport.replace("/dev/", ""),
85
92
  abbrv_family(mcu.family, is_wide),
@@ -8,16 +8,20 @@ from pathlib import Path
8
8
  from typing import List, Optional, Union
9
9
 
10
10
  import serial.tools.list_ports
11
- from loguru import logger as log
12
11
  from rich.progress import track
13
12
  from tenacity import retry, stop_after_attempt, wait_fixed
14
13
 
15
14
  from mpflash.errors import MPFlashError
15
+ from mpflash.logger import log
16
16
  from mpflash.mpboard_id.board_id import find_board_id_by_description
17
17
  from mpflash.mpremoteboard.runner import run
18
18
 
19
+ if sys.version_info >= (3, 11):
20
+ import tomllib # type: ignore
21
+ else:
22
+ import tomli as tomllib # type: ignore
23
+
19
24
  ###############################################################################################
20
- # TODO : make this a bit nicer
21
25
  HERE = Path(__file__).parent
22
26
 
23
27
  OK = 0
@@ -52,6 +56,7 @@ class MPRemoteBoard:
52
56
  self.mpy = ""
53
57
  self.build = ""
54
58
  self.location = location
59
+ self.toml = {}
55
60
  if update:
56
61
  self.get_mcu_info()
57
62
 
@@ -111,13 +116,14 @@ class MPRemoteBoard:
111
116
  ["run", str(HERE / "mpy_fw_info.py")],
112
117
  no_info=True,
113
118
  timeout=timeout,
119
+ resume=True, # Avoid restarts
114
120
  )
115
121
  if rc != OK:
116
122
  raise ConnectionError(f"Failed to get mcu_info for {self.serialport}")
117
123
  # Ok we have the info, now parse it
118
- s = result[0].strip()
119
- if s.startswith("{") and s.endswith("}"):
120
- info = eval(s)
124
+ raw_info = result[0].strip()
125
+ if raw_info.startswith("{") and raw_info.endswith("}"):
126
+ info = eval(raw_info)
121
127
  self.family = info["family"]
122
128
  self.version = info["version"]
123
129
  self.build = info["build"]
@@ -132,6 +138,43 @@ class MPRemoteBoard:
132
138
  self.board = board_name
133
139
  else:
134
140
  self.board = "UNKNOWN_BOARD"
141
+ # get the board_info.toml
142
+ self.get_board_info_toml()
143
+ # now we know the board is connected
144
+ self.connected = True
145
+
146
+ @retry(stop=stop_after_attempt(RETRIES), wait=wait_fixed(0.2), reraise=True) # type: ignore ## retry_error_cls=ConnectionError,
147
+ def get_board_info_toml(self, timeout: int = 1):
148
+ """
149
+ Reads the content of the board_info.toml file from the connected board,
150
+ and adds that to the board object.
151
+
152
+ Parameters:
153
+ - timeout (int): The timeout value in seconds.
154
+
155
+ Raises:
156
+ - ConnectionError: If failed to communicate with the serial port.
157
+ """
158
+ try:
159
+ rc, result = self.run_command(
160
+ ["cat", ":board_info.toml"],
161
+ no_info=True,
162
+ timeout=timeout,
163
+ log_errors=False,
164
+ )
165
+ except Exception as e:
166
+ raise ConnectionError(f"Failed to get board_info.toml for {self.serialport}: {e}")
167
+ # this is optional - so only parse if we got the file
168
+ self.toml = {}
169
+ if rc in [OK]: # sometimes we get an -9 ???
170
+ try:
171
+ # Ok we have the info, now parse it
172
+ self.toml = tomllib.loads("".join(result))
173
+ log.debug(f"board_info.toml: {self.toml}")
174
+ except Exception as e:
175
+ log.error(f"Failed to parse board_info.toml: {e}")
176
+ else:
177
+ log.trace(f"Failed to read board_info.toml: {result}")
135
178
 
136
179
  def disconnect(self) -> bool:
137
180
  """
@@ -159,6 +202,7 @@ class MPRemoteBoard:
159
202
  log_errors: bool = True,
160
203
  no_info: bool = False,
161
204
  timeout: int = 60,
205
+ resume: bool = False,
162
206
  **kwargs,
163
207
  ):
164
208
  """
@@ -179,7 +223,7 @@ class MPRemoteBoard:
179
223
  if self.serialport:
180
224
  prefix += ["connect", self.serialport]
181
225
  # if connected add resume to keep state between commands
182
- if self.connected:
226
+ if self.connected or resume:
183
227
  prefix += ["resume"]
184
228
  cmd = prefix + cmd
185
229
  log.debug(" ".join(cmd))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mpflash
3
- Version: 0.9.1.post2
3
+ Version: 1.0.1
4
4
  Summary: Flash and download tool for MicroPython firmwares
5
5
  Home-page: https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md
6
6
  License: MIT
@@ -78,6 +78,32 @@ You can use mpflash to perform various operations on your MicroPython boards. He
78
78
  | `mpflash download` | Download the MicroPython firmware(s) for the connected board(s) |
79
79
  | `mpflash flash` | Flash the latest stable firmware to the connected board(s) |
80
80
 
81
+ ## selecting or ignoring specific serial ports
82
+
83
+ You can use the `--serial` option to select a specific serial port to flash, or the `--ignore` option to ignore a specific serial port.
84
+ both options can be specified multiple times
85
+ Both can be globs (e.g. COM*) or exact port names (e.g. COM1)
86
+ in addition there is a --bluetooth option to simplify ignoring bluetooth ports
87
+
88
+ ```
89
+ --serial,--serial-port -s SERIALPORT Serial port(s) (or globs) to list. [default: *] > > --ignore -i SERIALPORT Serial port(s) (or globs) to ignore. Defaults to MPFLASH_IGNORE. │
90
+ --bluetooth/--no-bluetooth -b/-nb Include bluetooth ports in the list [default: no-bluetooth]
91
+ ```
92
+
93
+ ## Distinguishing similar boards
94
+ The `mpflash list` command will list all connected boards, but sometimes you have multiple boards of the same type connected.
95
+ To help you identify the boards, you can add a board_info.toml file to the top/default folder for the board.
96
+ This file can contain a description of the board, which will be shown in the list and json output.
97
+ ```toml
98
+ description = "Blue Norwegian actuator"
99
+ ```
100
+
101
+ If you want the board to be ignored by mpflash, you can add the following to the board_info.toml file:
102
+ ```toml
103
+ [mpflash]
104
+ ignore = true
105
+ ```
106
+
81
107
 
82
108
  ## Linux permissions to access usb devices
83
109
  In order to flash the firmware to the board, you need to have the correct permissions to access the USB devices.
@@ -8,14 +8,14 @@ mpflash/bootloader/detect.py,sha256=eXL_JPcowb8g0tpZmj9DQXYbpfZFoSrzq86lScKhkT4,
8
8
  mpflash/bootloader/manual.py,sha256=qGInguhYil4v8EkUxPFlxzvs3m__KraPAj3LAKbV1Ts,3069
9
9
  mpflash/bootloader/micropython.py,sha256=0KDrfdZPtK7fLaxh-_4VxSO-u4IUj7qCyNVw9-LQ74M,517
10
10
  mpflash/bootloader/touch1200.py,sha256=tL2H4ERh0-YSdR8_v6aK_pDRPMjMevHWUGq4-TTFcWo,1083
11
- mpflash/cli_download.py,sha256=Ip5HViXCVAiG88XgJ3Lg_hhBGIF5DKFTNpL-_gQkdV0,3520
12
- mpflash/cli_flash.py,sha256=KFuJRNgOZ62m70I_KqxqLfLE69b4bOCj69MOfIWdZRo,7136
11
+ mpflash/cli_download.py,sha256=_9JGBZ0zXtHe3W61rZmsrKRLQQaF58yLsnHYarejyuM,3531
12
+ mpflash/cli_flash.py,sha256=U64IAqwTVeYubXTUO6UXY9SiS_e5NsQwyPYxf1juX8s,7166
13
13
  mpflash/cli_group.py,sha256=JFBtp4qhakJeQkuupEoObHeSFke8eWIU1HjnOZ-JfH0,2504
14
- mpflash/cli_list.py,sha256=AvYq5_Z7l0Z4rkbr23TwFNzstuZsQgopFpdcrTLwUvs,1965
14
+ mpflash/cli_list.py,sha256=51iLSehG9vWOvgeovJ8UYBjKkdnZStG1gAgYa0Cheog,2340
15
15
  mpflash/cli_main.py,sha256=cElgh8Soq3U5TEAvrrD1sj7NDi-Eb-pei3QcMI0tlwE,1094
16
- mpflash/common.py,sha256=h4pVuOpopn5oIy5NQdbggtOOktTL_c92cS_oUfPG4v8,5783
16
+ mpflash/common.py,sha256=P5Pt_Cjr6e5P8J5SB7Uhy6H-ARZSRTL2pApZ1rJOX_M,6067
17
17
  mpflash/config.py,sha256=h2Oq7kSe40tOnglpo02wkpaPHxHNVqyB3uGxreIu57U,1029
18
- mpflash/connected.py,sha256=p6RMix-tFr0pfT9TErh0LD1nm24ApTr3CqVGcrnDHk8,3024
18
+ mpflash/connected.py,sha256=LtyNWloEtEOKvmnTCSSNOADT0KeVbtjHpDQwu4dot2o,3053
19
19
  mpflash/download.py,sha256=mckR3pdMFQMYBKNmKBEJm9bJnTtQEnkuQ1vWYXcRRv8,13941
20
20
  mpflash/downloaded.py,sha256=YPN0LDf8DSDvdB9gbVny61bvaJHIDbUs81XUwftTb1c,4808
21
21
  mpflash/errors.py,sha256=6lUhVtECY3syV2bBGKzegGH4pPKXhevvhYQZd74sy6o,238
@@ -30,7 +30,7 @@ mpflash/flash/uf2/macos.py,sha256=sncXJsc2FVfm9rvLDjcEu7ZIyrDeHmazHiNQTUaf1Y0,11
30
30
  mpflash/flash/uf2/uf2disk.py,sha256=dQ8_U6e3qkFOyfXZDpWAsvEBIlMr-ZzLkzTDD8SADqM,286
31
31
  mpflash/flash/uf2/windows.py,sha256=k9Yv71YswPnLx-Z5rf4KjhtVkEWr8SU8EXpeRv87h3A,1290
32
32
  mpflash/flash/worklist.py,sha256=1uBvn-T35Oey04g6xxNxo5t68q5_tp18eZcRAamF0tY,5828
33
- mpflash/list.py,sha256=O0tX4BvclmDMnnjMxCN9Zh8hdL6vnuvS9pLNxYLBya8,3112
33
+ mpflash/list.py,sha256=Qt_3AUgA6LqejfGETgaa49fzqlI-m_OvsPosr6xMBMY,3464
34
34
  mpflash/logger.py,sha256=BAVrSXMGZLfSDRFbtVBtvb7Rl0sTJxooCgBS5t-6bXo,1057
35
35
  mpflash/mpboard_id/__init__.py,sha256=rQrPCN30GP-lfB2a2deA-lQ6iKvaKPK_xbtBoIavGsM,3716
36
36
  mpflash/mpboard_id/add_boards.py,sha256=ehQn560S0XxAD3nsUMo4o_f6w8XTVAfO0GCnfTKa6-4,9379
@@ -38,7 +38,7 @@ mpflash/mpboard_id/board.py,sha256=yQ8IDHQS09AelvTvmPhpmsL4oX3L7IXGqHorkxDOkoE,1
38
38
  mpflash/mpboard_id/board_id.py,sha256=wzGrxJu_ciOVT7n2861lhoKmPAjh1QjWnAdfcqNUUqc,2871
39
39
  mpflash/mpboard_id/board_info.zip,sha256=F6YowS96DAqjten4ySe4MXgZwPtE-saZOUfY5OQkqKk,19759
40
40
  mpflash/mpboard_id/store.py,sha256=lQQgHSxcaM_ZURcfZNSUv3-ZJjUKMC_xEOOSdpzVvBU,1493
41
- mpflash/mpremoteboard/__init__.py,sha256=7uI-5HJgNsQz_EOCW3cRy2xtqXKt9kX51gDSx6HC0Kc,7522
41
+ mpflash/mpremoteboard/__init__.py,sha256=oB0HwQOBhTtI4KR46_FvXZ_I6V5xuuxQ3MPeR6lVGVk,9240
42
42
  mpflash/mpremoteboard/mpy_fw_info.py,sha256=BTupe4rZDTs3UHRqvs429XqWHCchSpwa05yACOiOt5U,4413
43
43
  mpflash/mpremoteboard/runner.py,sha256=YUmo5Y0aOgMaww8CXSdNdgXD-wRKncILuMZ0OB_2qRU,4646
44
44
  mpflash/vendor/click_aliases.py,sha256=K98inhtze8td1dw312kexJS7OX_0ojlptPQ5Z0SHxJY,3065
@@ -46,8 +46,8 @@ mpflash/vendor/dfu.py,sha256=jGsiD3lbSV1Ar9qJubhoY_hy-L8FI-K55aow8vgwoYQ,5590
46
46
  mpflash/vendor/pydfu.py,sha256=1ObubGsPFrQ7T9M3JRlIPNIG2xx8uYffaEe0Y6bdf_g,19937
47
47
  mpflash/vendor/readme.md,sha256=ZVg7kuUYyXcWcrWkaSJ0CunwebCqu2SiS2sqDadwrT8,84
48
48
  mpflash/versions.py,sha256=x5VrdVfWhZJfH7tZmwu2vVx-mPrK1iunYSpSce9VUXU,4492
49
- mpflash-0.9.1.post2.dist-info/LICENSE,sha256=xHwgxGNkI0R2iN4KNfbPbQSzRomWyRz7bJnR1O2mln8,1057
50
- mpflash-0.9.1.post2.dist-info/METADATA,sha256=SFrk166YQmHI5NcNGZYbOmSx9O2D1r9zvG-DxKs26EM,16064
51
- mpflash-0.9.1.post2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
52
- mpflash-0.9.1.post2.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
53
- mpflash-0.9.1.post2.dist-info/RECORD,,
49
+ mpflash-1.0.1.dist-info/LICENSE,sha256=xHwgxGNkI0R2iN4KNfbPbQSzRomWyRz7bJnR1O2mln8,1057
50
+ mpflash-1.0.1.dist-info/METADATA,sha256=b5hg5kCyvR3IBzo03N7SiqzesIDbTMkV9QiIjbLbZVE,17649
51
+ mpflash-1.0.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
52
+ mpflash-1.0.1.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
53
+ mpflash-1.0.1.dist-info/RECORD,,