Oscaria Audio logo

KARON

Fail-safe A/B bootloader that receives firmware updates as audio. Encode, play, done -- no USB, no debug probe, no special tools. Just a WAV file and a 3.5 mm cable.

Fail-safe Audio transport Field-updatable

Specs

Built for resource-constrained MCUs with no floating-point hardware and no external oscillator.

Platform: STM32F030RC (Cortex-M0, 48 MHz)
Bootloader size: 16 KB
Slot layout: A/B, 118 KB each
Boot control: Dual-page wear-leveled log (CRC32 atomic commit)
Rollback: Automatic after 2 failed boots
Transport: 4-FSK over audio (3.5 mm jack)
Frequencies: 2400 / 3200 / 4000 / 4800 Hz
Symbol rate: 200 sym/s (2 bits/symbol)
Demodulation: Goertzel algorithm, Q7 fixed-point (integer-only)
Error handling: CRC16 per packet, 2x redundancy, LFSR scrambling
Clock recovery: Adaptive calibration + Bresenham remainder tracking
FPU: None (pure integer math)

What it does

KARON turns an existing audio input into a firmware update channel. The user holds a button during power-on, plays a WAV file from any device, and waits for the LED to confirm. If anything goes wrong -- cable pulled, power loss, corrupted file -- the module reboots into the previous working firmware. It cannot brick.


How it works

A/B slot design

Active firmware lives in one slot, the incoming update goes into the other. The bootloader only switches after the full image is received, verified and committed. At no point are both slots in an inconsistent state.

Flash
Slot size: 118 KB each
Commit: CRC32 written last (atomic)
Rollback: Try counter, 2 attempts before fallback
Confirmation: App must call confirm after stable boot

4-FSK audio transport

Firmware is encoded as four audio tones. Each tone carries two bits. No amplitude or phase measurement needed -- just which frequency has the most energy. Works through uncalibrated analog front-ends and cheap phone DACs.

Signal
Tones: 2400 / 3200 / 4000 / 4800 Hz
Spacing: 800 Hz (4x symbol rate, orthogonal)
Detection: Goertzel filter, Q7 fixed-point
Guard band: 30 samples/side (absorbs clock drift)

Clock drift compensation

The transmitter and receiver clocks are never synchronized. KARON measures the drift during a calibration preamble and continuously corrects it using a Bresenham-style accumulator that distributes fractional corrections evenly across the stream.

Timing
Calibration: 200-symbol preamble, cross-buffer boundary sweep
Correction: Per-symbol skip/insert via accumulator
Remainder: Bresenham tracking (error bounded to <1 sample)
Tolerance: Handles internal oscillators off by 1%+

Error recovery

Every packet is CRC-checked and sent twice. An LFSR scrambler breaks up repetitive byte patterns in the firmware image that would otherwise degrade detection reliability. Packet gaps prevent cascade failures from propagating across the stream.

Integrity
Packet CRC: CRC16
Image CRC: CRC32/MPEG-2
Redundancy: Each packet sent 2x
Scrambling: 16-bit LFSR (self-inverse)
Anti-cascade: Inter-packet gaps absorb overreads

Lab notes

The full engineering story -- why audio, how the Goertzel filter works, what went wrong, and how every design decision connects back to the constraint of building a bootloader over the worst possible transport.

Read the KARON lab notes →


© Oscaria Audio. Berlin, Germany.