diff --git a/2sem_sem2/src/bin/main.rs b/2sem_sem2/src/bin/main.rs index e3176d8..01c307b 100644 --- a/2sem_sem2/src/bin/main.rs +++ b/2sem_sem2/src/bin/main.rs @@ -16,7 +16,7 @@ use semestralka2::send::{bit_send, nrz}; use {defmt_rtt as _, panic_probe as _}; -static PIPE: Channel = Channel::new(); +static PIPE_SEND: Channel = Channel::new(); static PIPE_REC: Channel = Channel::new(); // static REC_ALLOWED: AtomicBool = AtomicBool::new(true); @@ -28,11 +28,12 @@ async fn main(spawner: Spawner) { let tx = Output::new(p.PF2, gpio::Level::High, gpio::Speed::VeryHigh); let rx = ExtiInput::new(p.PA3, p.EXTI3, Pull::Up); - let sender = PIPE.sender(); - let receiver = PIPE.receiver(); + let sender = PIPE_SEND.sender(); + let receiver = PIPE_SEND.receiver(); - spawner.spawn(bit_send(tx, receiver)).unwrap(); - spawner.spawn(bit_receive_and_decode(rx)).unwrap(); + let e_nrz = semestralka2::Encoding::Nrz; + spawner.spawn(bit_send(tx, receiver, e_nrz)).unwrap(); + spawner.spawn(bit_receive_and_decode(rx, e_nrz)).unwrap(); info!("starting loop"); loop { diff --git a/2sem_sem2/src/lib.rs b/2sem_sem2/src/lib.rs index 79668fa..0689826 100644 --- a/2sem_sem2/src/lib.rs +++ b/2sem_sem2/src/lib.rs @@ -2,3 +2,9 @@ pub mod receive; pub mod send; + +#[derive(Copy, Clone, PartialEq)] +pub enum Encoding { + Nrz, + Nrzi, +} diff --git a/2sem_sem2/src/receive.rs b/2sem_sem2/src/receive.rs index 8f0f216..fdace8c 100644 --- a/2sem_sem2/src/receive.rs +++ b/2sem_sem2/src/receive.rs @@ -1,6 +1,8 @@ use defmt::info; -use embassy_stm32::exti::ExtiInput; -use embassy_time::{Duration, Timer}; +use embassy_stm32::{exti::ExtiInput, sai::FrameSyncDefinition}; +use embassy_time::{Ticker, Timer}; + +use crate::Encoding; const START: u8 = 0x7E; const STOP: u8 = 0x81; @@ -18,32 +20,73 @@ fn crc8(crc: u8, byte: u8) -> u8 { c } -async fn sample_byte(pin: &mut ExtiInput<'static>, bit_time: Duration) -> u8 { +async fn sample_byte( + pin: &mut ExtiInput<'static>, + encoding: Encoding, + ticker: &mut Ticker, + last_physical_level: &mut bool, +) -> u8 { let mut byte = 0u8; for _ in 0..8 { - let bit = if pin.is_high() { 1 } else { 0 }; + let current_level = pin.is_high(); + + let bit = match encoding { + Encoding::Nrz => { + if pin.is_high() { + 1 + } else { + 0 + } + } + Encoding::Nrzi => { + let bit = if current_level != *last_physical_level { + 1 + } else { + 0 + }; + *last_physical_level = current_level; + bit + } + }; byte = (byte << 1) | bit; - Timer::after(bit_time).await; + ticker.next().await; } byte } #[embassy_executor::task] -pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>) { +pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>, encoding: Encoding) { loop { pin.wait_for_falling_edge().await; - let t1 = embassy_time::Instant::now(); pin.wait_for_rising_edge().await; let bit_time = embassy_time::Instant::now().duration_since(t1); Timer::after(bit_time / 2).await; + let mut ticker = Ticker::every(bit_time); + + let mut last_level = true; + let mut start_byte = 0u8; for _ in 0..7 { - let bit = if pin.is_high() { 1 } else { 0 }; + let current_level = pin.is_high(); + let bit = match encoding { + Encoding::Nrz => { + if pin.is_high() { + 1 + } else { + 0 + } + } + Encoding::Nrzi => { + let b = if current_level != last_level { 1 } else { 0 }; + last_level = current_level; + b + } + }; start_byte = (start_byte << 1) | bit; - Timer::after(bit_time).await; + ticker.next().await; } if start_byte != START { @@ -52,7 +95,7 @@ pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>) { } // len - let len = sample_byte(&mut pin, bit_time).await; + let len = sample_byte(&mut pin, encoding, &mut ticker, &mut last_level).await; if len as usize > MAX_PAYLOAD { info!("bad len {}", len); continue; @@ -61,18 +104,32 @@ pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>) { // payload let mut payload = [0u8; MAX_PAYLOAD]; for i in 0..(len as usize) { - payload[i] = sample_byte(&mut pin, bit_time).await; + payload[i] = sample_byte(&mut pin, encoding, &mut ticker, &mut last_level).await; } // crc - let crc_recv = sample_byte(&mut pin, bit_time).await; + let crc_recv = sample_byte(&mut pin, encoding, &mut ticker, &mut last_level).await; // parita - let parity_recv = if pin.is_high() { 1 } else { 0 }; - Timer::after(bit_time).await; + let current_p = pin.is_high(); + let parity_recv = match encoding { + Encoding::Nrz => { + if current_p { + 1 + } else { + 0 + } + } + Encoding::Nrzi => { + let b = if current_p != last_level { 1 } else { 0 }; + last_level = current_p; + b + } + }; + ticker.next().await; // stop - let stop = sample_byte(&mut pin, bit_time).await; + let stop = sample_byte(&mut pin, encoding, &mut ticker, &mut last_level).await; if stop != STOP { info!("bad stop 0x{:02X}", stop); continue; diff --git a/2sem_sem2/src/send.rs b/2sem_sem2/src/send.rs index 98fd867..c52caff 100644 --- a/2sem_sem2/src/send.rs +++ b/2sem_sem2/src/send.rs @@ -7,6 +7,8 @@ use embassy_sync::{ }; use embassy_time::{Duration, Ticker}; +use crate::Encoding; + const START: u8 = 0x7E; const STOP: u8 = 0x81; const BIT_PERIOD: Duration = Duration::from_millis(10); @@ -66,15 +68,37 @@ fn crc8(crc: u8, byte: u8) -> u8 { pub async fn bit_send( mut pin: Output<'static>, rx: Receiver<'static, CriticalSectionRawMutex, u8, 128>, + encoding: Encoding, ) { let mut ticker = Ticker::every(BIT_PERIOD); + let mut is_high = true; + pin.set_high(); + loop { let bit = rx.receive().await; - if bit == 1 { - pin.set_high(); - } else { - pin.set_low(); - } + match encoding { + Encoding::Nrz => { + if bit == 1 { + is_high = true; + pin.set_high(); + } else { + is_high = false; + pin.set_low(); + } + } + // toggle, ak sme v 1, inac sa nedeje nic + Encoding::Nrzi => { + if bit == 1 { + is_high = !is_high; + if is_high { + pin.set_high(); + } else { + pin.set_low(); + } + } + } + }; + // bitrate ticker.next().await; }