use embassy_hal_internal::{Peri, PeripheralType};
use pac::peripherals::timer::TIM_GP;
use crate::pac;
pub mod complementary_pwm;
pub mod hall;
pub mod input_capture;
pub mod low_level;
pub mod one_pulse;
pub mod output_compare;
pub mod pwm;
pub mod pwm_input;
pub mod qei;
#[cfg(feature = "dma")]
pub mod ringbuffered;
pub use complementary_pwm::{ComplementaryPwm, ComplementaryPwmChannel};
pub use hall::HallSensor;
pub use input_capture::{Capture, InputCapture};
pub use one_pulse::OnePulse;
pub use output_compare::{OutputCompare, OutputCompareChannel};
pub use pwm::{Pwm, PwmChannel};
pub use pwm_input::{PwmInput, PwmMeasurement};
pub use qei::Qei;
#[cfg(feature = "dma")]
pub use ringbuffered::{
RingBufferedCapture, RingBufferedPwmBurst, RingBufferedPwmChannel, TimerDmaWord,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Channel {
Ch1,
Ch2,
Ch3,
Ch4,
}
impl Channel {
pub(crate) const fn index(self) -> usize {
match self {
Self::Ch1 => 0,
Self::Ch2 => 1,
Self::Ch3 => 2,
Self::Ch4 => 3,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Polarity {
ActiveHigh,
ActiveLow,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimerWidth {
Bits16,
Bits32,
}
pub(crate) trait SealedInstance {
fn regs() -> TIM_GP;
}
#[allow(private_bounds)]
pub trait Instance: SealedInstance + PeripheralType {
const IRQ: Option<u16>;
const WIDTH: TimerWidth;
}
macro_rules! impl_tim {
($instance:ident, $base:expr, $width:ident, $irq:expr) => {
impl crate::timer::SealedInstance for crate::peripherals::$instance {
#[inline]
fn regs() -> crate::pac::peripherals::timer::TIM_GP {
unsafe { crate::pac::peripherals::timer::TIM_GP::from_ptr($base as *mut ()) }
}
}
impl crate::timer::Instance for crate::peripherals::$instance {
const IRQ: ::core::option::Option<u16> = $irq;
const WIDTH: crate::timer::TimerWidth = crate::timer::TimerWidth::$width;
}
};
}
pub(crate) use impl_tim;
pub struct Timer {
tim: TIM_GP,
clock_hz: u32,
width: TimerWidth,
}
impl Timer {
pub fn new<T: Instance>(peri: Peri<'static, T>, clock_hz: u32) -> Self {
assert!(clock_hz > 0, "timer clock must be non-zero");
let _ = peri;
Self {
tim: T::regs(),
clock_hz,
width: T::WIDTH,
}
}
#[cfg(test)]
pub(crate) fn over(tim: TIM_GP, clock_hz: u32, width: TimerWidth) -> Self {
Self {
tim,
clock_hz,
width,
}
}
pub fn into_pwm(self, freq_hz: u32) -> Pwm {
Pwm::new(self, freq_hz)
}
pub fn into_pwm_with_mode(self, freq_hz: u32, counting_mode: low_level::CountingMode) -> Pwm {
Pwm::new_with_mode(self, freq_hz, counting_mode)
}
pub const fn clock_hz(&self) -> u32 {
self.clock_hz
}
pub const fn width(&self) -> TimerWidth {
self.width
}
pub(crate) const fn regs(&self) -> TIM_GP {
self.tim
}
}