Skip to content

Commit 3369f0f

Browse files
committed
fix: MacOS UF2 drive detection
The `wait_for_UF2_macos` function in `flash_uf2_macos.py` has been modified to improve the detection of the macOS UF2 drive.
1 parent 580b42c commit 3369f0f

File tree

4 files changed

+22
-65
lines changed

4 files changed

+22
-65
lines changed

src/mpflash/mpflash/flash_uf2.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from mpflash.mpremoteboard import MPRemoteBoard
1515

1616
from .common import PORT_FWTYPES
17-
from .config import config
17+
from .flash_uf2_boardid import get_board_id
1818
from .flash_uf2_linux import dismount_uf2_linux, wait_for_UF2_linux
1919
from .flash_uf2_macos import wait_for_UF2_macos
2020
from .flash_uf2_windows import wait_for_UF2_windows
@@ -45,11 +45,7 @@ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemo
4545
destination = wait_for_UF2_windows()
4646
elif sys.platform == "darwin":
4747
log.warning(f"OS {sys.platform} not tested/supported")
48-
# TODO: test which of the options is best
49-
if "macos_uf2" in config.tests:
50-
destination = wait_for_UF2_macos()
51-
else:
52-
destination = wait_for_UF2_linux()
48+
destination = wait_for_UF2_macos()
5349
else:
5450
log.warning(f"OS {sys.platform} not tested/supported")
5551
return None
@@ -59,6 +55,8 @@ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemo
5955
return None
6056

6157
log.info("Board is in bootloader mode")
58+
board_id = get_board_id(destination) # type: ignore
59+
log.info(f"Board ID: {board_id}")
6260
log.info(f"Copying {fw_file} to {destination}.")
6361
shutil.copy(fw_file, destination)
6462
log.success("Done copying, resetting the board and wait for it to restart")

src/mpflash/mpflash/flash_uf2_macos.py

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,32 @@
66
import sys
77
import time
88
from pathlib import Path
9+
from typing import Optional
910

1011
from loguru import logger as log
1112
from rich.progress import track
1213

1314
from .flash_uf2_boardid import get_board_id
14-
from .uf2disk import UF2Disk
1515

1616

17-
def get_uf2_drives():
18-
"""
19-
Get a list of all the (un)mounted UF2 drives
20-
"""
21-
if sys.platform != "linux":
22-
log.error("pumount only works on Linux")
23-
return
24-
# import blkinfo only on linux
25-
from blkinfo import BlkDiskInfo
26-
27-
myblkd = BlkDiskInfo()
28-
filters = {
29-
"tran": "usb",
30-
}
31-
usb_disks = myblkd.get_disks(filters)
32-
for disk in usb_disks:
33-
if disk["fstype"] == "vfat":
34-
uf2_part = disk
35-
# unpartioned usb disk or partition (e.g. /dev/sdb )
36-
# SEEED WIO Terminal is unpartioned
37-
# print( json.dumps(uf2_part, indent=4))
38-
uf2 = UF2Disk()
39-
uf2.device_path = "/dev/" + uf2_part["name"]
40-
uf2.label = uf2_part["label"]
41-
uf2.mountpoint = uf2_part["mountpoint"]
42-
yield uf2
43-
elif disk["type"] == "disk" and disk.get("children") and len(disk.get("children")) > 0:
44-
if disk.get("children")[0]["type"] == "part" and disk.get("children")[0]["fstype"] == "vfat":
45-
uf2_part = disk.get("children")[0]
46-
# print( json.dumps(uf2_part, indent=4))
47-
uf2 = UF2Disk()
48-
uf2.device_path = "/dev/" + uf2_part["name"]
49-
uf2.label = uf2_part["label"]
50-
uf2.mountpoint = uf2_part["mountpoint"]
51-
yield uf2
52-
53-
54-
def wait_for_UF2_macos(s_max: int = 10):
55-
destination = ""
56-
wait = 10
57-
uf2_drives = []
58-
# while not destination and wait > 0:
17+
def wait_for_UF2_macos(s_max: int = 10) -> Optional[Path]:
18+
"""Wait for the MCU to mount as a drive"""
19+
if s_max < 1:
20+
s_max = 10
21+
destination = None
5922
for _ in track(
6023
range(s_max), description="Waiting for mcu to mount as a drive", transient=True, refresh_per_second=2
6124
):
62-
# log.info(f"Waiting for mcu to mount as a drive : {wait} seconds left")
63-
uf2_drives += list(get_uf2_drives())
64-
for drive in get_uf2_drives():
65-
time.sleep(1)
25+
# log.info(f"Waiting for mcu to mount as a drive : {n} seconds left")
26+
vol_mounts = Path("/Volumes").iterdir()
27+
for vol in vol_mounts:
6628
try:
67-
if Path(drive.mountpoint, "INFO_UF2.TXT").exists():
68-
board_id = get_board_id(Path(drive.mountpoint)) # type: ignore
69-
destination = Path(drive.mountpoint)
29+
if Path(vol, "INFO_UF2.TXT").exists():
30+
destination = Path(vol)
7031
break
71-
except PermissionError:
72-
log.debug(f"Permission error on {drive.mountpoint}")
73-
continue
32+
except OSError:
33+
pass
7434
if destination:
7535
break
7636
time.sleep(1)
77-
wait -= 1
7837
return destination

src/mpflash/mpflash/flash_uf2_windows.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@
55

66
import time
77
from pathlib import Path
8+
from typing import Optional
89

910
import psutil
1011
from rich.progress import track
1112

12-
from .flash_uf2_boardid import get_board_id
1313

1414

15-
def wait_for_UF2_windows(s_max: int = 10):
15+
16+
def wait_for_UF2_windows(s_max: int = 10) -> Optional[Path]:
1617
"""Wait for the MCU to mount as a drive"""
1718
if s_max < 1:
1819
s_max = 10
19-
destination = ""
20+
destination = None
2021
for _ in track(range(s_max), description="Waiting for mcu to mount as a drive", transient=True,refresh_per_second=2):
2122
# log.info(f"Waiting for mcu to mount as a drive : {n} seconds left")
2223
drives = [drive.device for drive in psutil.disk_partitions()]
2324
for drive in drives:
2425
try:
2526
if Path(drive, "INFO_UF2.TXT").exists():
26-
board_id = get_board_id(Path(drive)) # type: ignore
2727
destination = Path(drive)
2828
break
2929
except OSError:

src/mpflash/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "mpflash"
3-
version = "0.8.0"
3+
version = "0.8.1b1"
44
description = "Flash and download tool for MicroPython firmwares"
55
authors = ["Jos Verlinde <[email protected]>"]
66
license = "MIT"

0 commit comments

Comments
 (0)