diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9e6ccc6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,200 @@ +# CLAUDE.md + +This file provides guidance to Claude Code when working with gr-apollo. + +## Project Overview + +GNU Radio 3.10+ out-of-tree (OOT) module for decoding **Apollo Unified S-Band (USB)** telecommunications signals. Based on the 1965 NAA Telecommunication Systems Study Guide (Course A-624) and Virtual AGC project. + +**Target signals:** +- Downlink: 2287.5 MHz (spacecraft → ground) +- Uplink: 2106.40625 MHz (ground → spacecraft) +- Coherent ratio: 240/221 (Tx = Rx × 240/221) + +## Repository Structure + +``` +gr-apollo/ +├── src/apollo/ # GNU Radio Python blocks (src-layout) +│ ├── pm_demod.py # PM demodulator (0.133 rad peak) +│ ├── bpsk_subcarrier_demod.py # 1.024 MHz BPSK subcarrier +│ ├── pcm_frame_sync.py # 32-bit sync, 128-word frames +│ ├── pcm_demux.py # Frame demultiplexer +│ └── voice_subcarrier_demod.py # 1.25 MHz FM voice +├── grc/ # GRC block YAML definitions +├── docs/ # Reference documentation +├── examples/ # Example flowgraphs +├── pyproject.toml # Python package configuration +└── README.md +``` + +## Development Commands + +```bash +# Install in development mode +uv pip install -e . + +# Install GRC block definitions +cp grc/*.yml ~/.local/share/gnuradio/grc/blocks/ + +# Test with gr-mcp (if available) +# Use protocol analysis tools to generate decoder chain +``` + +## Signal Architecture + +### Downlink Signal Chain (2287.5 MHz) + +``` +RF Input → Carrier PLL → PM Demod → Subcarrier Separation + │ + ┌───────────────────────┼───────────────────────┐ + ↓ ↓ ↓ + 1.024 MHz BPSK 1.25 MHz FM Ranging + (PCM telemetry) (Voice) (PRN code) + ↓ ↓ + Symbol Sync FM Discriminator + ↓ ↓ + 51.2 kbps NRZ 300-3000 Hz audio + ↓ + Frame Sync (32-bit) + ↓ + 128-word demux +``` + +### Key Parameters + +| Parameter | Value | Notes | +|-----------|-------|-------| +| Downlink frequency | 2287.5 MHz | Coherent with uplink | +| PM peak deviation | 0.133 rad (7.6°) | Phase modulation | +| PCM subcarrier | 1.024 MHz | BPSK modulated | +| PCM bit rate | 51.2 kbps (high) / 1.6 kbps (low) | NRZ, MSB first | +| Voice subcarrier | 1.25 MHz | FM, ±29 kHz deviation | +| Frame length | 128 words × 8 bits | 50 fps high rate | +| Frame sync | 32-bit pattern | Complements on odd frames | +| Master clock | 512 kHz | All timing derived from this | + +### PCM Frame Structure + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Frame Sync (32 bits = 4 words) │ +│ [5-bit A][15-bit core][6-bit B][6-bit frame ID] │ +├─────────────────────────────────────────────────────────────┤ +│ Data Words 5-128 (124 words) │ +│ - High-level analog (0-5V, 8-bit) │ +│ - Low-level analog (0-40mV, 8-bit with ×125 gain) │ +│ - Digital parallel/serial inputs │ +│ - AGC downlink data (channels 34, 35, 57) │ +└─────────────────────────────────────────────────────────────┘ + +50 frames = 1 subframe (1 second at high rate) +``` + +### Subcarrier Oscillators (FM Mode) + +| SCO | Center Freq | Deviation | Use | +|-----|-------------|-----------|-----| +| 1 | 14,500 Hz | ±7.5% | Analog sensor | +| 2 | 22,000 Hz | ±7.5% | Analog sensor | +| 3 | 30,000 Hz | ±7.5% | Analog sensor | +| 4 | 40,000 Hz | ±7.5% | Analog sensor | +| 5 | 52,500 Hz | ±7.5% | Analog sensor | +| 6 | 70,000 Hz | ±7.5% | Analog sensor | +| 7 | 95,000 Hz | ±7.5% | Analog sensor | +| 8 | 125,000 Hz | ±7.5% | Analog sensor | +| 9 | 165,000 Hz | ±7.5% | Analog sensor | + +## GNU Radio Blocks to Implement + +### Phase 1: Core Demodulation +| Block | Type | I/O | Description | +|-------|------|-----|-------------| +| `pm_demod` | `gr.sync_block` | complex→float | PM demodulator with carrier recovery | +| `subcarrier_extract` | `gr.sync_block` | float→complex | Bandpass + downconvert subcarrier | +| `bpsk_demod` | `gr.sync_block` | complex→byte | BPSK demodulation with symbol sync | + +### Phase 2: PCM Processing +| Block | Type | I/O | Description | +|-------|------|-----|-------------| +| `pcm_frame_sync` | `gr.basic_block` | byte→PDU | 32-bit sync detection, frame extraction | +| `pcm_demux` | `gr.basic_block` | PDU→PDU | Demultiplex 128-word frames by word position | +| `downlink_decoder` | `gr.basic_block` | PDU→dict | Interpret AGC telemetry lists | + +### Phase 3: Voice & Analog +| Block | Type | I/O | Description | +|-------|------|-----|-------------| +| `fm_voice_demod` | `gr.sync_block` | complex→float | 1.25 MHz FM subcarrier → audio | +| `sco_demod` | `gr.sync_block` | float→float | FM SCO demodulator (configurable) | + +## Virtual AGC Integration + +The Virtual AGC emulator communicates via TCP socket (port 19697+): + +``` +4-byte packet format: +Byte 0: [Channel bits 8-4][0x00] +Byte 1: [0x40 | Channel bits 3-1][Value bits 14-12] +Byte 2: [0x80 | Value bits 11-6] +Byte 3: [0xC0 | Value bits 5-0] +``` + +Key telecom channels: +- **Ch 45 (INLINK)**: Uplink data input +- **Ch 57 (OUTLINK)**: Downlink data output +- **Ch 34/35 (DNTM1/2)**: Telemetry word stream + +## References + +- [Implementation Spec](../virtualagc/telecom_study_guide/IMPLEMENTATION_SPEC.md) +- [Virtual AGC Project](https://www.ibiblio.org/apollo/) +- [NASA Apollo USB Description](https://ntrs.nasa.gov/) +- [NAA Course A-624 Study Guide](https://archive.org/details/apollo-telecommunications) + +## Code Style + +- Python: Follow GNU Radio block patterns (numpy for DSP) +- Use gr-mcp protocol analysis tools for decoder chain generation +- Test blocks in Docker before integration + +## Docs Site Deployment + +Starlight documentation site in `docs/` subdirectory. + +- **Production**: https://gr-apollo.warehack.ing +- **Local dev**: Set `DOMAIN=gr-apollo.l.warehack.ing` in `docs/.env` +- **Git**: `git@git.supported.systems:warehack.ing/gr-apollo.git` +- **Server**: `ssh -A warehack-ing@warehack.ing`, repo at `~/gr-apollo` + +### Environment + +Copy `.env.example` to `.env` and set: + +```env +COMPOSE_PROJECT=gr-apollo-docs +DOMAIN=gr-apollo.warehack.ing +``` + +### Commands + +```bash +# From docs/ directory: +make up # Production — Caddy serves static dist/ +make dev # Development — Astro dev server with HMR +make down # Stop all containers +make logs # Tail container logs +``` + +### Deploy to Production + +```bash +# One-liner from local machine +ssh -A warehack-ing@warehack.ing "cd ~/gr-apollo && git pull && cd docs && make up" +``` + +### Notes + +- Uses Docker Compose profiles (`prod` / `dev`) +- Playwright + Chromium installed in build stage for mermaid diagram rendering +- caddy-docker-proxy on external `caddy` network handles TLS automatically