compiled and working

This commit is contained in:
Priec
2025-11-01 23:47:15 +01:00
parent 4365c72688
commit 15b3b96b68
4 changed files with 38 additions and 20 deletions

10
dma_gpio/Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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<CriticalSectionRawMutex, PIPE_TX_SIZE> = Pipe::new();
static PIPE_RX: Pipe<CriticalSectionRawMutex, PIPE_RX_SIZE> = 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;

View File

@@ -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<CriticalSectionRawMutex, 256>,
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<CriticalSectionRawMutex, 256>,
) {
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;
}