From 15b3b96b6876659c5baa30d0af536c7b39e5f622 Mon Sep 17 00:00:00 2001 From: Priec Date: Sat, 1 Nov 2025 23:47:15 +0100 Subject: [PATCH] compiled and working --- dma_gpio/Cargo.lock | 10 ++++++++++ dma_gpio/Cargo.toml | 1 + dma_gpio/src/bin/main.rs | 27 +++++++++++++-------------- dma_gpio/src/software_uart/runtime.rs | 20 ++++++++++++++------ 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/dma_gpio/Cargo.lock b/dma_gpio/Cargo.lock index 51b0be3..2cf9391 100644 --- a/dma_gpio/Cargo.lock +++ b/dma_gpio/Cargo.lock @@ -279,6 +279,7 @@ dependencies = [ "micromath", "panic-halt", "panic-probe", + "static_cell", "tinybmp", ] @@ -1033,6 +1034,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + [[package]] name = "stm32-fmc" version = "0.3.2" diff --git a/dma_gpio/Cargo.toml b/dma_gpio/Cargo.toml index c209525..2aec6cd 100644 --- a/dma_gpio/Cargo.toml +++ b/dma_gpio/Cargo.toml @@ -26,3 +26,4 @@ tinybmp = "0.6.0" panic-probe = { version = "1.0.0", features = ["defmt"] } defmt-rtt = "1.1.0" defmt = "1.0.1" +static_cell = "2.1.1" diff --git a/dma_gpio/src/bin/main.rs b/dma_gpio/src/bin/main.rs index 3b0bd86..df65f8b 100644 --- a/dma_gpio/src/bin/main.rs +++ b/dma_gpio/src/bin/main.rs @@ -5,6 +5,7 @@ use defmt::*; 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 dma_gpio::software_uart::{ dma_timer::{init_tim6_for_uart, init_tim7_for_uart}, @@ -12,6 +13,7 @@ use dma_gpio::software_uart::{ runtime::{rx_dma_task, tx_dma_task}, debug::dump_tim6_regs, }; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; /// SOFTWARE UART CONFIGURATION @@ -25,36 +27,33 @@ const RX_RING_BYTES: usize = 4096; static PIPE_TX: Pipe = Pipe::new(); static PIPE_RX: Pipe = Pipe::new(); -// Large hardware RX DMA circular buffer, scales with oversampling rate -static mut RX_RING: [u8; RX_RING_BYTES] = [0; RX_RING_BYTES]; +static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { - // Initialize peripheral access - let mut p = embassy_stm32::init(Default::default()); - info!("UART DMA demo starting..."); + let p = embassy_stm32::init(Default::default()); + info!("Hehe"); - // GPIO setup - let rx = Input::new(p.PA3, Pull::Up); + let _rx = Input::new(p.PA3, Pull::Up); let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh); - // Timer setup init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE); init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE); - dump_tim6_regs(); // debug + dump_tim6_regs(); - // Spawn DMA tasks - spawner.spawn(tx_dma_task(p.GPDMA1_CH0)).unwrap(); - spawner.spawn(rx_dma_task(p.GPDMA1_CH1)).unwrap(); + // Safe one-time init from StaticCell + let ring: &mut [u8; RX_RING_BYTES] = RX_RING.init([0; RX_RING_BYTES]); + + // Spawn tasks + spawner.spawn(tx_dma_task(p.GPDMA1_CH0, &PIPE_TX).unwrap()); + spawner.spawn(rx_dma_task(p.GPDMA1_CH1, &PIPE_RX, ring).unwrap()); - // UART config (8N1 default) let uart_cfg = UartConfig { data_bits: 8, parity: Parity::None, stop_bits: StopBits::One, }; - // Main loop: send data periodically loop { write_uart_frames_to_pipe(&PIPE_TX, TX_PIN_BIT, b"Hello marshmallow\r\n", &uart_cfg).await; Timer::after(Duration::from_secs(2)).await; diff --git a/dma_gpio/src/software_uart/runtime.rs b/dma_gpio/src/software_uart/runtime.rs index c111745..af26bf0 100644 --- a/dma_gpio/src/software_uart/runtime.rs +++ b/dma_gpio/src/software_uart/runtime.rs @@ -9,39 +9,47 @@ use embassy_stm32::{ use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use embassy_time::Duration; use crate::software_uart::{ - gpio_dma_uart_rx::TIM7_UP_REQ, gpio_dma_uart_tx::GpioDmaBsrrTx, + gpio_dma_uart_rx::TIM7_UP_REQ, + gpio_dma_uart_tx::GpioDmaBsrrTx, debug::{dump_dma_ch0_regs, dump_tim6_regs}, }; /// RX DMA task: reads GPIO samples paced by TIM7 and fills PIPE_RX #[task] -pub async fn rx_dma_task(ch: Peri<'static, GPDMA1_CH1>) { - let ring = unsafe { &mut RX_RING }; +pub async fn rx_dma_task( + ch: Peri<'static, GPDMA1_CH1>, + pipe_rx: &'static Pipe, + ring: &'static mut [u8], +) { let gpioa_idr = embassy_stm32::pac::GPIOA.idr().as_ptr() as *mut u8; let mut opts = TransferOptions::default(); opts.half_transfer_ir = true; opts.complete_transfer_ir = true; + // SAFETY: ring is exclusive to this task let mut rx = unsafe { DmaRingRx::new(ch, TIM7_UP_REQ, gpioa_idr, ring, opts) }; rx.start(); let mut chunk = [0u8; 256]; loop { let _ = rx.read_exact(&mut chunk).await; - PIPE_RX.write(&chunk).await; + pipe_rx.write(&chunk).await; } } /// TX DMA task: dequeues prebuilt frames from PIPE_TX and writes to GPIOA.BSRR #[task] -pub async fn tx_dma_task(ch: Peri<'static, GPDMA1_CH0>) { +pub async fn tx_dma_task( + ch: Peri<'static, GPDMA1_CH0>, + pipe_tx: &'static Pipe, +) { let mut tx = GpioDmaBsrrTx::new(ch); info!("DMA TX task started"); loop { let mut b = [0u8; 4]; - let n = PIPE_TX.read(&mut b).await; + let n = pipe_tx.read(&mut b).await; if n != 4 { continue; }