From 0a893cc6558f8f9a9f3d56f127434eb868800c42 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 9 Nov 2024 11:58:23 +0100 Subject: [PATCH] HRTIM - Fix some warnings --- src/hrtim/capture.rs | 3 +- src/hrtim/control.rs | 6 +- src/hrtim/event.rs | 3 +- src/hrtim/event.rs_old | 619 ++++++++++++++++++++++++++++++++++++++++ src/hrtim/mod.rs | 3 + src/hrtim/output.rs | 40 ++- src/hrtim/output.rs_old | 300 +++++++++++++++++++ src/hrtim/timer.rs | 26 +- 8 files changed, 961 insertions(+), 39 deletions(-) create mode 100644 src/hrtim/event.rs_old create mode 100644 src/hrtim/output.rs_old diff --git a/src/hrtim/capture.rs b/src/hrtim/capture.rs index f2081344..831ac7ae 100644 --- a/src/hrtim/capture.rs +++ b/src/hrtim/capture.rs @@ -25,7 +25,8 @@ pub enum CountingDirection { /// Implemented for /// * TIM's update event /// * EEVT1-10 -/// TODO: This sould be implemeted +/// +/// TODO: /// * All neighbor timers CMP1, CPM2, OUT1_RST and OUT1_SET events pub trait CaptureEvent { const BITS: u32; diff --git a/src/hrtim/control.rs b/src/hrtim/control.rs index 234d25d1..6173d887 100644 --- a/src/hrtim/control.rs +++ b/src/hrtim/control.rs @@ -211,9 +211,9 @@ impl HrTimCalibrated { } } -impl<'a> Into<&'a mut HrPwmCtrl> for &'a mut HrPwmControl { - fn into(self) -> &'a mut HrPwmCtrl { - &mut self.control +impl<'a> From<&'a mut HrPwmControl> for &'a mut HrPwmCtrl { + fn from(val: &'a mut HrPwmControl) -> Self { + &mut val.control } } diff --git a/src/hrtim/event.rs b/src/hrtim/event.rs index 5c472809..29a1f7b9 100644 --- a/src/hrtim/event.rs +++ b/src/hrtim/event.rs @@ -3,6 +3,8 @@ pub trait EventSource { const BITS: u32; } +/// Event that can be used reset the timer counter +/// /// Done: /// * [x] Eev1-10 /// * [x] Master period @@ -10,7 +12,6 @@ pub trait EventSource { /// * [x] Cmp2, Cmp4 /// * [x] Timer Update /// * [ ] Neighbor timers compare events -/// Event that can be used reset the timer counter pub trait TimerResetEventSource { const BITS: u32; } diff --git a/src/hrtim/event.rs_old b/src/hrtim/event.rs_old new file mode 100644 index 00000000..65258c1c --- /dev/null +++ b/src/hrtim/event.rs_old @@ -0,0 +1,619 @@ +use core::marker::PhantomData; + +use crate::stm32::{ + HRTIM_MASTER, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF, +}; + +use super::{compare_register::{HrCr1, HrCr2, HrCr3, HrCr4}, external_event_old::ExternalEventSource}; +use crate::hrtim::timer::HrTim; + +macro_rules! impl_into_es { + ($dst:ident: [$(($t:ty, $ES:ident),)*]) => {$( + impl_into_es!($dst, $t, $ES); + )*}; + + ($dst:ident, $t:ty, $ES:ident) => { + impl From<&$t> for EventSource { + fn from(_: &$t) -> Self { + EventSource::$ES{ _x: PhantomData } + } + } + }; + ($dst:ident) => { + impl_into_es! { + $dst: [ + (HrCr1<$dst, PSCL>, Cr1), + (HrCr2<$dst, PSCL>, Cr2), + (HrCr3<$dst, PSCL>, Cr3), + (HrCr4<$dst, PSCL>, Cr4), + (HrTim<$dst, PSCL>, Period), + + (HrCr1, MasterCr1), + (HrCr2, MasterCr2), + (HrCr3, MasterCr3), + (HrCr4, MasterCr4), + (HrTim, MasterPeriod), + ] + } + }; +} + +impl_into_es!(HRTIM_TIMA); +impl_into_es!(HRTIM_TIMB); +impl_into_es!(HRTIM_TIMC); +impl_into_es!(HRTIM_TIMD); +impl_into_es!(HRTIM_TIME); +impl_into_es!(HRTIM_TIMF); + +macro_rules! impl_into_neighbor_es { + ( + DST: $dst:ident: [ + ($src1:ident, $cr1:ident), + ($src2:ident, $cr2:ident), + ($src3:ident, $cr3:ident), + ($src4:ident, $cr4:ident), + ($src5:ident, $cr5:ident), + ($src6:ident, $cr6:ident), + ($src7:ident, $cr7:ident), + ($src8:ident, $cr8:ident), + ($src9:ident, $cr9:ident), + ] + ) => { + impl_into_neighbor_es!($dst, $src1, $cr1, TimEvent1); + impl_into_neighbor_es!($dst, $src2, $cr2, TimEvent2); + impl_into_neighbor_es!($dst, $src3, $cr3, TimEvent3); + impl_into_neighbor_es!($dst, $src4, $cr4, TimEvent4); + impl_into_neighbor_es!($dst, $src5, $cr5, TimEvent5); + impl_into_neighbor_es!($dst, $src6, $cr6, TimEvent6); + impl_into_neighbor_es!($dst, $src7, $cr7, TimEvent7); + impl_into_neighbor_es!($dst, $src8, $cr8, TimEvent8); + impl_into_neighbor_es!($dst, $src9, $cr9, TimEvent9); + }; + + ($dst:ident, $src:ident, $cr:ident, $TimEventX:ident) => { + impl From<&$cr<$src, PSCL>> for EventSource { + fn from(_: &$cr<$src, PSCL>) -> Self { + EventSource::NeighborTimer { + n: NeighborTimerEventSource::$TimEventX { _x: PhantomData }, + } + } + } + }; +} + +impl_into_neighbor_es! { + DST: HRTIM_TIMA: [ + // src + (HRTIM_TIMB, HrCr1), + (HRTIM_TIMB, HrCr2), + (HRTIM_TIMC, HrCr2), + (HRTIM_TIMC, HrCr3), + (HRTIM_TIMD, HrCr1), + (HRTIM_TIMD, HrCr2), + (HRTIM_TIME, HrCr3), + (HRTIM_TIME, HrCr4), + (HRTIM_TIMF, HrCr4), + ] +} + +impl_into_neighbor_es! { + DST: HRTIM_TIMB: [ + // src + (HRTIM_TIMA, HrCr1), + (HRTIM_TIMA, HrCr2), + (HRTIM_TIMC, HrCr3), + (HRTIM_TIMC, HrCr4), + (HRTIM_TIMD, HrCr3), + (HRTIM_TIMD, HrCr4), + (HRTIM_TIME, HrCr1), + (HRTIM_TIME, HrCr2), + (HRTIM_TIMF, HrCr3), + ] +} + +impl_into_neighbor_es! { + DST: HRTIM_TIMC: [ + // src + (HRTIM_TIMA, HrCr2), + (HRTIM_TIMA, HrCr3), + (HRTIM_TIMB, HrCr2), + (HRTIM_TIMB, HrCr3), + (HRTIM_TIMD, HrCr2), + (HRTIM_TIMD, HrCr4), + (HRTIM_TIME, HrCr3), + (HRTIM_TIME, HrCr4), + (HRTIM_TIMF, HrCr2), + ] +} + +// TODO: Continue for TIMD, TIME and TIMF, see RM0440 Table 218. 'Events mapping across timer A to F' + +pub enum EventSource { + /// Compare match with compare register 1 of this timer + Cr1 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 2 of this timer + Cr2 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 3 of this timer + Cr3 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 4 of this timer + Cr4 { _x: PhantomData<(PSCL, DST)> }, + + /// On complete period + Period { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 1 of master timer + MasterCr1 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 2 of master timer + MasterCr2 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 3 of master timer + MasterCr3 { _x: PhantomData<(PSCL, DST)> }, + + /// Compare match with compare register 4 of master timer + MasterCr4 { _x: PhantomData<(PSCL, DST)> }, + + /// On complete master period + MasterPeriod { _x: PhantomData<(PSCL, DST)> }, + + ExternalEvent(ExternalEventSource), // This is fine + + NeighborTimer { + n: NeighborTimerEventSource, + }, +} + +/// Compare events from neighbor timers +/// +/// See RM0440 Table 218. 'Events mapping across timer A to F' +pub enum NeighborTimerEventSource { + /// Timer event 1 + /// + /// This is different depending on destination timer: + /// |dest | source | + /// |-----|--------| + /// |TimA | B CR1 | + /// |TimB | A CR1 | + /// |TimC | A CR2 | + /// |TimD | A CR1 | + /// |TimE | A CR4 | + /// |TimF | A CR3 | + TimEvent1 { + _x: PhantomData<(PSCL, DST)>, + }, + + /// Timer event x + /// + /// This is different depending on destination timer: + /// |dest | source | + /// |-----|--------| + /// |TimA | x CRy | + /// |TimB | x CRy | + /// |TimC | x CRy | + /// |TimD | x CRy | + /// |TimE | x CRy | + /// |TimF | x CRy | + //TimEventx, + + /// Timer event 2 + /// + /// This is different depending on destination timer: + /// |dest | source | + /// |-----|--------| + /// |TimA | B CR2 | + /// |TimB | A CR2 | + /// |TimC | A CR3 | + /// |TimD | A CR4 | + /// |TimE | B CR3 | + /// |TimF | B CR1 | + TimEvent2 { + _x: PhantomData<(PSCL, DST)>, + }, + + /// Timer event 3 + /// + /// This is different depending on destination timer: + /// |dest | source | + /// |-----|--------| + /// |TimA | C CR2 | + /// |TimB | C CR3 | + /// |TimC | B CR2 | + /// |TimD | B CR2 | + /// |TimE | B CR4 | + /// |TimF | B CR4 | + TimEvent3 { + _x: PhantomData<(PSCL, DST)>, + }, + + /// Timer event 4 + /// + /// This is different depending on destination timer: + /// |dest | source | + /// |-----|--------| + /// |TimA | C CR3 | + /// |TimB | C CR4 | + /// |TimC | B CR3 | + /// |TimD | B CR4 | + /// |TimE | C CR1 | + /// |TimF | C CR1 | + TimEvent4 { + _x: PhantomData<(PSCL, DST)>, + }, + // TODO: Document those + TimEvent5 { + _x: PhantomData<(PSCL, DST)>, + }, + TimEvent6 { + _x: PhantomData<(PSCL, DST)>, + }, + TimEvent7 { + _x: PhantomData<(PSCL, DST)>, + }, + TimEvent8 { + _x: PhantomData<(PSCL, DST)>, + }, + TimEvent9 { + _x: PhantomData<(PSCL, DST)>, + }, +} + +macro_rules! hr_timer_reset_event_source_common { + ($(#[$($attrss:tt)*])* pub enum $t:ident { [COMMON], $(#[$($attrss2:tt)*] $vals:tt = 1 << $x:literal,)*}) => { + $(#[$($attrss)*])* + pub enum $t { + $(#[$($attrss2)*] $vals = 1 << $x,)* + + /// The timer counter is reset upon external event 10. + Eevnt10 = 1 << 18, + + /// The timer counter is reset upon external event 9. + Eevnt9 = 1 << 17, + + /// The timer counter is reset upon external event 8. + Eevnt8 = 1 << 16, + + /// The timer counter is reset upon external event 7. + Eevnt7 = 1 << 15, + + /// The timer counter is reset upon external event 6. + Eevnt6 = 1 << 14, + + /// The timer counter is reset upon external event 5. + Eevnt5 = 1 << 13, + + /// The timer counter is reset upon external event 4. + Eevnt4 = 1 << 12, + + /// The timer counter is reset upon external event 3. + Eevnt3 = 1 << 11, + + /// The timer counter is reset upon external event 2. + Eevnt2 = 1 << 10, + + /// The timer counter is reset upon external event 1. + Eevnt1 = 1 << 9, + + /// The timer counter is reset upon master timer compare 4 event. + MasterCmp4 = 1 << 8, + + /// The timer counter is reset upon master timer compare 3 event. + MasterCmp3 = 1 << 7, + + /// The timer counter is reset upon master timer compare 2 event. + MasterCmp2 = 1 << 6, + + /// The timer counter is reset upon master timer compare 1 event. + MasterCmp1 = 1 << 5, + + /// The timer counter is reset upon master timer period event. + MasterPeriod = 1 << 4, + + /// The timer counter is reset upon timer its own compare 4 event + Cmp4 = 1 << 3, + + /// The timer counter is reset upon timer its own compare 2 event + Cmp2 = 1 << 2, + + /// The timer counter is reset upon update event. + Update = 1 << 1, + } + }; +} + +hr_timer_reset_event_source_common!( + /// A + pub enum TimerAResetEventSource { + [COMMON], + /// The timer counter is reset upon timer F compare 2 event. + TimFCmp2 = 1 << 31, + + /// The timer counter is reset upon timer E compare 4 event. + TimECmp4 = 1 << 30, + + /// The timer counter is reset upon timer E compare 2 event. + TimECmp2 = 1 << 29, + + /// The timer counter is reset upon timer E compare 1 event. + TimECmp1 = 1 << 28, + + /// The timer counter is reset upon timer D compare 4 event. + TimDCmp4 = 1 << 27, + + /// The timer counter is reset upon timer D compare 2 event. + TimDCmp2 = 1 << 26, + + /// The timer counter is reset upon timer D compare 1 event. + TimDCmp1 = 1 << 25, + + /// The timer counter is reset upon timer C compare 4 event. + TimCCmp4 = 1 << 24, + + /// The timer counter is reset upon timer C compare 2 event. + TimCCmp2 = 1 << 23, + + /// The timer counter is reset upon timer C compare 1 event. + TimCCmp1 = 1 << 22, + + /// The timer counter is reset upon timer B compare 4 event. + TimBCmp4 = 1 << 21, + + /// The timer counter is reset upon timer B compare 2 event. + TimBCmp2 = 1 << 20, + + /// The timer counter is reset upon timer B compare 1 event. + TimBCmp1 = 1 << 19, + + /// The timer counter is reset upon timer F compare 1 event. + TimFCmp1 = 1 << 0, + } +); + +hr_timer_reset_event_source_common!( + /// B + pub enum TimerBResetEventSource { + [COMMON], + + /// The timer counter is reset upon timer F compare 2 event. + TimFCmp2 = 1 << 31, + + /// The timer counter is reset upon timer E compare 4 event. + TimECmp4 = 1 << 30, + + /// The timer counter is reset upon timer E compare 2 event. + TimECmp2 = 1 << 29, + + /// The timer counter is reset upon timer E compare 1 event. + TimECmp1 = 1 << 28, + + /// The timer counter is reset upon timer D compare 4 event. + TimDCmp4 = 1 << 27, + + /// The timer counter is reset upon timer D compare 2 event. + TimDCmp2 = 1 << 26, + + /// The timer counter is reset upon timer D compare 1 event. + TimDCmp1 = 1 << 25, + + /// The timer counter is reset upon timer C compare 4 event. + TimCCmp4 = 1 << 24, + + /// The timer counter is reset upon timer C compare 2 event. + TimCCmp2 = 1 << 23, + + /// The timer counter is reset upon timer C compare 1 event. + TimCCmp1 = 1 << 22, + + /// The timer counter is reset upon timer A compare 4 event. + TimACmp4 = 1 << 21, + + /// The timer counter is reset upon timer A compare 2 event. + TimACmp2 = 1 << 20, + + /// The timer counter is reset upon timer A compare 1 event. + TimACmp1 = 1 << 19, + + /// The timer counter is reset upon timer F compare 1 event. + TimFCmp1 = 1 << 0, + } +); + +hr_timer_reset_event_source_common!( + /// C + pub enum TimerCResetEventSource { + [COMMON], + + /// The timer counter is reset upon timer F compare 2 event. + TimFCmp2 = 1 << 31, + + /// The timer counter is reset upon timer E compare 4 event. + TimECmp4 = 1 << 30, + + /// The timer counter is reset upon timer E compare 2 event. + TimECmp2 = 1 << 29, + + /// The timer counter is reset upon timer E compare 1 event. + TimECmp1 = 1 << 28, + + /// The timer counter is reset upon timer D compare 4 event. + TimDCmp4 = 1 << 27, + + /// The timer counter is reset upon timer D compare 2 event. + TimDCmp2 = 1 << 26, + + /// The timer counter is reset upon timer D compare 1 event. + TimDCmp1 = 1 << 25, + + /// The timer counter is reset upon timer B compare 4 event. + TimBCmp4 = 1 << 24, + + /// The timer counter is reset upon timer B compare 2 event. + TimBCmp2 = 1 << 23, + + /// The timer counter is reset upon timer B compare 1 event. + TimBCmp1 = 1 << 22, + + /// The timer counter is reset upon timer A compare 4 event. + TimACmp4 = 1 << 21, + + /// The timer counter is reset upon timer A compare 2 event. + TimACmp2 = 1 << 20, + + /// The timer counter is reset upon timer A compare 1 event. + TimACmp1 = 1 << 19, + + + /// The timer counter is reset upon timer F compare 1 event. + TimFCmp1 = 1 << 0, + } +); + +hr_timer_reset_event_source_common!( + /// D + pub enum TimerDResetEventSource { + [COMMON], + + /// The timer counter is reset upon timer F compare 2 event. + TimFCmp2 = 1 << 31, + + /// The timer counter is reset upon timer E compare 4 event. + TimECmp4 = 1 << 30, + + /// The timer counter is reset upon timer E compare 2 event. + TimECmp2 = 1 << 29, + + /// The timer counter is reset upon timer E compare 1 event. + TimECmp1 = 1 << 28, + + /// The timer counter is reset upon timer C compare 4 event. + TimCCmp4 = 1 << 27, + + /// The timer counter is reset upon timer C compare 2 event. + TimCCmp2 = 1 << 26, + + /// The timer counter is reset upon timer C compare 1 event. + TimCCmp1 = 1 << 25, + + /// The timer counter is reset upon timer B compare 4 event. + TimBCmp4 = 1 << 24, + + /// The timer counter is reset upon timer B compare 2 event. + TimBCmp2 = 1 << 23, + + /// The timer counter is reset upon timer B compare 1 event. + TimBCmp1 = 1 << 22, + + /// The timer counter is reset upon timer A compare 4 event. + TimACmp4 = 1 << 21, + + /// The timer counter is reset upon timer A compare 2 event. + TimACmp2 = 1 << 20, + + /// The timer counter is reset upon timer A compare 1 event. + TimACmp1 = 1 << 19, + + /// The timer counter is reset upon timer F compare 1 event. + TimFCmp1 = 1 << 0, + } +); + +hr_timer_reset_event_source_common!( + /// E + pub enum TimerEResetEventSource { + [COMMON], + + /// The timer counter is reset upon timer F compare 2 event. + TimFCmp2 = 1 << 31, + + /// The timer counter is reset upon timer D compare 4 event. + TimDCmp4 = 1 << 30, + + /// The timer counter is reset upon timer D compare 2 event. + TimDCmp2 = 1 << 29, + + /// The timer counter is reset upon timer D compare 1 event. + TimDCmp1 = 1 << 28, + + /// The timer counter is reset upon timer C compare 4 event. + TimCCmp4 = 1 << 27, + + /// The timer counter is reset upon timer C compare 2 event. + TimCCmp2 = 1 << 26, + + /// The timer counter is reset upon timer C compare 1 event. + TimCCmp1 = 1 << 25, + + /// The timer counter is reset upon timer B compare 4 event. + TimBCmp4 = 1 << 24, + + /// The timer counter is reset upon timer B compare 2 event. + TimBCmp2 = 1 << 23, + + /// The timer counter is reset upon timer B compare 1 event. + TimBCmp1 = 1 << 22, + + /// The timer counter is reset upon timer A compare 4 event. + TimACmp4 = 1 << 21, + + /// The timer counter is reset upon timer A compare 2 event. + TimACmp2 = 1 << 20, + + /// The timer counter is reset upon timer A compare 1 event. + TimACmp1 = 1 << 19, + + + /// The timer counter is reset upon timer F compare 1 event. + TimFCmp1 = 1 << 0, + } +); + +hr_timer_reset_event_source_common!( + /// F + pub enum TimerFResetEventSource { + [COMMON], + + /// The timer counter is reset upon timer E compare 2 event. + TimECmp2 = 1 << 31, + + /// The timer counter is reset upon timer D compare 4 event. + TimDCmp4 = 1 << 30, + + /// The timer counter is reset upon timer D compare 2 event. + TimDCmp2 = 1 << 29, + + /// The timer counter is reset upon timer D compare 1 event. + TimDCmp1 = 1 << 28, + + /// The timer counter is reset upon timer C compare 4 event. + TimCCmp4 = 1 << 27, + + /// The timer counter is reset upon timer C compare 2 event. + TimCCmp2 = 1 << 26, + + /// The timer counter is reset upon timer C compare 1 event. + TimCCmp1 = 1 << 25, + + /// The timer counter is reset upon timer B compare 4 event. + TimBCmp4 = 1 << 24, + + /// The timer counter is reset upon timer B compare 2 event. + TimBCmp2 = 1 << 23, + + /// The timer counter is reset upon timer B compare 1 event. + TimBCmp1 = 1 << 22, + + /// The timer counter is reset upon timer A compare 4 event. + TimACmp4 = 1 << 21, + + /// The timer counter is reset upon timer A compare 2 event. + TimACmp2 = 1 << 20, + + /// The timer counter is reset upon timer A compare 1 event. + TimACmp1 = 1 << 19, + + /// The timer counter is reset upon timer E compare 1 event. + TimECmp1 = 1 << 0, + } +); diff --git a/src/hrtim/mod.rs b/src/hrtim/mod.rs index d0666197..ae6d522d 100644 --- a/src/hrtim/mod.rs +++ b/src/hrtim/mod.rs @@ -121,6 +121,7 @@ pub enum InterleavedMode { /// /// Automatically force /// * Cr1 to PERIOD / 2 (not visable through `get_duty`). + /// /// Automatically updates when changing period /// /// NOTE: Affects Cr1 @@ -131,6 +132,7 @@ pub enum InterleavedMode { /// Automatically force /// * Cr1 to 1 * PERIOD / 3 and /// * Cr2 to 2 * PERIOD / 3 + /// /// (not visable through `get_duty`). Automatically updates when changing period. /// /// NOTE: Must not be used simultaneously with other modes @@ -143,6 +145,7 @@ pub enum InterleavedMode { /// * Cr1 to 1 * PERIOD / 4, /// * Cr2 to 2 * PERIOD / 4 and /// * Cr3 to 3 * PERIOD / 4 + /// /// (not visable through `get_duty`). Automatically updates when changing period. /// /// NOTE: Must not be used simultaneously with other modes diff --git a/src/hrtim/output.rs b/src/hrtim/output.rs index f0d140d2..e3ba34bb 100644 --- a/src/hrtim/output.rs +++ b/src/hrtim/output.rs @@ -14,6 +14,10 @@ use crate::{ stm32::HRTIM_COMMON, }; +mod sealed { + pub trait Sealed {} +} + macro_rules! hrtim_out { ($($TIMX:ident: $out_type:ident: $tXYoen:ident, $tXYodis:ident, $tXYods:ident, $setXYr:ident, $rstXYr:ident,)+) => {$( impl HrOutput<$TIMX, PSCL> for $out_type<$TIMX, PSCL> { @@ -136,13 +140,20 @@ impl State { } } -pub unsafe trait ToHrOut { +pub trait ToHrOut: sealed::Sealed { type Out; fn connect_to_hrtim(self); } -unsafe impl ToHrOut for (PA, PB) +impl sealed::Sealed for (PA, PB) +where + PA: ToHrOut, + PB: ToHrOut, +{ +} + +impl ToHrOut for (PA, PB) where PA: ToHrOut, PB: ToHrOut, @@ -161,16 +172,10 @@ pub struct HrOut2(PhantomData<(TIM, PSCL)>); macro_rules! pins { ($($TIMX:ty: CH1: $CH1:ident<$CH1_AF:ident>, CH2: $CH2:ident<$CH2_AF:ident>)+) => { $( - /*impl Pins<$TIMX, CH1, ComplementaryImpossible> for $CH1 { - type Channel = Pwm<$TIMX, CH1, ComplementaryImpossible, ActiveHigh, ActiveHigh>; - } - - impl Pins<$TIMX, CH2, ComplementaryImpossible> for $CH2 { - type Channel = Pwm<$TIMX, CH2, ComplementaryImpossible, ActiveHigh, ActiveHigh>; - } + impl sealed::Sealed<$TIMX> for $CH1> {} + impl sealed::Sealed<$TIMX> for $CH2> {} - */ - unsafe impl ToHrOut<$TIMX> for $CH1> { + impl ToHrOut<$TIMX> for $CH1> { type Out = HrOut1<$TIMX, PSCL>; fn connect_to_hrtim(self) { @@ -178,21 +183,13 @@ macro_rules! pins { } } - unsafe impl ToHrOut<$TIMX> for $CH2> { + impl ToHrOut<$TIMX> for $CH2> { type Out = HrOut2<$TIMX, PSCL>; fn connect_to_hrtim(self) { let _: $CH2> = self.into_alternate(); } } - - /*unsafe impl ToHrOut for HrOut1<$TIMX, PSCL> { - type Out

= HrOut1<$TIMX, P>; - } - - unsafe impl ToHrOut for HrOut2<$TIMX, PSCL> { - type Out

= HrOut2<$TIMX, P>; - }*/ )+ } } @@ -212,7 +209,8 @@ impl Pins for () { type Channel = (); } -unsafe impl ToHrOut for () { +impl sealed::Sealed for () {} +impl ToHrOut for () { type Out = (); fn connect_to_hrtim(self) {} diff --git a/src/hrtim/output.rs_old b/src/hrtim/output.rs_old new file mode 100644 index 00000000..0ab07d6d --- /dev/null +++ b/src/hrtim/output.rs_old @@ -0,0 +1,300 @@ +use core::marker::PhantomData; +use stm32g4::stm32g474::{ + HRTIM_MASTER, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF, +}; +use crate::hrtim::external_event_old::ExternalEventSource; + +use super::event::{EventSource, NeighborTimerEventSource}; +use crate::{ + gpio::{ + gpioa::{PA10, PA11, PA8, PA9}, + gpiob::{PB12, PB13, PB14, PB15}, + gpioc::{PC6, PC7, PC8, PC9}, + Alternate, AF13, AF3, + }, + pwm::{ActiveHigh, ComplementaryImpossible, Pins, Pwm}, + stm32::HRTIM_COMMON, +}; + +macro_rules! hrtim_out_common { + ($TIMX:ident, $set_event:expr, $register:ident, $action:ident) => {{ + let tim = unsafe { &*$TIMX::ptr() }; + + match $set_event { + EventSource::Cr1 { .. } => tim.$register.modify(|_r, w| w.cmp1().$action()), + EventSource::Cr2 { .. } => tim.$register.modify(|_r, w| w.cmp2().$action()), + EventSource::Cr3 { .. } => tim.$register.modify(|_r, w| w.cmp3().$action()), + EventSource::Cr4 { .. } => tim.$register.modify(|_r, w| w.cmp4().$action()), + EventSource::Period { .. } => tim.$register.modify(|_r, w| w.per().$action()), + + EventSource::MasterCr1 { .. } => tim.$register.modify(|_r, w| w.mstcmp1().$action()), + EventSource::MasterCr2 { .. } => tim.$register.modify(|_r, w| w.mstcmp2().$action()), + EventSource::MasterCr3 { .. } => tim.$register.modify(|_r, w| w.mstcmp3().$action()), + EventSource::MasterCr4 { .. } => tim.$register.modify(|_r, w| w.mstcmp4().$action()), + EventSource::MasterPeriod { .. } => tim.$register.modify(|_r, w| w.mstper().$action()), + + EventSource::ExternalEvent(e) => match e { + ExternalEventSource::Eevnt1 { .. } => { + tim.$register.modify(|_r, w| w.extevnt1().$action()) + }, + ExternalEventSource::Eevnt2 { .. } => { + tim.$register.modify(|_r, w| w.extevnt2().$action()) + }, + ExternalEventSource::Eevnt3 { .. } => { + tim.$register.modify(|_r, w| w.extevnt3().$action()) + }, + ExternalEventSource::Eevnt4 { .. } => { + tim.$register.modify(|_r, w| w.extevnt4().$action()) + }, + ExternalEventSource::Eevnt5 { .. } => { + tim.$register.modify(|_r, w| w.extevnt5().$action()) + }, + ExternalEventSource::Eevnt6 { .. } => { + tim.$register.modify(|_r, w| w.extevnt6().$action()) + }, + ExternalEventSource::Eevnt7 { .. } => { + tim.$register.modify(|_r, w| w.extevnt7().$action()) + }, + ExternalEventSource::Eevnt8 { .. } => { + tim.$register.modify(|_r, w| w.extevnt8().$action()) + }, + ExternalEventSource::Eevnt9 { .. } => { + tim.$register.modify(|_r, w| w.extevnt9().$action()) + }, + ExternalEventSource::Eevnt10 { .. } => { + tim.$register.modify(|_r, w| w.extevnt10().$action()) + }, + } + + EventSource::NeighborTimer { n } => match n { + NeighborTimerEventSource::TimEvent1 { .. } => { + tim.$register.modify(|_r, w| w.timevnt1().$action()) + } + NeighborTimerEventSource::TimEvent2 { .. } => { + tim.$register.modify(|_r, w| w.timevnt2().$action()) + } + NeighborTimerEventSource::TimEvent3 { .. } => { + tim.$register.modify(|_r, w| w.timevnt3().$action()) + } + NeighborTimerEventSource::TimEvent4 { .. } => { + tim.$register.modify(|_r, w| w.timevnt4().$action()) + } + NeighborTimerEventSource::TimEvent5 { .. } => { + tim.$register.modify(|_r, w| w.timevnt5().$action()) + } + NeighborTimerEventSource::TimEvent6 { .. } => { + tim.$register.modify(|_r, w| w.timevnt6().$action()) + } + NeighborTimerEventSource::TimEvent7 { .. } => { + tim.$register.modify(|_r, w| w.timevnt7().$action()) + } + NeighborTimerEventSource::TimEvent8 { .. } => { + tim.$register.modify(|_r, w| w.timevnt8().$action()) + } + NeighborTimerEventSource::TimEvent9 { .. } => { + tim.$register.modify(|_r, w| w.timevnt9().$action()) + } + }, + } + }}; +} + +macro_rules! hrtim_out { + ($($TIMX:ident: $out_type:ident: $tXYoen:ident, $tXYodis:ident, $tXYods:ident, $setXYr:ident, $rstXYr:ident,)+) => {$( + impl HrOutput for $out_type<$TIMX, PSCL> { + fn enable(&mut self) { + let common = unsafe { &*HRTIM_COMMON::ptr() }; + common.oenr.write(|w| { w.$tXYoen().set_bit() }); + } + + fn disable(&mut self) { + let common = unsafe { &*HRTIM_COMMON::ptr() }; + common.odisr.write(|w| { w.$tXYodis().set_bit() }); + } + + fn enable_set_event(&mut self, set_event: impl Into>) { + hrtim_out_common!($TIMX, set_event.into(), $setXYr, set_bit) + } + fn disable_set_event(&mut self, set_event: impl Into>) { + hrtim_out_common!($TIMX, set_event.into(), $setXYr, clear_bit) + } + + fn enable_rst_event(&mut self, reset_event: impl Into>) { + hrtim_out_common!($TIMX, reset_event.into(), $rstXYr, set_bit) + } + fn disable_rst_event(&mut self, reset_event: impl Into>) { + hrtim_out_common!($TIMX, reset_event.into(), $rstXYr, clear_bit) + } + + fn get_state(&self) -> State { + let ods; + let oen; + + unsafe { + let common = &*HRTIM_COMMON::ptr(); + ods = common.odsr.read().$tXYods().bit_is_set(); + oen = common.oenr.read().$tXYoen().bit_is_set(); + } + + match (oen, ods) { + (true, _) => State::Running, + (false, false) => State::Idle, + (false, true) => State::Fault + } + } + } + )+}; +} + +hrtim_out! { + HRTIM_TIMA: HrOut1: ta1oen, ta1odis, ta1ods, seta1r, rsta1r, + HRTIM_TIMA: HrOut2: ta2oen, ta2odis, ta2ods, seta2r, rsta2r, + + HRTIM_TIMB: HrOut1: tb1oen, tb1odis, tb1ods, setb1r, rstb1r, + HRTIM_TIMB: HrOut2: tb2oen, tb2odis, tb2ods, setb2r, rstb2r, + + HRTIM_TIMC: HrOut1: tc1oen, tc1odis, tc1ods, setc1r, rstc1r, + HRTIM_TIMC: HrOut2: tc2oen, tc2odis, tc2ods, setc2r, rstc2r, + + HRTIM_TIMD: HrOut1: td1oen, td1odis, td1ods, setd1r, rstd1r, + HRTIM_TIMD: HrOut2: td2oen, td2odis, td2ods, setd2r, rstd2r, + + HRTIM_TIME: HrOut1: te1oen, te1odis, te1ods, sete1r, rste1r, + HRTIM_TIME: HrOut2: te2oen, te2odis, te2ods, sete2r, rste2r, + + HRTIM_TIMF: HrOut1: tf1oen, tf1odis, tf1ods, setf1r, rstf1r, + HRTIM_TIMF: HrOut2: tf2oen, tf2odis, tf2ods, setf2r, rstf2r, +} + +pub trait HrOutput { + /// Enable this output + fn enable(&mut self); + + /// Disable this output + fn disable(&mut self); + + /// Set this output to active every time the specified event occurs + /// + /// NOTE: Enabling the same event for both SET and RESET + /// will make that event TOGGLE the output + fn enable_set_event(&mut self, set_event: impl Into>); + + /// Stop listening to the specified event + fn disable_set_event(&mut self, set_event: impl Into>); + + /// Set this output to *not* active every time the specified event occurs + /// + /// NOTE: Enabling the same event for both SET and RESET + /// will make that event TOGGLE the output + fn enable_rst_event(&mut self, reset_event: impl Into>); + + /// Stop listening to the specified event + fn disable_rst_event(&mut self, reset_event: impl Into>); + + /// Get current state of the output + fn get_state(&self) -> State; +} + +#[derive(Debug, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum State { + Idle, + Running, + Fault, +} + +pub unsafe trait ToHrOut { + type Out: ToHrOut; +} + +unsafe impl ToHrOut for (PA, PB) +where + PA: ToHrOut, + PB: ToHrOut, +{ + type Out = (PA::Out, PB::Out); +} + +pub struct HrOut1(PhantomData<(TIM, PSCL)>); +pub struct HrOut2(PhantomData<(TIM, PSCL)>); + +macro_rules! pins { + ($($TIMX:ty: CH1: $CH1:ty, CH2: $CH2:ty)+) => { + $( + impl Pins<$TIMX, CH1, ComplementaryImpossible> for $CH1 { + type Channel = Pwm<$TIMX, CH1, ComplementaryImpossible, ActiveHigh, ActiveHigh>; + } + + impl Pins<$TIMX, CH2, ComplementaryImpossible> for $CH2 { + type Channel = Pwm<$TIMX, CH2, ComplementaryImpossible, ActiveHigh, ActiveHigh>; + } + + unsafe impl ToHrOut for $CH1 { + type Out = HrOut1<$TIMX, PSCL>; + } + + unsafe impl ToHrOut for $CH2 { + type Out = HrOut2<$TIMX, PSCL>; + } + + unsafe impl ToHrOut for HrOut1<$TIMX, PSCL> { + type Out

= HrOut1<$TIMX, P>; + } + + unsafe impl ToHrOut for HrOut2<$TIMX, PSCL> { + type Out

= HrOut2<$TIMX, P>; + } + )+ + } +} + +pins! { + HRTIM_TIMA: CH1: PA8>, CH2: PA9> + + HRTIM_TIMB: CH1: PA10>, CH2: PA11> + HRTIM_TIMC: CH1: PB12>, CH2: PB13> + HRTIM_TIMD: CH1: PB14>, CH2: PB15> + + HRTIM_TIME: CH1: PC8>, CH2: PC9> + HRTIM_TIMF: CH1: PC6>, CH2: PC7> +} + +impl Pins for () { + type Channel = (); +} + +unsafe impl ToHrOut for () { + type Out = (); +} + +// automatically implement Pins trait for tuples of individual pins +macro_rules! pins_tuples { + // Tuple of two pins + ($(($CHA:ident, $CHB:ident)),*) => { + $( + impl Pins, $CHB), (TA, TB)> for (CHA, CHB) + where + CHA: Pins, TA>, + CHB: Pins, TB>, + { + type Channel = (Pwm, TA, ActiveHigh, ActiveHigh>, Pwm, TB, ActiveHigh, ActiveHigh>); + } + + impl HrtimChannel for ($CHA, $CHB) {} + )* + }; +} + +pins_tuples! { + (CH1, CH2), + (CH2, CH1) +} + +pub struct CH1(PhantomData); +pub struct CH2(PhantomData); + +impl HrtimChannel for () {} +pub trait HrtimChannel {} + +impl HrtimChannel for CH1 {} +impl HrtimChannel for CH2 {} diff --git a/src/hrtim/timer.rs b/src/hrtim/timer.rs index 689d7bd7..344234e9 100644 --- a/src/hrtim/timer.rs +++ b/src/hrtim/timer.rs @@ -91,6 +91,12 @@ pub trait HrSlaveTimer: HrTimer { ); } +pub struct TimerSplitCapture { + pub timer: HrTim, + pub ch1: HrCapt, + pub ch2: HrCapt, +} + /// Trait for unsplit slave timer which still contains its capture modules pub trait HrSlaveTimerCpt: HrSlaveTimer { type CaptureCh1: HrCapture; @@ -100,11 +106,7 @@ pub trait HrSlaveTimerCpt: HrSlaveTimer { fn capture_ch2(&mut self) -> &mut ::CaptureCh2; fn split_capture( self, - ) -> ( - HrTim, - HrCapt, - HrCapt, - ); + ) -> TimerSplitCapture; } macro_rules! hrtim_timer { @@ -267,7 +269,7 @@ macro_rules! hrtim_timer { &mut self.capture_ch2 } - fn split_capture(self) -> (HrTim<$TIMX, PSCL, (), ()>, HrCapt<$TIMX, PSCL, capture::Ch1, capture::NoDma>, HrCapt<$TIMX, PSCL, capture::Ch2, capture::NoDma>) { + fn split_capture(self) -> TimerSplitCapture<$TIMX, PSCL, capture::Ch1, capture::Ch2> { let HrTim{ _timer, _prescaler, @@ -275,16 +277,16 @@ macro_rules! hrtim_timer { capture_ch2, } = self; - ( - HrTim{ + TimerSplitCapture { + timer: HrTim{ _timer, _prescaler, capture_ch1: (), capture_ch2: (), }, - capture_ch1, - capture_ch2, - ) + ch1: capture_ch1, + ch2: capture_ch2, + } } } @@ -295,8 +297,6 @@ macro_rules! hrtim_timer { } /// Timer Update event - /// - /// TODO: What dows this mean? impl super::capture::CaptureEvent<$TIMX, PSCL> for HrTim<$TIMX, PSCL, CPT1, CPT2> { const BITS: u32 = 1 << 1; }