use crate::pac::HRTIM_COMMON;
use crate::Polarity;
use super::control::HrTimCalibrated;
#[non_exhaustive]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, PartialEq)]
pub struct ExternalEventSource<const N: u8, const IS_FAST: bool>;
pub struct EevInputs {
pub eev_input1: EevInput<1>,
pub eev_input2: EevInput<2>,
pub eev_input3: EevInput<3>,
pub eev_input4: EevInput<4>,
pub eev_input5: EevInput<5>,
pub eev_input6: EevInput<6>,
pub eev_input7: EevInput<7>,
pub eev_input8: EevInput<8>,
pub eev_input9: EevInput<9>,
pub eev_input10: EevInput<10>,
}
impl EevInputs {
pub(crate) unsafe fn new() -> Self {
EevInputs {
eev_input1: EevInput,
eev_input2: EevInput,
eev_input3: EevInput,
eev_input4: EevInput,
eev_input5: EevInput,
eev_input6: EevInput,
eev_input7: EevInput,
eev_input8: EevInput,
eev_input9: EevInput,
eev_input10: EevInput,
}
}
}
#[non_exhaustive]
pub struct EevInput<const N: u8>;
pub unsafe trait EevSrcBits<const EEV_N: u8>: Sized {
const SRC_BITS: u8;
fn cfg(self) {}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EdgeOrPolarity {
Edge(Edge),
Polarity(Polarity),
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Edge {
Rising = 0b01,
Falling = 0b10,
Both = 0b11,
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EevSamplingFilter {
None = 0b0000,
HrtimN2 = 0b0001,
HrtimN4 = 0b0010,
HrtimN8 = 0b0011,
EevsDiv2N6 = 0b0100,
EevsDiv2N8 = 0b0101,
EevsDiv4N6 = 0b0110,
EevsDiv4N8 = 0b0111,
EevsDiv8N6 = 0b1000,
EevsDiv8N8 = 0b1001,
EevsDiv16N5 = 0b1010,
EevsDiv16N6 = 0b1011,
EevsDiv16N8 = 0b1100,
EevsDiv32N5 = 0b1101,
EevsDiv32N6 = 0b1110,
EevsDiv32N8 = 0b1111,
}
pub trait ExternalEventBuilder1To5 {}
pub trait ExternalEventBuilder6To10 {}
pub struct SourceBuilder<const N: u8, const IS_FAST: bool> {
src_bits: u8,
edge_or_polarity_bits: u8,
polarity_bit: bool,
filter_bits: u8,
}
#[cfg(feature = "stm32g4")]
impl<const N: u8, const IS_FAST: bool> SourceBuilder<N, IS_FAST> {
pub unsafe fn new(src_bits: u8) -> Self {
Self {
src_bits,
edge_or_polarity_bits: 0, polarity_bit: false, filter_bits: 0, }
}
}
impl<const N: u8> SourceBuilder<N, false> {
pub fn edge_or_polarity(mut self, edge_or_polarity: EdgeOrPolarity) -> Self {
(self.edge_or_polarity_bits, self.polarity_bit) = match edge_or_polarity {
EdgeOrPolarity::Polarity(Polarity::ActiveHigh) => (0b00, false),
EdgeOrPolarity::Polarity(Polarity::ActiveLow) => (0b00, true),
EdgeOrPolarity::Edge(Edge::Rising) => (0b01, false),
EdgeOrPolarity::Edge(Edge::Falling) => (0b10, false),
EdgeOrPolarity::Edge(Edge::Both) => (0b11, false),
};
self
}
}
impl<const N: u8> SourceBuilder<N, true> {
pub fn polarity(mut self, polarity: Polarity) -> Self {
(self.edge_or_polarity_bits, self.polarity_bit) = match polarity {
Polarity::ActiveHigh => (0b00, false),
Polarity::ActiveLow => (0b00, true),
};
self
}
}
impl<const N: u8> SourceBuilder<N, false>
where
SourceBuilder<N, false>: ExternalEventBuilder6To10,
{
pub fn filter(mut self, filter: EevSamplingFilter) -> Self {
self.filter_bits = filter as _;
self
}
}
pub trait ToExternalEventSource<const N: u8, const IS_FAST: bool> {
fn finalize(self, _calibrated: &mut HrTimCalibrated) -> ExternalEventSource<N, IS_FAST>;
}
macro_rules! impl_eev1_5_to_es {
($eev:ident, $N:literal, $eeXsrc:ident, $eeXpol:ident, $eeXsns:ident, $eeXfast:ident) => {
impl<const IS_FAST: bool> ExternalEventBuilder1To5 for SourceBuilder<$N, IS_FAST> {}
impl SourceBuilder<$N, false> {
pub fn fast(self) -> SourceBuilder<$N, true> {
let SourceBuilder {
src_bits,
edge_or_polarity_bits,
polarity_bit,
filter_bits,
} = self;
SourceBuilder {
src_bits,
edge_or_polarity_bits,
polarity_bit,
filter_bits,
}
}
}
impl<const IS_FAST: bool> ToExternalEventSource<$N, IS_FAST>
for SourceBuilder<$N, IS_FAST>
{
fn finalize(
self,
_calibrated: &mut HrTimCalibrated,
) -> ExternalEventSource<$N, IS_FAST> {
let SourceBuilder {
src_bits,
edge_or_polarity_bits,
polarity_bit,
filter_bits: _,
} = self;
let common = unsafe { &*HRTIM_COMMON::ptr() };
unsafe {
common.eecr1().modify(|_r, w| {
w.$eeXsrc()
.bits(src_bits)
.$eeXpol()
.bit(polarity_bit)
.$eeXsns()
.bits(edge_or_polarity_bits)
.$eeXfast()
.bit(IS_FAST)
});
}
ExternalEventSource
}
}
impl<const IS_FAST: bool, DST, PSCL> super::event::EventSource<DST, PSCL>
for ExternalEventSource<$N, IS_FAST>
{
const BITS: u32 = 1 << ($N + 20); }
};
}
macro_rules! impl_eev6_10_to_es {
($eev:ident, $N:literal, $eeXsrc:ident, $eeXpol:ident, $eeXsns:ident, $eeXf:ident) => {
impl ExternalEventBuilder6To10 for SourceBuilder<$N, false> {}
impl ToExternalEventSource<$N, false> for SourceBuilder<$N, false> {
fn finalize(self, _calibrated: &mut HrTimCalibrated) -> ExternalEventSource<$N, false> {
let SourceBuilder {
src_bits,
edge_or_polarity_bits,
polarity_bit,
filter_bits,
} = self;
let common = unsafe { &*HRTIM_COMMON::ptr() };
unsafe {
common.eecr2().modify(|_r, w| {
w.$eeXsrc()
.bits(src_bits)
.$eeXpol()
.bit(polarity_bit)
.$eeXsns()
.bits(edge_or_polarity_bits)
});
common.eecr3().modify(|_r, w| w.$eeXf().bits(filter_bits));
}
ExternalEventSource
}
}
impl<DST, PSCL> super::event::EventSource<DST, PSCL> for ExternalEventSource<$N, false> {
const BITS: u32 = 1 << ($N + 20); }
};
}
impl_eev1_5_to_es!(Eevnt1, 1, ee1src, ee1pol, ee1sns, ee1fast);
impl_eev1_5_to_es!(Eevnt2, 2, ee2src, ee2pol, ee2sns, ee2fast);
impl_eev1_5_to_es!(Eevnt3, 3, ee3src, ee3pol, ee3sns, ee3fast);
impl_eev1_5_to_es!(Eevnt4, 4, ee4src, ee4pol, ee4sns, ee4fast);
impl_eev1_5_to_es!(Eevnt5, 5, ee5src, ee5pol, ee5sns, ee5fast);
impl_eev6_10_to_es!(Eevnt6, 6, ee6src, ee6pol, ee6sns, ee6f);
impl_eev6_10_to_es!(Eevnt7, 7, ee7src, ee7pol, ee7sns, ee7f);
impl_eev6_10_to_es!(Eevnt8, 8, ee8src, ee8pol, ee8sns, ee8f);
impl_eev6_10_to_es!(Eevnt9, 9, ee9src, ee9pol, ee9sns, ee9f);
impl_eev6_10_to_es!(Eevnt10, 10, ee10src, ee10pol, ee10sns, ee10f);
impl<const N: u8, const IS_FAST: bool, TIM, PSCL> super::capture::CaptureEvent<TIM, PSCL>
for ExternalEventSource<N, IS_FAST>
{
const BITS: u32 = 1 << (N + 1); }
impl<const N: u8, const IS_FAST: bool, DST, PSCL> super::event::TimerResetEventSource<DST, PSCL>
for ExternalEventSource<N, IS_FAST>
{
const BITS: u32 = 1 << (N + 8); }