// src/dma_timer.rs

use embassy_stm32::{
    peripherals::{TIM6, TIM7},
    timer::low_level::Timer,
    Peri,
    time::Hertz,
};
use core::mem;
use embassy_stm32::timer::BasicInstance;

/// 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);
    configure_basic_timer(&ll, baud, oversample);
    mem::forget(ll);
}

/// Initializes TIM7 to tick at `baud * oversample` frequency.
/// Each TIM7 update event triggers one DMA beat.
pub fn init_tim7_for_uart<'d>(tim7: Peri<'d, TIM7>, baud: u32, oversample: u16) {
    let ll = Timer::new(tim7);
    configure_basic_timer(&ll, baud, oversample);
    ll.enable_update_interrupt(false); //Disable CPU interrupts
    mem::forget(ll);
}

fn configure_basic_timer<T: BasicInstance>(ll: &Timer<'_, T>, baud: u32, oversample: u16) {
    let target = baud.saturating_mul(oversample.max(1) as u32).max(1);
    let target_freq = Hertz(target);

    ll.stop();
    ll.set_frequency(target_freq);
    ll.enable_update_dma(true);

    ll.clear_update_interrupt();
    ll.start();
}
