From f56fe0561b8bf8d573bb60b38edc5cdba10de32c Mon Sep 17 00:00:00 2001 From: Priec Date: Fri, 31 Oct 2025 00:05:19 +0100 Subject: [PATCH] timer is now separated --- dma_gpio/src/bin/main.rs | 20 +++++--------------- dma_gpio/src/dma_timer.rs | 29 +++++++++++++++++++++++++++++ dma_gpio/src/lib.rs | 4 ++++ 3 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 dma_gpio/src/dma_timer.rs diff --git a/dma_gpio/src/bin/main.rs b/dma_gpio/src/bin/main.rs index 00afd74..1728d5d 100644 --- a/dma_gpio/src/bin/main.rs +++ b/dma_gpio/src/bin/main.rs @@ -7,18 +7,17 @@ use defmt::*; use embassy_executor::Spawner; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use embassy_time::{Duration, Timer}; +use dma_gpio::dma_timer::init_tim6_for_uart; use {defmt_rtt as _, panic_probe as _}; use embassy_stm32::{ gpio::{Level, Output, Speed}, - peripherals::{GPDMA1_CH0, TIM6}, - rcc, - timer::low_level::Timer as LlTimer, + peripherals::GPDMA1_CH0, }; use embassy_stm32::Peri; use dma_gpio::gpio_dma_uart::{ - write_uart_frames_to_pipe, GpioDmaBsrrTx, Parity, StopBits, UartConfig, TIM6_UP_REQ, + write_uart_frames_to_pipe, GpioDmaBsrrTx, Parity, StopBits, UartConfig, }; static PIPE: Pipe = Pipe::new(); @@ -26,6 +25,7 @@ static PIPE: Pipe = Pipe::new(); // Baud rate: one TIM6 update equals one UART bit-time const BAUD: u32 = 115_200; const TX_PIN_BIT: u8 = 2; // PA2 +const OVERSAMPLE: u16 = 6; const UART_CFG: UartConfig = UartConfig { data_bits: 8, @@ -41,17 +41,7 @@ async fn main(spawner: Spawner) { // PA2 is the TX "wire" let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh); drop(_pa2); - - // TIM6 generates one DMA request per bit-time - let tim6 = LlTimer::new(p.TIM6); - let f_tim6 = rcc::frequency::().0; - let arr = (f_tim6 / BAUD).saturating_sub(1) as u16; - tim6.regs_basic().arr().modify(|w| w.set_arr(arr)); - tim6.regs_basic().dier().modify(|w| w.set_ude(true)); - tim6.regs_basic().cr1().modify(|w| { - w.set_opm(false); - w.set_cen(true); - }); + init_tim6_for_uart(p.TIM6, BAUD, OVERSAMPLE); // Start DMA consumer task spawner.spawn(dma_tx_task(p.GPDMA1_CH0)).unwrap(); diff --git a/dma_gpio/src/dma_timer.rs b/dma_gpio/src/dma_timer.rs new file mode 100644 index 0000000..52bf1c0 --- /dev/null +++ b/dma_gpio/src/dma_timer.rs @@ -0,0 +1,29 @@ +// src/dma_timer.rs + +use embassy_stm32::{ + peripherals::TIM6, + rcc, + timer::low_level::Timer, + Peri, +}; + +/// Initializes TIM6 to tick at `baud * oversample` frequency. +/// Each TIM6 update event triggers one DMA beat. +pub fn init_tim6_for_uart<'d>(tim6: Peri<'d, TIM6>, baud: u32, oversample: u16) { + + let ll = Timer::new(tim6); + + let f_tim6 = rcc::frequency::().0; + let target = baud.saturating_mul(oversample.max(1) as u32); + + // Compute ARR for desired frequency (16-bit timer) + let arr = (f_tim6 / target).saturating_sub(1) as u16; + + // Apply registers + ll.regs_basic().arr().write(|w| w.set_arr(arr)); + ll.regs_basic().dier().write(|w| w.set_ude(true)); + ll.regs_basic().cr1().write(|w| { + w.set_opm(false); + w.set_cen(true); + }); +} diff --git a/dma_gpio/src/lib.rs b/dma_gpio/src/lib.rs index 2533591..26fe4b2 100644 --- a/dma_gpio/src/lib.rs +++ b/dma_gpio/src/lib.rs @@ -1,3 +1,7 @@ #![no_std] + pub mod gpio_dma_uart; pub use gpio_dma_uart::*; + +pub mod dma_timer; +pub use dma_timer::*;