Skip to content

Commit fcad567

Browse files
committed
Add hrtim support
1 parent 17bd782 commit fcad567

File tree

9 files changed

+345
-4
lines changed

9 files changed

+345
-4
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- stm32g431
2020
- stm32g441
2121
- stm32g473
22-
- stm32g474
22+
- stm32g474,hrtim
2323
- stm32g483
2424
- stm32g484
2525
- stm32g491 # Does not seem ready yet

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"rust-analyzer.cargo.features": [
99
"stm32g484",
1010
"defmt",
11-
"cordic"
11+
"cordic",
12+
"hrtim"
1213
]
1314
}

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ fugit = "0.3.7"
1919
stm32-usbd = { version = "0.7.0", optional = true }
2020
fixed = { version = "1.28.0", optional = true }
2121
embedded-io = "0.6"
22+
stm32-hrtim = { version = "0.1.0", optional = true }
2223

2324
[dependencies.cortex-m]
2425
version = "0.7.7"
@@ -81,9 +82,9 @@ usb = ["dep:stm32-usbd"]
8182
stm32g431 = ["stm32g4/stm32g431", "cat2"]
8283
stm32g441 = ["stm32g4/stm32g441", "cat2"]
8384
stm32g473 = ["stm32g4/stm32g473", "cat3", "adc3", "adc4", "adc5"]
84-
stm32g474 = ["stm32g4/stm32g474", "cat3", "adc3", "adc4", "adc5"]
85+
stm32g474 = ["stm32g4/stm32g474", "cat3", "adc3", "adc4", "adc5", "stm32-hrtim/stm32g474"]
8586
stm32g483 = ["stm32g4/stm32g483", "cat3", "adc3", "adc4", "adc5"]
86-
stm32g484 = ["stm32g4/stm32g484", "cat3", "adc3", "adc4", "adc5"]
87+
stm32g484 = ["stm32g4/stm32g484", "cat3", "adc3", "adc4", "adc5", "stm32-hrtim/stm32g484"]
8788
stm32g491 = ["stm32g4/stm32g491", "cat4", "adc3"]
8889
stm32g4a1 = ["stm32g4/stm32g4a1", "cat4", "adc3"]
8990

@@ -105,6 +106,7 @@ defmt = [
105106
"embedded-hal/defmt-03",
106107
"embedded-io/defmt-03",
107108
"embedded-test/defmt",
109+
"stm32-hrtim?/defmt"
108110
]
109111
cordic = ["dep:fixed"]
110112
adc3 = []
@@ -117,6 +119,7 @@ cat3 = ["gpio-g47x"]
117119
cat4 = ["gpio-g49x"]
118120

119121
can = ["dep:fdcan"]
122+
hrtim = ["dep:stm32-hrtim"] # Only available for stm32g474 and stm32g484
120123

121124
[profile.dev]
122125
codegen-units = 1

src/hrtim/adc_trigger.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::adc;
2+
use stm32_hrtim::adc_trigger::{
3+
AdcTrigger1, AdcTrigger10, AdcTrigger2, AdcTrigger3, AdcTrigger4, AdcTrigger5, AdcTrigger6,
4+
AdcTrigger7, AdcTrigger8, AdcTrigger9,
5+
};
6+
7+
macro_rules! impl_adc1234_trigger {
8+
($($t:ident: [$variant345:ident $(, $variant12:ident)*]),*) => {$(
9+
$(impl From<&$t> for adc::config::ExternalTrigger12 {
10+
fn from(_val: &$t) -> Self {
11+
adc::config::ExternalTrigger12::$variant12
12+
}
13+
})*
14+
15+
impl From<&$t> for adc::config::ExternalTrigger345 {
16+
fn from(_val: &$t) -> Self {
17+
adc::config::ExternalTrigger345::$variant345
18+
}
19+
}
20+
)*}
21+
}
22+
23+
macro_rules! impl_adc5678910_trigger {
24+
($($t:ident: [$variant:ident]),*) => {$(
25+
impl From<&$t> for adc::config::ExternalTrigger12 {
26+
fn from(_val: &$t) -> Self {
27+
adc::config::ExternalTrigger12::$variant
28+
}
29+
}
30+
31+
impl From<&$t> for adc::config::ExternalTrigger345 {
32+
fn from(_val: &$t) -> Self {
33+
adc::config::ExternalTrigger345::$variant
34+
}
35+
}
36+
)*}
37+
}
38+
39+
impl_adc1234_trigger! {//adc345, adc12
40+
AdcTrigger1: [Hrtim_adc_trg_1, Hrtim_adc_trg_1],
41+
AdcTrigger2: [Hrtim_adc_trg_2],
42+
AdcTrigger3: [Hrtim_adc_trg_3, Hrtim_adc_trg_3],
43+
AdcTrigger4: [Hrtim_adc_trg_4]
44+
}
45+
46+
impl_adc5678910_trigger! {
47+
AdcTrigger5: [Hrtim_adc_trg_5],
48+
AdcTrigger6: [Hrtim_adc_trg_6],
49+
AdcTrigger7: [Hrtim_adc_trg_7],
50+
AdcTrigger8: [Hrtim_adc_trg_8],
51+
AdcTrigger9: [Hrtim_adc_trg_9],
52+
AdcTrigger10: [Hrtim_adc_trg_10]
53+
}

