Skip to content

Commit 0dd9106

Browse files
committed
ext
1 parent d103db2 commit 0dd9106

File tree

11 files changed

+1308
-710
lines changed

11 files changed

+1308
-710
lines changed

.zed/settings.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"lsp": {
3+
"rust-analyzer": {
4+
"initialization_options": {
5+
"cargo": {
6+
"features": ["stm32g474"]
7+
},
8+
"check": {
9+
"allTargets": false,
10+
"targets": "thumbv7em-none-eabihf"
11+
}
12+
}
13+
}
14+
}
15+
}

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
87
stm32f3 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies", optional = true }
9-
stm32h7 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies", fatures = ["critical-section"], optional = true }
10-
#stm32g4 = { git = "", optional = true }
8+
stm32h7 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies", features = [
9+
"critical-section",
10+
], optional = true }
11+
stm32g4 = { version = "0.21.1", package = "stm32g4-staging" }
1112

1213
#stm32f3xx-hal = { version = "0.10.0", optional = true }
1314
stm32f3xx-hal = { git = "https://github.com/usbalbin/stm32f3xx-hal", branch = "update_for_new_pac", optional = true }
@@ -115,4 +116,4 @@ path = "examples/stm32g4/master.rs"
115116
[[example]]
116117
name = "stm32h7"
117118
required-features = ["stm32h7"]
118-
path = "examples/stm32h7/hrtim.rs"
119+
path = "examples/stm32h7/hrtim.rs"

src/capture.rs

Lines changed: 84 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
use crate::stm32;
2-
3-
use super::timer;
4-
5-
#[cfg(feature = "stm32g4")]
6-
use crate::hal::dma::PeripheralToMemory;
7-
#[cfg(feature = "stm32g4")]
8-
use crate::mcu::DmaMuxResources;
9-
1+
use super::timer::{self, Ch1, Ch2, ChExt, InstanceX};
2+
use crate::ext::{Cptcr, MasterExt, TimExt};
103
use core::marker::PhantomData;
11-
#[cfg(feature = "hrtim_v2")]
12-
use stm32::HRTIM_TIMF;
13-
use stm32::{HRTIM_TIMA, HRTIM_TIMB, HRTIM_TIMC, HRTIM_TIMD, HRTIM_TIME};
14-
15-
pub struct Ch1;
16-
pub struct Ch2;
174

185
pub struct Dma;
196
pub struct NoDma;
@@ -168,121 +155,101 @@ pub fn dma_value_to_signed(x: u32, #[allow(unused_variables)] period: u16) -> i3
168155
}
169156
}
170157

