pub(crate) mod sealed {
use super::super::*;
use crate::clock::timer_pclk;
use crate::pac;
pub trait Instance {
fn id() -> Timer;
#[inline]
fn block() -> &'static pac::tim3::RegisterBlock {
match Self::id() {
Timer::TIM3 => unsafe { pac::TIM3::PTR.as_ref().unwrap() },
}
}
#[inline]
fn start() {
Self::block().cr1.modify(|_, w| w.cen().set_bit())
}
#[inline]
fn stop() {
Self::block().cr1.modify(|_, w| w.cen().clear_bit())
}
#[inline]
fn get_time_pclk() -> u32 {
timer_pclk()
}
#[inline]
fn set_prescaler(prescaler: u16) {
Self::block()
.psc
.write(|w| unsafe { w.psc().bits(prescaler) })
}
#[inline]
fn set_period_cnt(cnt: u16) {
Self::block()
.psc
.modify(|_, w| unsafe { w.psc().bits(cnt) })
}
#[inline]
fn set_cnt(cnt: u16) {
Self::block().cnt.write(|w| unsafe { w.cnt().bits(cnt) })
}
#[inline]
fn get_cnt() -> u16 {
Self::block().cnt.read().cnt().bits()
}
#[inline]
fn set_cms(cms: CenterAlignedMode) {
Self::block()
.cr1
.modify(|_, w| unsafe { w.cms().bits(cms as u8) });
}
#[inline]
fn set_dir(dir: CountDirection) {
Self::block()
.cr1
.modify(|_, w| w.dir().bit(dir == CountDirection::Down));
}
#[inline]
fn set_auto_reload(load: u16) {
Self::block().arr.write(|w| unsafe { w.arr().bits(load) })
}
#[inline]
fn get_reload() -> u16 {
Self::block().arr.read().arr().bits()
}
#[inline]
fn enable_single_mode(en: bool) {
Self::block().cr1.modify(|_, w| w.opm().bit(en))
}
#[inline]
fn enable_auto_reload_buff(en: bool) {
Self::block().cr1.modify(|_, w| w.arpe().bit(en))
}
#[inline]
fn counter_frequency() -> u32 {
let psc: u32 = Self::block().psc.read().bits();
timer_pclk() / (psc + 1)
}
fn set_channel_type(channel: Channel, channel_type: ChannelType) {
let block = Self::block();
match channel {
Channel::CH1 => block
.ccmr1_output()
.modify(|_, w| unsafe { w.cc1s().bits(channel_type as u8) }),
Channel::CH2 => block
.ccmr1_output()
.modify(|_, w| unsafe { w.cc2s().bits(channel_type as u8) }),
Channel::CH3 => block
.ccmr2_output()
.modify(|_, w| unsafe { w.cc3s().bits(channel_type as u8) }),
Channel::CH4 => block
.ccmr2_output()
.modify(|_, w| unsafe { w.cc4s().bits(channel_type as u8) }),
}
}
fn set_channel_output_config(
channel: Channel,
mode: ChannelMode,
clear: bool,
fast: bool,
preload: bool,
) {
let block = Self::block();
match channel {
Channel::CH1 => block.ccmr1_output().modify(|_, w| unsafe {
w.oc1m()
.bits(mode as u8)
.oc1ce()
.bit(clear)
.oc1fe()
.bit(fast)
.oc1pe()
.bit(preload)
}),
Channel::CH2 => block.ccmr1_output().modify(|_, w| {
unsafe { w.oc2m().bits(mode as u8) }
.oc2ce()
.bit(clear)
.oc2fe()
.bit(fast)
.oc2pe()
.bit(preload)
}),
Channel::CH3 => block.ccmr2_output().modify(|_, w| unsafe {
w.oc3m()
.bits(mode as u8)
.oc3ce()
.bit(clear)
.oc3fe()
.bit(fast)
.oc3pe()
.bit(preload)
}),
Channel::CH4 => block.ccmr2_output().modify(|_, w| unsafe {
w.oc4m()
.bits(mode as u8)
.oc4ce()
.bit(clear)
.oc4fe()
.bit(fast)
.oc4pe()
.bit(preload)
}),
}
}
fn set_channel_compare(channel: Channel, ccr: u16) {
let block = Self::block();
match channel {
Channel::CH1 => block.ccr1.write(|w| unsafe { w.ccr1().bits(ccr) }),
Channel::CH2 => block.ccr2.modify(|_, w| unsafe { w.ccr2().bits(ccr) }),
Channel::CH3 => block.ccr3.modify(|_, w| unsafe { w.ccr3().bits(ccr) }),
Channel::CH4 => block.ccr4.modify(|_, w| unsafe { w.ccr4().bits(ccr) }),
}
}
fn get_channel_capture(channel: Channel) -> u16 {
let block = Self::block();
match channel {
Channel::CH1 => block.ccr1.read().ccr1().bits(),
Channel::CH2 => block.ccr2.read().ccr2().bits(),
Channel::CH3 => block.ccr3.read().ccr3().bits(),
Channel::CH4 => block.ccr4.read().ccr4().bits(),
}
}
fn set_enable_channel(channel: Channel, en: bool) {
let block = Self::block();
match channel {
Channel::CH1 => block.ccer.modify(|_, w| w.cc1e().bit(en)),
Channel::CH2 => block.ccer.modify(|_, w| w.cc2e().bit(en)),
Channel::CH3 => block.ccer.modify(|_, w| w.cc3e().bit(en)),
Channel::CH4 => block.ccer.modify(|_, w| w.cc4e().bit(en)),
}
}
#[inline]
fn triggle(signal: Triggle) {
let egr = &Self::block().egr;
match signal {
Triggle::UG => egr.write(|w| w.ug().set_bit()),
Triggle::CC1G => egr.write(|w| w.cc1g().set_bit()),
Triggle::CC2G => egr.write(|w| w.cc2g().set_bit()),
Triggle::CC3G => egr.write(|w| w.cc3g().set_bit()),
Triggle::CC4G => egr.write(|w| w.cc4g().set_bit()),
Triggle::TG => egr.write(|w| w.tg().set_bit()),
}
}
#[inline]
fn event_flag(event: Event) -> bool {
let sr = Self::block().sr.read();
match event {
Event::UIF => sr.uif().bit(),
Event::CC1IF => sr.cc1if().bit(),
Event::CC2IF => sr.cc2if().bit(),
Event::CC3IF => sr.cc3if().bit(),
Event::CC4IF => sr.cc4if().bit(),
Event::TIF => sr.tif().bit(),
Event::CC1OF => sr.cc1of().bit(),
Event::CC2OF => sr.cc2of().bit(),
Event::CC3OF => sr.cc3of().bit(),
Event::CC4OF => sr.cc4of().bit(),
}
}
#[inline]
fn event_config(event: Event, en: bool) {
Self::block().dier.modify(|_, w| match event {
Event::UIF => w.uie().bit(en),
Event::CC1IF => w.cc1ie().bit(en),
Event::CC2IF => w.cc2ie().bit(en),
Event::CC3IF => w.cc3ie().bit(en),
Event::CC4IF => w.cc4ie().bit(en),
Event::TIF => w.tie().bit(en),
Event::CC1OF => w.cc1de().bit(en),
Event::CC2OF => w.cc2de().bit(en),
Event::CC3OF => w.cc3de().bit(en),
Event::CC4OF => w.cc4de().bit(en),
})
}
#[inline]
fn event_clear(event: Event) {
Self::block().sr.modify(|_, w| match event {
Event::UIF => w.uif().clear_bit(),
Event::CC1IF => w.cc1if().clear_bit(),
Event::CC2IF => w.cc2if().clear_bit(),
Event::CC3IF => w.cc3if().clear_bit(),
Event::CC4IF => w.cc4if().clear_bit(),
Event::TIF => w.tif().clear_bit(),
Event::CC1OF => w.cc1of().clear_bit(),
Event::CC2OF => w.cc2of().clear_bit(),
Event::CC3OF => w.cc3of().clear_bit(),
Event::CC4OF => w.cc4of().clear_bit(),
});
}
fn micros_to_compute_with_rep(micros: u64) -> (u16, u16) {
let ticks = micros * Self::get_time_pclk() as u64 / 1_000_000;
let psc = ticks / (1u64 << 16);
let count = ticks / (psc + 1);
assert!(count < u16::MAX as u64);
(psc as u16, count as u16)
}
fn nanosecond_to_compute_with_rep(nano: u64) -> (u16, u16) {
let ticks = nano * Self::get_time_pclk() as u64 / 1_000_000_000;
let psc = ticks / (1u64 << 16);
let count = ticks / (psc + 1);
assert!(count < u16::MAX as u64);
(psc as u16, count as u16)
}
}
}