src/hrtim/capture.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use stm32_hrtim::{
2+
capture::{Ch1, Ch2, Dma, HrCapt},
3+
pac::{HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF},
4+
};
5+
6+
use crate::dma::{mux::DmaMuxResources, traits::TargetAddress, PeripheralToMemory};
7+
8+
macro_rules! impl_dma_traits {
9+
($TIMX:ident, $CH:ident, $cptXr:ident) => {
10+
unsafe impl<PSCL> TargetAddress<PeripheralToMemory> for HrCapt<$TIMX, PSCL, $CH, Dma> {
11+
#[inline(always)]
12+
fn address(&self) -> u32 {
13+
let tim = unsafe { &*$TIMX::ptr() };
14+
&tim.$cptXr() as *const _ as u32
15+
}
16+
17+
type MemSize = u32;
18+
19+
const REQUEST_LINE: Option<u8> = Some(DmaMuxResources::$TIMX as u8);
20+
}
21+
};
22+
($($TIMX:ident),+) => {
23+
$(
24+
impl_dma_traits!($TIMX, Ch1, cpt1r);
25+
impl_dma_traits!($TIMX, Ch2, cpt2r);
26+
)+
27+
}
28+
}
29+
30+
impl_dma_traits! {
31+
HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF
32+
}

src/hrtim/external_event.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use stm32_hrtim::external_event::{EevInput, EevSrcBits, SourceBuilder};
2+
3+
use crate::gpio::{
4+
self,
5+
gpiob::{PB3, PB4, PB5, PB6, PB7, PB8, PB9},
6+
gpioc::{PC11, PC12, PC5, PC6},
7+
};
8+
9+
pub trait EevInputExt<const N: u8> {
10+
fn bind<const IS_FAST: bool, SRC>(self, src: SRC) -> SourceBuilder<N, IS_FAST>
11+
where
12+
SRC: EevSrcBits<N>;
13+
}
14+
15+
macro_rules! impl_eev_input {
16+
($($N:literal: COMP=[$compX:ident $(, ($compY:ident, $compY_src_bits:literal))*], PINS=[$(($pin:ident, $af:literal)),*])*) => {$(
17+
$(unsafe impl EevSrcBits<$N> for $pin<gpio::Input>{
18+
const SRC_BITS: u8 = 0b00;
19+
fn cfg(self) {
20+
self.into_alternate::<$af>();
21+
}
22+
})*
23+
24+
unsafe impl<ED> EevSrcBits<$N> for &crate::comparator::Comparator<crate::comparator::$compX, ED>
25+
where ED: crate::comparator::EnabledState
26+
{
27+
const SRC_BITS: u8 = 0b01;
28+
}
29+
30+
$(
31+
unsafe impl<ED> EevSrcBits<$N> for &crate::comparator::Comparator<crate::comparator::$compY, ED>
32+
where ED: crate::comparator::EnabledState
33+
{
34+
const SRC_BITS: u8 = $compY_src_bits;
35+
}
36+
)*
37+
38+
impl EevInputExt<$N> for EevInput<$N> {
39+
fn bind<const IS_FAST: bool, SRC>(self, src: SRC) -> SourceBuilder<$N, IS_FAST>
40+
where SRC: EevSrcBits<$N>
41+
{
42+
src.cfg();
43+
unsafe { SourceBuilder::new(SRC::SRC_BITS) }
44+
}
45+
}
46+
)*};
47+
}
48+
49+
impl_eev_input! {
50+
1: COMP = [COMP2], PINS = [(PC12, 3)]
51+
2: COMP = [COMP4], PINS = [(PC11, 3)]
52+
3: COMP = [COMP6], PINS = [(PB7, 13)]
53+
4: COMP = [COMP1, (COMP5, 0b10)], PINS = [(PB6, 13)]
54+
5: COMP = [COMP3, (COMP7, 0b10)], PINS = [(PB9, 13)]
55+
6: COMP = [COMP2, (COMP1, 0b10)], PINS = [(PB5, 13)]
56+
7: COMP = [COMP4], PINS = [(PB4, 13)]
57+
8: COMP = [COMP6, (COMP3, 0b10)], PINS = [(PB8, 13)]
58+
9: COMP = [COMP5, (COMP4, 0b11)], PINS = [(PB3, 13)]
59+
10: COMP = [COMP7], PINS = [(PC5, 13), (PC6, 3)]
60+
}

