diff options
| author | Bruno Bousquet <[email protected]> | 2024-05-30 17:43:38 -0400 |
|---|---|---|
| committer | Bruno Bousquet <[email protected]> | 2024-05-30 17:43:53 -0400 |
| commit | 84707af5d7f3e62caafed06c416cf12fa82e4664 (patch) | |
| tree | 2f5a34ed76944338a5b6634f439df17637e1dba6 /embassy-stm32/src/timer | |
| parent | a87b33303403ba3601d0c631b9efe1cb3853c73b (diff) | |
create functions in inner to handle register modification
Diffstat (limited to 'embassy-stm32/src/timer')
| -rw-r--r-- | embassy-stm32/src/timer/input_capture.rs | 21 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/low_level.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/pwm_input.rs | 42 |
3 files changed, 31 insertions, 46 deletions
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index b3434ae63..8d1a77867 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs | |||
| @@ -7,7 +7,7 @@ use core::task::{Context, Poll}; | |||
| 7 | 7 | ||
| 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 9 | 9 | ||
| 10 | use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, Timer}; | 10 | use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; |
| 11 | use super::{ | 11 | use super::{ |
| 12 | CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, | 12 | CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, |
| 13 | GeneralInstance4Channel, | 13 | GeneralInstance4Channel, |
| @@ -40,11 +40,9 @@ macro_rules! channel_impl { | |||
| 40 | #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] | 40 | #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] |
| 41 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull_type: Pull) -> Self { | 41 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull_type: Pull) -> Self { |
| 42 | into_ref!(pin); | 42 | into_ref!(pin); |
| 43 | critical_section::with(|_| { | 43 | |
| 44 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); | 44 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); |
| 45 | #[cfg(gpio_v2)] | 45 | |
| 46 | pin.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 47 | }); | ||
| 48 | CapturePin { | 46 | CapturePin { |
| 49 | _pin: pin.map_into(), | 47 | _pin: pin.map_into(), |
| 50 | phantom: PhantomData, | 48 | phantom: PhantomData, |
| @@ -130,8 +128,6 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { | |||
| 130 | } | 128 | } |
| 131 | 129 | ||
| 132 | fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture<T> { | 130 | fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture<T> { |
| 133 | use stm32_metapac::timer::vals::FilterValue; | ||
| 134 | |||
| 135 | // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5 | 131 | // Configuration steps from ST RM0390 (STM32F446) chapter 17.3.5 |
| 136 | // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode | 132 | // or ST RM0008 (STM32F103) chapter 15.3.5 Input capture mode |
| 137 | self.inner.set_input_ti_selection(channel, tisel); | 133 | self.inner.set_input_ti_selection(channel, tisel); |
| @@ -184,11 +180,6 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { | |||
| 184 | } | 180 | } |
| 185 | } | 181 | } |
| 186 | 182 | ||
| 187 | /// Convert pointer to TIM instance to TimGp16 object | ||
| 188 | fn regs_gp16(ptr: *mut ()) -> crate::pac::timer::TimGp16 { | ||
| 189 | unsafe { crate::pac::timer::TimGp16::from_ptr(ptr) } | ||
| 190 | } | ||
| 191 | |||
| 192 | #[must_use = "futures do nothing unless you `.await` or poll them"] | 183 | #[must_use = "futures do nothing unless you `.await` or poll them"] |
| 193 | struct InputCaptureFuture<T: GeneralInstance4Channel> { | 184 | struct InputCaptureFuture<T: GeneralInstance4Channel> { |
| 194 | channel: Channel, | 185 | channel: Channel, |
| @@ -198,7 +189,7 @@ struct InputCaptureFuture<T: GeneralInstance4Channel> { | |||
| 198 | impl<T: GeneralInstance4Channel> Drop for InputCaptureFuture<T> { | 189 | impl<T: GeneralInstance4Channel> Drop for InputCaptureFuture<T> { |
| 199 | fn drop(&mut self) { | 190 | fn drop(&mut self) { |
| 200 | critical_section::with(|_| { | 191 | critical_section::with(|_| { |
| 201 | let regs = regs_gp16(T::regs()); | 192 | let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) }; |
| 202 | 193 | ||
| 203 | // disable interrupt enable | 194 | // disable interrupt enable |
| 204 | regs.dier().modify(|w| w.set_ccie(self.channel.index(), false)); | 195 | regs.dier().modify(|w| w.set_ccie(self.channel.index(), false)); |
| @@ -212,7 +203,7 @@ impl<T: GeneralInstance4Channel> Future for InputCaptureFuture<T> { | |||
| 212 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | 203 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 213 | T::state().cc_waker[self.channel.index()].register(cx.waker()); | 204 | T::state().cc_waker[self.channel.index()].register(cx.waker()); |
| 214 | 205 | ||
| 215 | let regs = regs_gp16(T::regs()); | 206 | let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) }; |
| 216 | 207 | ||
| 217 | let dier = regs.dier().read(); | 208 | let dier = regs.dier().read(); |
| 218 | if !dier.ccie(self.channel.index()) { | 209 | if !dier.ccie(self.channel.index()) { |
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs index 141e96894..8482fad7b 100644 --- a/embassy-stm32/src/timer/low_level.rs +++ b/embassy-stm32/src/timer/low_level.rs | |||
| @@ -12,6 +12,10 @@ use super::*; | |||
| 12 | use crate::pac::timer::vals; | 12 | use crate::pac::timer::vals; |
| 13 | use crate::time::Hertz; | 13 | use crate::time::Hertz; |
| 14 | 14 | ||
| 15 | pub use stm32_metapac::timer::vals::FilterValue; | ||
| 16 | pub use stm32_metapac::timer::vals::Sms as SlaveMode; | ||
| 17 | pub use stm32_metapac::timer::vals::Ts as TriggerSource; | ||
| 18 | |||
| 15 | /// Input capture mode. | 19 | /// Input capture mode. |
| 16 | #[derive(Clone, Copy)] | 20 | #[derive(Clone, Copy)] |
| 17 | pub enum InputCaptureMode { | 21 | pub enum InputCaptureMode { |
| @@ -588,6 +592,16 @@ impl<'d, T: GeneralInstance4Channel> Timer<'d, T> { | |||
| 588 | pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { | 592 | pub fn set_cc_dma_enable_state(&self, channel: Channel, ccde: bool) { |
| 589 | self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) | 593 | self.regs_gp16().dier().modify(|w| w.set_ccde(channel.index(), ccde)) |
| 590 | } | 594 | } |
| 595 | |||
| 596 | /// Set Timer Slave Mode | ||
| 597 | pub fn set_slave_mode(&self, sms: SlaveMode) { | ||
| 598 | self.regs_gp16().smcr().modify(|r| r.set_sms(sms)); | ||
| 599 | } | ||
| 600 | |||
| 601 | /// Set Timer Trigger Source | ||
| 602 | pub fn set_trigger_source(&self, ts: TriggerSource) { | ||
| 603 | self.regs_gp16().smcr().modify(|r| r.set_ts(ts)); | ||
| 604 | } | ||
| 591 | } | 605 | } |
| 592 | 606 | ||
| 593 | #[cfg(not(stm32l0))] | 607 | #[cfg(not(stm32l0))] |
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index 7bcb7802a..dcf098a78 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | use embassy_hal_internal::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | 4 | ||
| 5 | use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, Timer}; | 5 | use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; |
| 6 | use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; | 6 | use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; |
| 7 | use crate::gpio::{AFType, Pull}; | 7 | use crate::gpio::{AFType, Pull}; |
| 8 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| @@ -14,11 +14,6 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> { | |||
| 14 | inner: Timer<'d, T>, | 14 | inner: Timer<'d, T>, |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | /// Convert pointer to TIM instance to TimGp16 object | ||
| 18 | fn regs_gp16(ptr: *mut ()) -> crate::pac::timer::TimGp16 { | ||
| 19 | unsafe { crate::pac::timer::TimGp16::from_ptr(ptr) } | ||
| 20 | } | ||
| 21 | |||
| 22 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | 17 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { |
| 23 | /// Create a new PWM input driver. | 18 | /// Create a new PWM input driver. |
| 24 | pub fn new( | 19 | pub fn new( |
| @@ -28,11 +23,8 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | |||
| 28 | freq: Hertz, | 23 | freq: Hertz, |
| 29 | ) -> Self { | 24 | ) -> Self { |
| 30 | into_ref!(pin); | 25 | into_ref!(pin); |
| 31 | critical_section::with(|_| { | 26 | |
| 32 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); | 27 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); |
| 33 | #[cfg(gpio_v2)] | ||
| 34 | pin.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 35 | }); | ||
| 36 | 28 | ||
| 37 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) | 29 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) |
| 38 | } | 30 | } |
| @@ -45,18 +37,13 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | |||
| 45 | freq: Hertz, | 37 | freq: Hertz, |
| 46 | ) -> Self { | 38 | ) -> Self { |
| 47 | into_ref!(pin); | 39 | into_ref!(pin); |
| 48 | critical_section::with(|_| { | 40 | |
| 49 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); | 41 | pin.set_as_af_pull(pin.af_num(), AFType::Input, pull_type); |
| 50 | #[cfg(gpio_v2)] | ||
| 51 | pin.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 52 | }); | ||
| 53 | 42 | ||
| 54 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) | 43 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) |
| 55 | } | 44 | } |
| 56 | 45 | ||
| 57 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { | 46 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { |
| 58 | use stm32_metapac::timer::vals::{Sms, Ts}; | ||
| 59 | |||
| 60 | let mut inner = Timer::new(tim); | 47 | let mut inner = Timer::new(tim); |
| 61 | 48 | ||
| 62 | inner.set_counting_mode(CountingMode::EdgeAlignedUp); | 49 | inner.set_counting_mode(CountingMode::EdgeAlignedUp); |
| @@ -72,21 +59,14 @@ impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | |||
| 72 | inner.set_input_ti_selection(ch2, InputTISelection::Alternate); | 59 | inner.set_input_ti_selection(ch2, InputTISelection::Alternate); |
| 73 | inner.set_input_capture_mode(ch2, InputCaptureMode::Falling); | 60 | inner.set_input_capture_mode(ch2, InputCaptureMode::Falling); |
| 74 | 61 | ||
| 75 | let regs = regs_gp16(T::regs()); | 62 | inner.set_trigger_source(match ch1 { |
| 76 | regs.smcr().modify(|r| { | 63 | Channel::Ch1 => TriggerSource::TI1FP1, |
| 77 | // Select the valid trigger input: write the TS bits to 101 in the TIMx_SMCR register | 64 | Channel::Ch2 => TriggerSource::TI2FP2, |
| 78 | // (TI1FP1 selected). | 65 | _ => panic!("Invalid channel for PWM input"), |
| 79 | r.set_ts(match ch1 { | ||
| 80 | Channel::Ch1 => Ts::TI1FP1, | ||
| 81 | Channel::Ch2 => Ts::TI2FP2, | ||
| 82 | _ => panic!("Invalid channel for PWM input"), | ||
| 83 | }); | ||
| 84 | |||
| 85 | // Configure the slave mode controller in reset mode: write the SMS bits to 100 in the | ||
| 86 | // TIMx_SMCR register. | ||
| 87 | r.set_sms(Sms::RESET_MODE); | ||
| 88 | }); | 66 | }); |
| 89 | 67 | ||
| 68 | inner.set_slave_mode(SlaveMode::RESET_MODE); | ||
| 69 | |||
| 90 | // Must call the `enable` function after | 70 | // Must call the `enable` function after |
| 91 | 71 | ||
| 92 | Self { channel: ch1, inner } | 72 | Self { channel: ch1, inner } |