171-
macro_rules! impl_capture {
172-
($($TIMX:ident),+) => {$(
173-
impl_capture!($TIMX: Ch1, cpt1r, cpt1cr, cpt1, cpt1ie, cpt1de, cpt1c);
174-
impl_capture!($TIMX: Ch2, cpt2r, cpt2cr, cpt2, cpt2ie, cpt2de, cpt2c);
175-
)+};
176-
177-
($TIMX:ident: $CH:ident, $cptXr:ident, $cptXcr:ident, $cptX:ident, $cptXie:ident, $cptXde:ident, $cptXc:ident) => {
178-
impl<PSCL> HrCapt<$TIMX, PSCL, $CH, NoDma> {
179-
/// Add event to capture
180-
///
181-
/// If multiple events are added, they will be ORed together meaning
182-
/// that a capture will be trigger if any one of the events triggers
183-
pub fn add_event<E: CaptureEvent<$TIMX, PSCL>>(&mut self, _event: &E) {
184-
let tim = unsafe { &*$TIMX::ptr() };
185-
186-
// SAFETY: We are the only one with access to cptXYcr
187-
unsafe {
188-
tim.$cptXcr().modify(|r, w| w.bits(r.bits() | E::BITS));
189-
}
190-
}
191-
192-
/// Remove event to capture
193-
pub fn remove_event<E: CaptureEvent<$TIMX, PSCL>>(&mut self, _event: &E) {
194-
let tim = unsafe { &*$TIMX::ptr() };
195-
196-
// SAFETY: We are the only one with access to cptXYcr
197-
unsafe {
198-
tim.$cptXcr().modify(|r, w| w.bits(r.bits() & !E::BITS));
199-
}
200-
}
201-
202-
/// Force capture trigger now
203-
pub fn trigger_now(&mut self) {
204-
// SAFETY: We are the only one with access to cptXYcr
205-
let tim = unsafe { &*$TIMX::ptr() };
206-
207-
tim.$cptXcr().modify(|_, w| w.swcpt().set_bit());
208-
}
209-
210-
// TODO: It would be sufficient to instead of hr_control only require exclusive access to the owning timer
211-
// however that would be hard to do since typically the capture device is a field of that same timer.
212-
// Would it make more sense to have this method direcly on HrTim instead?
213-
pub fn enable_interrupt(&mut self, enable: bool, _hr_control: &mut super::HrPwmControl) {
214-
let tim = unsafe { &*$TIMX::ptr() };
215-
216-
tim.dier().modify(|_r, w| w.$cptXie().bit(enable));
217-
}
218-
219-
pub fn enable_dma(self, _ch: timer::DmaChannel<$TIMX>) -> HrCapt<$TIMX, PSCL, $CH, Dma> {
220-
// SAFETY: We own the only insance of this timers dma channel, no one else can do this
221-
let tim = unsafe { &*$TIMX::ptr() };
222-
tim.dier().modify(|_r, w| w.$cptXde().set_bit());
223-
HrCapt {
224-
_x: PhantomData
225-
}
226-
}
158+
impl<TIM: InstanceX, CH: ChExt, PSCL> HrCapt<TIM, PSCL, CH, NoDma> {
159+
/// Add event to capture
160+
///
161+
/// If multiple events are added, they will be ORed together meaning
162+
/// that a capture will be trigger if any one of the events triggers
163+
pub fn add_event<E: CaptureEvent<TIM, PSCL>>(&mut self, _event: &E) {
164+
let tim = unsafe { &*TIM::ptr() };
165+
166+
// SAFETY: We are the only one with access to cptXYcr
167+
unsafe {
168+
tim.cptcr(CH::CH).modify(|r, w| w.bits(r.bits() | E::BITS));
169+
}
170+
}
171+
172+
/// Remove event to capture
173+
pub fn remove_event<E: CaptureEvent<TIM, PSCL>>(&mut self, _event: &E) {
174+
let tim = unsafe { &*TIM::ptr() };
175+
176+
// SAFETY: We are the only one with access to cptXYcr
177+
unsafe {
178+
tim.cptcr(CH::CH).modify(|r, w| w.bits(r.bits() & !E::BITS));
227179
}
180+
}
181+
182+
/// Force capture trigger now
183+
pub fn trigger_now(&mut self) {
184+
// SAFETY: We are the only one with access to cptXYcr
185+
let tim = unsafe { &*TIM::ptr() };
186+
187+
tim.cptcr(CH::CH)
188+
.modify(|_, w| <TIM::RB as TimExt>::CPT1CRrs::set_swcpt(w));
189+
}
228190

229-
impl<PSCL, DMA> HrCapture for HrCapt<$TIMX, PSCL, $CH, DMA> {
230-
fn get_last(&self) -> (u16, CountingDirection) {
231-
let tim = unsafe { &*$TIMX::ptr() };
232-
let data = tim.$cptXr().read();
191+
// TODO: It would be sufficient to instead of hr_control only require exclusive access to the owning timer
192+
// however that would be hard to do since typically the capture device is a field of that same timer.
193+
// Would it make more sense to have this method direcly on HrTim instead?
194+
pub fn enable_interrupt(&mut self, enable: bool, _hr_control: &mut super::HrPwmControl) {
195+
let tim = unsafe { &*TIM::ptr() };
233196

234-
#[cfg(feature = "hrtim_v2")]
235-
let dir = match data.dir().bit() {
236-
true => CountingDirection::Down,
237-
false => CountingDirection::Up,
238-
};
239-
#[cfg(any(feature = "hrtim_v1", feature = "hrtim_v1_1"))]
240-
let dir = CountingDirection::Up;
197+
tim.dier().modify(|_r, w| w.cptie(CH::CH as _).bit(enable));
198+
}
241199

242-
let value = data.cpt().bits();
200+
pub fn enable_dma(self, _ch: timer::DmaChannel<TIM>) -> HrCapt<TIM, PSCL, CH, Dma> {
201+
// SAFETY: We own the only insance of this timers dma channel, no one else can do this
202+
let tim = unsafe { &*TIM::ptr() };
203+
tim.dier().modify(|_r, w| w.cptde(CH::CH as _).set_bit());
204+
HrCapt { _x: PhantomData }
205+
}
206+
}
243207

244-
(value, dir)
245-
}
208+
impl<TIM: InstanceX, CH: ChExt, PSCL, DMA> HrCapture for HrCapt<TIM, PSCL, CH, DMA> {
209+
fn get_last(&self) -> (u16, CountingDirection) {
210+
let tim = unsafe { &*TIM::ptr() };
211+
let data = tim.cptr(CH::CH).read();
246212

247-
fn clear_interrupt(&mut self) {
248-
let tim = unsafe { &*$TIMX::ptr() };
213+
#[cfg(feature = "hrtim_v2")]
214+
let dir = match data.dir().bit() {
215+
true => CountingDirection::Down,
216+
false => CountingDirection::Up,
217+
};
218+
#[cfg(any(feature = "hrtim_v1", feature = "hrtim_v1_1"))]
219+
let dir = CountingDirection::Up;
249220

250-
// No need for exclusive access since this is a write only register
251-
tim.icr().write(|w| w.$cptXc().clear());
252-
}
221+
let value = data.cpt().bits();
253222

254-
fn is_pending(&self) -> bool {
255-
let tim = unsafe { &*$TIMX::ptr() };
223+
(value, dir)
224+
}
256225

257-
// No need for exclusive access since this is a read only register
258-
tim.isr().read().$cptX().bit()
259-
}
260-
}
226+
fn clear_interrupt(&mut self) {
227+
let tim = unsafe { &*TIM::ptr() };
261228

262-
#[cfg(feature = "stm32g4")]
263-
unsafe impl<PSCL> crate::hal::dma::traits::TargetAddress<PeripheralToMemory> for HrCapt<$TIMX, PSCL, $CH, Dma> {
264-
#[inline(always)]
265-
fn address(&self) -> u32 {
266-
let tim = unsafe { &*$TIMX::ptr() };
267-
&tim.$cptXr() as *const _ as u32
268-
}
229+
// No need for exclusive access since this is a write only register
230+
tim.icr().write(|w| w.cptc(CH::CH as _).clear());
231+
}
269232

270-
type MemSize = u32;
233+
fn is_pending(&self) -> bool {
234+
let tim = unsafe { &*TIM::ptr() };
271235

272-
const REQUEST_LINE: Option<u8> = Some(DmaMuxResources::$TIMX as u8);
273-
}
274-
};
236+
// No need for exclusive access since this is a read only register
237+
tim.isr().read().cpt(CH::CH as _).bit()
238+
}
275239
}
276240

277-
impl_capture! {
278-
HRTIM_TIMA,
279-
HRTIM_TIMB,
280-
HRTIM_TIMC,
281-
HRTIM_TIMD,
282-
HRTIM_TIME
283-
}
241+
#[cfg(feature = "stm32g4")]
242+
unsafe impl<TIM: InstanceX, CH: ChExt, PSCL>
243+
crate::hal::dma::traits::TargetAddress<crate::hal::dma::PeripheralToMemory>
244+
for HrCapt<TIM, PSCL, CH, Dma>
245+
{
246+
#[inline(always)]
247+
fn address(&self) -> u32 {
248+
let tim = unsafe { &*TIM::ptr() };
249+
&tim.cptr(CH::CH) as *const _ as u32
250+
}
251+
252+
type MemSize = u32;
284253

285-
#[cfg(feature = "hrtim_v2")]
286-
impl_capture! {
287-
HRTIM_TIMF
254+
const REQUEST_LINE: Option<u8> = Some(TIM::DMA_MUX as u8);
288255
}

0 commit comments

Comments
 (0)