Skip to content

Commit ed8bdaa

Browse files
committed
More work on dac trigger and tests
1 parent 721db56 commit ed8bdaa

File tree

7 files changed

+457
-53
lines changed

7 files changed

+457
-53
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +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 = { git = "https://github.com/usbalbin/stm32-hrtim", rev = "ce1da43264a59b932eaf01651eba20b9cd0d96ba", optional = true }
22+
stm32-hrtim = { git = "https://github.com/usbalbin/stm32-hrtim", rev = "0886bf2", optional = true }
2323

2424
[dependencies.cortex-m]
2525
version = "0.7.7"
@@ -138,6 +138,10 @@ harness = false
138138
name = "nucleo-g474_w_jumpers"
139139
harness = false
140140

141+
[[test]]
142+
name = "nucleo-g474_w_jumpers-hrtim"
143+
harness = false
144+
141145
[lib]
142146
test = false
143147

examples/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//! Utilities for examples
22
33
pub mod logger;
4+
pub mod test;

examples/utils/test.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#![allow(dead_code)]
2+
3+
use fugit::MicrosDurationU32;
4+
5+
use stm32g4xx_hal::stm32;
6+
7+
pub fn is_pax_low(gpioa: &stm32::gpioa::RegisterBlock, x: u8) -> bool {
8+
gpioa.idr().read().idr(x).is_low()
9+
}
10+
11+
#[cfg_attr(feature = "defmt", defmt::Format)]
12+
#[derive(Debug)]
13+
pub struct ErrorTimedOut;
14+
15+
pub fn await_lo(
16+
gpioa: &stm32::gpioa::RegisterBlock,
17+
pin: u8,
18+
timeout: MicrosDurationU32,
19+
now: impl FnMut() -> MicrosDurationU32,
20+
) -> Result<MicrosDurationU32, ErrorTimedOut> {
21+
await_p(|| is_pax_low(gpioa, pin), timeout, now)
22+
}
23+
24+
pub fn await_hi(
25+
gpioa: &stm32::gpioa::RegisterBlock,
26+
pin: u8,
27+
timeout: MicrosDurationU32,
28+
now: impl FnMut() -> MicrosDurationU32,
29+
) -> Result<MicrosDurationU32, ErrorTimedOut> {
30+
await_p(|| !is_pax_low(gpioa, pin), timeout, now)
31+
}
32+
33+
pub fn await_p(
34+
mut p: impl FnMut() -> bool,
35+
timeout: MicrosDurationU32,
36+
mut now: impl FnMut() -> MicrosDurationU32,
37+
) -> Result<MicrosDurationU32, ErrorTimedOut> {
38+
let before = now();
39+
40+
loop {
41+
let passed_time = now() - before;
42+
if p() {
43+
return Ok(passed_time);
44+
}
45+
if passed_time > timeout {
46+
return Err(ErrorTimedOut);
47+
}
48+
}
49+
}

src/hrtim/dac_trigger.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use stm32_hrtim::DacResetOnCounterReset;
2+
use stm32_hrtim::{
3+
compare_register::HrCr2, output::HrOut1, timer::HrTim, DacResetOnOut1Set, DacResetTrigger,
4+
DacStepOnCmp2, DacStepOnOut1Rst, DacStepTrigger,
5+
};
6+
7+
use crate::dac::{IncTriggerSource, TriggerSource as RstTriggerSource};
8+
use crate::stm32;
9+
10+
// TODO: use crate::stasis instead of references
11+
macro_rules! impl_dac_triggers {
12+
($($TIM:ident: $bits:expr),*) => {$(
13+
unsafe impl<PSCL> IncTriggerSource for &HrCr2<stm32::$TIM, PSCL, DacStepOnCmp2> {
14+
const BITS: u8 = $bits;
15+
}
16+
unsafe impl<PSCL, R: DacResetTrigger> IncTriggerSource for &HrOut1<stm32::$TIM, PSCL, R, DacStepOnOut1Rst> {
17+
const BITS: u8 = $bits;
18+
}
19+
20+
unsafe impl<PSCL, CPT1, CPT2> RstTriggerSource for &HrTim<stm32::$TIM, PSCL, CPT1, CPT2, DacResetOnCounterReset> {
21+
const BITS: u8 = $bits;
22+
}
23+
unsafe impl<PSCL, S: DacStepTrigger> RstTriggerSource for &HrOut1<stm32::$TIM, PSCL, DacResetOnOut1Set, S> {
24+
const BITS: u8 = $bits;
25+
}
26+
)*};
27+
}
28+
29+
// RM0440 DAC1 interconnection
30+
impl_dac_triggers! {
31+
HRTIM_TIMA: 9,
32+
HRTIM_TIMB: 10,
33+
HRTIM_TIMC: 11,
34+
HRTIM_TIMD: 12,
35+
HRTIM_TIME: 13,
36+
HRTIM_TIMF: 14
37+
}

