// src/bin/main.rs #![no_std] #![no_main] use defmt::*; use embassy_executor::Spawner; use embassy_stm32::dma::Request; use embassy_stm32::gpio::{Input, Output, Level, Pull, Speed}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use embassy_stm32::dma::{TransferOptions, WritableRingBuffer}; use dma_gpio::software_uart::{ dma_timer::{init_tim6_for_uart, init_tim7_for_uart}, gpio_dma_uart_tx::encode_uart_frames, gpio_dma_uart_rx::rx_dma_task, debug::dump_tim6_regs, }; use dma_gpio::config::{BAUD, TX_PIN_BIT, RX_OVERSAMPLE, TX_OVERSAMPLE}; use dma_gpio::config::{TX_RING_BYTES, RX_RING_BYTES, PIPE_RX_SIZE}; use static_cell::StaticCell; use embassy_futures::yield_now; use {defmt_rtt as _, panic_probe as _}; pub const TIM6_UP_REQ: Request = 4; static PIPE_RX: Pipe = Pipe::new(); static TX_RING: StaticCell<[u32; TX_RING_BYTES]> = StaticCell::new(); static RX_RING: StaticCell<[u8; RX_RING_BYTES]> = StaticCell::new(); #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hehe"); let _rx = Input::new(p.PA3, Pull::Up); let _tx = Output::new(p.PA2, Level::High, Speed::VeryHigh); init_tim6_for_uart(p.TIM6, BAUD, TX_OVERSAMPLE); init_tim7_for_uart(p.TIM7, BAUD, RX_OVERSAMPLE); dump_tim6_regs(); // Safe one-time init from StaticCell let rx_ring: &mut [u8; RX_RING_BYTES] = RX_RING.init([0; RX_RING_BYTES]); let tx_ring_mem: &mut [u32; TX_RING_BYTES] = TX_RING.init([0; TX_RING_BYTES]); // Spawn tasks spawner.spawn(rx_dma_task(p.GPDMA1_CH1, &PIPE_RX, rx_ring).unwrap()); // Create and start the TX DMA ring in main. // let bsrr_ptr = embassy_stm32::pac::GPIOA.bsrr().as_ptr() as *mut u32; let odr_ptr = embassy_stm32::pac::GPIOA.odr().as_ptr() as *mut u32; let mut tx_opts = TransferOptions::default(); tx_opts.half_transfer_ir = true; tx_opts.complete_transfer_ir = true; // SAFETY: tx_ring_mem is exclusive let mut tx_ring = unsafe { WritableRingBuffer::new( p.GPDMA1_CH0, TIM6_UP_REQ, odr_ptr, tx_ring_mem, tx_opts, ) }; // Start DMA tx_ring.start(); info!("TX DMA ring started"); let mut frame_buf = [0u32; 4096]; loop { info!("tick start"); // Timer::after(Duration::from_millis(100)).await; // info!("tick end"); let used = encode_uart_frames( TX_PIN_BIT, b"Hello marshmallow\r\n", &mut frame_buf, ) .await; if used == 0 { info!("encode_uart_frames() produced 0 words, skipping write"); yield_now().await; continue; } let _ = tx_ring.write_exact(&frame_buf[..used]).await; info!("text"); yield_now().await; } }