gr-rylr998/docs/BLOCK_REFERENCE.md
Ryan Malloy 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

254 lines
7.8 KiB
Markdown

# gr-rylr998 Block Reference
## Overview
gr-rylr998 provides GNU Radio blocks for complete LoRa TX/RX chains compatible with RYLR998 modems.
## Block Categories
### Modulation/Demodulation
#### CSS Demodulator (`rylr998_css_demod`)
FFT-based Chirp Spread Spectrum demodulator.
**Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| sf | int | 9 | Spreading factor (7-12) |
| sample_rate | float | 250e3 | Input sample rate (Hz) |
| bw | float | 125e3 | Signal bandwidth (Hz) |
**Input:** Complex IQ stream
**Output:** Integer bin values (0 to 2^SF - 1)
#### CSS Modulator (`rylr998_css_mod`)
Chirp generator from bin values.
**Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| sf | int | 9 | Spreading factor (7-12) |
| sample_rate | float | 125e3 | Output sample rate (Hz) |
| bw | float | 125e3 | Signal bandwidth (Hz) |
**Input:** Integer bin values
**Output:** Complex IQ stream
---
### PHY Layer
#### PHY Decoder (`rylr998_phy_decode`)
Complete RX PHY chain: Gray → Deinterleave → Hamming FEC → Dewhiten → CRC.
**Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| sf | int | 9 | Spreading factor (7-12) |
| cr | int | 1 | Coding rate (1=4/5, 2=4/6, 3=4/7, 4=4/8) |
| has_crc | bool | True | CRC enabled |
| ldro | bool | False | Low Data Rate Optimization |
| implicit_header | bool | False | Implicit header mode |
| payload_len | int | 0 | Expected payload length (implicit mode) |
**Decode Method Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| use_grlora_gray | bool | True | Use gr-lora_sdr Gray mapping (for real SDR captures) |
| soft_decoding | bool | False | Skip -1 bin offset (use True for loopback testing) |
**Input:** Symbol bin values (from Frame Sync)
**Output:** Decoded payload bytes, frame metadata
**Usage Notes:**
- For **real SDR captures** (gr-lora_sdr compatible): `use_grlora_gray=True, soft_decoding=False` (defaults)
- For **loopback testing** with gr-rylr998 TX: `use_grlora_gray=False, soft_decoding=True`
#### PHY Encoder (`rylr998_phy_encode`)
Complete TX PHY chain: CRC → Whiten → Hamming FEC → Interleave → Gray.
**Parameters:** Same as PHY Decoder (minus `payload_len`)
**Input:** Raw payload bytes
**Output:** Encoded symbol bin values
---
### Framing
#### Frame Sync (`rylr998_frame_sync`)
Preamble detection, sync word extraction, symbol alignment.
**Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| sf | int | 9 | Spreading factor |
| sample_rate | float | 250e3 | Sample rate (Hz) |
| expected_networkid | int | -1 | Filter by NETWORKID (-1 = any) |
| preamble_min | int | 4 | Minimum preamble symbols |
**Input:** Complex IQ stream
**Output:** Aligned data symbols, NETWORKID
**Note:** Detects preamble upchirps, extracts NETWORKID from sync word, identifies SFD downchirps, and outputs aligned data symbols.
#### Frame Generator (`rylr998_frame_gen`)
Generates complete frame: Preamble + Sync Word + SFD + Data.
**Parameters:**
| Name | Type | Default | Description |
|------|------|---------|-------------|
| sf | int | 9 | Spreading factor |
| sample_rate | float | 125e3 | Sample rate (Hz) |
| preamble_len | int | 8 | Preamble length (symbols) |
| networkid | int | 18 | RYLR998 NETWORKID (0-255) |
**Input:** Encoded data symbol bins
**Output:** Complete IQ frame samples
---
### Hierarchical Blocks
#### RYLR998 Receiver (`rylr998_rx`)
Complete RX chain in one block.
**Chain:** IQ Source → CSS Demod → Frame Sync → PHY Decode → Payload
**Parameters:** Combines CSS Demod, Frame Sync, and PHY Decode parameters.
#### RYLR998 Transmitter (`rylr998_tx`)
Complete TX chain in one block.
**Chain:** Payload → PHY Encode → Frame Gen → CSS Mod → IQ Output
**Parameters:** Combines PHY Encode, Frame Gen, and CSS Mod parameters.
---
## Signal Flow
### RX Chain
```
IQ Samples
┌─────────────────┐
│ CSS Demod │ FFT peak detection
└────────┬────────┘
↓ bins
┌─────────────────┐
│ Frame Sync │ Preamble detect, NETWORKID extract
└────────┬────────┘
↓ aligned symbols
┌─────────────────┐
│ PHY Decode │ Gray → Deinter → Hamming → Dewhiten
└────────┬────────┘
Payload Bytes
```
### TX Chain
```
Payload Bytes
┌─────────────────┐
│ PHY Encode │ CRC → Whiten → Hamming → Inter → Gray
└────────┬────────┘
↓ symbol bins
┌─────────────────┐
│ Frame Gen │ Add preamble, sync word, SFD
└────────┬────────┘
↓ all bins
┌─────────────────┐
│ CSS Mod │ Generate chirps
└────────┬────────┘
IQ Samples
```
---
## Common Parameters
### Spreading Factor (SF)
| SF | Chips/Symbol | Data Rate | Sensitivity | Range |
|----|--------------|-----------|-------------|-------|
| 7 | 128 | Highest | Lowest | Shortest |
| 8 | 256 | ↓ | ↓ | ↓ |
| 9 | 512 | (default) | (typical) | (typical) |
| 10 | 1024 | ↓ | ↓ | ↓ |
| 11 | 2048 | ↓ | ↓ | ↓ |
| 12 | 4096 | Lowest | Highest | Longest |
### Coding Rate (CR)
| CR Value | Rate | Redundancy | Error Correction |
|----------|------|------------|------------------|
| 1 | 4/5 | 25% | Low |
| 2 | 4/6 | 50% | Medium |
| 3 | 4/7 | 75% | Good |
| 4 | 4/8 | 100% | Best |
### NETWORKID / Sync Word
The RYLR998 NETWORKID (0-255) maps directly to the LoRa sync word byte. See `NETWORKID_MAPPING.md` for details.
Common values:
- **18** (0x12): Private networks, RYLR998 default
- **52** (0x34): LoRaWAN public networks
---
## Implementation Notes
### Fractional SFD Handling
The LoRa SFD (Start Frame Delimiter) is **2.25 downchirps**, not an integer. This means data symbols start at a fractional sample offset.
The `FrameSync` block handles this by:
1. Counting 2 full downchirps in the state machine
2. Adding a 0.25 symbol offset when extracting data
If you see data symbols offset by 1-2 positions, check that fractional SFD handling is correct.
### Gray Coding
LoRa uses Gray coding to minimize bit errors when adjacent symbols are confused.
- **TX (encode):** `g = b ^ (b >> 1)` — converts binary to Gray
- **RX (decode):** Iterative XOR unwinding — converts Gray back to binary
The decoder's `use_grlora_gray` parameter controls which direction:
- `True`: Applies `x ^ (x >> 1)` (same as TX encode) — use for gr-lora_sdr captures
- `False`: Applies iterative Gray decode (inverse) — use for loopback testing
### Bin Offset Convention
Different receiver implementations use different bin conventions:
| Source | Bin Convention | Decoder Setting |
|--------|----------------|-----------------|
| gr-lora_sdr | Raw bins + 1 | `soft_decoding=False` (default) |
| gr-rylr998 loopback | Raw bins | `soft_decoding=True` |
### Troubleshooting
| Symptom | Likely Cause | Solution |
|---------|--------------|----------|
| Data symbols offset by 1-2 | Fractional SFD not handled | Check FrameSync version |
| Payload garbage, CRC fails | Wrong Gray mode | Toggle `use_grlora_gray` |
| Payload off by 1 symbol | Wrong bin offset | Toggle `soft_decoding` |
| NETWORKID wrong | CFO not subtracted | Check `cfo_bin` parameter |
| Preamble not detected | Threshold too high | Lower `preamble_min` |