From d57d16935d5d0b7af76ec5bf92a7e0e727c6ed93 Mon Sep 17 00:00:00 2001 From: Priec Date: Wed, 5 Nov 2025 09:44:41 +0100 Subject: [PATCH] compiled, config in src/config, but i get hardfault crash at runtime --- dma_gpio/src/bin/main.rs | 25 ++------ dma_gpio/src/config.rs | 16 +++++ dma_gpio/src/lib.rs | 1 + .../src/software_uart/gpio_dma_uart_rx.rs | 5 +- dma_gpio/src/software_uart/uart_emulation.rs | 61 +++++++++++++++++++ 5 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 dma_gpio/src/config.rs diff --git a/dma_gpio/src/bin/main.rs b/dma_gpio/src/bin/main.rs index 445f01f..bd76645 100644 --- a/dma_gpio/src/bin/main.rs +++ b/dma_gpio/src/bin/main.rs @@ -7,29 +7,18 @@ use embassy_executor::Spawner; use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use embassy_time::{Duration, Timer}; +use embassy_stm32::dma::{TransferOptions, WritableRingBuffer}; use dma_gpio::software_uart::{ dma_timer::{init_tim6_for_uart, init_tim7_for_uart}, - uart_emulation::{Parity, StopBits, UartConfig}, gpio_dma_uart_tx::{write_uart_frames_to_ring, TIM6_UP_REQ}, gpio_dma_uart_rx::rx_dma_task, debug::dump_tim6_regs, }; -use embassy_stm32::dma::{TransferOptions, WritableRingBuffer}; +use dma_gpio::config::{BAUD, TX_PIN_BIT, RX_OVERSAMPLE, TX_OVERSAMPLE, UART_CFG}; +use dma_gpio::config::{TX_RING_BYTES, RX_RING_BYTES, PIPE_RX_SIZE}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -/// SOFTWARE UART CONFIGURATION -const BAUD: u32 = 115_200; -const TX_PIN_BIT: u8 = 2; // PA2 -const TX_OVERSAMPLE: u16 = 1; -const RX_OVERSAMPLE: u16 = 16; -const RX_RING_BYTES: usize = 4096; -const TX_RING_BYTES: usize = 4096; - -// Nemoze by generic, v taskoch treba manualne zmenit -// Compiler upozorni, takze ostava takto -const PIPE_RX_SIZE: usize = 256; - static PIPE_RX: Pipe = Pipe::new(); static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new(); static TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new(); @@ -75,18 +64,12 @@ async fn main(spawner: Spawner) { tx_ring.start(); info!("TX DMA ring started"); - let uart_cfg = UartConfig { - data_bits: 8, - parity: Parity::None, - stop_bits: StopBits::One, - }; - loop { write_uart_frames_to_ring( &mut tx_ring, TX_PIN_BIT, b"Hello marshmallow\r\n", - &uart_cfg, + &UART_CFG, ) .await; Timer::after(Duration::from_secs(2)).await; diff --git a/dma_gpio/src/config.rs b/dma_gpio/src/config.rs new file mode 100644 index 0000000..048e9f5 --- /dev/null +++ b/dma_gpio/src/config.rs @@ -0,0 +1,16 @@ +// src/config.rs +use crate::software_uart::uart_emulation::{Parity, StopBits, UartConfig}; + +pub const BAUD: u32 = 115_200; +pub const TX_PIN_BIT: u8 = 2; // PA2 +pub const TX_OVERSAMPLE: u16 = 1; +pub const RX_OVERSAMPLE: u16 = 16; +pub const RX_RING_BYTES: usize = 4096; +pub const TX_RING_BYTES: usize = 4096; +pub const PIPE_RX_SIZE: usize = 256; + +pub const UART_CFG: UartConfig = UartConfig { + data_bits: 8, + parity: Parity::None, + stop_bits: StopBits::One, +}; diff --git a/dma_gpio/src/lib.rs b/dma_gpio/src/lib.rs index 869e157..9123142 100644 --- a/dma_gpio/src/lib.rs +++ b/dma_gpio/src/lib.rs @@ -1,3 +1,4 @@ #![no_std] pub mod software_uart; +pub mod config; diff --git a/dma_gpio/src/software_uart/gpio_dma_uart_rx.rs b/dma_gpio/src/software_uart/gpio_dma_uart_rx.rs index a55140e..f3d5a6c 100644 --- a/dma_gpio/src/software_uart/gpio_dma_uart_rx.rs +++ b/dma_gpio/src/software_uart/gpio_dma_uart_rx.rs @@ -9,6 +9,8 @@ use embassy_stm32::dma::{ ReadableRingBuffer as DmaRingRx, TransferOptions, }; +use crate::config::{RX_OVERSAMPLE, UART_CFG}; +use crate::software_uart::decode_uart_samples; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; // datasheet tabulka 137 @@ -34,6 +36,7 @@ pub async fn rx_dma_task( let mut chunk = [0u8; 256]; loop { let _ = rx.read_exact(&mut chunk).await; - pipe_rx.write(&chunk).await; + let decoded = decode_uart_samples(&chunk, RX_OVERSAMPLE, &UART_CFG); + pipe_rx.write(&decoded).await; } } diff --git a/dma_gpio/src/software_uart/uart_emulation.rs b/dma_gpio/src/software_uart/uart_emulation.rs index edd2fd5..085dc7d 100644 --- a/dma_gpio/src/software_uart/uart_emulation.rs +++ b/dma_gpio/src/software_uart/uart_emulation.rs @@ -1,4 +1,5 @@ // src/software_uart/uart_emulation.rs +use heapless::Vec; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Parity { @@ -87,3 +88,63 @@ pub fn encode_uart_byte_cfg( idx } + +/// Decode an oversampled stream of logic levels into UART bytes. +pub fn decode_uart_samples( + samples: &[u8], + oversample: u16, + cfg: &UartConfig, +) -> heapless::Vec { + + let mut out = Vec::::new(); + let mut idx = 0usize; + let nbits = cfg.data_bits as usize; + + while idx + (oversample as usize * (nbits + 3)) < samples.len() { + // Wait for start bit (falling edge: high -> low) + if samples[idx] != 0 && samples[idx + 1] == 0 { + // Align to middle of start bit + idx += (oversample / 2) as usize; + + // Sanity check start bit really low + if samples.get(idx).copied().unwrap_or(1) != 0 { + idx += 1; + continue; + } + + // Sample data bits + let mut data: u8 = 0; + for bit in 0..nbits { + idx += oversample as usize; + let bit_val = samples + .get(idx) + .map(|&b| if b != 0 { 1u8 } else { 0u8 }) + .unwrap_or(1); + data |= bit_val << bit; + } + + // Parity: skip / verify + match cfg.parity { + Parity::None => {} + Parity::Even | Parity::Odd => { + idx += oversample as usize; + // You can optionally add parity check here if needed + } + } + + // Move past stop bits + let stop_skip = match cfg.stop_bits { + StopBits::One => oversample as usize, + StopBits::Two => (oversample * 2) as usize, + }; + idx += stop_skip; + + // Push decoded byte + let _ = out.push(data); + } else { + idx += 1; + } + } + + out +}