gr-apollo/grc/apollo_pcm_frame_sync.block.yml
Ryan Malloy 0ee7ff0ad7 Implement full Apollo USB downlink decoder chain
Complete signal processing pipeline from complex baseband to decoded
PCM telemetry, verified against the 1965 NAA Study Guide (A-624):

Core demod (Phase 1):
  - PM demodulator with carrier PLL recovery
  - 1.024 MHz subcarrier extractor (bandpass + downconvert)
  - BPSK demodulator with Costas loop + symbol sync
  - Convenience hier_block2 combining subcarrier + BPSK

PCM frame processing (Phase 2):
  - 32-bit frame sync with Hamming distance correlator
  - SEARCH/VERIFY/LOCKED state machine, complement-on-odd handling
  - Frame demultiplexer (128-word, A/D voltage scaling)
  - AGC downlink decoder (15-bit word reassembly from DNTM1/DNTM2)

Voice and analog (Phase 3):
  - 1.25 MHz FM voice subcarrier demod to 8 kHz audio
  - SCO demodulator for 9 analog sensor channels (14.5-165 kHz)

Virtual AGC integration (Phase 4):
  - TCP bridge client with auto-reconnect and channel filtering
  - DSKY uplink encoder (VERB/NOUN/DATA command sequences)

Top-level receiver (Phase 5):
  - usb_downlink_receiver hier_block2: one block, complex in, PDUs out
  - 14 GRC block YAML definitions for GNU Radio Companion
  - Example scripts for signal analysis and full-chain demo

Infrastructure:
  - constants.py with all timing/frequency/frame parameters
  - protocol.py for sync word + AGC packet encode/decode
  - Synthetic USB signal generator for testing
  - 222 tests passing, ruff lint clean
2026-02-20 13:18:42 -07:00

59 lines
1.5 KiB
YAML

id: apollo_pcm_frame_sync
label: Apollo PCM Frame Sync
category: '[Apollo USB]'
flags: [python]
parameters:
- id: bit_rate
label: Bit Rate (bps)
dtype: int
default: '51200'
options: ['51200', '1600']
option_labels: ['High (51.2 kbps)', 'Low (1.6 kbps)']
- id: max_bit_errors
label: Max Sync Bit Errors
dtype: int
default: '3'
inputs:
- label: in
domain: stream
dtype: byte
outputs:
- label: frames
domain: message
templates:
imports: from apollo import pcm_frame_sync
make: >-
apollo.pcm_frame_sync.pcm_frame_sync(
bit_rate=${bit_rate},
max_bit_errors=${max_bit_errors})
documentation: |-
Apollo PCM Frame Synchronizer
Acquires the 32-bit frame sync pattern from an NRZ bit stream and
outputs complete PCM frames as PDU messages.
The sync word format is:
[5-bit A][15-bit core][6-bit B][6-bit frame ID]
The 15-bit core is complemented on odd-numbered frames. The correlator
checks against both patterns simultaneously using Hamming distance.
State machine: SEARCH -> VERIFY -> LOCKED (back to SEARCH on N misses).
Parameters:
bit_rate: 51200 (128 words/frame, 50 fps) or 1600 (200 words/frame, 1 fps)
max_bit_errors: Hamming distance threshold for sync detection (default 3)
Output PDU metadata:
frame_id: Frame number within subframe (1-50)
odd_frame: True if odd frame (complemented core)
sync_confidence: Number of correct sync bits (out of 32)
timestamp: System time at frame detection
file_format: 1