Skip to content

Commit 4faa9aa

Browse files
committed
tooling: Add make deploy-usb for DAPLink mass-storage flashing.
1 parent 1f060e6 commit 4faa9aa

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ make firmware # Clone micropython-steami (if needed), link local drivers,
195195
make firmware-update # Refresh the MicroPython clone and board-specific submodules
196196
make deploy # Flash firmware via pyOCD (default)
197197
make deploy-openocd # Flash firmware via OpenOCD (alternative)
198+
make deploy-usb # Flash firmware via DAPLink USB mass-storage (alternative)
198199
make run SCRIPT=lib/steami_config/examples/show_config.py # Run with live output
199200
make deploy-script SCRIPT=lib/.../calibrate_magnetometer.py # Deploy as main.py for autonomous use
200201
make run-main # Re-execute the deployed main.py

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ deploy-pyocd: $(MPY_DIR) ## Flash firmware via pyOCD (CMSIS-DAP)
134134
deploy-openocd: $(MPY_DIR) ## Flash firmware via OpenOCD
135135
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD) deploy-openocd
136136

137+
.PHONY: deploy-usb
138+
deploy-usb: $(MPY_DIR) ## Flash firmware via DAPLink USB mass-storage
139+
@$(PYTHON) scripts/deploy_usb.py $(STM32_DIR)/build-$(BOARD)/firmware.bin
140+
137141
.PHONY: run
138142
run: ## Run a script on the board with live output (SCRIPT=path/to/file.py)
139143
@if [ -z "$(SCRIPT)" ]; then \

scripts/deploy_usb.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""Deploy MicroPython firmware to a STeaMi board via DAPLink USB mass-storage.
2+
3+
Detects the STeaMi volume by its label across Linux, macOS, and Windows,
4+
copies the firmware .bin to it, and lets DAPLink auto-reset the target.
5+
6+
Usage:
7+
python scripts/deploy_usb.py path/to/firmware.bin
8+
"""
9+
10+
import os
11+
import platform
12+
import shutil
13+
import subprocess
14+
import sys
15+
16+
VOLUME_LABEL = "STeaMi"
17+
18+
19+
def find_steami_linux():
20+
"""Find STeaMi mount point on Linux via findmnt."""
21+
try:
22+
result = subprocess.run(
23+
["findmnt", "-n", "-o", "TARGET", "-S", "LABEL=" + VOLUME_LABEL],
24+
capture_output=True,
25+
text=True,
26+
check=False,
27+
)
28+
if result.returncode == 0:
29+
mount = result.stdout.strip().split("\n")[0]
30+
return mount or None
31+
except FileNotFoundError:
32+
pass
33+
return None
34+
35+
36+
def find_steami_macos():
37+
"""Find STeaMi mount point on macOS (always /Volumes/<label>)."""
38+
path = "/Volumes/" + VOLUME_LABEL
39+
if os.path.isdir(path):
40+
return path
41+
return None
42+
43+
44+
def find_steami_windows():
45+
"""Find STeaMi drive letter on Windows via WMI."""
46+
try:
47+
result = subprocess.run(
48+
[
49+
"wmic",
50+
"logicaldisk",
51+
"where",
52+
"VolumeName='" + VOLUME_LABEL + "'",
53+
"get",
54+
"DeviceID",
55+
"/value",
56+
],
57+
capture_output=True,
58+
text=True,
59+
check=False,
60+
)
61+
if result.returncode == 0:
62+
for line in result.stdout.splitlines():
63+
if line.startswith("DeviceID="):
64+
drive = line.split("=", 1)[1].strip()
65+
if drive:
66+
return drive + "\\"
67+
except FileNotFoundError:
68+
pass
69+
return None
70+
71+
72+
def find_steami():
73+
"""Detect the STeaMi USB volume across platforms."""
74+
system = platform.system()
75+
if system == "Linux":
76+
return find_steami_linux()
77+
if system == "Darwin":
78+
return find_steami_macos()
79+
if system == "Windows":
80+
return find_steami_windows()
81+
print("Error: unsupported OS: " + system, file=sys.stderr)
82+
sys.exit(1)
83+
84+
85+
def main():
86+
if len(sys.argv) != 2:
87+
print("Usage: deploy_usb.py <firmware.bin>", file=sys.stderr)
88+
sys.exit(1)
89+
90+
firmware = sys.argv[1]
91+
if not os.path.isfile(firmware):
92+
print("Error: firmware not found: " + firmware, file=sys.stderr)
93+
sys.exit(1)
94+
95+
mount = find_steami()
96+
if not mount or not os.path.isdir(mount):
97+
print(
98+
"Error: STeaMi board not found. Is it connected and mounted?",
99+
file=sys.stderr,
100+
)
101+
sys.exit(1)
102+
103+
print("Copying firmware to " + mount + "...")
104+
shutil.copy(firmware, mount)
105+
106+
# Best-effort flush on Unix (no-op on Windows)
107+
if hasattr(os, "sync"):
108+
os.sync()
109+
110+
print("Firmware deployed via USB. Board will reset automatically.")
111+
112+
113+
if __name__ == "__main__":
114+
main()

0 commit comments

Comments
 (0)