Add README
This commit is contained in:
123
README.md
Normal file
123
README.md
Normal file
@@ -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 <repo-url> 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 |
|
||||
Reference in New Issue
Block a user