{"id":51029173,"url":"https://github.com/hardwario/jolt","last_synced_at":"2026-06-21T22:30:42.052Z","repository":{"id":365780823,"uuid":"1273724129","full_name":"hardwario/jolt","owner":"hardwario","description":"Tiny Rust CLI that flashes an STM32L083CZ over the UART bootloader","archived":false,"fork":false,"pushed_at":"2026-06-18T20:29:14.000Z","size":29,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T22:21:28.047Z","etag":null,"topics":["flasher","hardwario","rust","stm32","tower"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hardwario.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T20:09:21.000Z","updated_at":"2026-06-18T20:36:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hardwario/jolt","commit_stats":null,"previous_names":["hardwario/jolt"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/hardwario/jolt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardwario%2Fjolt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardwario%2Fjolt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardwario%2Fjolt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardwario%2Fjolt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hardwario","download_url":"https://codeload.github.com/hardwario/jolt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hardwario%2Fjolt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34628453,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-21T02:00:05.568Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flasher","hardwario","rust","stm32","tower"],"created_at":"2026-06-21T22:30:40.783Z","updated_at":"2026-06-21T22:30:42.047Z","avatar_url":"https://github.com/hardwario.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jolt — STM32L0 UART programmer\n\n[![CI](https://github.com/hardwario/jolt/actions/workflows/ci.yml/badge.svg)](https://github.com/hardwario/jolt/actions/workflows/ci.yml)\n\nA small, focused Rust CLI that programs **STM32L0** microcontrollers\n(STM32L0x1 / L0x2 / L0x3) over a serial port using the STM32 embedded **UART\nbootloader** (ST AN3155 protocol). It flashes, erases, reads device info, and\nincludes a serial monitor.\n\nAny board exposing the STM32L0 bootloader UART works. `jolt` can also enter the\nbootloader **automatically** — with no buttons — on boards whose USB-UART bridge\ndrives the MCU's NRST and BOOT0 pins, which is how it's been tested on the\n**HARDWARIO TOWER Radio Dongle** and **TOWER Core Module**. On other boards you\nmay need to enter the bootloader manually (see [How it works](#how-it-works)).\n\nFlash size is not assumed: a full-chip `erase` adapts to the connected part's\ndensity automatically, so the whole STM32L0 range (16–192 KiB) is supported.\n\n## Build\n\n```sh\ncargo build --release\n# binary at target/release/jolt\n```\n\nmacOS builds with a plain `cargo build` (the `serialport` crate pulls only\nIOKit deps, no libudev).\n\n## Usage\n\n```\njolt \u003cCOMMAND\u003e [OPTIONS]\n\nCommands:\n  list     List all serial ports\n  info     Read bootloader info (chip id, version, commands) — read-only\n  flash    Flash a raw firmware .bin file\n  erase    Erase the entire flash (adapts to the device's density)\n  reset    Reset the device into the application or the bootloader\n  monitor  Open the serial port and print incoming data (serial monitor)\n\nGlobal options:\n  -p, --port \u003cPATH\u003e   Serial port (default: the only port present, else required)\n  -v, --verbose       Verbose output (e.g. per-attempt bootloader-entry errors)\n```\n\nThe bootloader runs at **115200 baud, 8-E-1** — 115200 is the maximum baud rate\nST specifies for the USART bootloader.\n\n### Examples\n\n```sh\njolt list\njolt --port /dev/cu.usbserial-112140 info\njolt -p /dev/cu.usbserial-112140 flash firmware.bin\njolt -p /dev/cu.usbserial-112140 flash firmware.bin --no-verify   # skip read-back verify\njolt -p /dev/cu.usbserial-112140 flash firmware.bin --no-run      # leave in bootloader\njolt -p /dev/cu.usbserial-112140 flash firmware.bin --go          # start via Go, not reset\njolt -p /dev/cu.usbserial-112140 erase\njolt -p /dev/cu.usbserial-112140 reset --app                      # or --bootloader\njolt -p /dev/cu.usbserial-112140 monitor                          # 115200 8N1, Ctrl-C to exit\njolt -p /dev/cu.usbserial-112140 monitor -b 9600 --parity even    # 9600 8E1\njolt -p /dev/cu.usbserial-112140 monitor --reset                  # reset into app first, catch boot logs\njolt -p /dev/cu.usbserial-112140 monitor \u003e log.txt                # banner on stderr, device bytes only\n```\n\n`monitor` is read-only: it streams whatever the device sends to stdout until\nyou press Ctrl-C. The frame format defaults to **115200 8N1** (the application\nconsole; note this differs from the bootloader's 8-E-1) and is configurable via\n`-b/--baudrate`, `-d/--databits` (5–8), `--parity` (none/even/odd), and\n`-s/--stopbits` (1–2). Opening the port drives the bridge to the run state so\nthe application keeps running; `--reset` additionally pulses NRST into the\napplication so you catch its boot output.\n\n`flash` accepts a **raw `.bin`** only (written at `0x08000000`). Convert ELF/HEX\nfirst, e.g. `arm-none-eabi-objcopy -O binary firmware.elf firmware.bin`.\n\nIf exactly one serial port is present, `--port` may be omitted; otherwise pass\nit explicitly (use `jolt list` to find it).\n\n## How it works\n\nTo enter the bootloader automatically, `jolt` pulses NRST while raising BOOT0,\nin raw modem-line terms (`true` = line asserted):\n\n```\n(rts=T,dtr=T) → (rts=T,dtr=F) → (rts=F,dtr=T) → (rts=F,dtr=F) → send 0x7F\n```\n\n`(T,F)` asserts RESET; switching to `(F,T)` raises BOOT0 while the 1 µF cap on\nthe TOWER boards lets NRST ramp up slowly, so BOOT0 is high when the chip\nlatches it and boots system memory. This sequence is tuned for that auto-reset\ncircuit (FT231X driving NRST/BOOT0 through transistors). **On a board without\nit, pull BOOT0 high and reset the MCU yourself**, then run `jolt` — the protocol\nitself is hardware-independent.\n\nOnce in the bootloader, `jolt` speaks the standard ST protocol (init `0x7F`,\nACK `0x79`). `Get ID` reports the product id (e.g. `0x447` for STM32L0x3);\nany recognized STM32L0 id is accepted, and an unknown id only prints a warning.\nErase uses an explicit page list (the STM32L0 bootloader rejects the 0xFFFF\nmass-erase code); because the bootloader won't report the flash size, a\nfull-chip `erase` walks the page list up to the family maximum and stops as soon\nas the device NACKs an out-of-range page — i.e. once the part's flash is wiped.\n\n## Tests\n\n`cargo test` covers the protocol logic with no hardware: command/address/data\nchecksums and framing, the Get-ID reply parse, the Extended-Erase page list,\nwrite padding, and chunk/address bookkeeping.\n\n## License\n\nLicensed under the [MIT License](LICENSE) — © 2026 HARDWARIO a.s.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhardwario%2Fjolt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhardwario%2Fjolt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhardwario%2Fjolt/lists"}