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
254 lines
7.8 KiB
Markdown
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` |
|