From: Thomas Karpiniec Date: Mon, 20 Jan 2025 09:57:46 +0000 (+1100) Subject: Track preamble and EOT and estimate DCD X-Git-Tag: v0.1.0~9 X-Git-Url: https://code.octet-stream.net/m17rt/commitdiff_plain/d5f46a2d5d294c5a4287780dd609475fa73df9a8?ds=inline;hp=bb98d1726f35a41236b66bcf9fa0a8fa36633342 Track preamble and EOT and estimate DCD --- diff --git a/m17core/src/decode.rs b/m17core/src/decode.rs index 86567d9..911d673 100755 --- a/m17core/src/decode.rs +++ b/m17core/src/decode.rs @@ -3,8 +3,8 @@ use crate::{ fec::{self, p_1, p_2, p_3}, interleave::interleave, protocol::{ - LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, LSF_SYNC, PACKET_SYNC, - STREAM_SYNC, + LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, END_OF_TRANSMISSION, + LSF_SYNC, PACKET_SYNC, PREAMBLE, STREAM_SYNC, }, random::random_xor, }; @@ -33,6 +33,8 @@ pub(crate) enum SyncBurst { Bert, Stream, Packet, + Preamble, + EndOfTransmission, } impl SyncBurst { @@ -42,6 +44,8 @@ impl SyncBurst { Self::Bert => BERT_SYNC, Self::Stream => STREAM_SYNC, Self::Packet => PACKET_SYNC, + Self::Preamble => PREAMBLE, + Self::EndOfTransmission => END_OF_TRANSMISSION, } } } diff --git a/m17core/src/modem.rs b/m17core/src/modem.rs index b333ef5..8cbd003 100644 --- a/m17core/src/modem.rs +++ b/m17core/src/modem.rs @@ -29,6 +29,8 @@ pub struct SoftDemodulator { sample: u64, /// Remaining samples to read in before attempting to decode the current candidate samples_until_decode: Option, + /// Do we think there is a data carrier, i.e., channel in use? If so, at what sample does it expire? + dcd: Option, } impl SoftDemodulator { @@ -41,6 +43,25 @@ impl SoftDemodulator { candidate: None, sample: 0, samples_until_decode: None, + dcd: None, + } + } +} + +impl SoftDemodulator { + fn dcd_until(&mut self, end_sample: u64) { + if self.dcd.is_none() { + debug!("SoftDemodulator DCD on"); + } + self.dcd = Some(end_sample); + } + + fn check_dcd(&mut self) { + if let Some(end_sample) = self.dcd { + if self.sample > end_sample { + self.dcd = None; + debug!("SoftDemodulator DCD off"); + } } } } @@ -59,6 +80,7 @@ impl Demodulator for SoftDemodulator { self.rx_cursor = (self.rx_cursor + 1) % 1920; self.sample += 1; + self.check_dcd(); if let Some(samples_until_decode) = self.samples_until_decode { let sud = samples_until_decode - 1; @@ -97,6 +119,9 @@ impl Demodulator for SoftDemodulator { return Some(Frame::Packet(frame)); } } + SyncBurst::Preamble | SyncBurst::EndOfTransmission => { + // should never be chosen as a candidate + } } } } @@ -107,6 +132,15 @@ impl Demodulator for SoftDemodulator { burst_window[i] = self.rx_win[c]; } + for burst in [SyncBurst::Preamble, SyncBurst::EndOfTransmission] { + let (diff, _, _) = sync_burst_correlation(burst.target(), &burst_window); + if diff < SYNC_THRESHOLD { + // arbitrary choice, 240 samples = 5ms + // these bursts keep repeating so it will keep pushing out the DCD end time + self.dcd_until(self.sample + 240); + } + } + for burst in [ SyncBurst::Lsf, SyncBurst::Bert, @@ -148,6 +182,8 @@ impl Demodulator for SoftDemodulator { self.sample - c.age as u64, c.diff ); + // After any of these frame types you would expect to see a full EOT + self.dcd_until(self.sample + 1920 + 1920); } } diff --git a/m17core/src/protocol.rs b/m17core/src/protocol.rs index f2e154e..e4b3b15 100755 --- a/m17core/src/protocol.rs +++ b/m17core/src/protocol.rs @@ -4,6 +4,8 @@ pub(crate) const LSF_SYNC: [i8; 8] = [1, 1, 1, 1, -1, -1, 1, -1]; pub(crate) const BERT_SYNC: [i8; 8] = [-1, 1, -1, -1, 1, 1, 1, 1]; pub(crate) const STREAM_SYNC: [i8; 8] = [-1, -1, -1, -1, 1, 1, -1, 1]; pub(crate) const PACKET_SYNC: [i8; 8] = [1, -1, 1, 1, -1, -1, -1, -1]; +pub(crate) const PREAMBLE: [i8; 8] = [1, -1, 1, -1, 1, -1, 1, -1]; +pub(crate) const END_OF_TRANSMISSION: [i8; 8] = [1, 1, 1, 1, 1, 1, -1, 1]; #[derive(Debug, Clone, PartialEq, Eq, Copy)] pub enum Mode {