3 Commits

Author SHA1 Message Date
ec0dfedc50 Add sub-symbol timing recovery to FrameSync
Implement precision timing recovery functions:
- _refine_symbol_boundary(): Scans at 1/32-symbol resolution to find
  exact chirp boundary by maximizing dechirped SNR
- _find_sfd_boundary(): FFT-based correlation with downchirp template
  to find exact data start position

Bug fixes:
- Fix _is_downchirp() false positives by comparing both correlations
- Fix _estimate_cfo() to return values in [0, N) range

The improved sync_from_samples() now produces bins identical to the
reference lora_decode_gpu decoder.
2026-02-05 14:25:20 -07:00
3660f139ec Add channelizer and fix FrameSync for real SDR captures
- Add Channelizer class for wideband capture processing (2 MHz → 125 kHz)
  - FIR low-pass filter with scipy.firwin (or fallback windowed-sinc)
  - Proper decimation for anti-aliasing
- Fix FrameSync preamble detection to accept any CFO
  - Real captures have significant carrier frequency offset
  - Preamble bins appear at arbitrary values, not just near 0
  - Now accepts any strong signal as first preamble, validates consistency
- Add decode_capture.py example script for processing raw BladeRF captures
- PHYDecode verified to match existing lora_phy decoder output
2026-02-05 14:00:17 -07:00
c839d225a8 Initial release: complete LoRa TX/RX for RYLR998 modems
GNU Radio Out-of-Tree module providing:
- Complete TX chain: PHYEncode → FrameGen → CSSMod
- Complete RX chain: CSSDemod → FrameSync → PHYDecode
- NETWORKID extraction/encoding (0-255 range)
- All SF (7-12) and CR (4/5-4/8) combinations
- Loopback tested with 24/24 configurations passing

Key features:
- Fractional SFD (2.25 downchirp) handling
- Gray encode/decode with proper inverse operations
- gr-lora_sdr compatible decode modes
- GRC block definitions and example flowgraphs
- Comprehensive documentation

Discovered RYLR998 sync word mapping:
  sync_bin_1 = (NETWORKID >> 4) * 8
  sync_bin_2 = (NETWORKID & 0x0F) * 8
2026-02-05 13:38:07 -07:00