// src/bin/main.rs #![no_std] #![no_main] use defmt::*; use embassy_executor::Spawner; use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed}; use embassy_time::{Duration, Timer}; use dma_gpio::software_uart::{ dma_timer::{init_tim6_for_uart, init_tim7_for_uart}, gpio_dma_uart_tx::{write_uart_frames_to_pipe, UartConfig, Parity, StopBits}, runtime::{rx_dma_task, tx_dma_task}, debug::dump_tim6_regs, }; 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 PIPE_TX_SIZE: usize = 256; const PIPE_RX_SIZE: usize = 256; 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]; #[embassy_executor::main] async fn main(spawner: Spawner) { // Initialize peripheral access let mut p = embassy_stm32::init(Default::default()); info!("UART DMA demo starting..."); // GPIO setup 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 // Spawn DMA tasks spawner.spawn(tx_dma_task(p.GPDMA1_CH0)).unwrap(); spawner.spawn(rx_dma_task(p.GPDMA1_CH1)).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; } }