Field Guide · term

Also known as: dPMR FEC, dPMR channel coding

dPMR channel coding is the forward-error-correction that protects a dPMR CSBK or traffic payload as it crosses a noisy 4FSK channel.1 Per ETSI TS 102 658 §6, dPMR wraps its payload bits in a short-block cyclic code under a rate-¾ convolutional outer code, then interleaves the result across the burst so a fade turns into scattered single errors the decoder can repair.2 GopherTrunk currently parses dPMR at the layer above this stage — an honest, documented deferral covered below.

payload bits (CSBK / traffic) cyclic short block conv R=3/4 outer code interleave on-air burst dashed = documented follow-up (GopherTrunk parses above this stage)
dPMR's coding stack runs payload bits through a short-block cyclic code, a rate-3/4 convolutional outer code, and an interleaver before the burst goes on air. GopherTrunk implements the structured payload layer at the top; the cyclic, convolutional, and interleave stages (dashed) are a named deferral.

What the coding does

The three stages each answer a different failure mode. The short-block cyclic code adds a small number of parity bits so the receiver can detect — and for the shortest blocks, correct — a handful of bit errors, and it doubles as an integrity check like a CRC. The rate-¾ convolutional outer code spreads each input bit’s influence across several output bits, so a Viterbi-style decoder can reconstruct the original stream even where individual bits were lost; the ¾ rate keeps the overhead modest, appropriate for dPMR’s narrow 6.25 kHz channel where bandwidth is scarce. The interleaver then reorders the coded bits so that a burst error on the channel — a fade lasting several symbols — is spread out into isolated single-bit errors once de-interleaved, which is exactly the error pattern the cyclic and convolutional decoders handle best. Together they let a marginal dPMR signal deliver a correct CSBK where an uncoded block would be discarded.

The implementation gap

GopherTrunk is deliberate about what it has and has not built. Its dPMR package ships a clean structured surface — frame sync detection, CSBK parsing, the opcode enum, the band-plan resolver, and the trunking state machine — so the engine can consume grants end-to-end against fixtures. The CSBK parser, though, assumes the upstream caller has already corrected errors: it maps 80 clean bits into fields, and the FEC that would produce those 80 clean bits from an on-air burst is listed among the package’s honest deferrals. The source names the missing pieces explicitly: the interleaver plus the short-block-cyclic / rate-¾-convolutional FEC over the CSBK bits, the 4FSK demodulator and symbol-clock recovery for the 2400 sym/sec air interface, and voice-frame extraction into the AMBE+2 vocoder. Flagging these as named follow-ups — rather than silently shipping a half-built decoder — is a deliberate choice: the structured layer is testable now against pre-corrected fixtures, and the FEC slots in beneath it without changing the surface above.

Relevance to SDR

internal/radio/dpmr/dpmr.go documents this boundary in the package doc comment, and the parsing in csbk.go operates on the post-FEC bit layer. For a live off-air dPMR control channel the chain would be: 4FSK demod → FS3 sync → de-interleave → convolutional + cyclic decode → 80-bit CSBK → parse. Today GopherTrunk implements the sync-and-parse ends of that chain and defers the demod-and-FEC middle, which is the correct order for a decoder built against captured and replayed fixtures: the structured trunking logic is proven first, and the error-correction that feeds it is added as a self-contained stage once conformance vectors are in hand.

Sources

  1. dPMR — Wikipedia, on the ETSI dPMR standard and its physical layer. 

  2. Convolutional code — Wikipedia, on the outer code family dPMR’s channel coding uses. 

See also