diff --git a/semestralka_1d_rx_bez_dma/src/bin/main.rs b/semestralka_1d_rx_bez_dma/src/bin/main.rs index 1897a0e..d459421 100644 --- a/semestralka_1d_rx_bez_dma/src/bin/main.rs +++ b/semestralka_1d_rx_bez_dma/src/bin/main.rs @@ -38,8 +38,7 @@ use cortex_m::interrupt::Mutex; use core::cell::RefCell; use embassy_sync::channel::Channel; -static RX_PIN_GLOBAL: Mutex>>> = Mutex::new(RefCell::new(None)); -static PD6_BITS: Channel = Channel::new(); +static PD6_BITS: Channel = Channel::new(); bind_interrupts!(struct Irqs { USART1 => BufferedInterruptHandler; @@ -52,6 +51,7 @@ bind_interrupts!(struct Irqs2 { pub const TIM6_UP_REQ: Request = 4; static SW_TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new(); static SW_RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new(); +static mut RX_PIN: Option> = None; #[embassy_executor::main] async fn main(spawner: Spawner) { @@ -107,11 +107,7 @@ async fn main(spawner: Spawner) { // SOFTWARE UART // let _rx = Input::new(p.PD6, Pull::Up); let rx_pin = Input::new(p.PD6, Pull::Up); - - // Rx ready for the interrupt - use cortex_m::interrupt::free; - let rx_pin_ref: &'static Input<'static> = unsafe { core::mem::transmute(&rx_pin) }; - free(|cs| RX_PIN_GLOBAL.borrow(cs).replace(Some(rx_pin_ref))); + unsafe { RX_PIN = Some(rx_pin) }; // Configure TX as output (PB0) let mut tx_pin = Output::new(p.PB0, Level::High, Speed::VeryHigh); @@ -123,46 +119,59 @@ async fn main(spawner: Spawner) { unsafe { cortex_m::peripheral::NVIC::unmask(pac::Interrupt::TIM7); } - let mut rx_samples = [1u8; 1024]; +let frame_samples = (10 * RX_OVERSAMPLE as usize); // 1 start + 8 data + 1 stop + let mut rx_samples = [0u8; 4096]; // plenty of space let mut rx_count = 0usize; + loop { - // 1. Drain the channel into the local buffer + // === 1. Drain channel into local buffer in bursts === + let mut drained = 0; while let Ok(bit) = PD6_BITS.try_receive() { if rx_count < rx_samples.len() { rx_samples[rx_count] = bit; rx_count += 1; } else { - // Buffer full: discarding oldest data by rotating - // Simple naive strategy: just clear half - // Ideally we should prevent this by processing faster warn!("RX Buffer overflow, resetting"); rx_count = 0; } + + drained += 1; + // Periodically yield while draining to avoid hogging CPU + if drained >= 512 { + yield_now().await; + drained = 0; + } } - // 2. Try to decode UART frames from the buffer - if rx_count > 0 { - // Try to decode + // === 2. Process only when we have enough samples for a frame === + if rx_count >= frame_samples { let (decoded, consumed) = decode_uart_samples( - &rx_samples[..rx_count], - RX_OVERSAMPLE, - &UART_CFG + &rx_samples[..rx_count], + RX_OVERSAMPLE, + &UART_CFG, ); - // Print received characters - for b in decoded { - info!("Received: {}", b as char); + // Print decoded chars + if !decoded.is_empty() { + // For debugging: only print when you actually have data + for &b in &decoded { + info!("{}", b as char); + } } - // 3. Remove processed samples from the buffer + // === 3. Remove processed samples === if consumed > 0 { - // Shift remaining data to the front - // copy_within is efficient for slices + // Slide unprocessed samples to the start rx_samples.copy_within(consumed..rx_count, 0); rx_count -= consumed; } + + // Yield briefly so other embassy tasks run + yield_now().await; + } else { + // === 4. Buffer not yet full enough, short sleep === + yield_now().await; } - yield_now().await; } } @@ -173,16 +182,13 @@ fn TIM7() { if tim.sr().read().uif() { tim.sr().modify(|w| w.set_uif(false)); - let bit = cortex_m::interrupt::free(|cs| { - RX_PIN_GLOBAL - .borrow(cs) - .borrow() - .as_ref() - .map(|pin| pin.is_high()) - .unwrap_or(false) - }) as u8; - - let _ = PD6_BITS.try_send(bit); + unsafe { + if let Some(ref pin) = RX_PIN { + // one instruction read – no locking needed + let bit = pin.is_high() as u8; + let _ = PD6_BITS.try_send(bit); + } + } } } @@ -196,7 +202,7 @@ pub async fn bridge_usart1_rx_to_usart2_tx( let n = usart1_rx.read(&mut buf).await; if n > 0 { let _ = usart2_tx.write(&buf[..n]).await; - info!("bridge: USART1 -> USART2 sent {} bytes", n); + // info!("bridge: USART1 -> USART2 sent {} bytes", n); } yield_now().await; } diff --git a/semestralka_1d_rx_bez_dma/src/config.rs b/semestralka_1d_rx_bez_dma/src/config.rs index c189e21..1a5defb 100644 --- a/semestralka_1d_rx_bez_dma/src/config.rs +++ b/semestralka_1d_rx_bez_dma/src/config.rs @@ -9,7 +9,7 @@ pub const BAUD: u32 = 600; pub const TX_PIN_BIT: u8 = 0; // PB2 pub const RX_PIN_BIT: u8 = 3; // PC3 pub const TX_OVERSAMPLE: u16 = 1; -pub const RX_OVERSAMPLE: u16 = 1; +pub const RX_OVERSAMPLE: u16 = 2; pub const RX_RING_BYTES: usize = 4096; pub const TX_RING_BYTES: usize = 4096;