1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-License-Identifier: GPL-3.0-or-later
//! Frame-head preamble for uvpacket's coherent QPSK modem.
//!
//! Replaces the 4-FSK Costas-4 head pattern that the Phase 1 design
//! used (and that Phase 2 found could not survive the modulation
//! pivot to coherent QPSK — Costas arrays are FSK-tone-index
//! sequences, not constellation-point sequences).
//!
//! The new sync is a **31-bit maximum-length sequence** (PRBS,
//! generator polynomial `x⁵ + x² + 1`) mapped to BPSK at the
//! channel-symbol rate. 31 chips × 1 sym/chip = 26 ms preamble at
//! 1200 baud. Autocorrelation sidelobes are bounded by `1/31` ≈
//! −15 dB amplitude, giving a clean correlator peak that the
//! receiver uses for symbol-timing acquisition, frequency-offset
//! estimation, and initial carrier-phase lock.
//!
//! After the preamble, the receiver maintains phase via
//! decision-directed PLL with periodic [`PILOT_SYMBOL_INTERVAL`]
//! known-QPSK pilot symbols (one per 32 transmitted symbols ≈ 3.1 %
//! overhead). The pilot's constellation point is `+1 + 0j` —
//! the QPSK symbol mapped from bit pair `[0, 0]`.
//!
//! ## Trait-level placeholder
//!
//! [`UVPACKET_SYNC_BLOCKS`] is kept as a `[Costas-4 at symbol 0]`
//! placeholder so that `Protocol::SYNC_MODE = SyncMode::Block(...)`
//! has something non-empty to point at and `protocol_invariants`
//! tests pass. The uvpacket TX / RX paths are bespoke and do **not**
//! consult this constant — they use [`UVPACKET_PREAMBLE_BPSK_BITS`]
//! and [`PILOT_SYMBOL_INTERVAL`] directly.
use crateSyncBlock;
/// Length of the m-sequence preamble in BPSK chips (= QPSK
/// transmitted symbols since the preamble is BPSK-mapped onto the
/// QPSK constellation's I axis).
pub const PREAMBLE_LEN: usize = 31;
/// 31-bit maximum-length sequence from a Fibonacci LFSR with
/// polynomial `x⁵ + x² + 1` and initial state `[0, 0, 0, 0, 1]`.
/// Bits run in TX order. Reproducible: any LFSR walker with the
/// same polynomial / initial state regenerates this exact sequence.
///
/// Each `true` maps to BPSK `−1`, each `false` maps to `+1` (the
/// standard NRZ-mapping used by the receiver's correlator).
pub const UVPACKET_PREAMBLE_BPSK_BITS: = ;
/// Pilot interval: every `PILOT_SYMBOL_INTERVAL`th transmitted
/// symbol after the preamble is a known pilot, the rest are data.
/// 32 means 1 pilot per 31 data → ~3.1 % overhead, comfortable
/// margin against 10 Hz Doppler at 1200 baud (coherence time ≈
/// 100 ms = 120 symbols, so a pilot every 32 symbols is well
/// inside the coherence interval).
pub const PILOT_SYMBOL_INTERVAL: usize = 32;
/// QPSK pilot constellation point. Chosen as constellation index
/// 0 (= bit pair `[0, 0]`) so it maps to `+1 + 0j` — receiver-side
/// phase reference is straightforward (the pilot's expected angle
/// is the carrier reference angle).
pub const PILOT_QPSK_POINT: u8 = 0;
// ── Trait-level placeholder (unused by uvpacket bespoke pipeline) ──
/// Decorative 4-FSK Costas pattern kept around so `Protocol::
/// SYNC_MODE = SyncMode::Block(&UVPACKET_SYNC_BLOCKS)` has
/// something to point at and `protocol_invariants` checks pass.
/// Not consulted by [`crate::uvpacket::tx::encode`] /
/// [`crate::uvpacket::rx::decode_known_layout`] / [`crate::uvpacket::rx::decode`].
///
/// (Kept under the legacy `UVPACKET_COSTAS` name through the
/// modulation pivot; existing TX / RX modules — which are about
/// to be rewritten — still import this symbol. The real frame
/// sync after the pivot is the m-sequence preamble above.)
pub const UVPACKET_COSTAS: = ;
/// `Protocol::SYNC_MODE` placeholder. See module docs.
pub const UVPACKET_SYNC_BLOCKS: = ;