mpflash 1.25.0rc3__py3-none-any.whl → 1.25.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
@@ -23,15 +23,6 @@ from .download import download
23
23
  "download",
24
24
  help="Download MicroPython firmware for specific ports, boards and versions.",
25
25
  )
26
- @click.option(
27
- "--destination",
28
- "-d",
29
- "fw_folder",
30
- type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
31
- default=None,
32
- show_default=False,
33
- help="The folder to download the firmware to.",
34
- )
35
26
  @click.option(
36
27
  "--version",
37
28
  "-v",
@@ -94,9 +85,6 @@ def cli_download(**kwargs) -> int:
94
85
  params.boards = list(params.boards)
95
86
  params.serial = list(params.serial)
96
87
  params.ignore = list(params.ignore)
97
- if params.fw_folder:
98
- config.firmware_folder = Path(params.fw_folder)
99
- # all_boards: List[MPRemoteBoard] = []
100
88
  if params.boards:
101
89
  if not params.ports:
102
90
  # no ports specified - resolve ports from specified boards by resolving board IDs
mpflash/cli_flash.py CHANGED
@@ -1,4 +1,3 @@
1
- from pathlib import Path
2
1
  from typing import List
3
2
 
4
3
  import rich_click as click
@@ -10,8 +9,7 @@ from mpflash.ask_input import ask_missing_params
10
9
  from mpflash.cli_download import connected_ports_boards
11
10
  from mpflash.cli_group import cli
12
11
  from mpflash.cli_list import show_mcus
13
- from mpflash.common import BootloaderMethod, FlashParams, Params
14
- from mpflash.config import config
12
+ from mpflash.common import BootloaderMethod, FlashParams, filtered_comports
15
13
  from mpflash.errors import MPFlashError
16
14
  from mpflash.flash import flash_list
17
15
  from mpflash.flash.worklist import WorkList, full_auto_worklist, manual_worklist, single_auto_worklist
@@ -27,15 +25,6 @@ from mpflash.versions import clean_version
27
25
  "flash",
28
26
  short_help="Flash one or all connected MicroPython boards with a specific firmware and version.",
29
27
  )
30
- @click.option(
31
- "--firmware",
32
- "-f",
33
- "fw_folder",
34
- type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
35
- default=None,
36
- show_default=False,
37
- help="The folder to retrieve the firmware from.",
38
- )
39
28
  @click.option(
40
29
  "--version",
41
30
  "-v",
@@ -95,7 +84,7 @@ from mpflash.versions import clean_version
95
84
  )
96
85
  @click.option(
97
86
  "--variant",
98
- "-var",
87
+ "--var",
99
88
  "variant", # single board
100
89
  multiple=False,
101
90
  help="The board VARIANT to flash or '-'. If not specified will try to read the variant from the connected MCU.",
@@ -134,7 +123,7 @@ from mpflash.versions import clean_version
134
123
  )
135
124
  @click.option(
136
125
  "--flash_mode",
137
- "-fm",
126
+ "--fm",
138
127
  type=click.Choice(["keep", "qio", "qout", "dio", "dout"]),
139
128
  default="keep",
140
129
  show_default=True,
@@ -164,8 +153,6 @@ def cli_flash_board(**kwargs) -> int:
164
153
  # No bard specified
165
154
  params.boards = ["?"]
166
155
 
167
- if params.fw_folder:
168
- config.firmware_folder = Path(params.fw_folder)
169
156
  # Detect connected boards if not specified,
170
157
  # and ask for input if boards cannot be detected
171
158
  all_boards: List[MPRemoteBoard] = []
@@ -197,8 +184,23 @@ def cli_flash_board(**kwargs) -> int:
197
184
  params.versions = [clean_version(v) for v in params.versions]
198
185
  worklist: WorkList = []
199
186
 
187
+ if len(params.versions) == 1 and len(params.boards) == 1 and params.serial == ["*"]:
188
+ # A one or more serial port including the board / variant
189
+ comports = filtered_comports(
190
+ ignore=params.ignore,
191
+ include=params.ports,
192
+ bluetooth=params.bluetooth,
193
+ )
194
+ board_id = f"{params.boards[0]}-{params.variant}" if params.variant else params.boards[0]
195
+ log.info(f"Flashing {board_id} {params.versions[0]} to {len(comports)} serial ports")
196
+ log.info(f"Target ports: {', '.join(comports)}")
197
+ worklist = manual_worklist(
198
+ comports,
199
+ board_id=board_id,
200
+ version=params.versions[0],
201
+ )
200
202
  # if serial port == auto and there are one or more specified/detected boards
201
- if params.serial == ["*"] and params.boards:
203
+ elif params.serial == ["*"] and params.boards:
202
204
  if not all_boards:
203
205
  log.trace("No boards detected yet, scanning for connected boards")
204
206
  _, _, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
@@ -215,8 +217,13 @@ def cli_flash_board(**kwargs) -> int:
215
217
  )