src/hrtim/mod.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod adc_trigger;
22
pub mod capture;
3+
pub mod dac_trigger;
34
pub mod external_event;
45
pub mod fault;
56

@@ -15,7 +16,7 @@ use crate::{
1516
use stm32_hrtim::{
1617
control::{HrPwmControl, HrTimOngoingCalibration},
1718
output::{HrOut1, HrOut2, ToHrOut},
18-
HrParts, HrPwmBuilder,
19+
DacResetTrigger, DacStepTrigger, HrParts, HrPwmBuilder,
1920
};
2021

2122
pub use stm32_hrtim;
@@ -36,18 +37,31 @@ impl HrControltExt for crate::stm32::HRTIM_COMMON {
3637
}
3738
}
3839

39-
pub trait HrPwmBuilderExt<TIM, PSCL, PINS: ToHrOut<TIM>> {
40-
fn finalize(self, control: &mut HrPwmControl) -> HrParts<TIM, PSCL, PINS::Out<PSCL>>;
40+
pub trait HrPwmBuilderExt<TIM, PSCL, PINS: ToHrOut<TIM>, DacRst, DacStp>
41+
where
42+
DacRst: DacResetTrigger,
43+
DacStp: DacStepTrigger,
44+
{
45+
fn finalize(
46+
self,
47+
control: &mut HrPwmControl,
48+
) -> HrParts<TIM, PSCL, PINS::Out<PSCL>, DacRst, DacStp>;
4149
}
50+
4251
macro_rules! impl_finalize {
4352
($($TIMX:ident),+) => {$(
44-
impl<PSCL: stm32_hrtim::HrtimPrescaler, PINS: HrtimPin<$TIMX>> HrPwmBuilderExt<$TIMX, PSCL, PINS>
45-
for HrPwmBuilder<$TIMX, PSCL, stm32_hrtim::PreloadSource, PINS>
53+
impl<PSCL, PINS, DacRst, DacStp> HrPwmBuilderExt<$TIMX, PSCL, PINS, DacRst, DacStp>
54+
for HrPwmBuilder<$TIMX, PSCL, stm32_hrtim::PreloadSource, PINS, DacRst, DacStp>
55+
where
56+
PSCL: stm32_hrtim::HrtimPrescaler,
57+
PINS: HrtimPin<$TIMX>,
58+
DacRst: DacResetTrigger,
59+
DacStp: DacStepTrigger
4660
{
4761
fn finalize(
4862
self,
4963
control: &mut HrPwmControl,
50-
) -> HrParts<$TIMX, PSCL, <PINS as ToHrOut<$TIMX>>::Out<PSCL>> {
64+
) -> HrParts<$TIMX, PSCL, <PINS as ToHrOut<$TIMX>>::Out<PSCL>, DacRst, DacStp> {
5165
let pins = self._init(control);
5266
pins.connect_to_hrtim();
5367
unsafe { MaybeUninit::uninit().assume_init() }
@@ -96,8 +110,12 @@ macro_rules! pins_helper {
96110
($TIMX:ty, $HrOutY:ident, $CHY:ident<$CHY_AF:literal>) => {
97111
//impl sealed::Sealed<$TIMX> for $CHY<GpioInputMode> {}
98112

99-
unsafe impl ToHrOut<$TIMX> for $CHY<gpio::DefaultMode> {
100-
type Out<PSCL> = $HrOutY<$TIMX, PSCL>;
113+
unsafe impl<DacRst, DacStp> ToHrOut<$TIMX, DacRst, DacStp> for $CHY<gpio::DefaultMode>
114+
where
115+
DacRst: DacResetTrigger,
116+
DacStp: DacStepTrigger,
117+
{
118+
type Out<PSCL> = $HrOutY<$TIMX, PSCL, DacRst, DacStp>;
101119
}
102120

103121
impl HrtimPin<$TIMX> for $CHY<gpio::DefaultMode> {

tests/nucleo-g474.rs

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ mod utils;
66

77
use utils::logger::debug;
88

9-
use core::ops::FnMut;
10-
use core::result::Result;
119
use fugit::{ExtU32, HertzU32, MicrosDurationU32};
1210
use hal::delay::DelayExt;
1311
use hal::stm32;
@@ -52,6 +50,8 @@ mod tests {
5250
stm32::GPIOA,
5351
};
5452

53+
use crate::utils::test::{await_hi, await_lo, is_pax_low};
54+
5555
#[test]
5656
fn gpio_push_pull() {
5757
use super::*;
@@ -149,16 +149,16 @@ mod tests {
149149
let max: MicrosDurationU32 = 505u32.micros();
150150

151151
debug!("Awaiting first rising edge...");
152-
let duration_until_lo = await_lo(gpioa, max).unwrap();
153-
let first_lo_duration = await_hi(gpioa, max).unwrap();
152+
let duration_until_lo = await_lo(gpioa, 8, max, now).unwrap();
153+
let first_lo_duration = await_hi(gpioa, 8, max, now).unwrap();
154154

155155
let mut hi_duration = 0.micros();
156156
let mut lo_duration = 0.micros();
157157

158158
for _ in 0..10 {
159159
// Make sure the timer half periods are within 495-505us
160160

161-
hi_duration = await_lo(gpioa, max).unwrap();
161+
hi_duration = await_lo(gpioa, 8, max, now).unwrap();
162162
assert!(
163163
hi_duration > min && hi_duration < max,
164164
"hi: {} < {} < {}",
@@ -167,7 +167,7 @@ mod tests {
167167
max
168168
);
169169

170-
lo_duration = await_hi(gpioa, max).unwrap();
170+
lo_duration = await_hi(gpioa, 8, max, now).unwrap();
171171
assert!(
172172
lo_duration > min && lo_duration < max,
173173
"lo: {} < {} < {}",
@@ -365,41 +365,3 @@ mod tests {
365365
assert!(!is_pax_low(gpioa, 4));
366366
}
367367
}
368-
369-
fn is_pax_low(gpioa: &stm32::gpioa::RegisterBlock, x: u8) -> bool {
370-
gpioa.idr().read().idr(x).is_low()
371-
}
372-
373-
#[derive(Debug, defmt::Format)]
374-
struct ErrorTimedOut;
375-
376-
fn await_lo(
377-
gpioa: &stm32::gpioa::RegisterBlock,
378-
timeout: MicrosDurationU32,
379-
) -> Result<MicrosDurationU32, ErrorTimedOut> {
380-
await_p(|| is_pax_low(gpioa, 8), timeout)
381-
}
382-
383-
fn await_hi(
384-
gpioa: &stm32::gpioa::RegisterBlock,
385-
timeout: MicrosDurationU32,
386-
) -> Result<MicrosDurationU32, ErrorTimedOut> {
387-
await_p(|| !is_pax_low(gpioa, 8), timeout)
388-
}
389-
390-
fn await_p(
391-
mut p: impl FnMut() -> bool,
392-
timeout: MicrosDurationU32,
393-
) -> Result<MicrosDurationU32, ErrorTimedOut> {
394-
let before = now();
395-
396-
loop {
397-
let passed_time = now() - before;
398-
if p() {
399-
return Ok(passed_time);
400-
}
401-
if passed_time > timeout {
402-
return Err(ErrorTimedOut);
403-
}
404-
}
405-
}

0 commit comments

Comments
 (0)