From f4a9078dd271d1b7d3493ddc9b32b5cf87b972b8 Mon Sep 17 00:00:00 2001 From: Albin Chaboissier Date: Wed, 29 Oct 2025 11:28:53 +0100 Subject: [PATCH] Radio ptt enable --- run_net.sh | 2 +- src/main.rs | 33 +++++++++++++++++++-------------- src/ted/elg.rs | 23 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/run_net.sh b/run_net.sh index ce77178..76d5d80 100755 --- a/run_net.sh +++ b/run_net.sh @@ -3,7 +3,7 @@ echo "running as $1" cargo b --release sudo setcap cap_net_admin+eip target/release/rdsp -./target/release/rdsp 0 & +./target/release/rdsp 0 > /dev/ttyACM0 & sleep .5 sudo ip a a $1/24 dev radio0 sudo ip -6 addr flush radio0 diff --git a/src/main.rs b/src/main.rs index 3dc5327..1ec5462 100644 --- a/src/main.rs +++ b/src/main.rs @@ -145,10 +145,10 @@ impl FSKReceiver { let elg = ELGate::new(samples_per_symbol, FIRFilter::new(&loop_ir)); // Baseband filter - let bbf_length = estimate_fir_length(500., SAMPLE_RATE as f32).floor() as usize; + let bbf_length = estimate_fir_length(100., SAMPLE_RATE as f32).floor() as usize; let mut frequency_response = vec![Complex32::zero(); bbf_length].into_boxed_slice(); let cutoff_bin = map( - hz_to_rad_per_sample(DEVIATION + 100., SAMPLE_RATE as f32), + hz_to_rad_per_sample(DEVIATION + 300., SAMPLE_RATE as f32), 0., 2. * PI, 0., @@ -181,9 +181,10 @@ impl FSKReceiver { async fn receive(&mut self, iq: Complex32) -> Result, FrameConstructionError> { // Frame reconstruction let filtered_bb = self.baseband_filter.next(iq); - let dphi = self - .phase_lowpass - .next_real((self.last_sample * filtered_bb.conj()).arg()); + // let dphi = self + // .phase_lowpass + // .next_real((self.last_sample * filtered_bb.conj()).arg()); + let dphi = (self.last_sample * filtered_bb.conj()).arg(); self.last_sample = filtered_bb; if let Some((bit_sample, eye)) = self.elg.next_eye(dphi) { let _ = self.eye_sender.send(eye).await; @@ -206,7 +207,7 @@ impl FSKReceiver { let frame_opt = self.frame_constructor.add_byte(self.last_byte); self.bit_count = Some(0); //print!("{}", last_byte as char); - print!(".{:x}.", self.last_byte); + eprint!(".{:x}.", self.last_byte); let _ = std::io::stdout().flush(); return frame_opt; } @@ -265,7 +266,7 @@ impl Transceiver { let receiving = Arc::new(RwLock::new(false)); tokio::spawn(async move { - let mut squelch = Squelch::new(200, 0.1); + let mut squelch = Squelch::new(200, 0.5); let mut iq_sampler = IQSampler::new(hz_to_rad_per_sample(CENTER_FREQ, SAMPLE_RATE as f32)); @@ -288,7 +289,7 @@ impl Transceiver { match recv.as_mut().unwrap().receive(iq).await { Ok(Some(Frame::Data(dat))) => { - println!("GOT DATA"); + eprintln!("GOT DATA"); let _ = rx_stream_sender.try_send(dat); send_ack = false; recv = None; @@ -319,10 +320,10 @@ impl Transceiver { } => { state_tx.try_send(TransceiverState::Sending); - println!("Sending message"); + eprintln!("Sending message"); Self::transmit(Frame::Data(message.clone()), &mut sample_sender).await; current_message = None; - println!("Sent message"); + eprintln!("Sent message"); state_tx.try_send(TransceiverState::Waiting); } }; @@ -412,7 +413,7 @@ impl FrameConstructor { pub fn add_byte(&mut self, byte: u8) -> Result, FrameConstructionError> { if self.frame.is_empty() && byte != 0xC4 && byte != 0x4C && !self.started { - println!("Wrong type {:x}", byte); + eprintln!("Wrong type {:x}", byte); self.started = true; return Err(()); } @@ -447,7 +448,7 @@ impl FrameConstructor { ))); } - println!("Checksum failed"); + eprintln!("Checksum failed"); return Err(()); } @@ -500,7 +501,7 @@ impl Frame { #[tokio::main] async fn main() { // Read instance - println!( + eprintln!( "fir length: {}", impulse_response::design::estimate_fir_length(1000., 48000.) ); @@ -554,7 +555,7 @@ impl EguiApp { let instance_id = unsafe { INSTANCE_ID }; tokio::task::spawn(async move { - println!("Waiting for connection ..."); + eprintln!("Waiting for connection ..."); // let socket = Arc::new( // UdpSocket::bind(format!("0.0.0.0:{}", 9000 + instance_id)) @@ -609,6 +610,8 @@ impl EguiApp { let progression = Arc::new(AtomicU64::new(0)); let (finished_tx, mut finished_rx) = channel::<()>(16); + print!("o"); + stdout().flush().unwrap(); let send_stream = device .build_output_stream( &config, @@ -634,6 +637,8 @@ impl EguiApp { .unwrap(); send_stream.play().unwrap(); let _ = finished_rx.recv().await; + print!("c"); + stdout().flush().unwrap(); } }); diff --git a/src/ted/elg.rs b/src/ted/elg.rs index 599c6be..b87cf16 100644 --- a/src/ted/elg.rs +++ b/src/ted/elg.rs @@ -1,10 +1,11 @@ -use std::collections::VecDeque; use crate::filtering::fir::FIRFilter; +use std::collections::VecDeque; // Crued Early late gate timing error detector pub struct ELGate { samples_per_symbol: f32, buffer: VecDeque, // Store baseband, matched filtered samples, + eye_buffer: VecDeque, loop_filter: FIRFilter, delta: f32, @@ -18,6 +19,7 @@ impl ELGate { samples_per_symbol, loop_filter, buffer: VecDeque::with_capacity(2 * samples_per_symbol.ceil() as usize), + eye_buffer: VecDeque::with_capacity(2 * samples_per_symbol.ceil() as usize), delta: 0.5, next_sample: samples_per_symbol, current_position: 0., @@ -30,8 +32,26 @@ impl ELGate { pub fn next_eye(&mut self, sample: f32) -> Option<(f32, Vec)> { self.buffer.push_front(sample); + self.eye_buffer.push_front(sample); + self.current_position += 1.; if self.current_position >= self.next_sample { + // Eye stuff + let mut eye = Vec::new(); + if self.eye_buffer.len() >= (self.samples_per_symbol / 2.) as usize { + let start_index = (self.samples_per_symbol / 2.) as usize; + let end_index = (start_index * 3).min(self.eye_buffer.len()); + eye = self + .eye_buffer + .range(start_index..) + .copied() + .collect::>(); + + while self.eye_buffer.len() > start_index { + self.eye_buffer.pop_back(); + } + } + // Sample center, early late let early_id = (self.samples_per_symbol / 2. + self.samples_per_symbol * self.delta) .floor() @@ -63,4 +83,3 @@ impl ELGate { } } } -