216
218
  elif params.versions[0] and params.boards[0] and params.serial:
217
219
  # A one or more serial port including the board / variant
220
+ comports = filtered_comports(
221
+ ignore=params.ignore,
222
+ include=params.ports,
223
+ bluetooth=params.bluetooth,
224
+ )
218
225
  worklist = manual_worklist(
219
- params.serial[0],
226
+ comports,
220
227
  board_id=params.boards[0],
221
228
  version=params.versions[0],
222
229
  )
mpflash/cli_list.py CHANGED
@@ -86,6 +86,8 @@ def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json
86
86
  if mcu.family == "circuitpython":
87
87
  # CircuitPython boards need a special reset command
88
88
  mcu.run_command(["exec", "--no-follow", "import microcontroller,time;time.sleep(0.01);microcontroller.reset()"], resume=False)
89
+ elif mcu.family == "unknown":
90
+ continue
89
91
  else:
90
92
  mcu.run_command("reset")
91
93
  return 0 if conn_mcus else 1
mpflash/common.py CHANGED
@@ -36,7 +36,6 @@ class Params:
36
36
  boards: List[str] = field(default_factory=list)
37
37
  variant: str = ""
38
38
  versions: List[str] = field(default_factory=list)
39
- fw_folder: Optional[Path] = None
40
39
  serial: List[str] = field(default_factory=list)
41
40
  ignore: List[str] = field(default_factory=list)
42
41
  bluetooth: bool = False
@@ -79,6 +78,17 @@ def filtered_comports(
79
78
  ignore: Optional[List[str]] = None,
80
79
  include: Optional[List[str]] = None,
81
80
  bluetooth: bool = False,
81
+ ) -> List[str]:
82
+ """
83
+ Get a list of filtered comports using the include and ignore lists.
84
+ both can be globs (e.g. COM*) or exact port names (e.g. COM1)
85
+ """
86
+ return [p.device for p in filtered_portinfos(ignore, include, bluetooth)]
87
+
88
+ def filtered_portinfos(
89
+ ignore: Optional[List[str]] = None,
90
+ include: Optional[List[str]] = None,
91
+ bluetooth: bool = False,
82
92
  ) -> List[ListPortInfo]: # sourcery skip: assign-if-exp
83
93
  """
84
94
  Get a list of filtered comports using the include and ignore lists.
mpflash/config.py CHANGED
@@ -4,9 +4,10 @@ import os
4
4
  from importlib.metadata import version
5
5
  from pathlib import Path
6
6
  from typing import List, Optional
7
-
8
7
  import platformdirs
9
8
 
9
+ from mpflash.errors import MPFlashError
10
+
10
11
 
11
12
  def get_version():
12
13
  name = __package__ or "mpflash"
@@ -44,7 +45,15 @@ class MPFlashConfig:
44
45
  def firmware_folder(self) -> Path:
45
46
  """The folder where firmware files are stored"""
46
47
  if not self._firmware_folder:
47
- self._firmware_folder = platformdirs.user_downloads_path() / "firmware"
48
+ from mpflash.logger import log
49
+ # Check if MPFLASH_FIRMWARE environment variable is set
50
+ env_firmware_path = os.getenv("MPFLASH_FIRMWARE")
51
+ if env_firmware_path:
52
+ firmware_path = Path(env_firmware_path)
53
+ if firmware_path.exists() and firmware_path.is_dir():
54
+ self._firmware_folder = firmware_path
55
+ else:
56
+ log.warning(f"Environment variable MPFLASH_FIRMWARE points to invalid directory: {env_firmware_path}. Using default location.")
48
57
  # allow testing in CI
49
58
  if Path(os.getenv("GITHUB_ACTIONS", "")).as_posix().lower() == "true":
50
59
  workspace = os.getenv("GITHUB_WORKSPACE")
@@ -53,6 +62,13 @@ class MPFlashConfig:
53
62
  ws_path.mkdir(parents=True, exist_ok=True)
54
63
  print(f"Detected GitHub Actions environment. Using workspace path: {ws_path}")
55
64
  self._firmware_folder = ws_path
65
+ if not self._firmware_folder:
66
+ self._firmware_folder = platformdirs.user_downloads_path() / "firmware"
67
+ if not self._firmware_folder.exists():
68
+ log.info(f"Creating firmware folder at {self._firmware_folder}")
69
+ self._firmware_folder.mkdir(parents=True, exist_ok=True)
70
+ if not self._firmware_folder.is_dir():
71
+ raise MPFlashError(f"Firmware folder {self._firmware_folder} is not a directory.")
56
72
  return self._firmware_folder
57
73
 
58
74
  @firmware_folder.setter
mpflash/connected.py CHANGED
@@ -4,7 +4,7 @@ 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, find_serial_by_path
7
+ from mpflash.common import filtered_portinfos, find_serial_by_path
8
8
  from mpflash.mpremoteboard import MPRemoteBoard
9
9
 
10
10
 
@@ -21,6 +21,7 @@ def connected_ports_boards(
21
21
  - A list of unique board names of the connected MCUs.
22
22
  - A list of MPRemoteBoard instances of the connected MCUs.
23
23
  """
