# 物理层详解 本文详细解释 SparkLink SLE 物理层的设计与实现, 覆盖调制波形、帧结构、信道编码和收发流水线, 逐一对标 TXS-10002-2025 标准条款并说明代码中的实现方式。 ## 调制方式 SLE 物理层支持两大类调制: 频移键控 (GFSK) 和相移键控 (PSK), 分别用于不同帧类型。 ### GFSK 调制 (§6.2.1.1) 高斯频移键控是 FT1 帧的唯一调制方式。标准规定: - 高斯滤波器带宽时间积 BT = 0.5 - 调制系数 h 在 0.45 至 0.55 范围内, 默认 0.5 - 比特 1 对应正频偏, 比特 0 对应负频偏 SLE 定义了 7 种带宽配置, 从 0.1 MHz 到 4 MHz: | 带宽 | 符号周期 | 最小频偏 | |------|----------|----------| | 0.1 MHz | 10 $\mu$s | 23.125 kHz | | 0.25 MHz | 4 $\mu$s | 92.5 kHz | | 1.0 MHz | 1 $\mu$s | 185 kHz | | 2.0 MHz | 0.5 $\mu$s | 370 kHz | | 4.0 MHz | 0.25 $\mu$s | 740 kHz | **代码实现**: `phy.gfsk.GFSKModulator` 类。调制过程为 NRZ 映射 → 上采样 → 高斯滤波 → 频率积分 → 复基带: $$ s(t) = \exp\!\left(j \cdot 2\pi h \int_0^t \sum_k a_k \cdot g(\tau - kT)\,d\tau\right) $$ 解调采用非相干的频率鉴别器方案 (`GFSKDemodulator`), 通过相邻采样点的相位差提取瞬时频率。 ### PSK 调制 (§6.2.1.2) FT2-FT4 帧使用相移键控, 支持三种调制阶数: **BPSK** (每符号 1 bit): - 比特 0 → 相位 90°, 比特 1 → 相位 -90° - 偶数位符号额外顺时针旋转 90° **QPSK** (每符号 2 bit): - 00→45°, 01→135°, 11→-135°, 10→-45° - 偶数位额外 -45° 旋转 **8PSK** (每符号 3 bit): - Gray 编码, 22.5° 间隔 - 偶数位额外 -22.5° 旋转 "偶数位"的定义: 无线帧的第一个符号处于奇数位 (索引 0 = 奇), 索引 1 = 偶, 以此类推。这一额外旋转有助于改善时钟恢复性能。 脉冲成型使用平方根升余弦 (RRC) 滤波器, 滚降系数 $\beta = 0.4$, 每符号采样数默认 4。收发两端各一个 RRC 滤波器, 级联后满足 Nyquist 无码间干扰准则。 **代码实现**: `phy.psk.PSKModulator` 类。星座映射定义在 `BPSK_MAP`, `QPSK_MAP`, `_8PSK_MAP` 等常量中。导频符号共用同一相位查找表, 由 `phy.pilot` 模块生成。 此外还有一种**无旋转 BPSK** 映射 (0→0°, 1→180°), 用于同步信号 3/4 中的 m 序列调制, 不参与偶数位旋转。 ### 多音信号 (§6.2.1.3) 多音信号由 N 个单音叠加: $$ S(t) = \sum_{i=0}^{N-1} A_i \cdot e^{j(\omega_i t + \phi_i)} $$ 主要用于射频校准和测量场景。`phy.multitone` 模块实现了可配置音数、幅度和初始相位的多音信号生成。 ### UWB 脉冲 (§6.2.1.4) 超宽带脉冲信号采用 Kaiser 窗参考波形 ($\beta = 10$), 支持两种带宽: | 信号带宽 | 脉冲宽度 $T_p$ | 窗口 $T_w$ | |----------|----------------|------------| | $\geq$ 500 MHz | 2 ns | 0.5 ns | | $>$ 1300 MHz | 0.75 ns | 0.2 ns | 码片调制 $c(n) \in \{-1, 0, +1\}$, 最大脉冲重复频率 499.2 MHz。 **代码实现**: `phy.uwb_pulse` 模块, 提供参考脉冲生成、码片调制和互相关验证。 ## 帧结构 (§6.3) ### 无线帧的组成 每个物理帧由帧头和数据两部分构成: ```text ┌─────────── 帧头 ───────────┐┌───── 数据 ──────┐ │ 前导码 │ 同步序列 │ 控制信息 │ 载荷数据 │ CRC │ └───────┴─────────┴─────────┘└─────────┴───────┘ ``` 各帧类型的差异集中在帧头的编码和调制方式上: ### FT1 — 广播帧 (§6.3.2) - **前导码**: GFSK, [0,1] 交替, 10 $\mu$s - **同步序列**: sync_signal_1, 32 位→32 个 GFSK 符号 - **控制信息**: A 组, 无 Polar 编码, GFSK 调制 - **载荷**: 不经 Polar 编码, 直接 GFSK 调制 - **典型用途**: 广播、发现、接入请求/响应 FT1 是最轻量的帧类型, 没有前向纠错编码开销。控制信息头部用 BCH 码保护, CRC 种子由同步序列低位确定。 ### FT2 — 短头数据帧 (§6.3.3) - **前导码**: PSK, [$\pi/4$, 0] 交替, 10 $\mu$s - **同步序列**: sync_signal_2, 64 位→32 个 QPSK 符号 - **控制信息**: A 组, Polar(64,K) 编码→32 QPSK 符号, 导频间隔 16 - **载荷**: 码块分割 (无段内 CRC) → Polar 编码 → PSK 调制 + 导频 - **导频**: 可选, 间隔 4/8/16 ### FT3 — 长头数据帧 (§6.3.4) - **前导码**: PSK, [$\pi/4$, 0] 交替, 12 $\mu$s - **同步序列**: sync_signal_3, 31+31 位→62 个 BPSK 符号 (基于 m31 序列) - **控制信息**: B 组, Polar(256,K)→128 QPSK 符号, 导频间隔 4 - **载荷**: 码块分割 (含段内 CRC) → Polar 编码 → PSK 调制 + 导频 - **特点**: B 组 CRC 种子 = `0x555555 ^ LLID` ### FT4 — 扩展头数据帧 (§6.3.5) - **前导码**: PSK, [$\pi/4$, 0] 交替, 16 $\mu$s - **同步序列**: sync_signal_4, 63+63 位→126 个 BPSK 符号 (基于 m63 序列) - **控制信息**: B 组, Polar(256,K)→256 BPSK 符号, 导频间隔 4 - **载荷**: 与 FT3 相同的编码方案, 但同步序列更长, 适合低信噪比场景 ### 时序参数 系统基础时隙 $T_{sys} = 125\,\mu s$, 由 30 位计数器表示当前时刻。调度时隙有 25/50/75/100/125 $\mu$s 五种选择。帧的空口时长由以下公式决定: $$ T_{frame} = T_{preamble} + T_{sync} + T_{ctrl} + T_{data} + T_{guard} $$ **代码实现**: `phy.frame` 模块的 `_SYNC_CONFIG` 和 `_CTRL_CONFIG` 字典定义了四种帧类型的完整参数。`assemble_frame_bits()` 生成比特级帧结构, `frame_to_symbols()` 完成到调制符号的转换。 ## 物理层控制信息 (§6.4) 控制信息是帧头中紧跟同步序列之后的结构化字段, 携带帧类型、载荷长度、MCS 等元信息。 ### A 组 (FT1/FT2) A 组控制信息使用 CRC12 校验, 种子来自同步序列的低 12 位。定义了 7 种子类型: | 类型 | 用途 | |------|------| | A1 | 广播/发现/接入 | | A2 | 异步数据 (控制面) | | A3 | 异步数据 (数据面) | | A4 | 异步数据 (复用) | | A5 | 同步等时 | | A6 | 半可靠组播反馈 | | A7 | 测量管理 | ### B 组 (FT3/FT4) B 组使用 CRC24B 校验, 种子固定为 `0x555555`, CRC 结果与链路标识 LLID 异或。定义了 5 种子类型 (B1-B5), 对应异步数据、同步等时和测量等场景。 **代码实现**: `phy.control_info` 模块提供 `ControlInfoA1` 至 `ControlInfoA7` 和 `ControlInfoB1` 至 `ControlInfoB5` 等数据类, 各自实现 `pack()` 和 `unpack()` 方法。 ## 同步信号 (§6.2.3) 同步序列用于接收端定位帧起始位置。SLE 定义了 6 种同步信号: | 信号 | 长度 | 调制 | 生成方式 | 帧类型 | |------|------|------|----------|--------| | sync_signal_1 | 32 bit | GFSK | GoldCode(32) | FT1 | | sync_signal_2 | 64 bit | QPSK | GoldCode(64) | FT2 | | sync_signal_3 | 62 bit | BPSK | m31+m31, pid 控制 | FT3 | | sync_signal_4 | 126 bit | BPSK | m63+m63, pid 控制 | FT4 | | sync_signal_5 | 32 bit | GFSK | 安全随机函数 | FT1 (安全) | | sync_signal_6 | 64 bit | BPSK | 安全随机函数 | FT2 (安全) | sync_signal_3/4 的两段 m 序列由 PID (24 位) 通过哈希选择初始状态, 使得不同链路的同步序列正交。sync_signal_5/6 使用密码学安全随机数生成, 防止被预测。 **代码实现**: `phy.sync_sequence` 模块实现全部 6 种信号的生成, `common.m_sequence` 提供底层 m 序列算法。 ## 前导码 (§6.2.2) 前导码位于帧最前端, 用于接收端的载波同步和符号定时恢复: | 帧类型 | 波形 | 持续时间 | 样式 | |--------|------|----------|------| | FT1 | GFSK | 10 $\mu$s | [0,1,0,1...] 交替 | | FT2 | PSK | 10 $\mu$s | [$\pi/4$, 0, $\pi/4$, 0...] 交替 | | FT3 | PSK | 12 $\mu$s | 同上 | | FT4 | PSK | 16 $\mu$s | 同上 | 前导码长度随帧类型递增, FT4 最长 (16 $\mu$s), 提供更好的同步捕获性能。 **代码实现**: `phy.preamble.generate_preamble()` 函数根据帧类型自动选择波形和时长。 ## 导频 (§6.7) 导频符号是已知相位的参考符号, 周期性插入数据符号流中, 用于接收端进行信道估计和相位跟踪。 导频相位与该调制阶数的标准相位一致: BPSK 90°, QPSK 45°, 8PSK 22.5°。偶数位导频执行与数据符号相同的额外旋转。 插入规则: 每 $N$ 个数据符号后插入 1 个导频, $N$ 可选 4/8/16。帧末尾的导频可省略。 FT1 不使用导频。FT2 导频可选 (默认间隔 16)。FT3/FT4 强制使用导频 (默认间隔 4)。 **代码实现**: `phy.pilot.insert_pilots()` 和 `remove_pilots()` 函数。 ## 信道编码 (§6.9-6.11) ### CRC 校验 (§6.9) SLE 使用四种 CRC: | 类型 | 生成多项式 | 用途 | |------|-----------|------| | CRC12 | $D^{12}+D^{11}+D^3+D^2+D+1$ | A 组控制信息 | | CRC24A | $D^{24}+D^{23}+D^{18}+D^{17}+D^{14}+D^{11}+D^{10}+D^7+D^6+D^5+D^4+D^3+D+1$ | 载荷段, B组 | | CRC24B | (同 24A 不同多项式) | 码块分割段内 CRC | | CRC32 | 标准 CRC-32 | 长载荷 | CRC 计算支持种子值, A 组种子来自同步序列, B 组种子 = `0x555555 ^ LLID`。 **代码实现**: `common.crc.crc_calculate()`, 支持 Rust 加速 (`_HAS_RUST_CRC` 自动检测)。 ### Polar 编码 (§6.10.1) SLE 的前向纠错采用 Polar 码, 核心参数: - 母码长度 $N$: 32, 64, 128, 256, 512, 1024 - 信息位数 $K$: 由 MCS 索引和载荷长度决定 - 可靠性序列: 标准附录 C 给出 1024 阶固定排序 编码器执行蝶形 GF(2) 变换, 解码器采用逐次消除 (SC) 算法, 辅以 SSC 剪枝 (rate-0/rate-1 子树快速路径)。 **代码实现**: `common.polar.PolarEncoder` / `PolarDecoder`, 均支持 Rust 加速 (PyO3 扩展 `nearlink_sdr_accel`)。编码加速约 10 倍, 解码加速约 10 倍。 ### 码块分割 (§6.10.2) 当载荷超过单个 Polar 码块容量时, 进行码块分割: - **无段内 CRC** (FT2): 载荷等分为多个码块, 每块独立 Polar 编码 - **含段内 CRC** (FT3/FT4): 每个码块附加额外 CRC, 增强可靠性 **代码实现**: `common.code_block_seg` 模块的 `segment_without_crc()` 和 `segment_with_crc()` 函数。 ### BCH 编码 (§6.11) FT1 控制信息头部使用 BCH 码保护: - BCH(31,26): 可纠正 1 位错误 - BCH(63,24): 可纠正更多错误, 用于更长的控制字段 **代码实现**: `common.bch` 模块。 ### 信道比特加扰 (§6.10.4) 加扰使用 7 位 Galois LFSR, 多项式 $x^7 + x^4 + 1$, 周期 127。种子 (whitening_seed) 在控制信息中标明, 收发端使用相同种子即可还原。 **代码实现**: `common.scrambler.scramble()`, 内部预计算一个周期的加扰序列后用 tile 扩展。 ## MCS 表 (§6.10.5-6.10.6) 调制与编码方案 (MCS) 索引决定了一次传输的调制阶数和码率: | MCS | 调制 | 每符号比特 | 码率 | |-----|------|-----------|------| | 0 | BPSK | 1 | 1/4 | | 1 | BPSK | 1 | 1/3 | | 2 | BPSK | 1 | 1/2 | | 3 | BPSK | 1 | 2/3 | | 4 | BPSK | 1 | 3/4 | | 5 | QPSK | 2 | 1/2 | | 6 | QPSK | 2 | 2/3 | | 7 | QPSK | 2 | 3/4 | | 8 | (无编码 FT1) | 1 | 1 | | 9 | 8PSK | 3 | 1/2 | | 10 | 8PSK | 3 | 2/3 | | 11 | 8PSK | 3 | 3/4 | MCS 8 用于 FT1 的不编码直通模式。速率匹配通过重复或打孔将 Polar 编码输出适配到目标资源数。 **代码实现**: `common.mcs` 模块定义了完整的 MCS 表和速率匹配参数。 ## 跳频 (§6.10.3, §8.1) SLE 窄带系统在 2402-2480 MHz 频段内使用 79 个信道 (1 MHz 步进)。跳频序列由伪随机数生成器驱动, 每个调度点切换一次信道。 关键参数: - **跳频种子**: 24 位, 决定序列的随机性 - **跳频地图**: 79 位 bitmap, 标记每个信道的可用状态 - **最少可用信道**: 有下限门限, 防止可用信道过少 **代码实现**: `phy.freq_hopping` 模块的 `FreqTable`, 管理信道列表、跳频序列和屏蔽操作。 ## 发射流水线 (§6.10) 完整的 TX 处理链路 (`phy.tx_pipeline.tx_chain`): ```text 应用数据 ↓ CRC 附加 ← common.crc ↓ 码块分割 ← common.code_block_seg ↓ (FT2-4) Polar 编码 ← common.polar ↓ 比特加扰 ← common.scrambler ↓ 符号映射 ← phy.psk / phy.gfsk ↓ (FT2-4) 导频插入 ← phy.pilot ↓ 帧组装 ← phy.frame (前导 + 同步 + 控制信息 + 载荷) ↓ 脉冲成型 ← RRC / GFSK 滤波 ↓ 复基带 IQ 信号输出 ``` 发射参数通过 `TxConfig` 配置, 包含帧类型、MCS 索引、PID、加扰种子、CRC 长度和导频间隔等。 ## 接收流水线 (§6.10) RX 处理链路 (`phy.rx_pipeline.rx_chain`) 是发射的逆操作: ```text 复基带 IQ 信号输入 ↓ 匹配滤波 ← RRC / GFSK 频率鉴别 ↓ 帧同步 ← 同步序列互相关 ↓ 头部提取与解码 符号解映射 → 解扰 → Polar 解码 → CRC 校验 ↓ 导频去除 ← phy.pilot ↓ 载荷解调与解码 符号解映射 → 解扰 → Polar 解码 → 码块重组 → CRC 校验 ↓ 数据比特输出 + CRC 状态 ``` 帧同步通过滑动互相关检测同步序列的峰值位置, 超过门限则认为检测到帧。 ## 测量帧 (§6.3.6-6.3.11) SLE 定义了多种专用测量帧, 用于定位和感知: | 类型 | 结构 | 用途 | |------|------|------| | 测量帧类型 1 | 前导+同步+均衡保护+切换间隔+测量信号 | 窄带测距 | | 测量帧类型 2 | 仅测量信号 | 简化测量 | | 测量帧类型 3 | 前导+同步+均衡保护 | 信道探测 | | 测量帧类型 4 | 完整数据帧+测量信号 | 通信+测量混合 | | UWB 脉冲测量帧 | UWB 脉冲序列 | 超宽带测距 | **代码实现**: `phy.measurement_frame`, `phy.measurement`, `phy.measurement_tx` 模块。 ## 射频合规 (§8) `phy.rf_compliance` 模块实现了标准第 8 章的射频参数校验: - **发射机**: 输出功率等级、GFSK 调制精度 (频偏容限)、PSK 调制精度 (EVM)、GFSK 杂散发射、PSK 频谱模板 - **接收机**: 灵敏度与最大输入电平、信道选择性、杂散发射、RSSI 测量精度 - **UWB**: 信道参数合规、频谱掩模、归一化均方根误差 这些校验函数返回合规/不合规的判定, 可用于仿真结束后的自动验证。