From a3464e05bda62c2034236c7e2b25308f14c932ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Cie=C5=9Blik?= Date: Thu, 21 May 2026 19:59:55 +0200 Subject: [PATCH] Add README --- README.md | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc0fa32 --- /dev/null +++ b/README.md @@ -0,0 +1,123 @@ +# ptt-fhss + +Bare-metal PTT (Push-to-Talk) firmware for the **Seeed XIAO BLE (nRF52840)** with +frequency-hopping spread spectrum (FHSS) on the 2.4 GHz band. + +Designed to be low-power, hard to detect, and built with a fully open toolchain — +no Zephyr, no Nordic SDK, no SoftDevice. + +## Hardware + +| Component | Part | +|-----------|------| +| Target | Seeed XIAO BLE (nRF52840) | +| Programmer | RP2040 running DAPLink | + +## How it works + +### FHSS + +The radio hops across 40 channels (2402–2480 MHz, 2 MHz steps) every 2 ms. +The hopping sequence is generated by AES-128-ECB keyed with a shared secret — +both devices derive identical sequences independently without any synchronisation +traffic. To an observer with an SDR the transmissions appear as short, scattered +impulses with no identifiable pattern. + +### Low power + +The nRF52840 stays in SYSTEM_ON sleep (`WFI`) with the DC/DC converter active +(~1.5 µA quiescent). A GPIOTE edge event on the PTT button wakes the CPU; +the radio is active only during the burst. + +### Register access + +All hardware register writes use typed bitfield unions defined in `include/regs.h` +rather than raw bit-shift expressions. The union layout is guaranteed correct with +`arm-none-eabi-gcc` (LSB-first bitfields on Cortex-M). + +## Toolchain + +Everything that produces the binary runs inside a container. The host only needs +tools that talk to hardware (pyocd) or manage the build (just). + +| Tool | Purpose | Install | +|------|---------|---------| +| podman or docker | Container runtime | distro package | +| just | Task runner | `cargo install just` or distro package | +| pyocd | Flash / debug via DAPLink | `pip install pyocd` | +| git | Source control + submodules | distro package | + +Inside the container: `debian:bookworm-slim` + `gcc-arm-none-eabi` from apt + +`cmake` + `ninja`. + +## Quick start + +```sh +git clone ptt +cd ptt +git submodule update --init --depth=1 + +just build # build firmware.hex inside container +just flash # flash via DAPLink (host pyocd) +``` + +On first run `just build` pulls the container image and compiles. Subsequent +builds reuse the cached image and only recompile changed files. + +## Tasks + +``` +just build compile firmware inside the container +just flash build + flash via DAPLink +just gdbserver start pyocd GDB server on port 3333 +just clean remove build/ +just clean-all remove build/ and the container image +``` + +## Project structure + +``` +. +├── Dockerfile container image (debian + arm-gcc from apt) +├── justfile build / flash / debug tasks +├── CMakeLists.txt +├── cmake/ +│ └── arm-none-eabi.cmake CMake toolchain file +├── link/ +│ └── nrf52840.ld linker script (no SoftDevice, Flash @ 0x00000000) +├── include/ +│ ├── regs.h hardware register bitfield unions +│ ├── radio.h +│ ├── fhss.h +│ └── power.h +├── src/ +│ ├── startup.c vector table (64 entries) + Reset_Handler +│ ├── main.c +│ ├── radio.c RADIO peripheral driver (stub) +│ ├── fhss.c AES-ECB hopping sequence generator +│ └── power.c DC/DC, GPIOTE wakeup, WFI sleep +└── vendor/ + ├── nrfx/ Nordic HAL headers, pinned to v2.9.0 (includes mdk/) + ├── CMSIS_5/ ARM core headers (core_cm4.h etc.) + └── tiny-aes-c/ Public domain AES-128 implementation +``` + +## Before first flash + +The XIAO BLE ships with a SoftDevice which occupies the start of Flash. +Erase it before flashing bare-metal firmware: + +```sh +pyocd erase --target nrf52840 --chip +``` + +## Status + +| Module | State | +|--------|-------| +| Startup / vector table | done | +| Linker script | done | +| Power management (sleep + wakeup) | done | +| FHSS sequence generator | done | +| RADIO driver | stub — TX loop not yet implemented | +| Sync protocol | not started |