24
+ conn_mcus = [b for b in list_mcus(include=include, ignore=ignore, bluetooth=bluetooth)]
24
25
  conn_mcus = [b for b in list_mcus(include=include, ignore=ignore, bluetooth=bluetooth) if b.connected]
25
26
  # ignore boards that have the [mpflash] ignore flag set
26
27
  conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
@@ -47,7 +48,7 @@ def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False)
47
48
  """
48
49
  # conn_mcus = [MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards(bluetooth) if sp not in config.ignore_ports]
49
50
 
50
- comports = filtered_comports(
51
+ comports = filtered_portinfos(
51
52
  ignore=ignore,
52
53
  include=include,
53
54
  bluetooth=bluetooth,
mpflash/download/jid.py CHANGED
@@ -48,7 +48,7 @@ def ensure_firmware_downloaded(worklist: WorkList, version: str, force: bool) ->
48
48
  newlist.append((mcu, new_firmware[0]))
49
49
  else:
50
50
  log.info(f"Found {version} firmware {board_firmwares[-1].firmware_file} for {mcu.board} on {mcu.serialport}.")
51
- newlist.append((mcu, firmware))
51
+ newlist.append((mcu, board_firmwares[0]))
52
52
 
53
53
  worklist.clear()
54
54
  worklist.extend(newlist)
@@ -7,13 +7,15 @@ import time
7
7
  from pathlib import Path
8
8
  from typing import Optional
9
9
 
10
- from .boardid import get_board_id
11
10
  import psutil
12
11
  from rich.progress import track
13
12
 
13
+ from .boardid import get_board_id
14
+
14
15
 
15
16
  def wait_for_UF2_windows(board_id: str, s_max: int = 10) -> Optional[Path]:
16
17
  """Wait for the MCU to mount as a drive"""
18
+
17
19
  if s_max < 1:
18
20
  s_max = 10
19
21
  destination = None
mpflash/flash/worklist.py CHANGED
@@ -1,11 +1,12 @@
1
1
  """Worklist for updating boards"""
2
2
 
3
- from pathlib import Path
4
- from typing import Dict, List, Optional, Tuple
3
+ from typing import List, Optional, Tuple
5
4
 
6
5
  from loguru import logger as log
6
+ from serial.tools.list_ports_common import ListPortInfo
7
+ from typing_extensions import TypeAlias
7
8
 
8
- from mpflash.common import filtered_comports
9
+ from mpflash.common import filtered_portinfos
9
10
  from mpflash.db.models import Firmware
10
11
  from mpflash.downloaded import find_downloaded_firmware
11
12
  from mpflash.errors import MPFlashError
@@ -14,11 +15,12 @@ from mpflash.mpboard_id import find_known_board
14
15
  from mpflash.mpremoteboard import MPRemoteBoard
15
16
 
16
17
  # #########################################################################################################
17
- WorkList = List[Tuple[MPRemoteBoard, Optional[Firmware]]]
18
+ FlashItem: TypeAlias = Tuple[MPRemoteBoard, Optional[Firmware]]
19
+ WorkList: TypeAlias = List[FlashItem]
18
20
  # #########################################################################################################
19
21
 
20
22
 
21
- def auto_update(
23
+ def auto_update_worklist(
22
24
  conn_boards: List[MPRemoteBoard],
23
25
  target_version: str,
24
26
  ) -> WorkList:
@@ -59,12 +61,26 @@ def auto_update(
59
61
 
60
62
 
61
63
  def manual_worklist(
62
- serial: str,
64
+ serial: List[str],
63
65
  *,
64
66
  board_id: str,
65
67
  version: str,
66
68
  ) -> WorkList:
67
- """Create a worklist for a single board specified manually.
69
+ """Create a worklist for manually specified boards."""
70
+ wl: WorkList = []
71
+ for comport in serial:
72
+ log.trace(f"Manual updating {comport} to {board_id} {version}")
73
+ wl.append(manual_board(comport, board_id=board_id, version=version))
74
+ return wl
75
+
76
+
77
+ def manual_board(
78
+ serial: str,
79
+ *,
80
+ board_id: str,
81
+ version: str,
82
+ ) -> FlashItem:
83
+ """Create a Flash work item for a single board specified manually.
68
84
 
69
85
  Args:
70
86
  serial (str): Serial port of the board
@@ -72,7 +88,7 @@ def manual_worklist(
72
88
  version (str): Firmware version
73
89
 
74
90
  Returns:
75
- WorkList: List of boards and firmware information to update
91
+ FlashItem: Board and firmware information to update
76
92
  """
