Field Guide · term

Also known as: TETRA sync word, normal training sequence, synchronisation training sequence

TETRA training sequences are the fixed bit patterns embedded at known positions in every TETRA burst that let a receiver find the slot boundary and resolve the constellation rotation.1 They play the role a frame sync word plays elsewhere: a decoder slides the known pattern over the demodulated symbol stream and declares a burst wherever the mismatch count falls under a threshold — exactly access-code correlation. TETRA defines three, by length: the Normal training sequence (22 bits / 11 dibits), the Extended training sequence (30 bits / 15 dibits), and the longer Synchronisation training sequence (38 bits / 19 dibits) carried by the synchronisation burst.2

Normal · 22 bits / 11 dibits Extended · 30 bits / 15 dibits Synchronisation · 38 bits / 19 dibits
The three fixed training sequences differ only in length; the longer synchronisation pattern gives the cold-acquisition synchronisation burst a sharper, more reliable correlation peak.

The fixed patterns

The training sequences are specified as literal on-air bit arrays, MSB-first. GopherTrunk stores the real over-the-air values — validated against live captures — rather than any packed constant. The synchronisation training sequence, the longest and the one a receiver hunts first, is:

// SyncTrainingSeq — synchronisation training sequence (§9.4.4.3.4), carried by
// the synchronisation downlink burst (SB) at slot 1 of frame 18 per multiframe.
// internal/radio/tetra/sync.go, ETSI EN 300 392-2 §9.4.4.3.4.
var SyncTrainingSeq = []uint8{1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1,
    0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1}

The two Normal training sequences (NTS1 and NTS2) and the Extended sequence are stored the same way. An earlier GopherTrunk implementation used packed uint64 “hex” constants that were both truncated and matched no spec value, so the control channel could never lock on real air — a reminder that a training sequence must be the exact on-air pattern, not an approximation.

The bit-to-dibit convention

TETRA is π/4-DQPSK, so the demodulator does not emit bits — it emits a dibit value 0..3 per symbol, derived from the phase step between successive symbols. The mapping from a transmitted bit pair (b1, b2) to a dibit value is TETRA’s own Gray mapping: (b1<<1) | (b1^b2), giving 00→0, 01→1, 11→2, 10→3. This is deliberately distinct from the linear dibit convention the C4FM family (P25, DMR, NXDN, dPMR) uses, and mixing them silently mis-decodes everything. GopherTrunk therefore keeps TetraBitsToDibits / TetraDibitsToBits as the single source of truth: the correlator converts each training sequence to its dibit form once, then slides that dibit pattern over the receiver’s dibit output. Because π/4-DQPSK leaves a constant residual rotation (from carrier offset), the detector correlates against all four rotations of the pattern and records which one matched, so the rest of the burst can be de-rotated before channel decoding.

Relevance to SDR

internal/radio/tetra/sync.go holds the four sequences as MSB-first bit arrays, the bit↔dibit Gray helpers, and a SyncDetector that reports each position where a pattern matches within tolerance. The traffic extractor and the control-channel state machine both build their detectors from these — normal sequences at tolerance 2, the synchronisation sequence at tolerance 3 — under all four rotations. Because the training sequence is the only part of a burst that is not scrambled, it still correlates even when a downstream bug leaves every scrambled block undecodable, which is why lock succeeding while nothing decodes is a classic TETRA failure signature.

Sources

  1. Terrestrial Trunked Radio — Wikipedia, on the TETRA air interface and its burst structure. 

  2. Gray code — Wikipedia, on the reflected-binary mapping TETRA uses between symbol bit pairs and dibit values. 

See also