CLAUDE.md 3.8 KB

CLAUDE.md

Context for any Claude Code session working in this repo.

What this is

An ESP-IDF firmware project putting a Dante-interoperable audio-over-IP endpoint on the ESP32-P4. Phase 1 is AES67 interop; native Dante protocol support is a phase 2 stretch goal. Full background/rationale is in README.md — read that first if you haven't.

Hard rule: licensing boundary (read this before touching Dante protocol work)

This repo is Apache-2.0. It forks components/aes67 from DatanoiseTV/aes67-esp32p4 (also Apache-2.0). That's fine to build on directly.

reference/inferno (teodly/inferno) is GPL-3.0-or-later / AGPL-3.0-or-later and is present locally for reading only — it is not part of this repo and must never be copied into it.

  • Never copy, translate, or closely paraphrase code from reference/inferno into any file in this repo.
  • It's fine to read inferno_aoip to understand what Dante devices do on the wire (message shapes, mDNS service records, control flow) — but the resulting implementation here must be written independently, from that understanding, not from their source.
  • Write protocol understanding as plain-English behavioural notes in docs/dante-protocol-notes.md (what the protocol does), not as annotated/translated code (how their code does it).
  • If a task would involve porting or closely mirroring a specific inferno_aoip file, stop and flag it instead of proceeding — don't make that judgment call silently.

Repo layout

components/aes67/   AES67 engine, forked from aes67-esp32p4 (PTP, RTP, I2S, SAP/SDP, mDNS)
main/                App entry point, board/pin config
docs/                Design notes, incl. dante-protocol-notes.md
reference/           Local clones of both source repos — read-only, gitignored
  aes67-esp32p4/     Fork basis
  inferno/           Dante protocol reference — see licensing rule above

Build & flash

Requires ESP-IDF v5.5+.

idf.py set-target esp32p4
idf.py build
idf.py flash monitor

Target hardware (confirm before relying on this)

Reference pinout is DatanoiseTV's ESP32-P4-NANO board config — Ethernet via IP101 GRI PHY (RMII), I2S out via APLL-clocked codec (ES8311 onboard), full pin table in README.md. If the actual target board differs, update main/main.c pin config and the README table together.

Known hard problems

  • PTPv1: Dante needs it; the forked AES67 stack's PTP code (components/aes67/third_party/ptpd, aes67_ptp.c, aes67_hw_timer.c) targets PTPv2 against the P4's hardware timestamp path. Scope of adding v1 isn't assessed yet.
  • Dante's control protocol (routing/subscription — Inferno calls this ARC/CMC) is undocumented and proprietary. The only way to understand it is reading Inferno's protocol handling, read-only, per the licensing rule above — there's no spec to implement against.
  • No multi-process model on FreeRTOS/ESP-IDF: Inferno's Linux design relies on its PTP daemon (Statime) running as a separate OS process communicating over a socket/clock device. There's no equivalent process boundary here — any PTPv1 work has to live inside the single firmware image, most likely inside the existing aes67_ptp task structure rather than as a separate cooperating component.

Conventions

Match the existing aes67-esp67p4 component style:

  • -O2, hot-path conversion/ISR functions placed in IRAM
  • Tasks pinned to core 0 for cache coherency
  • ISR-driven DMA playback where possible, avoid task-scheduling on the audio hot path
  • Quiet logging by default (errors + first PTP lock only)

Useful links