src/hrtim/fault.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use stm32_hrtim::fault::{self, SourceBuilder};
2+
3+
use crate::{
4+
comparator::{COMP1, COMP2, COMP3, COMP4, COMP5, COMP6},
5+
gpio::{
6+
self,
7+
gpioa::{PA12, PA15},
8+
gpiob::{PB0, PB10, PB11},
9+
gpioc::{PC10, PC7},
10+
},
11+
};
12+
13+
// TODO: Come up with a better names
14+
15+
pub trait FaultInput<S> {
16+
fn bind(self, src: S) -> SourceBuilder<Self>
17+
where
18+
Self: Sized;
19+
}
20+
21+
macro_rules! impl_faults {
22+
($(
23+
$input:ident:
24+
PINS=[($pin:ident, $af:literal) $(,($pin_b:ident, $af_b:literal))*],
25+
COMP=$compX:ident,
26+
)+) => {$(
27+
impl FaultInput<$pin<gpio::Alternate<$af>>> for fault::$input {
28+
fn bind(self, _pin: $pin<gpio::Alternate<$af>>) -> SourceBuilder<fault::$input> {
29+
unsafe { SourceBuilder::new(self, 0b00) }
30+
}
31+
}
32+
33+
$(
34+
impl FaultInput<$pin_b<gpio::Alternate<$af_b>>> for fault::$input {
35+
fn bind(self, _pin: $pin_b<gpio::Alternate<$af_b>>) -> SourceBuilder<fault::$input> {
36+
unsafe { SourceBuilder::new(self, 0b00) }
37+
}
38+
}
39+
)*
40+
41+
impl FaultInput<crate::comparator::Comparator<$compX, crate::comparator::Enabled>> for fault::$input {
42+
fn bind(self, _comp: crate::comparator::Comparator<$compX, crate::comparator::Enabled>) -> SourceBuilder<fault::$input> {
43+
unsafe { SourceBuilder::new(self, 0b01) }
44+
}
45+
}
46+
47+
/*pub fn bind_external(?) {
48+
SourceBuilder::new(self, 0b10);
49+
}*/
50+
)+}
51+
}
52+
53+
impl_faults!(
54+
FaultInput1: PINS=[(PA12, 13)], COMP=COMP2,
55+
FaultInput2: PINS=[(PA15, 13)], COMP=COMP4,
56+
FaultInput3: PINS=[(PB10, 13)], COMP=COMP6,
57+
FaultInput4: PINS=[(PB11, 13)], COMP=COMP1,
58+
FaultInput5: PINS=[(PB0, 13), (PC7, 3)], COMP=COMP3,
59+
FaultInput6: PINS=[(PC10, 13)], COMP=COMP5,
60+
);

