====== PineBuds Pro — ANC Analysis & Open Firmware ======
Factory firmware ANC coefficients extracted and integrated into OpenPineBuds (2026-04-08).
===== Hardware =====
* **SoC:** BES2300YP (dual Cortex-M4F @ 300MHz)
* **ANC:** Hardware-accelerated in codec silicon (not software DSP)
* **Paths:** Feedforward (FF), Feedback (FB), Talk-Through (TT), Music Cancel (MC)
* **Flashing:** USB-UART via charging case (WCH CH342, vendor 1a86)
* **Tool:** bestool (Ralim, Rust) — ''cargo install --git https://github.com/Ralim/bestool''
===== Flash Layout (4 MB) =====
^ Region ^ Address ^ Size ^ Content ^
| Bootloader | 0x000000-0x014000 | 80 KB | BES boot ROM, identical L/R |
| Gap | 0x014000-0x018000 | 16 KB | Erased |
| Firmware | 0x018000-0x140000 | 1184 KB | Main firmware, identical L/R, matches factory AC08 |
| Unused | 0x140000-0x3EC000 | 2736 KB | Fully erased |
| NV Records | 0x3EC000-0x3FE000 | 72 KB | BT pairing, config, 116 bytes differ L/R |
| Erased | 0x3FE000-0x3FF000 | 4 KB | |
| Factory Cal | 0x3FF000-0x400000 | 4 KB | "PineBuds Pro" string, BT MAC, 17 bytes differ L/R |
===== ANC Audio Section (0x3EE000) =====
Stored in flash at 0x3EE000. Header: magic=0xDAD1, version=1.
**Extracted ANC Coefficients (factory firmware):**
^ Path ^ Gain (48k) ^ Gain (44.1k) ^ Biquads ^ Status ^
| Feedforward L | 512 | 660 | 8 | Active — full IIR chain |
| Feedforward R | 0 | 0 | 1 (unity) | Passthrough |
| Feedback L | 512 | 512 | 6 | Active — full IIR chain |
| Feedback R | 0 | 0 | 1 (unity) | Passthrough |
| Talk-Through | 0 | 0 | 1 (bypass=1) | Passthrough |
| Music Cancel | 0 | 0 | 0 | Not used |
**Key findings:**
* **L = R identical** — zero per-unit calibration from factory
* **Mono ANC** — only left channel has real filters, right is passthrough
* **ADC gain offset: -6 dB** on all active paths (prevents mic clipping)
* **44.1 kHz FF gain is 660 vs 512 at 48 kHz** — compensates for different spectral resolution
* IIR coefficients are Q27 format (unity = 134217728 = 0x8000000)
===== Community ANC Status (as of 2026-04) =====
* OpenPineBuds main branch: ANC listed as "non-functional, WIP"
* ''anc-testing'' branch (2023): one tester got "pretty good" results with tuned gains
* Merge blocked by CMake migration that never happened
* ''anc-tuning'' branch: last commit Jan 2026, no merge
* **Root cause of bad ANC:** empty coefficient arrays in open firmware
* **Our fix:** extracted factory coefficients, integrated into ''config/open_source/tgt_hardware.c''
===== Tools =====
=== anc_extract.py ===
Extracts ANC IIR coefficients from a bestool flash dump:
# Human-readable summary
python3 anc_extract.py backup_left.bin
# C header for OpenPineBuds integration
python3 anc_extract.py backup_left.bin --c-header > anc_coefs.h
Located in ''dev_tools/anc_extract.py'' in our OpenPineBuds fork.
=== bestool ===
# Backup firmware (CRITICAL — do this first!)
bestool read-image --port /dev/ttyACM0 backup_right.bin
bestool read-image --port /dev/ttyACM1 backup_left.bin
# Flash new firmware
bestool write-image out/open_source/open_source.bin --port /dev/ttyACM0
# Serial monitor (2 Mbaud)
bestool serial-monitor /dev/ttyACM0 --baud-rate 2000000
===== Repos =====
* Our fork: [[https://git.reauktion.de/marfrit/openpinebuds|marfrit/openpinebuds]] (with factory ANC coefficients)
* Upstream: [[https://github.com/pine64/OpenPineBuds|pine64/OpenPineBuds]]
* Flash tool: [[https://github.com/Ralim/bestool|Ralim/bestool]]
* Factory firmware: [[https://files.pine64.org/os/PineBudsPro/AC08_20221102.bin]]
===== Build Environment =====
VM 120 ''pinebuds'' on data (192.168.88.44):
* Debian 11, 4 cores, 4 GB RAM, 64 GB ZFS
* ARM GCC 9-2019-q4-major at ''~/gcc-arm-none-eabi-9-2019-q4-major/''
* bestool (Ralim) via cargo
* Docker available but native build preferred (12 sec)
* SPICE USB passthrough for CH342 charging case (vendor 1a86)
* lmcp on port 8080
export PATH="$HOME/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH"
cd ~/OpenPineBuds
make -j4 T=open_source DEBUG=1
# Output: out/open_source/open_source.bin (883 KB)
===== Backups =====
Factory flash dumps stored on: hertz, data, boltzmann, pinebuds VM.
* ''backup_left.bin'' — md5: 05c0200d73e99633d41d8e757dfc4d6c
* ''backup_right.bin'' — md5: 0cf360d3a92fcddb39c3f9bf53f3b9fc
* ''factory_AC08.bin'' — md5: 4d2810bdb6fc32ccea3a034538b3fbf7 (Pine64 download, code only)
===== Status =====
**Phase:** Firmware built with factory ANC coefficients. Awaiting flash test on actual hardware.