Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM mcr.microsoft.com/devcontainers/python:3.10

# System packages for firmware build and board communication
# System packages for MicroPython firmware build and board communication
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc-arm-none-eabi \
libnewlib-arm-none-eabi \
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},

// USB access for STeaMi board (DAPLink / mpremote / pyOCD / OpenOCD).
// Privileged mode is required for firmware flashing and board communication.
// Privileged mode is required for MicroPython firmware flashing and board communication.
// This is incompatible with GitHub Codespaces but essential for local use.
"privileged": true,
"mounts": ["type=bind,source=/dev/bus/usb,target=/dev/bus/usb"],
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
sudo apt-get install -y --no-install-recommends gcc-arm-none-eabi libnewlib-arm-none-eabi

- name: Build firmware
run: make firmware
run: make micropython-firmware

- name: Attach firmware to release
env:
Expand Down
37 changes: 22 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ For local development (without dev container):

* Python 3.10+
* Node.js 22+ (for husky, commitlint, lint-staged, semantic-release)
* `arm-none-eabi-gcc` toolchain (for `make firmware`)
* `pyocd` (for `make deploy`, installed via `pip install -e ".[flash]"`)
* OpenOCD (optional, for `make deploy-openocd`)
* `arm-none-eabi-gcc` toolchain (for `make micropython-firmware`)
* `pyocd` (for `make micropython-deploy`, installed via `pip install -e ".[flash]"`)
* OpenOCD (optional, for `make micropython-deploy-openocd`)
* `mpremote` (installed via `pip install -e ".[test]"`)
* GitHub CLI (`gh`)

Expand All @@ -140,7 +140,7 @@ The container also provides:
* **zsh + oh-my-zsh** as default shell with persistent shell history
* **Pylance** configured with MicroPython STM32 stubs (no false `import machine` errors)
* **Serial Monitor** extension for board communication
* **USB passthrough** for mpremote, pyOCD, OpenOCD, and firmware flashing (the container runs in privileged mode with `/dev/bus/usb` mounted)
* **USB passthrough** for mpremote, pyOCD, OpenOCD, and MicroPython firmware flashing (the container runs in privileged mode with `/dev/bus/usb` mounted)
* **udev rules** for the DAPLink interface (auto-started on container creation)

