Skip to content

Commit da19e8f

Browse files
committed
HRTIM - Fix bugs in capture module with get_signed and some restructurings
1 parent 352cada commit da19e8f

File tree

3 files changed

+89
-14
lines changed

3 files changed

+89
-14
lines changed

src/hrtim/adc_trigger.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ pub trait Adc6810Trigger {
1616
const BITS: u32;
1717
}
1818

19+
/// Handle to timers reset/roll-over event
1920
pub struct TimerReset<T>(pub(crate) PhantomData<T>);
21+
22+
/// Handle to timers period event
2023
pub struct TimerPeriod<T>(pub(crate) PhantomData<T>);

src/hrtim/capture.rs

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,72 @@ pub trait CaptureEvent<TIM, PSCL> {
3131
const BITS: u32;
3232
}
3333

34+
/// Trait for capture channels used for capturing edges
35+
///
36+
/// ```
37+
/// let capture: HrCapt<_, _, _> = todo!();
38+
/// if capture.is_pending() {
39+
/// let (value, dir) = capture.get_last();
40+
/// capture.clear_interrupt();
41+
/// defmt::info!("Edge captured at counter value: {}, with: {}", value, dir);
42+
/// }
43+
/// ```
44+
///
45+
/// or alternatively
46+
///
47+
/// ```
48+
/// let capture: HrCapt<_, _, _> = todo!();
49+
/// if let Some((value, dir)) = capture.get() {
50+
/// defmt::info!("Edge captured at counter value: {}, with: {}", value, dir);
51+
/// }
52+
/// ```
3453
pub trait HrCapture {
35-
fn get(&self) -> (u16, CountingDirection);
54+
/// Try to get the capture value
55+
///
56+
/// Returns none if edge has been captured since last time
57+
///
58+
/// NOTE: This function will use [`Self::is_pending`] to chech if there is a value available and
59+
/// [`Self::clear_interrupt`] to clear it.
60+
fn get(&mut self) -> Option<(u16, CountingDirection)> {
61+
if self.is_pending() {
62+
let value = self.get_last();
63+
self.clear_interrupt();
64+
Some(value)
65+
} else {
66+
None
67+
}
68+
}
69+
70+
/// Get number of ticks relative to beginning of upcounting
71+
///
72+
/// where captures during down counting count as negative (before the upcount)
73+
///
74+
/// ```txt
75+
/// Counter
76+
/// ---------------------------------- <--- period
77+
/// \ ^ /
78+
/// \ | /
79+
/// \ | /
80+
/// \ | /
81+
/// Down count \ | / Up count
82+
/// \|/
83+
/// <-------------- 0 --------------> t
84+
/// Negative result | positive result
85+
/// ```
86+
///
87+
/// NOTE: This function will use [`Self::is_pending`] to chech if there is a value available and
88+
/// [`Self::clear_interrupt`] to clear it.
89+
fn get_signed(&mut self, period: u16) -> Option<i32> {
90+
if self.is_pending() {
91+
let value = self.get_last_signed(period);
92+
self.clear_interrupt();
93+
Some(value)
94+
} else {
95+
None
96+
}
97+
}
98+
99+
fn get_last(&self) -> (u16, CountingDirection);
36100

37101
/// Get number of ticks relative to beginning of upcounting
38102
///
@@ -50,12 +114,13 @@ pub trait HrCapture {
50114
/// <-------------- 0 --------------> t
51115
/// Negative result | positive result
52116
/// ````
53-
fn get_signed(&self, period: u16) -> i32 {
54-
let (value, dir) = self.get();
117+
fn get_last_signed(&self, period: u16) -> i32 {
118+
let (value, dir) = self.get_last();
55119

120+
// The capture counter always counts up and restarts at period
56121
match dir {
57122
CountingDirection::Up => i32::from(value),
58-
CountingDirection::Down => i32::from(period) - i32::from(value),
123+
CountingDirection::Down => i32::from(value) - i32::from(period),
59124
}
60125
}
61126

@@ -75,9 +140,10 @@ pub fn dma_value_to_dir_and_value(x: u32) -> (u16, CountingDirection) {
75140
pub fn dma_value_to_signed(x: u32, period: u16) -> i32 {
76141
let (value, dir) = dma_value_to_dir_and_value(x);
77142

143+
// The capture counter always counts up and restarts at period
78144
match dir {
79145
CountingDirection::Up => i32::from(value),
80-
CountingDirection::Down => i32::from(period) - i32::from(value),
146+
CountingDirection::Down => i32::from(value) - i32::from(period),
81147
}
82148
}
83149

@@ -135,7 +201,7 @@ macro_rules! impl_capture {
135201
}
136202

137203
impl<PSCL, DMA> HrCapture for HrCapt<$TIMX, PSCL, $CH, DMA> {
138-
fn get(&self) -> (u16, CountingDirection) {
204+
fn get_last(&self) -> (u16, CountingDirection) {
139205
let tim = unsafe { &*$TIMX::ptr() };
140206
let data = tim.$cptXYr.read();
141207

src/hrtim/timer.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::stm32::{
44
use core::marker::PhantomData;
55

66
use super::{
7-
capture::{self, HrCapt},
7+
capture::{self, HrCapt, HrCapture},
88
control::HrPwmControl,
99
HrtimPrescaler,
1010
};
@@ -52,16 +52,16 @@ pub trait HrTimer {
5252

5353
fn clear_repetition_interrupt(&mut self);
5454

55-
/// Make a handle to this timers reset event to use as adc trigger
55+
/// Make a handle to this timers reset/roll-over event to use as adc trigger
5656
fn as_reset_adc_trigger(&self) -> super::adc_trigger::TimerReset<Self::Timer>;
5757

5858
/// Make a handle to this timers period event to use as adc trigger
5959
fn as_period_adc_trigger(&self) -> super::adc_trigger::TimerPeriod<Self::Timer>;
6060
}
6161

6262
pub trait HrSlaveTimer: HrTimer {
63-
type CaptureCh1;
64-
type CaptureCh2;
63+
type CptCh1;
64+
type CptCh2;
6565

6666
/// Start listening to the specified event
6767
fn enable_reset_event<E: super::event::TimerResetEventSource<Self::Timer, Self::Prescaler>>(
@@ -78,8 +78,11 @@ pub trait HrSlaveTimer: HrTimer {
7878

7979
/// Trait for unsplit slave timer which still contains its capture modules
8080
pub trait HrSlaveTimerCpt: HrSlaveTimer {
81-
fn capture_ch1(&mut self) -> &mut <Self as HrSlaveTimer>::CaptureCh1;
82-
fn capture_ch2(&mut self) -> &mut <Self as HrSlaveTimer>::CaptureCh2;
81+
type CaptureCh1: HrCapture;
82+
type CaptureCh2: HrCapture;
83+
84+
fn capture_ch1(&mut self) -> &mut <Self as HrSlaveTimerCpt>::CaptureCh1;
85+
fn capture_ch2(&mut self) -> &mut <Self as HrSlaveTimerCpt>::CaptureCh2;
8386
fn split_capture(
8487
self,
8588
) -> (
@@ -179,8 +182,8 @@ macro_rules! hrtim_timer {
179182

180183
$(
181184
impl<PSCL: HrtimPrescaler, CPT1, CPT2> HrSlaveTimer for HrTim<$TIMX, PSCL, CPT1, CPT2> {
182-
type CaptureCh1 = HrCapt<Self::Timer, Self::Prescaler, capture::Ch1, capture::NoDma>;
183-
type CaptureCh2 = HrCapt<Self::Timer, Self::Prescaler, capture::Ch2, capture::NoDma>;
185+
type CptCh1 = HrCapt<Self::Timer, Self::Prescaler, capture::Ch1, capture::NoDma>;
186+
type CptCh2 = HrCapt<Self::Timer, Self::Prescaler, capture::Ch2, capture::NoDma>;
184187

185188
/// Reset this timer every time the specified event occurs
186189
///
@@ -212,6 +215,9 @@ macro_rules! hrtim_timer {
212215
}
213216

214217
impl<PSCL: HrtimPrescaler> HrSlaveTimerCpt for HrTim<$TIMX, PSCL, HrCapt<$TIMX, PSCL, capture::Ch1, capture::NoDma>, HrCapt<$TIMX, PSCL, capture::Ch2, capture::NoDma>> {
218+
type CaptureCh1 = <Self as HrSlaveTimer>::CptCh1;
219+
type CaptureCh2 = <Self as HrSlaveTimer>::CptCh2;
220+
215221
/// Access the timers first capture channel
216222
fn capture_ch1(&mut self) -> &mut Self::CaptureCh1 {
217223
&mut self.capture_ch1

0 commit comments

Comments
 (0)