77
93
  log.trace(f"Manual updating {serial} to {board_id} {version}")
78
94
  mcu = MPRemoteBoard(serial)
@@ -85,14 +101,14 @@ def manual_worklist(
85
101
  except (LookupError, MPFlashError) as e:
86
102
  log.error(f"Board {board_id} not found in board database")
87
103
  log.exception(e)
88
- return []
104
+ return (mcu, None)
89
105
  mcu.board = board_id
90
106
  firmwares = find_downloaded_firmware(board_id=board_id, version=version, port=mcu.port)
91
107
  if not firmwares:
92
- log.error(f"No firmware found for {mcu.port} {board_id} version {version}")
93
- return []
108
+ log.trace(f"No firmware found for {mcu.port} {board_id} version {version}")
109
+ return (mcu, None)
94
110
  # use the most recent matching firmware
95
- return [(mcu, firmwares[-1])] # type: ignore
111
+ return (mcu, firmwares[-1]) # type: ignore
96
112
 
97
113
 
98
114
  def single_auto_worklist(
@@ -111,7 +127,7 @@ def single_auto_worklist(
111
127
  """
112
128
  log.trace(f"Auto updating {serial} to {version}")
113
129
  conn_boards = [MPRemoteBoard(serial)]
114
- todo = auto_update(conn_boards, version) # type: ignore # List / list
130
+ todo = auto_update_worklist(conn_boards, version) # type: ignore # List / list
115
131
  show_mcus(conn_boards)
116
132
  return todo
117
133
 
@@ -125,7 +141,7 @@ def full_auto_worklist(
125
141
  ) -> WorkList:
126
142
  """
127
143
  Create a worklist for all connected micropython boards based on the information retrieved from the board.
128
- This allows the firmware version of one or moae boards to be changed without needing to specify the port or board_id manually.
144
+ This allows the firmware version of one or more boards to be changed without needing to specify the port or board_id manually.
129
145
 
130
146
  Args:
131
147
  version (str): Firmware version
@@ -135,7 +151,7 @@ def full_auto_worklist(
135
151
  """
136
152
  log.trace(f"Auto updating all boards to {version}")
137
153
  if selected_boards := filter_boards(all_boards, include=include, ignore=ignore):
138
- return auto_update(selected_boards, version)
154
+ return auto_update_worklist(selected_boards, version)
139
155
  else:
140
156
  return []
141
157
 
@@ -149,7 +165,7 @@ def filter_boards(
149
165
  try:
150
166
  comports = [
151
167
  p.device
152
- for p in filtered_comports(
168
+ for p in filtered_portinfos(
153
169
  ignore=ignore,
154
170
  include=include,
155
171
  bluetooth=False,
mpflash/logger.py CHANGED
@@ -5,6 +5,7 @@ Ensures log messages are compatible with the current console encoding.
5
5
  Removes or replaces Unicode icons if the encoding is not UTF-8.
6
6
  """
7
7
 
8
+ import functools
8
9
  import sys
9
10
 
10
11
  from loguru import logger as log
@@ -15,12 +16,15 @@ from .config import config
15
16
  console = Console()
16
17
 
17
18
  # Detect if the output encoding supports Unicode (UTF-8)
19
+ @functools.lru_cache(maxsize=1)
18
20
  def _is_utf8_encoding() -> bool:
19
- encoding = getattr(sys.stdout, "encoding", None)
20
- if encoding is None:
21
+ try:
22
+ encoding = getattr(sys.stdout, "encoding", None)
23
+ if encoding is None:
24
+ return False
25
+ return encoding.lower().replace("-", "") == "utf8"
26
+ except BaseException:
21
27
  return False
22
- return encoding.lower().replace("-", "") == "utf8"
23
-
24
28
 
25
29
  def _log_formatter(record: dict) -> str:
26
30
  """
@@ -216,9 +216,10 @@ class MPRemoteBoard:
216
216
  self.toml = {}
217
217
  if rc in [OK]: # sometimes we get an -9 ???
218
218
  try:
219
+ log.trace(result)
219
220
  # Ok we have the info, now parse it
220
221
  self.toml = tomllib.loads("".join(result))
221
- log.debug(f"board_info.toml: {self.toml}")
222
+ log.debug(f"board_info.toml: {self.toml['description']}")
222
223
  except Exception as e:
223
224
  log.error(f"Failed to parse board_info.toml: {e}")
224
225
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mpflash
3
- Version: 1.25.0rc3
3
+ Version: 1.25.1
4
4
  Summary: Flash and download tool for MicroPython firmwares
5
5
  License: MIT
6
6
  Keywords: MicroPython,firmware,flash,download,UF2,esptool
@@ -29,7 +29,7 @@ Requires-Dist: loguru (>=0.7.2,<0.8.0)
29
29
  Requires-Dist: mpremote (>=1.22.0,<2.0.0)
30
30
  Requires-Dist: packaging (>=24.2,<25.0)
31
31
  Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
32
- Requires-Dist: psutil (>=5.9.8,<8.0.0)
32
+ Requires-Dist: psutil (>=7.0.0,<8.0.0)
33
33
  Requires-Dist: pygithub (>=2.1.1,<3.0.0)
34
34
  Requires-Dist: pyusb (>=1.2.1,<2.0.0)
35
35
  Requires-Dist: pywin32 (>=310,<311) ; sys_platform == "win32"
@@ -58,9 +58,22 @@ This tool was initially created to be used in a CI/CD pipeline to automate the p
58
58
  - `samd`, using ` .uf2`, using filecopy
59
59
  - `esp32`, using `.bin`, using esptool,
60
60
  - `esp8266`, using `.bin`, using esptool
61
- - `stm32`, using ` .dfu`, using pydfu
61
+ - `stm32`, using ` .dfu`, using pydfu (also in Windows)
62
62
 
63
63
  Not yet implemented: `nrf`, `cc3200`, `mimxrt`, `renesas`
64
+
65
+ ## Release v1.25.0(.post2)
66
+
67
+ This release includes several new features and improvements:
68
+ - **New features:**
69
+ - Added support for `--variant` option to specify a specific variant of the board when flashing.
70
+ - mpflash now uses a slqlite database to store information on all possible micropython firmwares, and the management of the downloaded firmware files.
71
+ - This allows for a better identification of boards, and matches to the correct firmware.
72
+ - Use the MicroPython v1.25.0 `sys.implementation._build` to as board_id when avaialable
73
+ - Automatically try to download firmware if not yet available locally. No lonmger need to specify the `--download` option.
74
+ - Restructured mpboard_id to use a SQLite db to be able to ID more boards and variants
75
+ - vendored and adapted `board_database.py` from mpflash, kudos @mattytrentini
76
+
64
77
 
65
78
  ## Features
66
79
  1. List the connected boards including their firmware details, in a tabular or json format
@@ -79,15 +92,54 @@ You can use mpflash to perform various operations on your MicroPython boards. He
79
92
  | Command | Description |
80
93
  |---------|-------------|
81
94
  | `mpflash list` | List the connected board(s) including their firmware details |
95
+ | `mpflash flash` | Flash the latest stable firmware to the connected board(s), downloading the firmware if needed |
82
96
  | `mpflash download` | Download the MicroPython firmware(s) for the connected board(s) |
83
- | `mpflash flash` | Flash the latest stable firmware to the connected board(s) |
84
97
 
85
- ## selecting or ignoring specific serial ports
98
+ **Listing connected boards:**
99
+ `mpflash list` will list all connected boards in a table , including their serial port, family, board name, CPU, version and build number.
100
+ Options are available to list the boards in a json format, or to filter the list by serial port or board type.
101
+
102
+
103
+ **Flashing boards with new firmware:**
104
+ `mpflash flash` will flash the latest stable firmware to all connected boards, downloading the firmware if needed.
105
+ It will try to determine the current micropython borad and variant, download the firmware if needed, and flash the correct firmware to each board.
106
+
107
+ Common options are:
108
+
109
+ - `--version` to specify the version of the firmware to flash, defaults to the latest stable version.
110
+ - `--serial` to specify the serial port(s) to flash, defaults to all connected boards.
111
+ - `--board` to specify which firmware to flash to a single board
112
+ - `--variant` to specify a specific variant of the board
113
+
114
+ **Downloading firmware:**
115
+ `mpflash download` will download the latest stable firmware for all connected boards, or a specific board if specified. It will download the firmware from the official MicroPython website and save it in your `Downloads/firmware` directory.
116
+ When a board is specified for which multiple variants are available, all variants will be downloaded.
117
+
118
+ Common options are:
119
+
120
+ - `--version` to specify the version of the firmware to download, defaults to the latest stable version. (e.g. `stable`, `preview`, `x.y.z`)
121
+ - `--serial` to specify the serial port(s) to flash, defaults to all connected boards.
122
+ - `--board` to specify which firmware to flash to a single board
86
123
 
87
- You can use the `--serial` option to select a specific serial port to flash, or the `--ignore` option to ignore a specific serial port.
88
- both options can be specified multiple times
89
- Both can be globs (e.g. COM*) or exact port names (e.g. COM1)
90
- in addition there is a --bluetooth option to simplify ignoring bluetooth ports
124
+ ## Setting the Firmware Files and Database Location
125
+
126
+ You can override the default location for firmware files and the MPFlash database by setting the `MPFLASH_FIRMWARE` environment variable. For example, in a Bash shell:
127
+
128
+ ```bash
129
+ export MPFLASH_FIRMWARE="/path/to/custom/firmware"
130
+ ```
131
+
132
+ When this variable is set, `mpflash` will use that location to store firmware files and estabish it's database.
133
+
134
+ ## Selecting or ignoring specific serial ports
135
+
136
+ You can use the `--serial` option to select a specific serial port(s) to flash,
137
+ Or you can use the `--ignore` option to ignore a specific serial port(s).
138
+
139
+ Either option can be specified multiple times, can be globs (e.g. COM*) or exact port names (e.g. /dev/ttyUSB0).
140
+ To permenently ignore a port, you can set the `MPFLASH_IGNORE` environment variable to a space-separated list of serial ports or globs.
141
+
142
+ In addition there is a --bluetooth option to simplify ignoring bluetooth ports, where the default is to ignore bluetooth ports.
91
143
 
92
144
  ```
93
145
  --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. │
@@ -102,9 +154,9 @@ This file can contain a description of the board, which will be shown in the lis
102
154
  description = "Blue Norwegian actuator"
103
155
  ```
104
156
 
105
- If you want the board to be ignored by mpflash, you can add the following to the board_info.toml file:
157
+ If you want the board to be ignored by mpflash, no matter which serial port it is connected to, you can add the following to the `board_info.toml` file:
106
158
  ```toml
107
- description = "Blue Norwegian feeder"
159
+ description = "Blue Norwegian actuator"
108
160
  [mpflash]
109
161
  ignore = true
110
162
  ```
@@ -8,14 +8,14 @@ mpflash/bootloader/detect.py,sha256=OagP2QVWeLLWkZt2paqEF6r4_x3QDcBGNCPOWfMy9NQ,
8
8
  mpflash/bootloader/manual.py,sha256=WYC4x-dxrSwVUfgnKTlu34pCzckrWJKZnWsARDocycI,3169
9
9
  mpflash/bootloader/micropython.py,sha256=v_kZkvg0uWZDbMrT78gmiYHbD83QLdnrctvEClI8iRg,529
10
10
  mpflash/bootloader/touch1200.py,sha256=VND7_YniS9Vx6WEaAxjI72RZZ6WBOwmBTsKJkbuaAHk,1105
11
- mpflash/cli_download.py,sha256=sMMIVTE4P9O2GpWB9jcbOiKQX-XJ0nu2bBylRbWu0X8,3872
12
- mpflash/cli_flash.py,sha256=QQ7fml84UBK_dUDb1G7DT5_MBDbZbXcWEhkgOq2P8gA,7962
11
+ mpflash/cli_download.py,sha256=cfM3_4It2SE1inx7XsxVhl-j_2efhmuej0d58biOdLo,3507
12
+ mpflash/cli_flash.py,sha256=g-ii51MTzxm-CVpLMhC0TszBYREqlZVctoocNG95z9c,8463
13
13
  mpflash/cli_group.py,sha256=Uf_1ZmeeSIsaGLuuKn3KPPPVi8fJVbIacJYFZx_oPHc,2684
14
- mpflash/cli_list.py,sha256=ZuRalXXjDGo6FhgMTv54BQD_PNss7eeopeZQ_uE1J90,2632
14
+ mpflash/cli_list.py,sha256=dznrQrWQXvev20ai5AFvz2DFe3MNDR5RIrJmtvQou6A,2693
15
15
  mpflash/cli_main.py,sha256=NMhEtMtSe7ApE-210Q4p-g7ZgewgO-4z1Q-vNKLQ47Y,1277
16
- mpflash/common.py,sha256=iKDoc6Ut8XbZ8fYLEI2XsoU7GuG_pFG0KGcRWXPl1wE,5922
17
- mpflash/config.py,sha256=bmwNSJzk27iHcI-r3C6hm6-TeOat2ymzbbv-Q-xuO2o,3048
18
- mpflash/connected.py,sha256=oxZdk1o-AfNPhJsSxr3KrMH_gdYfrjqc_IpT6J8Ng9k,3496
16
+ mpflash/common.py,sha256=LVN3actI__gHorWIG5-55v6dZ1cD1GSIlevk3a8Je-Y,6278
17
+ mpflash/config.py,sha256=55cPkGvCajlEd1_lEGsPNCX9YdJqUr9muqBejVOyVVA,4066
18
+ mpflash/connected.py,sha256=Bx2R-nAeWC6iNG77mXDMu0n66bvTMyM4sH7ckuKnCFw,3591
19
19
  mpflash/db/__init__.py,sha256=wnIlO4nOXsPGXMbn2OCqHRsR-hUmtJsko8VdqjH3ZUE,45
20
20
  mpflash/db/core.py,sha256=hyzurZp8QMl8Q9B00Q-tOkOUp68T8XhM7tj3dm5cDHw,2283
21
21
  mpflash/db/gather_boards.py,sha256=8QS7NIt3n9ROqtgVAnoqU8YMeObLGaN2pvJL7d_kULA,3905
@@ -27,7 +27,7 @@ mpflash/db/tools.py,sha256=6SEGfshNob4yRQ4h-Cj_xcWMRY28sbA8CWauNXV_uMI,814
27
27
  mpflash/download/__init__.py,sha256=zidXvsSFCfR-BZCZ6TiB7uEucEuUqXnZhKSfTs60lzU,7930
28
28
  mpflash/download/from_web.py,sha256=PVJDaFfYLJGXlPva5fExh4Yg2H7j3idyJEcfOiVVJBs,7608
29
29
  mpflash/download/fwinfo.py,sha256=gpa92PkysT1B7mxPAFJ-b_6y03QCNgHKm-J6T_RFNMI,1852
30
- mpflash/download/jid.py,sha256=503HW4jIB22fsb9vYphXqqO33LTMtvPdENG81wKDgMs,2334
30
+ mpflash/download/jid.py,sha256=V57M4K0uXXxBYOB4zOKkmXvUvEQdM_-w22LZ-iMIJSE,2344
31
31
  mpflash/downloaded.py,sha256=508sqROPf0Ymz7UxMzReXtK6mG1EcoXA-ysGdzV-VM0,4040
32
32
  mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
33
33
  mpflash/flash/__init__.py,sha256=jif7-ifsXMabidjNdqUQyl1CwD5_USjCAZFhU5W-Aw8,2992
@@ -39,10 +39,10 @@ mpflash/flash/uf2/boardid.py,sha256=U5wGM8VA3wEpUxQCMtuXpMZZomdVH8J_Zd5_GekUMuU,
39
39
  mpflash/flash/uf2/linux.py,sha256=uTgqyS7C7xfQ25RrTcSUkt-m2u2Ks_o7bPLzIecPoC8,4355
40
40
  mpflash/flash/uf2/macos.py,sha256=JTaIpqnR_0k4oSEvzs9amhmK-PMxUJyZLnZ_wZwxa-0,1228
41
41
  mpflash/flash/uf2/uf2disk.py,sha256=4_P2l-kedM7VSliA2u706LQLxvu3xWSod1-lj-xjZis,298
42
- mpflash/flash/uf2/windows.py,sha256=S---sVjVrC00ZcnpOewtJIBfSCj2cr7FGQwEm_ZEDnY,1334
43
- mpflash/flash/worklist.py,sha256=ZqbgYChXFGEVLVlGKeS9eJJDToxBYqjrfWE2NIa7Cck,5622
42
+ mpflash/flash/uf2/windows.py,sha256=OEeskObPtpIE4a5NzYIcBqg3FkM5MGPGEa4lGGOfntY,1338
43
+ mpflash/flash/worklist.py,sha256=WIiBlbluAiU7UexOu1dlXguUmkvhW0uxvvUaiUCEZ1U,6165
44
44
  mpflash/list.py,sha256=NNhKpRh3ARZMdq56GLJgJ67GeuUf9SxjTzFhQjDsi9A,4008
45
- mpflash/logger.py,sha256=oMGBhfHv0edPJaUxiqAjkQ5Na2B687f94LqE-IR7C-U,1885
45
+ mpflash/logger.py,sha256=b2pNiAEXgpUDZKnMjtgBAGgMpPwTB3u030EhJiXyLZQ,2009
46
46
  mpflash/mpboard_id/__init__.py,sha256=Z6gDDWTCSKPp2fsuaUz80zgrklBR9XDlSLF9y_evR9A,391
47
47
  mpflash/mpboard_id/alternate.py,sha256=ZhqfdA9sLJmyOfJ6WwK9wrzzUn6JQdkAreiL0q5XEQg,1913
48
48
  mpflash/mpboard_id/board_id.py,sha256=dGbYnqaGHm6Z68P6aCq5bv95pyhi9KKhQleQXmlyO8Y,2046
@@ -50,7 +50,7 @@ mpflash/mpboard_id/board_info.json,sha256=A3ZIt38KvAy2NMB5srHorSBd3Q3wOZIXufWiIs
50
50
  mpflash/mpboard_id/board_info.zip,sha256=-2bnQGRsIQuJUfz-7_-GQ8pMWJ1evhCez6yfjhXocNw,23213
51
51
  mpflash/mpboard_id/known.py,sha256=GrNe4FtzVIdi9L9xuJ1gzorzXTvdfrugX1iVc_Nblb8,3325
52
52
  mpflash/mpboard_id/resolve.py,sha256=5KCZ0Tcg3FYZ3HK_zux5EguwoSC2E03kCpW2fh4rN2A,779
53
- mpflash/mpremoteboard/__init__.py,sha256=kZ-MziZPwx6UOs_ybLYEYeUDndC1XyylMcpGTiEHpTk,12043
53
+ mpflash/mpremoteboard/__init__.py,sha256=WWzAuUo3irKs_ZfHc7PREKrsywi45aPyZXuz5MaD6go,12093
54
54
  mpflash/mpremoteboard/mpy_fw_info.py,sha256=ZDEPJN9XJnoG_oeWcLNiLJAD5bkVX2yI_j4K7msUxWM,5196
55
55
  mpflash/mpremoteboard/runner.py,sha256=auJuK7uBq_qdZOX9DgzRARyAsTyhT8c9ycP02VqhMf4,4943
56
56
  mpflash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -62,8 +62,8 @@ mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2,sha256=QuPMppq
62
62
  mpflash/vendor/pydfu.py,sha256=KD1RHHuhvhWi-l1UB6GyggkxouDKtZgkG4ivRbIfwC4,21264
63
63
  mpflash/vendor/readme.md,sha256=BQ7Uxf8joeYMjTUuSLLBG49ob6a9MgFPIEwuc72-Mfw,415
64
64
  mpflash/versions.py,sha256=HuujLNdMKY_mQXyEqwXVHcU8nbuXeBiWP2TMA5JQhr4,4884
65
- mpflash-1.25.0rc3.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
66
- mpflash-1.25.0rc3.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
67
- mpflash-1.25.0rc3.dist-info/METADATA,sha256=mEXilzRfCv3IpCReXC9MiydCTo_XVD81flx9E6zFtnI,23938
68
- mpflash-1.25.0rc3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
69
- mpflash-1.25.0rc3.dist-info/RECORD,,
65
+ mpflash-1.25.1.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
66
+ mpflash-1.25.1.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
67
+ mpflash-1.25.1.dist-info/METADATA,sha256=IO9Axs0u59gBjzoIlCR7mNbb8jb0RkMi4bQ68JWXASA,27109
68
+ mpflash-1.25.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
69
+ mpflash-1.25.1.dist-info/RECORD,,