Py32ProgrammerCli 0.1.1

dotnet tool install --global Py32ProgrammerCli --version 0.1.1
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Py32ProgrammerCli --version 0.1.1
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Py32ProgrammerCli&version=0.1.1
                    
nuke :add-package Py32ProgrammerCli --version 0.1.1
                    

PY32ProgrammerCLI

License: MIT Build and Test Latest release

A cross-platform, scriptable command-line tool for programming and inspecting Puya PY32 / MS32 series Cortex-M0 microcontrollers — a terminal-first complement to Puya's official PY32Programmer GUI, aimed at CI pipelines, production-line scripting, and anyone who'd rather not open a GUI to flash a chip.

Early-stage / actively evolving. Not affiliated with or endorsed by Puya Semiconductor Co., Ltd. "PY32" and "PY-Link" are trademarks of their respective owner; this is an independent, community-built tool.

Why

The official GUI tool is fine for one-off bench work, but it doesn't fit headless or automated workflows: no CI integration, no scripting, no composability with other command-line tooling. py32cli targets the same capabilities — flashing, erasing, verifying, reading back, option-byte management — through a modern, discoverable CLI with a rich terminal UI (progress bars, spinners, tables) instead of a window.

Every command follows a strict exit-code contract: 0 only on genuine success, non-zero on any failure (including a silently-rejected write that a naive tool might otherwise report as "done"). Whatever invokes py32cli — a CI job, a production-line script, another program — can trust the exit code alone to know whether the operation actually worked, without having to parse terminal output.

Status

Area Status
Device catalog (list/inspect 170+ PY32/MS32 part numbers) ✅ working
Serial port discovery ✅ working
UART/USB ISP bootloader (connect, erase, program, verify, read, option bytes, auto-remove RDP) ✅ working
PY-Link probe support (info, read, reset, erase, program, verify, option bytes, interactive console) ✅ working
Option bytes (read / decode / modify / write) — over both UART and PY-Link ✅ working
Intel HEX / raw binary input ✅ working
ELF input 🚧 planned
Optional SEGGER J-Link passthrough 🚧 planned (not started)

Supported devices

The bundled catalog covers the full published PY32/MS32 lineup. Note that not every part has a ROM UART bootloader — e.g. PY32F002B does not, and requires SWD-based programming (PY-Link probe or J-Link) instead of the UART/USB ISP path. Check a given part with py32cli devices show <part>.

Actually tested against real hardware so far: only PY32F040ER1BT7 (on a PY32F040R1xT_START_V2.0 board), over both the UART/USB ISP bootloader and PY-Link. Every other part in the catalog is supported per its published memory layout and flash algorithm, but hasn't been validated on real silicon yet. Contributions from anyone testing other PY32/MS32 parts — bug reports, fixes, or just a confirmation that a given part works — are very welcome.

Getting started

Self-contained single-file binary (no .NET runtime required)

The quickest way to get running: download the binary for your platform from the latest GitHub Release, verify it against the accompanying .sha256 file, and run it directly — no .NET runtime or install step needed. To build one yourself instead, see "Build from source" below.

As a .NET tool

py32cli already packs and installs as a real dotnet tool today — confirmed working end to end (dotnet pack, dotnet tool install --global, then running py32cli from an unrelated directory with no repo checkout in sight). Once published to NuGet.org, installing will just be:

dotnet tool install --global Py32ProgrammerCli
py32cli devices list

Until then, you can install it from a local build the same way:

dotnet pack src/PY32Programmer.Cli -c Release -o ./nupkg
dotnet tool install --global --add-source ./nupkg Py32ProgrammerCli
py32cli devices list

This install path requires the .NET 10 runtime to already be on the machine. pylink commands work too — the tool package bundles the official libusb-1.0.dll (win-x64) that LibUsbDotNet needs, right next to the tool itself, confirmed end to end (dotnet tool install --global from a clean machine state, then a real pylink read against hardware). See THIRD-PARTY-NOTICES.md for that binary's license/provenance. win-x86 and other platforms aren't bundled this way yet (a portable tool package can only carry one native binary per OS without collisions) — use a self-contained publish (below) for those.

Build from source

Requires the .NET 10 SDK or later.

git clone https://github.com/ivancmz/py32cli.git
cd py32cli
dotnet build

# Explore the bundled device catalog
dotnet run --project src/PY32Programmer.Cli -- devices list --filter PY32F002
dotnet run --project src/PY32Programmer.Cli -- devices show PY32F040x8

# List serial ports visible to the OS
dotnet run --project src/PY32Programmer.Cli -- ports list

dotnet run --project src/PY32Programmer.Cli -- --help

To build your own self-contained single-file binary instead (no .NET runtime required to run the result, though you still need the SDK to build it):

dotnet publish src/PY32Programmer.Cli -c Release -r win-x64 \
  --self-contained true -p:PublishSingleFile=true \
  -p:IncludeNativeLibrariesForSelfExtract=true \
  -p:PublishTrimmed=true -p:TrimMode=partial -o ./publish

Swap win-x64 for linux-x64, osx-arm64, etc.

Architecture

PY32ProgrammerCLI.sln
├── src/
│   ├── PY32Programmer.Core/   # Device database, transports, wire protocols — no UI concerns
│   └── PY32Programmer.Cli/    # System.CommandLine command tree + Spectre.Console rendering
└── tests/
    └── PY32Programmer.Core.Tests/

PY32Programmer.Core has no dependency on the CLI framework or on Spectre.Console, so the same protocol/device logic could back a different front end (a library, a GUI, a web service) later without rework.

Tech stack

  • .NET 10 — long-term-support runtime, genuinely cross-platform (win/linux/osx, x64/arm64), publishable as self-contained single-file binaries per platform.
  • System.CommandLine — command/subcommand parsing, --help generation, argument validation.
  • Spectre.Console — tables, panels, progress bars, spinners, and prompts for the terminal UI.
  • xUnit — unit tests for anything that doesn't require physical hardware (device catalog parsing today; protocol framing/encoding logic later).

Cross-platform expectations

Transport Platforms Notes
UART/USB ISP bootloader Windows, Linux, (macOS with caveats) Uses the standard System.IO.Ports serial API; macOS's serial backend is historically less reliable and will be validated explicitly before being called "supported".
PY-Link probe Windows, Linux, macOS (planned) Cross-platform USB access; Windows may require a WinUSB/libusbK driver swap for the probe depending on how it enumerates.
SEGGER J-Link passthrough Windows, Linux, macOS (planned, optional) Requires the user to have SEGGER's J-Link Software installed; that pack itself ships for all three platforms.

Contributing / license

Licensed under the MIT License.

There's no formal contribution process yet (no CONTRIBUTING.md, no issue/PR templates) — for now, just open an issue or PR on GitHub. The most valuable contribution right now is real-hardware testing: as noted under "Supported devices" above, only PY32F040ER1BT7 has actually been validated, so a bug report or even just a confirmation that a given part works on real silicon is genuinely useful. See CHANGELOG.md for what's landed so far and THIRD-PARTY-NOTICES.md for bundled third-party license attribution (the vendored libusb-1.0.dll, LGPL-2.1).

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.1.1 45 8/28/2026