compiled, config in src/config, but i get hardfault crash at runtime

This commit is contained in:
Priec
2025-11-05 09:44:41 +01:00
parent 44f154e289
commit d57d16935d
5 changed files with 86 additions and 22 deletions

View File

@@ -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<CriticalSectionRawMutex, PIPE_RX_SIZE> = 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;

16
dma_gpio/src/config.rs Normal file
View File

@@ -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,
};

View File

@@ -1,3 +1,4 @@
#![no_std]
pub mod software_uart;
pub mod config;

View File

@@ -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;
}
}

View File

@@ -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<u8, 256> {
let mut out = Vec::<u8, 256>::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
}