src/hrtim/mod.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
pub mod adc_trigger;
2+
pub mod capture;
3+
pub mod external_event;
4+
pub mod fault;
5+
6+
use core::mem::MaybeUninit;
7+
8+
use crate::{
9+
gpio,
10+
rcc::{Enable, Reset},
11+
stm32::{HRTIM_COMMON, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF},
12+
};
13+
use stm32_hrtim::{
14+
control::{HrPwmControl, HrTimOngoingCalibration},
15+
output::{HrOut1, HrOut2, ToHrOut},
16+
HrParts, HrPwmBuilder,
17+
};
18+
19+
pub use stm32_hrtim;
20+
21+
pub trait HrControltExt {
22+
fn hr_control(self, rcc: &mut crate::rcc::Rcc) -> HrTimOngoingCalibration;
23+
}
24+
25+
impl HrControltExt for crate::stm32::HRTIM_COMMON {
26+
fn hr_control(self, rcc: &mut crate::rcc::Rcc) -> HrTimOngoingCalibration {
27+
HRTIM_COMMON::enable(rcc);
28+
HRTIM_COMMON::reset(rcc);
29+
30+
// TODO: Verify that the HRTIM gets a clock of 100-170MHz as input
31+
// SAFETY: We have enabled the rcc
32+
unsafe { HrTimOngoingCalibration::hr_control() }
33+
}
34+
}
35+
36+
pub trait HrPwmBuilderExt<TIM, PSCL, PINS: ToHrOut<TIM>> {
37+
fn finalize(self, control: &mut HrPwmControl) -> HrParts<TIM, PSCL, PINS::Out<PSCL>>;
38+
}
39+
macro_rules! impl_finalize {
40+
($($TIMX:ident),+) => {$(
41+
impl<PSCL: stm32_hrtim::HrtimPrescaler, PINS: HrtimPin<$TIMX>> HrPwmBuilderExt<$TIMX, PSCL, PINS>
42+
for HrPwmBuilder<$TIMX, PSCL, stm32_hrtim::PreloadSource, PINS>
43+
{
44+
fn finalize(
45+
self,
46+
control: &mut HrPwmControl,
47+
) -> HrParts<$TIMX, PSCL, <PINS as ToHrOut<$TIMX>>::Out<PSCL>> {
48+
let pins = self._init(control);
49+
pins.connect_to_hrtim();
50+
unsafe { MaybeUninit::uninit().assume_init() }
51+
}
52+
}
53+
)+};
54+
}
55+
56+
impl_finalize! {
57+
HRTIM_TIMA,
58+
HRTIM_TIMB,
59+
HRTIM_TIMC,
60+
HRTIM_TIMD,
61+
HRTIM_TIME,
62+
HRTIM_TIMF
63+
}
64+
65+
use gpio::{
66+
gpioa::{PA10, PA11, PA8, PA9},
67+
gpioc::PC8,
68+
};
69+
70+
use gpio::{
71+
gpiob::{PB12, PB13, PB14, PB15},
72+
gpioc::PC9,
73+
};
74+
75+
use gpio::gpioc::{PC6, PC7};
76+
77+
pub trait HrtimPin<TIM>: ToHrOut<TIM> {
78+
fn connect_to_hrtim(self);
79+
}
80+
81+
impl<TIM, PA, PB> HrtimPin<TIM> for (PA, PB)
82+
where
83+
PA: HrtimPin<TIM>,
84+
PB: HrtimPin<TIM>,
85+
{
86+
fn connect_to_hrtim(self) {
87+
self.0.connect_to_hrtim();
88+
self.1.connect_to_hrtim();
89+
}
90+
}
91+
92+
macro_rules! pins_helper {
93+
($TIMX:ty, $HrOutY:ident, $CHY:ident<$CHY_AF:literal>) => {
94+
//impl sealed::Sealed<$TIMX> for $CHY<GpioInputMode> {}
95+
96+
unsafe impl ToHrOut<$TIMX> for $CHY<gpio::DefaultMode> {
97+
type Out<PSCL> = $HrOutY<$TIMX, PSCL>;
98+
}
99+
100+
impl HrtimPin<$TIMX> for $CHY<gpio::DefaultMode> {
101+
// Pin<Gpio, Index, Alternate<PushPull, AF>>
102+
fn connect_to_hrtim(self) {
103+
let _: $CHY<gpio::Alternate<{ $CHY_AF }>> = self.into_alternate();
104+
}
105+
}
106+
};
107+
}
108+
109+
macro_rules! pins {
110+
($($TIMX:ty: CH1: $CH1:ident<$CH1_AF:literal>, CH2: $CH2:ident<$CH2_AF:literal>),+) => {$(
111+
pins_helper!($TIMX, HrOut1, $CH1<$CH1_AF>);
112+
pins_helper!($TIMX, HrOut2, $CH2<$CH2_AF>);
113+
)+};
114+
}
115+
116+
pins! {
117+
HRTIM_TIMA: CH1: PA8<13>, CH2: PA9<13>,
118+
HRTIM_TIMB: CH1: PA10<13>, CH2: PA11<13>,
119+
HRTIM_TIMC: CH1: PB12<13>, CH2: PB13<13>,
120+
HRTIM_TIMD: CH1: PB14<13>, CH2: PB15<13>,
121+
HRTIM_TIME: CH1: PC8<3>, CH2: PC9<3>,
122+
HRTIM_TIMF: CH1: PC6<13>, CH2: PC7<13>
123+
}

0 commit comments

Comments
 (0)