Skip to content

Commit 9d98f6b

Browse files
committed
Add hrtim support
1 parent b50e52c commit 9d98f6b

File tree

7 files changed

+306
-3
lines changed

7 files changed

+306
-3
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
],
66
"rust-analyzer.cargo.target": "thumbv7em-none-eabihf",
77
"rust-analyzer.cargo.features": [
8-
"stm32g473",
8+
"stm32g484",
99
"defmt",
10+
"hrtim"
1011
]
1112
}

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fugit = "0.3.7"
2222
stm32-usbd = { version = "0.7.0", optional = true }
2323
fixed = { version = "1.28.0", optional = true }
2424
embedded-io = "0.6"
25+
stm32-hrtim = { git = "https://github.com/usbalbin/stm32-hrtim", branch = "dont_depend_on_hal", optional = true }
2526

2627
[dependencies.cortex-m]
2728
version = "0.7.7"
@@ -91,9 +92,9 @@ stm32g431 = ["stm32g4/stm32g431"]
9192
stm32g441 = ["stm32g4/stm32g441"]
9293
stm32g471 = ["stm32g4/stm32g471"]
9394
stm32g473 = ["stm32g4/stm32g473"]
94-
stm32g474 = ["stm32g4/stm32g474"]
95+
stm32g474 = ["stm32g4/stm32g474", "stm32-hrtim/stm32g474"]
9596
stm32g483 = ["stm32g4/stm32g483"]
96-
stm32g484 = ["stm32g4/stm32g484"]
97+
stm32g484 = ["stm32g4/stm32g484", "stm32-hrtim/stm32g484"]
9798
stm32g491 = ["stm32g4/stm32g491"]
9899
stm32g4a1 = ["stm32g4/stm32g4a1"]
99100
log-itm = ["cortex-m-log/itm"]
@@ -107,6 +108,7 @@ defmt = [
107108
"embedded-io/defmt-03",
108109
]
109110
cordic = ["dep:fixed"]
111+
hrtim = ["dep:stm32-hrtim"]
110112

111113
[profile.dev]
112114
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/external_event.rs

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

src/hrtim/fault.rs

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

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 external_event;
3+
pub mod fault;
4+
5+
use core::mem::MaybeUninit;
6+
7+
use crate::{
8+
gpio,
9+
rcc::{Enable, Reset},
10+
stm32::{
11+
self, HRTIM_COMMON, HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME, HRTIM_TIMF,
12+
},
13+
};
14+
use stm32_hrtim::{
15+
control::{HrPwmControl, HrTimOngoingCalibration},
16+
output::{HrOut1, HrOut2, ToHrOut},
17+
HrParts, HrPwmBuilder,
18+
};
19+
20+
pub trait HrControltExt {
21+
fn hr_control(self, rcc: &mut crate::rcc::Rcc) -> HrTimOngoingCalibration;
22+
}
23+
24+
impl HrControltExt for crate::stm32::HRTIM_COMMON {
25+
fn hr_control(self, _rcc: &mut crate::rcc::Rcc) -> HrTimOngoingCalibration {
26+
let rcc = unsafe { &*stm32::RCC::ptr() };
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+
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+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ pub mod syscfg;
9898
pub mod time;
9999
pub mod timer;
100100
// pub mod watchdog;
101+
#[cfg(feature = "hrtim")]
102+
pub mod hrtim;
101103
pub mod independent_watchdog;
102104
#[cfg(feature = "usb")]
103105
pub mod usb;

0 commit comments

Comments
 (0)