Note: GitHub Codespaces is not supported because the container requires privileged mode and USB device access for board communication.
Expand Down Expand Up @@ -186,25 +186,32 @@ make bump PART=minor # minor: v1.0.1 → v1.1.0
make bump PART=major # major: v1.1.0 → v2.0.0
```

## Firmware build and deploy
## MicroPython firmware build and deploy

The drivers are "frozen" into the MicroPython firmware for the STeaMi board. The Makefile automates cloning, building, and flashing:
The STeaMi board has two distinct firmwares:

- **MicroPython firmware** — runs on the STM32WB55 main MCU and exposes the drivers from this repository
- **DAPLink firmware** — runs on the STM32F103 interface chip and provides the I2C bridge, mass-storage, and CMSIS-DAP debug interface (build targets planned in #377)

This section covers the **MicroPython firmware** only. The drivers in this repository are "frozen" into it. The Makefile automates cloning, building, and flashing:

```bash
make firmware # Clone micropython-steami (if needed), link local drivers, build
make firmware-update # Refresh the MicroPython clone and board-specific submodules
make deploy # Flash firmware via pyOCD (default)
make deploy-openocd # Flash firmware via OpenOCD (alternative)
make deploy-usb # Flash firmware via DAPLink USB mass-storage (alternative)
make micropython-firmware # Clone micropython-steami (if needed), link local drivers, build
make micropython-update # Refresh the MicroPython clone and board-specific submodules
make micropython-deploy # Flash MicroPython firmware via pyOCD (default)
make micropython-deploy-openocd # Flash MicroPython firmware via OpenOCD (alternative)
make micropython-deploy-usb # Flash MicroPython firmware via DAPLink USB mass-storage (alternative)
make micropython-clean # Clean MicroPython firmware build artifacts
make run SCRIPT=lib/steami_config/examples/show_config.py # Run with live output
make deploy-script SCRIPT=lib/.../calibrate_magnetometer.py # Deploy as main.py for autonomous use
make run-main # Re-execute the deployed main.py
make firmware-clean # Clean firmware build artifacts
make run-main # Re-execute main.py on the board
```

The firmware source is cloned into `.build/micropython-steami/` (gitignored). A symbolic link replaces the submodule `lib/micropython-steami-lib` with your local working directory, so the firmware always includes your latest changes — even uncommitted ones.
The legacy short names (`make firmware`, `make deploy`, etc.) are deprecated and now print an error message asking which firmware (MicroPython or DAPLink) you intended to target.

The MicroPython firmware source is cloned into `.build/micropython-steami/` (gitignored). A symbolic link replaces the submodule `lib/micropython-steami-lib` with your local working directory, so the firmware always includes your latest changes — even uncommitted ones.

Use `make firmware` for normal rebuilds from the existing local clone. Use `make firmware-update` only when you want to refresh the `micropython-steami` checkout itself or resync the board-specific submodules before rebuilding.
Use `make micropython-firmware` for normal rebuilds from the existing local clone. Use `make micropython-update` only when you want to refresh the `micropython-steami` checkout itself or resync the board-specific submodules before rebuilding.

All these tools are included in the dev container. For local development, see the [Prerequisites](#prerequisites) section.

Expand Down
57 changes: 42 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@ ci: lint test test-examples ## Run all CI checks (lint + tests + examples)
.PHONY: build
build: lint test ## Build (lint + test)

# --- Firmware ---
# --- MicroPython firmware ---

$(MPY_DIR):
@echo "Cloning micropython-steami into $(CURDIR)/$(MPY_DIR)..."
@mkdir -p $(dir $(CURDIR)/$(MPY_DIR))
git clone --branch $(MICROPYTHON_BRANCH) $(MICROPYTHON_REPO) $(CURDIR)/$(MPY_DIR)
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD) submodules

.PHONY: firmware
firmware: $(MPY_DIR) ## Build MicroPython firmware with current drivers
.PHONY: micropython-firmware
micropython-firmware: $(MPY_DIR) ## Build MicroPython firmware with current drivers
@set -e
@if [ ! -f "$(MPY_DIR)/lib/micropython-lib/README.md" ]; then \
echo "Initializing submodules for $(BOARD)..."; \
Expand All @@ -111,8 +111,8 @@ firmware: $(MPY_DIR) ## Build MicroPython firmware with current drivers
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD)
@echo "Firmware ready: $(STM32_DIR)/build-$(BOARD)/firmware.hex"

.PHONY: firmware-update
firmware-update: $(MPY_DIR) ## Update the MicroPython clone and board-specific submodules
.PHONY: micropython-update
micropython-update: $(MPY_DIR) ## Update the MicroPython clone and board-specific submodules
@set -e
@echo "Updating micropython-steami..."
rm -rf $(CURDIR)/$(MPY_DIR)/lib/micropython-steami-lib
Expand All @@ -123,21 +123,48 @@ firmware-update: $(MPY_DIR) ## Update the MicroPython clone and board-specific s
@echo "Updating required submodules for $(BOARD)..."
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD) submodules

.PHONY: deploy
deploy: deploy-pyocd ## Flash firmware (default: pyocd)
.PHONY: micropython-deploy
micropython-deploy: micropython-deploy-pyocd ## Flash MicroPython firmware (default: pyocd)

.PHONY: deploy-pyocd
deploy-pyocd: $(MPY_DIR) ## Flash firmware via pyOCD (CMSIS-DAP)
.PHONY: micropython-deploy-pyocd
micropython-deploy-pyocd: $(MPY_DIR) ## Flash MicroPython firmware via pyOCD (CMSIS-DAP)
$(PYTHON) -m pyocd flash $(STM32_DIR)/build-$(BOARD)/firmware.elf --format elf

.PHONY: deploy-openocd
deploy-openocd: $(MPY_DIR) ## Flash firmware via OpenOCD
.PHONY: micropython-deploy-openocd
micropython-deploy-openocd: $(MPY_DIR) ## Flash MicroPython firmware via OpenOCD
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD) deploy-openocd

.PHONY: deploy-usb
deploy-usb: $(MPY_DIR) ## Flash firmware via DAPLink USB mass-storage
.PHONY: micropython-deploy-usb
micropython-deploy-usb: $(MPY_DIR) ## Flash MicroPython firmware via DAPLink USB mass-storage
@$(PYTHON) scripts/deploy_usb.py $(STM32_DIR)/build-$(BOARD)/firmware.bin

# --- Deprecated targets (ambiguous since DAPLink build is also planned) ---
# Replaced by explicit micropython-* / daplink-* targets to avoid confusion
# about which firmware is being built or flashed.

define DEPRECATED_FIRMWARE
@echo "Error: 'make $(1)' is ambiguous. Use one of:"; \
echo " make micropython-$(2) (MicroPython firmware)"; \
echo " make daplink-$(2) (DAPLink firmware, see #377)"; \
exit 1
endef

.PHONY: firmware firmware-update firmware-clean deploy deploy-pyocd deploy-openocd deploy-usb
firmware:
$(call DEPRECATED_FIRMWARE,firmware,firmware)
firmware-update:
$(call DEPRECATED_FIRMWARE,firmware-update,update)
firmware-clean:
$(call DEPRECATED_FIRMWARE,firmware-clean,clean)
deploy:
$(call DEPRECATED_FIRMWARE,deploy,deploy)
deploy-pyocd:
$(call DEPRECATED_FIRMWARE,deploy-pyocd,deploy-pyocd)
deploy-openocd:
$(call DEPRECATED_FIRMWARE,deploy-openocd,deploy-openocd)
deploy-usb:
$(call DEPRECATED_FIRMWARE,deploy-usb,deploy-usb)

.PHONY: run
run: ## Run a script on the board with live output (SCRIPT=path/to/file.py)
@if [ -z "$(SCRIPT)" ]; then \
Expand All @@ -158,8 +185,8 @@ deploy-script: ## Deploy a script as main.py for autonomous execution (SCRIPT=pa
run-main: ## Re-execute main.py on the board and capture output
$(PYTHON) -m mpremote connect $(PORT) exec "exec(open('/flash/main.py').read())"

.PHONY: firmware-clean
firmware-clean: ## Clean firmware build artifacts
.PHONY: micropython-clean
micropython-clean: ## Clean MicroPython firmware build artifacts
@if [ -d "$(STM32_DIR)" ]; then \
$(MAKE) -C $(STM32_DIR) BOARD=$(BOARD) clean; \
fi
Expand Down
4 changes: 2 additions & 2 deletions lib/steami_config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Persistent configuration module for the STeaMi board.

Configuration data (board info, sensor calibration) is stored as compact JSON
in the STM32F103 internal flash config zone (1 KB) and survives firmware
updates and `clear_flash` operations.
in the STM32F103 internal flash config zone (1 KB) and survives MicroPython
firmware updates and `clear_flash` operations.

---

Expand Down
4 changes: 2 additions & 2 deletions lib/steami_config/examples/calibrate_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
config zone and survive power cycles.

Note: this example assumes the drivers are frozen into the firmware.
Use ``make firmware && make deploy`` to build a firmware with the
latest drivers before running this script.
Use ``make micropython-firmware && make micropython-deploy`` to build a
firmware with the latest drivers before running this script.
"""

from time import sleep_ms
Expand Down
2 changes: 1 addition & 1 deletion lib/wsen-hids/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,4 @@ The `examples/` directory provides practical scripts demonstrating how to use th
| `data_logger.py` | Log data every 5 seconds in CSV format (`timestamp, humidity, temperature`) for serial capture |
| `dew_point.py` | Compute and display dew point using temperature and humidity (Magnus formula) |
| `heater_demo.py` | Demonstrate the built-in heater: compare readings before and after enabling it |
| `low_power_sampling.py` | Low-power sampling: one-shot every 10 s with `power_off()` between reads. Requires firmware >= v0.1.0 (#238) |
| `low_power_sampling.py` | Low-power sampling: one-shot every 10 s with `power_off()` between reads. Requires MicroPython firmware >= v0.1.0 (#238) |
2 changes: 1 addition & 1 deletion scripts/deploy_usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def main():
firmware = sys.argv[1]
if not os.path.isfile(firmware):
print("Error: firmware binary not found: " + firmware, file=sys.stderr)
print("Run 'make firmware' first.", file=sys.stderr)
print("Run 'make micropython-firmware' first.", file=sys.stderr)
sys.exit(1)

mount = find_steami()
Expand Down
Loading