|
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}; |
10 | 3 | 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; |
17 | 4 |
|
18 | 5 | pub struct Dma;
|
19 | 6 | pub struct NoDma;
|
@@ -168,121 +155,101 @@ pub fn dma_value_to_signed(x: u32, #[allow(unused_variables)] period: u16) -> i3
|
168 | 155 | }
|
169 | 156 | }
|
170 | 157 |
|
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)); |
227 | 179 | }
|
| 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 | + } |
228 | 190 |
|
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() }; |
233 | 196 |
|
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 | + } |
241 | 199 |
|
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 | +} |
243 | 207 |
|
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(); |
246 | 212 |
|
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; |
249 | 220 |
|
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(); |
253 | 222 |
|
254 |
| - fn is_pending(&self) -> bool { |
255 |
| - let tim = unsafe { &*$TIMX::ptr() }; |
| 223 | + (value, dir) |
| 224 | + } |
256 | 225 |
|
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() }; |
261 | 228 |
|
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 | + } |
269 | 232 |
|
270 |
| - type MemSize = u32; |
| 233 | + fn is_pending(&self) -> bool { |
| 234 | + let tim = unsafe { &*TIM::ptr() }; |
271 | 235 |
|
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 | + } |
275 | 239 | }
|
276 | 240 |
|
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; |
284 | 253 |
|
285 |
| -#[cfg(feature = "hrtim_v2")] |
286 |
| -impl_capture! { |
287 |
| - HRTIM_TIMF |
| 254 | + const REQUEST_LINE: Option<u8> = Some(TIM::DMA_MUX as u8); |
288 | 255 | }
|
0 commit comments