diff --git a/2sem_sem2/src/bin/main.rs b/2sem_sem2/src/bin/main.rs index 24f05d9..a8e8ed7 100644 --- a/2sem_sem2/src/bin/main.rs +++ b/2sem_sem2/src/bin/main.rs @@ -9,10 +9,10 @@ use embassy_stm32::gpio; use embassy_stm32::gpio::{Output, Pull}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; -use embassy_time::{Duration, Timer}; -use heapless::Vec; -use semestralka2::receive::{bit_decode, bit_receive_and_decode}; -use semestralka2::send::*; +use embassy_time::Duration; +use semestralka2::receive::bit_receive_and_decode; +use semestralka2::send::nrz; +use semestralka2::send::Tx; use {defmt_rtt as _, panic_probe as _}; @@ -28,29 +28,21 @@ 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 config = Config::default(); let sender = PIPE.sender(); - let sender_receiver = PIPE.receiver(); - let receiver_sender = PIPE_REC.sender(); - let receiver_reader = PIPE_REC.receiver(); - // let receiver = PIPE.receiver(); + let receiver = PIPE.receiver(); - spawner.spawn(bit_send(tx, sender_receiver)).unwrap(); + spawner.spawn(bit_send(tx, receiver)).unwrap(); spawner.spawn(bit_receive_and_decode(rx)).unwrap(); - // spawner.spawn(bit_decode(receiver_reader)).unwrap(); - - info!("starting echo"); - let mut v: Vec = Vec::new(); + info!("starting loop"); loop { - let slovko = "ahoj"; - info!("slovo: {}", slovko); - let vektorik = encode(slovko, &mut v); - info!("slovo: {:#?}", vektorik); + nrz(b"ahoj", &sender).await; + nrz(b"hello", &sender).await; - info!("enkodovane, posielame do pipy..."); - nrz(&v, &sender).await; + let data = [0x01, 0x02, 0x03, 0x04]; + nrz(&data, &sender).await; - Timer::after(Duration::from_millis(1000)).await; + info!("frame sent"); + embassy_time::Timer::after(Duration::from_secs(1)).await; } } diff --git a/2sem_sem2/src/receive.rs b/2sem_sem2/src/receive.rs index 824f7d5..8f0f216 100644 --- a/2sem_sem2/src/receive.rs +++ b/2sem_sem2/src/receive.rs @@ -1,7 +1,32 @@ use defmt::info; use embassy_stm32::exti::ExtiInput; -use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Receiver}; -use embassy_time::Timer; +use embassy_time::{Duration, Timer}; + +const START: u8 = 0x7E; +const STOP: u8 = 0x81; +const MAX_PAYLOAD: usize = 64; + +fn crc8(crc: u8, byte: u8) -> u8 { + let mut c = crc ^ byte; + for _ in 0..8 { + c = if c & 0x80 != 0 { + (c << 1) ^ 0x07 + } else { + c << 1 + }; + } + c +} + +async fn sample_byte(pin: &mut ExtiInput<'static>, bit_time: Duration) -> u8 { + let mut byte = 0u8; + for _ in 0..8 { + let bit = if pin.is_high() { 1 } else { 0 }; + byte = (byte << 1) | bit; + Timer::after(bit_time).await; + } + byte +} #[embassy_executor::task] pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>) { @@ -13,59 +38,70 @@ pub async fn bit_receive_and_decode(mut pin: ExtiInput<'static>) { pin.wait_for_rising_edge().await; let bit_time = embassy_time::Instant::now().duration_since(t1); - let _ = Timer::after(bit_time).await; - - let mut message_buffer = [0u8; 8]; // sprava - let mut byte_idx = 0; - let mut frame_active = true; - - while frame_active && byte_idx < message_buffer.len() { - let mut current_byte = 0u8; - - for _ in 0..8 { - let bit = if pin.is_high() { 1 } else { 0 }; - current_byte = (current_byte << 1) | bit; - Timer::after(bit_time).await; - } - - if current_byte == 0xAA { - frame_active = false; - } else { - message_buffer[byte_idx] = current_byte; - byte_idx += 1; - } + Timer::after(bit_time / 2).await; + let mut start_byte = 0u8; + for _ in 0..7 { + let bit = if pin.is_high() { 1 } else { 0 }; + start_byte = (start_byte << 1) | bit; + Timer::after(bit_time).await; } - if let Ok(s) = core::str::from_utf8(&message_buffer[..byte_idx]) { - info!("sprava: {}", s); - } - } -} - -#[embassy_executor::task] -pub async fn bit_decode(receiver: Receiver<'static, CriticalSectionRawMutex, u8, 64>) { - let mut buffer = 0u64; - loop { - let bit = receiver.receive().await; - buffer = (buffer << 1) | (bit as u64); - - // sync 0xAA + start 0xAB - if (buffer & 0xFFFF) == 0xAAAB { - info!("frame"); - let mut message = [0u8; 4]; - - for byte in message.iter_mut() { - for _ in 0..8 { - let b = receiver.receive().await; - *byte = (*byte << 1) | b; - } - } - - if let Ok(s) = core::str::from_utf8(&message) { - info!("Received: {}", s); - } - - buffer = 0; + if start_byte != START { + info!("start fail: 0x{:02X}", start_byte); + continue; + } + + // len + let len = sample_byte(&mut pin, bit_time).await; + if len as usize > MAX_PAYLOAD { + info!("bad len {}", len); + continue; + } + + // payload + let mut payload = [0u8; MAX_PAYLOAD]; + for i in 0..(len as usize) { + payload[i] = sample_byte(&mut pin, bit_time).await; + } + + // crc + let crc_recv = sample_byte(&mut pin, bit_time).await; + + // parita + let parity_recv = if pin.is_high() { 1 } else { 0 }; + Timer::after(bit_time).await; + + // stop + let stop = sample_byte(&mut pin, bit_time).await; + if stop != STOP { + info!("bad stop 0x{:02X}", stop); + continue; + } + + // verify CRC + let mut crc_calc = crc8(0, len); + for i in 0..(len as usize) { + crc_calc = crc8(crc_calc, payload[i]); + } + if crc_calc != crc_recv { + info!("crc nesedi 0x{:02X} ma byt 0x{:02X}", crc_recv, crc_calc); + continue; + } + + // verify parity + let mut ones = len.count_ones() + crc_recv.count_ones(); + for i in 0..(len as usize) { + ones += payload[i].count_ones(); + } + if (ones as u8 & 1) != parity_recv { + info!("nesedi parita"); + continue; + } + + if let Ok(s) = core::str::from_utf8(&payload[..len as usize]) { + info!("RX OK: \"{}\"", s); + } else { + info!("RX OK: {} bytes", len); } } }