timer is now separated

This commit is contained in:
Priec
2025-10-31 00:05:19 +01:00
parent f2b6590473
commit f56fe0561b
3 changed files with 38 additions and 15 deletions

View File

@@ -7,18 +7,17 @@ use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, pipe::Pipe};
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use dma_gpio::dma_timer::init_tim6_for_uart;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
use embassy_stm32::{ use embassy_stm32::{
gpio::{Level, Output, Speed}, gpio::{Level, Output, Speed},
peripherals::{GPDMA1_CH0, TIM6}, peripherals::GPDMA1_CH0,
rcc,
timer::low_level::Timer as LlTimer,
}; };
use embassy_stm32::Peri; use embassy_stm32::Peri;
use dma_gpio::gpio_dma_uart::{ 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<CriticalSectionRawMutex, 256> = Pipe::new(); static PIPE: Pipe<CriticalSectionRawMutex, 256> = Pipe::new();
@@ -26,6 +25,7 @@ static PIPE: Pipe<CriticalSectionRawMutex, 256> = Pipe::new();
// Baud rate: one TIM6 update equals one UART bit-time // Baud rate: one TIM6 update equals one UART bit-time
const BAUD: u32 = 115_200; const BAUD: u32 = 115_200;
const TX_PIN_BIT: u8 = 2; // PA2 const TX_PIN_BIT: u8 = 2; // PA2
const OVERSAMPLE: u16 = 6;
const UART_CFG: UartConfig = UartConfig { const UART_CFG: UartConfig = UartConfig {
data_bits: 8, data_bits: 8,
@@ -41,17 +41,7 @@ async fn main(spawner: Spawner) {
// PA2 is the TX "wire" // PA2 is the TX "wire"
let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh); let _pa2 = Output::new(p.PA2, Level::High, Speed::VeryHigh);
drop(_pa2); drop(_pa2);
init_tim6_for_uart(p.TIM6, BAUD, OVERSAMPLE);
// TIM6 generates one DMA request per bit-time
let tim6 = LlTimer::new(p.TIM6);
let f_tim6 = rcc::frequency::<TIM6>().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);
});
// Start DMA consumer task // Start DMA consumer task
spawner.spawn(dma_tx_task(p.GPDMA1_CH0)).unwrap(); spawner.spawn(dma_tx_task(p.GPDMA1_CH0)).unwrap();

29
dma_gpio/src/dma_timer.rs Normal file
View File

@@ -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::<TIM6>().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);
});
}

View File

@@ -1,3 +1,7 @@
#![no_std] #![no_std]
pub mod gpio_dma_uart; pub mod gpio_dma_uart;
pub use gpio_dma_uart::*; pub use gpio_dma_uart::*;
pub mod dma_timer;
pub use dma_timer::*;