diff --git a/src/adc.rs b/src/adc.rs index ca69c3e4..0f1942b8 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use embedded_hal_02::adc::{Channel, OneShot}; use fugit::HertzU32 as Hertz; -#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl",),))] +#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl")))] use crate::dma::dma2; use crate::dma::{dma1, CircBuffer, Receive, RxDma, Transfer, TransferPayload, W}; use crate::gpio::{self, Analog}; @@ -153,7 +153,7 @@ adc_pins!(pac::ADC2, gpio::PC5 => 15, ); -#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl",),))] +#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl")))] adc_pins!(pac::ADC3, gpio::PA0 => 0, gpio::PA1 => 1, @@ -548,7 +548,7 @@ adc_hal! { pac::ADC2: (adc2), } -#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl",),))] +#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl")))] adc_hal! { pac::ADC3: (adc3), } @@ -810,7 +810,7 @@ adcdma! { ) } -#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl",),))] +#[cfg(all(feature = "stm32f103", any(feature = "high", feature = "xl")))] adcdma! { pac::ADC3: ( AdcDma3, diff --git a/src/qei.rs b/src/qei.rs index dd2a708b..a79c75af 100644 --- a/src/qei.rs +++ b/src/qei.rs @@ -6,11 +6,7 @@ */ use core::marker::PhantomData; -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -use crate::pac::TIM1; -#[cfg(feature = "medium")] -use crate::pac::TIM4; -use crate::pac::{TIM2, TIM3}; +use crate::pac; use embedded_hal_02 as hal; pub use hal::Direction; @@ -70,16 +66,16 @@ pub struct Qei { _remap: PhantomData, } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -impl Timer { +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +impl Timer { pub fn qei( self, pins: PINS, mapr: &mut MAPR, options: QeiOptions, - ) -> Qei + ) -> Qei where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) }); @@ -89,15 +85,15 @@ impl Timer { } } -impl Timer { +impl Timer { pub fn qei( self, pins: PINS, mapr: &mut MAPR, options: QeiOptions, - ) -> Qei + ) -> Qei where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) }); @@ -107,15 +103,15 @@ impl Timer { } } -impl Timer { +impl Timer { pub fn qei( self, pins: PINS, mapr: &mut MAPR, options: QeiOptions, - ) -> Qei + ) -> Qei where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) }); @@ -126,15 +122,15 @@ impl Timer { } #[cfg(feature = "medium")] -impl Timer { +impl Timer { pub fn qei( self, pins: PINS, mapr: &mut MAPR, options: QeiOptions, - ) -> Qei + ) -> Qei where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1)); @@ -145,68 +141,61 @@ impl Timer { } macro_rules! hal { - ($($TIMX:ident: ($timX:ident, $timXen:ident, $timXrst:ident),)+) => { - $( - impl Qei<$TIMX, REMAP, PINS> { - fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self { - // Configure TxC1 and TxC2 as captures - tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2()); - - // enable and configure to capture on rising edge - tim.ccer().write(|w| { - w.cc1e() - .set_bit() - .cc1p() - .clear_bit() - .cc2e() - .set_bit() - .cc2p() - .clear_bit() - }); - - // configure as quadrature encoder - tim.smcr().write(|w| w.sms().set(options.slave_mode as u8)); - - tim.arr().write(|w| w.arr().set(options.auto_reload_value)); - tim.cr1().write(|w| w.cen().set_bit()); - - Qei { tim, pins, _remap: PhantomData } + ($TIMX:ty: $timX:ident, $timXen:ident, $timXrst:ident) => { + impl Qei<$TIMX, REMAP, PINS> { + fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self { + // Configure TxC1 and TxC2 as captures + tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2()); + + // enable and configure to capture on rising edge + tim.ccer().write(|w| { + w.cc1e().set_bit(); + w.cc1p().clear_bit(); + w.cc2e().set_bit(); + w.cc2p().clear_bit() + }); + + // configure as quadrature encoder + tim.smcr().write(|w| w.sms().set(options.slave_mode as u8)); + + tim.arr().write(|w| w.arr().set(options.auto_reload_value)); + tim.cr1().write(|w| w.cen().set_bit()); + + Qei { + tim, + pins, + _remap: PhantomData, } + } - pub fn release(self) -> ($TIMX, PINS) { - (self.tim, self.pins) - } + pub fn release(self) -> ($TIMX, PINS) { + (self.tim, self.pins) } + } - impl hal::Qei for Qei<$TIMX, REMAP, PINS> { - type Count = u16; + impl hal::Qei for Qei<$TIMX, REMAP, PINS> { + type Count = u16; - fn count(&self) -> u16 { - self.tim.cnt().read().cnt().bits() - } + fn count(&self) -> u16 { + self.tim.cnt().read().cnt().bits() + } - fn direction(&self) -> Direction { - if self.tim.cr1().read().dir().bit_is_clear() { - Direction::Upcounting - } else { - Direction::Downcounting - } + fn direction(&self) -> Direction { + if self.tim.cr1().read().dir().bit_is_clear() { + Direction::Upcounting + } else { + Direction::Downcounting } } - - )+ - } + } + }; } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -hal! { - TIM1: (_tim1, tim1en, tim1rst), -} -hal! { - TIM2: (_tim2, tim2en, tim2rst), - TIM3: (_tim3, tim3en, tim3rst), -} +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +hal!(pac::TIM1: _tim1, tim1en, tim1rst); + +hal!(pac::TIM2: _tim2, tim2en, tim2rst); +hal!(pac::TIM3: _tim3, tim3en, tim3rst); + #[cfg(feature = "medium")] -hal! { - TIM4: (_tim4, tim4en, tim4rst), -} +hal!(pac::TIM4: _tim4, tim4en, tim4rst); diff --git a/src/rcc/enable.rs b/src/rcc/enable.rs index c6218145..c0a27517 100644 --- a/src/rcc/enable.rs +++ b/src/rcc/enable.rs @@ -165,14 +165,14 @@ bus! { TIM5 => (APB1, 3), } -#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high",)))] +#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high")))] bus! { TIM12 => (APB1, 6), TIM13 => (APB1, 7), TIM14 => (APB1, 8), } -#[cfg(all(feature = "stm32f103", feature = "high",))] +#[cfg(all(feature = "stm32f103", feature = "high"))] bus! { TIM8 => (APB2, 13), } diff --git a/src/timer.rs b/src/timer.rs index ead731f4..997507ce 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -751,19 +751,19 @@ hal!( pac::TIM3: [Timer3, u16, dbg_tim3_stop, c: (CH4), m: tim2,], ); -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] hal!( pac::TIM1: [Timer1, u16, dbg_tim1_stop, c: (CH4, _aoe), m: tim1,], ); -#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity",))] +#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity"))] hal! { pac::TIM6: [Timer6, u16, dbg_tim6_stop, m: tim6,], } #[cfg(any( - all(feature = "high", any(feature = "stm32f101", feature = "stm32f103",),), - any(feature = "stm32f100", feature = "connectivity",) + all(feature = "high", any(feature = "stm32f101", feature = "stm32f103")), + any(feature = "stm32f100", feature = "connectivity") ))] hal! { pac::TIM7: [Timer7, u16, dbg_tim7_stop, m: tim6,], @@ -786,7 +786,7 @@ hal! { pac::TIM5: [Timer5, u16, dbg_tim5_stop, c: (CH4), m: tim2,], } -#[cfg(all(feature = "stm32f103", feature = "high",))] +#[cfg(all(feature = "stm32f103", feature = "high"))] hal! { pac::TIM8: [Timer8, u16, dbg_tim8_stop, c: (CH4, _aoe), m: tim1,], } diff --git a/src/timer/monotonic.rs b/src/timer/monotonic.rs index 80c96134..aebb5d02 100644 --- a/src/timer/monotonic.rs +++ b/src/timer/monotonic.rs @@ -44,110 +44,112 @@ pub trait MonoTimerExt: Sized { } macro_rules! mono { - ($($TIM:ty,)+) => { - $( - impl MonoTimerExt for $TIM { - fn monotonic(self, clocks: &Clocks) -> MonoTimer { - FTimer::new(self, clocks).monotonic() - } + ($TIM:ty) => { + impl MonoTimerExt for $TIM { + fn monotonic(self, clocks: &Clocks) -> MonoTimer { + FTimer::new(self, clocks).monotonic() } + } - impl FTimer<$TIM, FREQ> { - pub fn monotonic(self) -> MonoTimer<$TIM, FREQ> { - MonoTimer::<$TIM, FREQ>::_new(self) - } + impl FTimer<$TIM, FREQ> { + pub fn monotonic(self) -> MonoTimer<$TIM, FREQ> { + MonoTimer::<$TIM, FREQ>::_new(self) } - - impl MonoTimer<$TIM, FREQ> { - fn _new(timer: FTimer<$TIM, FREQ>) -> Self { - timer.tim.arr().write(|w| w.arr().set(u16::MAX)); // Set auto-reload value. - timer.tim.egr().write(|w| w.ug().set_bit()); // Generate interrupt on overflow. - - // Start timer. - timer.tim.sr().modify(|_, w| w.uif().clear_bit()); // Clear interrupt flag. - timer.tim.cr1().modify(|_, w| { - w.cen() - .set_bit() // Enable counter. - .udis() - .clear_bit() // Overflow should trigger update event. - .urs() - .set_bit() // Only overflow triggers interrupt. - }); - - Self { timer, ovf: 0 } - } + } + + impl MonoTimer<$TIM, FREQ> { + fn _new(timer: FTimer<$TIM, FREQ>) -> Self { + // Set auto-reload value. + timer.tim.arr().write(|w| w.arr().set(u16::MAX)); + // Generate interrupt on overflow. + timer.tim.egr().write(|w| w.ug().set_bit()); + + // Start timer. + // Clear interrupt flag. + timer.tim.sr().modify(|_, w| w.uif().clear_bit()); + timer.tim.cr1().modify(|_, w| { + // Enable counter. + w.cen().set_bit(); + // Overflow should trigger update event. + w.udis().clear_bit(); + // Only overflow triggers interrupt. + w.urs().set_bit() + }); + + Self { timer, ovf: 0 } } + } - impl Monotonic for MonoTimer<$TIM, FREQ> { - type Instant = fugit::TimerInstantU32; - type Duration = fugit::TimerDurationU32; + impl Monotonic for MonoTimer<$TIM, FREQ> { + type Instant = fugit::TimerInstantU32; + type Duration = fugit::TimerDurationU32; - unsafe fn reset(&mut self) { - self.tim.dier().modify(|_, w| w.cc1ie().set_bit()); - } + unsafe fn reset(&mut self) { + self.tim.dier().modify(|_, w| w.cc1ie().set_bit()); + } - #[inline(always)] - fn now(&mut self) -> Self::Instant { - let cnt = self.tim.cnt().read().cnt().bits() as u32; + #[inline(always)] + fn now(&mut self) -> Self::Instant { + let cnt = self.tim.cnt().read().cnt().bits() as u32; - // If the overflow bit is set, we add this to the timer value. It means the `on_interrupt` - // has not yet happened, and we need to compensate here. - let ovf = if self.tim.sr().read().uif().bit_is_set() { - 0x10000 - } else { - 0 - }; + // If the overflow bit is set, we add this to the timer value. It means the `on_interrupt` + // has not yet happened, and we need to compensate here. + let ovf = if self.tim.sr().read().uif().bit_is_set() { + 0x10000 + } else { + 0 + }; - Self::Instant::from_ticks(cnt.wrapping_add(ovf).wrapping_add(self.ovf)) - } + Self::Instant::from_ticks(cnt.wrapping_add(ovf).wrapping_add(self.ovf)) + } - fn set_compare(&mut self, instant: Self::Instant) { - let now = self.now(); - let cnt = self.tim.cnt().read().cnt().bits(); + fn set_compare(&mut self, instant: Self::Instant) { + let now = self.now(); + let cnt = self.tim.cnt().read().cnt().bits(); - // Since the timer may or may not overflow based on the requested compare val, we check - // how many ticks are left. - let val = match instant.checked_duration_since(now) { - None => cnt.wrapping_add(0xffff), // In the past, RTIC will handle this - Some(x) if x.ticks() <= 0xffff => instant.duration_since_epoch().ticks() as u16, // Will not overflow - Some(_) => cnt.wrapping_add(0xffff), // Will overflow, run for as long as possible - }; + // Since the timer may or may not overflow based on the requested compare val, we check + // how many ticks are left. + let val = match instant.checked_duration_since(now) { + None => cnt.wrapping_add(0xffff), // In the past, RTIC will handle this + Some(x) if x.ticks() <= 0xffff => instant.duration_since_epoch().ticks() as u16, // Will not overflow + Some(_) => cnt.wrapping_add(0xffff), // Will overflow, run for as long as possible + }; - self.tim.ccr1().write(|w| w.ccr().set(val)); - } + self.tim.ccr1().write(|w| w.ccr().set(val)); + } - fn clear_compare_flag(&mut self) { - self.tim.sr().modify(|_, w| w.cc1if().clear_bit()); - } + fn clear_compare_flag(&mut self) { + self.tim.sr().modify(|_, w| w.cc1if().clear_bit()); + } - fn on_interrupt(&mut self) { - // If there was an overflow, increment the overflow counter. - if self.tim.sr().read().uif().bit_is_set() { - self.tim.sr().modify(|_, w| w.uif().clear_bit()); + fn on_interrupt(&mut self) { + // If there was an overflow, increment the overflow counter. + if self.tim.sr().read().uif().bit_is_set() { + self.tim.sr().modify(|_, w| w.uif().clear_bit()); - self.ovf += 0x10000; - } + self.ovf += 0x10000; } + } - #[inline(always)] - fn zero() -> Self::Instant { - Self::Instant::from_ticks(0) - } + #[inline(always)] + fn zero() -> Self::Instant { + Self::Instant::from_ticks(0) } - )+ - } + } + }; } -mono!(crate::pac::TIM2, crate::pac::TIM3,); +mono!(crate::pac::TIM2); +mono!(crate::pac::TIM3); -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -mono!(crate::pac::TIM1,); +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +mono!(crate::pac::TIM1); #[cfg(feature = "medium")] -mono!(crate::pac::TIM4,); +mono!(crate::pac::TIM4); #[cfg(any(feature = "high", feature = "connectivity"))] -mono!(crate::pac::TIM5,); +mono!(crate::pac::TIM5); -#[cfg(all(feature = "stm32f103", feature = "high",))] -mono!(crate::pac::TIM8,); +#[cfg(all(feature = "stm32f103", feature = "high"))] +mono!(crate::pac::TIM8); diff --git a/src/timer/pins.rs b/src/timer/pins.rs index 567e61b9..e0e9c716 100644 --- a/src/timer/pins.rs +++ b/src/timer/pins.rs @@ -36,7 +36,7 @@ macro_rules! remap { } } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] remap!( Tim1NoRemap: (pac::TIM1, 0b00, PA8, PA9, PA10, PA11, {|_, w| unsafe { w.tim1_remap().bits(Self::REMAP)}}), //Tim1PartialRemap: (pac::TIM1, 0b01, PA8, PA9, PA10, PA11), diff --git a/src/timer/pwm_input.rs b/src/timer/pwm_input.rs index b7f00ab0..78bb7c42 100644 --- a/src/timer/pwm_input.rs +++ b/src/timer/pwm_input.rs @@ -4,12 +4,7 @@ use core::marker::PhantomData; use core::mem; -use crate::pac::DBGMCU as DBG; -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -use crate::pac::TIM1; -#[cfg(feature = "medium")] -use crate::pac::TIM4; -use crate::pac::{TIM2, TIM3}; +use crate::pac::{self, DBGMCU as DBG}; use crate::afio::MAPR; use crate::gpio::{self, Input}; @@ -79,17 +74,17 @@ pub enum Configuration { RawValues { arr: u16, presc: u16 }, } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -impl Timer { +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +impl Timer { pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput + ) -> PwmInput where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { REMAP::remap(mapr); @@ -99,16 +94,16 @@ impl Timer { } } -impl Timer { +impl Timer { pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput + ) -> PwmInput where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { REMAP::remap(mapr); @@ -118,16 +113,16 @@ impl Timer { } } -impl Timer { +impl Timer { pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput + ) -> PwmInput where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { REMAP::remap(mapr); @@ -138,16 +133,16 @@ impl Timer { } #[cfg(feature = "medium")] -impl Timer { +impl Timer { pub fn pwm_input( mut self, pins: PINS, mapr: &mut MAPR, dbg: &mut DBG, mode: Configuration, - ) -> PwmInput + ) -> PwmInput where - REMAP: Remap, + REMAP: Remap, PINS: Pins, { REMAP::remap(mapr); @@ -167,147 +162,153 @@ fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u16) { (core::cmp::max(1, arr as u16), presc as u16) } macro_rules! hal { - ($($TIMX:ident: ($timX:ident),)+) => { - $( - fn $timX( - tim: $TIMX, - _pins: PINS, - clk: Hertz, - mode : Configuration, - ) -> PwmInput<$TIMX, REMAP, PINS> - where - REMAP: Remap, - PINS: Pins, - { - use Configuration::*; - // Disable capture on both channels during setting - // (for Channel X bit is CCXE) - tim.ccer().modify(|_,w| w.cc1e().clear_bit().cc2e().clear_bit() - .cc1p().clear_bit().cc2p().set_bit()); - - // Define the direction of the channel (input/output) - // and the used input - tim.ccmr1_input().modify( |_,w| w.cc1s().ti1().cc2s().ti1()); - - tim.dier().write(|w| w.cc1ie().set_bit()); - - // Configure slave mode control register - // Selects the trigger input to be used to synchronize the counter - // 101: Filtered Timer Input 1 (TI1FP1) - // --------------------------------------- - // Slave Mode Selection : - // 100: Reset Mode - Rising edge of the selected trigger input (TRGI) - // reinitializes the counter and generates an update of the registers. - tim.smcr().modify( |_,w| unsafe {w.ts().bits(0b101).sms().bits(0b100)}); - - match mode { - Frequency(f) => { - let freq = f.raw(); - let max_freq = if freq > 5 {freq/5} else {1}; - let (arr,presc) = compute_arr_presc(max_freq, clk.raw()); - tim.arr().write(|w| w.arr().set(arr)); - tim.psc().write(|w| w.psc().set(presc) ); - }, - DutyCycle(f) => { - let freq = f.raw(); - let max_freq = if freq > 2 {freq/2 + freq/4 + freq/8} else {1}; - let (arr,presc) = compute_arr_presc(max_freq, clk.raw()); - tim.arr().write(|w| w.arr().set(arr)); - tim.psc().write(|w| w.psc().set(presc) ); - }, - RawFrequency(f) => { - let freq = f.raw(); - let (arr,presc) = compute_arr_presc(freq, clk.raw()); - tim.arr().write(|w| w.arr().set(arr)); - tim.psc().write(|w| w.psc().set(presc) ); - } - RawValues{arr, presc} => { - tim.arr().write(|w| w.arr().set(arr)); - tim.psc().write(|w| w.psc().set(presc) ); - } + ($TIMX:ty: $timX:ident) => { + fn $timX( + tim: $TIMX, + _pins: PINS, + clk: Hertz, + mode: Configuration, + ) -> PwmInput<$TIMX, REMAP, PINS> + where + REMAP: Remap, + PINS: Pins, + { + use Configuration::*; + // Disable capture on both channels during setting + // (for Channel X bit is CCXE) + tim.ccer().modify(|_, w| { + w.cc1e().clear_bit(); + w.cc2e().clear_bit(); + w.cc1p().clear_bit(); + w.cc2p().set_bit() + }); + + // Define the direction of the channel (input/output) + // and the used input + tim.ccmr1_input().modify(|_, w| w.cc1s().ti1().cc2s().ti1()); + + tim.dier().write(|w| w.cc1ie().set_bit()); + + // Configure slave mode control register + // Selects the trigger input to be used to synchronize the counter + // 101: Filtered Timer Input 1 (TI1FP1) + // --------------------------------------- + // Slave Mode Selection : + // 100: Reset Mode - Rising edge of the selected trigger input (TRGI) + // reinitializes the counter and generates an update of the registers. + tim.smcr() + .modify(|_, w| unsafe { w.ts().bits(0b101).sms().bits(0b100) }); + + match mode { + Frequency(f) => { + let freq = f.raw(); + let max_freq = if freq > 5 { freq / 5 } else { 1 }; + let (arr, presc) = compute_arr_presc(max_freq, clk.raw()); + tim.arr().write(|w| w.arr().set(arr)); + tim.psc().write(|w| w.psc().set(presc)); + } + DutyCycle(f) => { + let freq = f.raw(); + let max_freq = if freq > 2 { + freq / 2 + freq / 4 + freq / 8 + } else { + 1 + }; + let (arr, presc) = compute_arr_presc(max_freq, clk.raw()); + tim.arr().write(|w| w.arr().set(arr)); + tim.psc().write(|w| w.psc().set(presc)); + } + RawFrequency(f) => { + let freq = f.raw(); + let (arr, presc) = compute_arr_presc(freq, clk.raw()); + tim.arr().write(|w| w.arr().set(arr)); + tim.psc().write(|w| w.psc().set(presc)); } + RawValues { arr, presc } => { + tim.arr().write(|w| w.arr().set(arr)); + tim.psc().write(|w| w.psc().set(presc)); + } + } - // Enable Capture on both channels - tim.ccer().modify(|_,w| w.cc1e().set_bit().cc2e().set_bit()); + // Enable Capture on both channels + tim.ccer() + .modify(|_, w| w.cc1e().set_bit().cc2e().set_bit()); + + tim.cr1().modify(|_, w| w.cen().set_bit()); + unsafe { mem::MaybeUninit::uninit().assume_init() } + } + + impl PwmInput<$TIMX, REMAP, PINS> + where + REMAP: Remap, + PINS: Pins, + { + /// Return the frequency sampled by the timer + pub fn read_frequency(&self, mode: ReadMode, clocks: &Clocks) -> Result { + if let ReadMode::WaitForNextCapture = mode { + self.wait_for_capture(); + } - tim.cr1().modify(|_,w| w.cen().set_bit()); - unsafe { mem::MaybeUninit::uninit().assume_init() } + let presc = unsafe { (*<$TIMX>::ptr()).psc().read().bits() as u16 }; + let ccr1 = unsafe { (*<$TIMX>::ptr()).ccr1().read().bits() as u16 }; + + // Formulas : + // + // F_timer = F_pclk / (PSC+1)*(ARR+1) + // Frac_arr = (CCR1+1)/(ARR+1) + // F_signal = F_timer/Frac_arr + // <=> F_signal = [(F_plck)/((PSC+1)*(ARR+1))] * [(ARR+1)/(CCR1+1)] + // <=> F_signal = F_pclk / ((PSC+1)*(CCR1+1)) + // + // Where : + // * PSC is the prescaler register + // * ARR is the auto-reload register + // * F_timer is the number of time per second where the timer overflow under normal + // condition + // + if ccr1 == 0 { + Err(Error::FrequencyTooLow) + } else { + let clk = <$TIMX>::timer_clock(&clocks); + Ok(clk / ((presc + 1) as u32 * (ccr1 + 1) as u32)) + } } - impl PwmInput<$TIMX, REMAP, PINS> - where - REMAP: Remap, - PINS: Pins, - { - /// Return the frequency sampled by the timer - pub fn read_frequency(&self, mode : ReadMode, clocks : &Clocks) -> Result { - if let ReadMode::WaitForNextCapture = mode { - self.wait_for_capture(); - } - - let presc = unsafe { (*$TIMX::ptr()).psc().read().bits() as u16}; - let ccr1 = unsafe { (*$TIMX::ptr()).ccr1().read().bits() as u16}; - - // Formulas : - // - // F_timer = F_pclk / (PSC+1)*(ARR+1) - // Frac_arr = (CCR1+1)/(ARR+1) - // F_signal = F_timer/Frac_arr - // <=> F_signal = [(F_plck)/((PSC+1)*(ARR+1))] * [(ARR+1)/(CCR1+1)] - // <=> F_signal = F_pclk / ((PSC+1)*(CCR1+1)) - // - // Where : - // * PSC is the prescaler register - // * ARR is the auto-reload register - // * F_timer is the number of time per second where the timer overflow under normal - // condition - // - if ccr1 == 0 { - Err(Error::FrequencyTooLow) - } else { - let clk = <$TIMX>::timer_clock(&clocks); - Ok(clk/((presc+1) as u32*(ccr1 + 1)as u32)) - } + /// Return the duty in the form of a fraction : (duty_cycle/period) + pub fn read_duty(&self, mode: ReadMode) -> Result<(u16, u16), Error> { + if let ReadMode::WaitForNextCapture = mode { + self.wait_for_capture(); } - /// Return the duty in the form of a fraction : (duty_cycle/period) - pub fn read_duty(&self, mode : ReadMode) -> Result<(u16,u16),Error> { - if let ReadMode::WaitForNextCapture = mode { - self.wait_for_capture(); - } - - // Formulas : - // Duty_cycle = (CCR2+1)/(CCR1+1) - let ccr1 = unsafe { (*$TIMX::ptr()).ccr1().read().bits() as u16}; - let ccr2 = unsafe { (*$TIMX::ptr()).ccr2().read().bits() as u16}; - if ccr1 == 0 { - Err(Error::FrequencyTooLow) - } else { - Ok((ccr2,ccr1)) - } + // Formulas : + // Duty_cycle = (CCR2+1)/(CCR1+1) + let ccr1 = unsafe { (*<$TIMX>::ptr()).ccr1().read().bits() as u16 }; + let ccr2 = unsafe { (*<$TIMX>::ptr()).ccr2().read().bits() as u16 }; + if ccr1 == 0 { + Err(Error::FrequencyTooLow) + } else { + Ok((ccr2, ccr1)) } + } - /// Wait until the timer has captured a period - fn wait_for_capture(&self) { - unsafe { (*$TIMX::ptr()).sr().write(|w| w.uif().clear_bit().cc1if().clear_bit().cc1of().clear_bit())}; - while unsafe { (*$TIMX::ptr()).sr().read().cc1if().bit_is_clear()} {} - } + /// Wait until the timer has captured a period + fn wait_for_capture(&self) { + unsafe { &(*<$TIMX>::ptr()) }.sr().write(|w| { + w.uif().clear_bit(); + w.cc1if().clear_bit(); + w.cc1of().clear_bit() + }); + while unsafe { (*<$TIMX>::ptr()).sr().read().cc1if().bit_is_clear() } {} } - )+ - } + } + }; } -#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity",))] -hal! { - TIM1: (tim1), -} +#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))] +hal!(pac::TIM1: tim1); -hal! { - TIM2: (tim2), - TIM3: (tim3), -} +hal!(pac::TIM2: tim2); +hal!(pac::TIM3: tim3); #[cfg(feature = "medium")] -hal! { - TIM4: (tim4), -} +hal!(pac::TIM4: tim4);