aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Berlin <[email protected]>2023-09-27 20:15:24 -0400
committerDaniel Berlin <[email protected]>2023-09-27 20:15:57 -0400
commitf866735802e142530491086adcb3f173c38ec570 (patch)
tree09f157814246fe928a22f6e7890e80628ec3d5bb
parent20ea76c19c709abf652b9a044292eb26fd656223 (diff)
Add support for input capture function
-rw-r--r--embassy-stm32/src/timer/mod.rs231
1 files changed, 231 insertions, 0 deletions
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 839548a53..ea72b36ae 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -15,6 +15,7 @@ pub mod low_level {
15} 15}
16 16
17pub(crate) mod sealed { 17pub(crate) mod sealed {
18
18 use super::*; 19 use super::*;
19 pub trait Basic16bitInstance: RccPeripheral { 20 pub trait Basic16bitInstance: RccPeripheral {
20 type Interrupt: interrupt::typelevel::Interrupt; 21 type Interrupt: interrupt::typelevel::Interrupt;
@@ -32,10 +33,16 @@ pub(crate) mod sealed {
32 fn clear_update_interrupt(&mut self) -> bool; 33 fn clear_update_interrupt(&mut self) -> bool;
33 34
34 fn enable_update_interrupt(&mut self, enable: bool); 35 fn enable_update_interrupt(&mut self, enable: bool);
36
37 fn set_autoreload_preload(&mut self, enable: vals::Arpe);
35 } 38 }
36 39
37 pub trait GeneralPurpose16bitInstance: Basic16bitInstance { 40 pub trait GeneralPurpose16bitInstance: Basic16bitInstance {
38 fn regs_gp16() -> crate::pac::timer::TimGp16; 41 fn regs_gp16() -> crate::pac::timer::TimGp16;
42
43 fn set_count_direction(&mut self, direction: vals::Dir);
44
45 fn set_clock_division(&mut self, ckd: vals::Ckd);
39 } 46 }
40 47
41 pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance { 48 pub trait GeneralPurpose32bitInstance: GeneralPurpose16bitInstance {
@@ -49,6 +56,16 @@ pub(crate) mod sealed {
49 } 56 }
50 57
51 pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance { 58 pub trait CaptureCompare16bitInstance: GeneralPurpose16bitInstance {
59 fn clear_input_interrupt(&mut self, channel: Channel);
60
61 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool);
62
63 fn set_input_capture_prescaler(&mut self, channel: Channel, val: u8);
64
65 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection);
66
67 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode);
68
52 /// Global output enable. Does not do anything on non-advanced timers. 69 /// Global output enable. Does not do anything on non-advanced timers.
53 fn enable_outputs(&mut self, enable: bool); 70 fn enable_outputs(&mut self, enable: bool);
54 71
@@ -60,6 +77,8 @@ pub(crate) mod sealed {
60 77
61 fn set_compare_value(&mut self, channel: Channel, value: u16); 78 fn set_compare_value(&mut self, channel: Channel, value: u16);
62 79
80 fn get_capture_value(&mut self, channel: Channel) -> u16;
81
63 fn get_max_compare_value(&self) -> u16; 82 fn get_max_compare_value(&self) -> u16;
64 } 83 }
65 84
@@ -74,6 +93,16 @@ pub(crate) mod sealed {
74 } 93 }
75 94
76 pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance { 95 pub trait CaptureCompare32bitInstance: GeneralPurpose32bitInstance {
96 fn clear_input_interrupt(&mut self, channel: Channel);
97
98 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool);
99
100 fn set_input_capture_prescaler(&mut self, channel: Channel, val: u8);
101
102 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection);
103
104 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode);
105
77 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode); 106 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
78 107
79 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity); 108 fn set_output_polarity(&mut self, channel: Channel, polarity: OutputPolarity);
@@ -82,6 +111,8 @@ pub(crate) mod sealed {
82 111
83 fn set_compare_value(&mut self, channel: Channel, value: u32); 112 fn set_compare_value(&mut self, channel: Channel, value: u32);
84 113
114 fn get_capture_value(&mut self, channel: Channel) -> u32;
115
85 fn get_max_compare_value(&self) -> u32; 116 fn get_max_compare_value(&self) -> u32;
86 } 117 }
87} 118}
@@ -106,6 +137,30 @@ impl Channel {
106} 137}
107 138
108#[derive(Clone, Copy)] 139#[derive(Clone, Copy)]
140pub enum InputCaptureMode {
141 Rising,
142 Falling,
143 BothEdges,
144}
145
146#[derive(Clone, Copy)]
147pub enum InputTISelection {
148 Normal,
149 Alternate,
150 TRC,
151}
152
153impl From<InputTISelection> for stm32_metapac::timer::vals::CcmrInputCcs {
154 fn from(tisel: InputTISelection) -> Self {
155 match tisel {
156 InputTISelection::Normal => stm32_metapac::timer::vals::CcmrInputCcs::TI4,
157 InputTISelection::Alternate => stm32_metapac::timer::vals::CcmrInputCcs::TI3,
158 InputTISelection::TRC => stm32_metapac::timer::vals::CcmrInputCcs::TRC,
159 }
160 }
161}
162
163#[derive(Clone, Copy)]
109pub enum OutputCompareMode { 164pub enum OutputCompareMode {
110 Frozen, 165 Frozen,
111 ActiveOnMatch, 166 ActiveOnMatch,
@@ -242,6 +297,10 @@ macro_rules! impl_basic_16bit_timer {
242 fn enable_update_interrupt(&mut self, enable: bool) { 297 fn enable_update_interrupt(&mut self, enable: bool) {
243 Self::regs().dier().write(|r| r.set_uie(enable)); 298 Self::regs().dier().write(|r| r.set_uie(enable));
244 } 299 }
300
301 fn set_autoreload_preload(&mut self, enable: vals::Arpe) {
302 Self::regs().cr1().modify(|r| r.set_arpe(enable));
303 }
245 } 304 }
246 }; 305 };
247} 306}
@@ -279,6 +338,51 @@ macro_rules! impl_32bit_timer {
279macro_rules! impl_compare_capable_16bit { 338macro_rules! impl_compare_capable_16bit {
280 ($inst:ident) => { 339 ($inst:ident) => {
281 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { 340 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
341 fn clear_input_interrupt(&mut self, channel: Channel) {
342 use sealed::GeneralPurpose16bitInstance;
343 Self::regs_gp16()
344 .sr()
345 .modify(|r| r.set_ccif(channel.raw(), false));
346 }
347
348 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
349 use sealed::GeneralPurpose16bitInstance;
350 Self::regs_gp16()
351 .dier()
352 .modify(|r| r.set_ccie(channel.raw(), enable));
353 }
354 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
355 use sealed::GeneralPurpose16bitInstance;
356 let raw_channel = channel.raw();
357 Self::regs_gp16()
358 .ccmr_input(raw_channel / 2)
359 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
360 }
361
362 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
363 use sealed::GeneralPurpose16bitInstance;
364 let raw_channel = channel.raw();
365 Self::regs_gp16()
366 .ccmr_input(raw_channel / 2)
367 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
368 }
369 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
370 use sealed::GeneralPurpose16bitInstance;
371 Self::regs_gp16().ccer().modify(|r| match mode {
372 InputCaptureMode::Rising => {
373 r.set_ccnp(channel.raw(), false);
374 r.set_ccp(channel.raw(), false);
375 }
376 InputCaptureMode::Falling => {
377 r.set_ccnp(channel.raw(), false);
378 r.set_ccp(channel.raw(), true);
379 }
380 InputCaptureMode::BothEdges => {
381 r.set_ccnp(channel.raw(), true);
382 r.set_ccp(channel.raw(), true);
383 }
384 });
385 }
282 fn enable_outputs(&mut self, _enable: bool) {} 386 fn enable_outputs(&mut self, _enable: bool) {}
283 387
284 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) { 388 fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode) {
@@ -308,6 +412,11 @@ macro_rules! impl_compare_capable_16bit {
308 Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value)); 412 Self::regs_gp16().ccr(channel.raw()).modify(|w| w.set_ccr(value));
309 } 413 }
310 414
415 fn get_capture_value(&mut self, channel: Channel) -> u16 {
416 use sealed::GeneralPurpose16bitInstance;
417 Self::regs_gp16().ccr(channel.raw()).read().ccr()
418 }
419
311 fn get_max_compare_value(&self) -> u16 { 420 fn get_max_compare_value(&self) -> u16 {
312 use sealed::GeneralPurpose16bitInstance; 421 use sealed::GeneralPurpose16bitInstance;
313 Self::regs_gp16().arr().read().arr() 422 Self::regs_gp16().arr().read().arr()
@@ -332,6 +441,14 @@ foreach_interrupt! {
332 fn regs_gp16() -> crate::pac::timer::TimGp16 { 441 fn regs_gp16() -> crate::pac::timer::TimGp16 {
333 crate::pac::$inst 442 crate::pac::$inst
334 } 443 }
444
445 fn set_count_direction(&mut self, direction: vals::Dir) {
446 Self::regs_gp16().cr1().modify(|r| r.set_dir(direction));
447 }
448
449 fn set_clock_division(&mut self, ckd: vals::Ckd) {
450 Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd));
451 }
335 } 452 }
336 }; 453 };
337 454
@@ -346,6 +463,51 @@ foreach_interrupt! {
346 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {} 463 impl GeneralPurpose32bitInstance for crate::peripherals::$inst {}
347 464
348 impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst { 465 impl sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
466 fn clear_input_interrupt(&mut self, channel: Channel) {
467 use sealed::GeneralPurpose32bitInstance;
468 Self::regs_gp32()
469 .sr()
470 .modify(|r| r.set_ccif(channel.raw(), false));
471 }
472 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
473 use sealed::GeneralPurpose32bitInstance;
474 Self::regs_gp32()
475 .dier()
476 .modify(|r| r.set_ccie(channel.raw(), enable));
477 }
478 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
479 use crate::timer::sealed::GeneralPurpose32bitInstance;
480 let raw_channel = channel.raw();
481 Self::regs_gp32()
482 .ccmr_input(raw_channel / 2)
483 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
484 }
485
486 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
487 use crate::timer::sealed::GeneralPurpose32bitInstance;
488 let raw_channel = channel.raw();
489 Self::regs_gp32()
490 .ccmr_input(raw_channel / 2)
491 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
492 }
493
494 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
495 use crate::timer::sealed::GeneralPurpose32bitInstance;
496 Self::regs_gp32().ccer().modify(|r| match mode {
497 InputCaptureMode::Rising => {
498 r.set_ccnp(channel.raw(), false);
499 r.set_ccp(channel.raw(), false);
500 }
501 InputCaptureMode::Falling => {
502 r.set_ccnp(channel.raw(), false);
503 r.set_ccp(channel.raw(), true);
504 }
505 InputCaptureMode::BothEdges => {
506 r.set_ccnp(channel.raw(), true);
507 r.set_ccp(channel.raw(), true);
508 }
509 });
510 }
349 fn set_output_compare_mode( 511 fn set_output_compare_mode(
350 &mut self, 512 &mut self,
351 channel: Channel, 513 channel: Channel,
@@ -373,6 +535,11 @@ foreach_interrupt! {
373 Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value)); 535 Self::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(value));
374 } 536 }
375 537
538 fn get_capture_value(&mut self, channel: Channel) -> u32 {
539 use crate::timer::sealed::GeneralPurpose32bitInstance;
540 Self::regs_gp32().ccr(channel.raw()).read().ccr()
541 }
542
376 fn get_max_compare_value(&self) -> u32 { 543 fn get_max_compare_value(&self) -> u32 {
377 use crate::timer::sealed::GeneralPurpose32bitInstance; 544 use crate::timer::sealed::GeneralPurpose32bitInstance;
378 Self::regs_gp32().arr().read().arr() as u32 545 Self::regs_gp32().arr().read().arr() as u32
@@ -383,6 +550,14 @@ foreach_interrupt! {
383 fn regs_gp16() -> crate::pac::timer::TimGp16 { 550 fn regs_gp16() -> crate::pac::timer::TimGp16 {
384 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } 551 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) }
385 } 552 }
553
554 fn set_count_direction(&mut self, direction: vals::Dir) {
555 Self::regs_gp16().cr1().modify(|r| r.set_dir(direction));
556 }
557
558 fn set_clock_division(&mut self, ckd: vals::Ckd) {
559 Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd));
560 }
386 } 561 }
387 }; 562 };
388 563
@@ -399,6 +574,14 @@ foreach_interrupt! {
399 fn regs_gp16() -> crate::pac::timer::TimGp16 { 574 fn regs_gp16() -> crate::pac::timer::TimGp16 {
400 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) } 575 unsafe { crate::pac::timer::TimGp16::from_ptr(crate::pac::$inst.as_ptr()) }
401 } 576 }
577
578 fn set_count_direction(&mut self, direction: vals::Dir) {
579 Self::regs_gp16().cr1().modify(|r| r.set_dir(direction));
580 }
581
582 fn set_clock_division(&mut self, ckd: vals::Ckd) {
583 Self::regs_gp16().cr1().modify(|r| r.set_ckd(ckd));
584 }
402 } 585 }
403 586
404 impl sealed::AdvancedControlInstance for crate::peripherals::$inst { 587 impl sealed::AdvancedControlInstance for crate::peripherals::$inst {
@@ -408,6 +591,49 @@ foreach_interrupt! {
408 } 591 }
409 592
410 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst { 593 impl sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
594 fn clear_input_interrupt(&mut self, channel: Channel) {
595 use crate::timer::sealed::AdvancedControlInstance;
596 Self::regs_advanced()
597 .sr()
598 .modify(|r| r.set_ccif(channel.raw(), false));
599 }
600 fn enable_input_interrupt(&mut self, channel: Channel, enable: bool) {
601 use crate::timer::sealed::AdvancedControlInstance;
602 Self::regs_advanced()
603 .dier()
604 .modify(|r| r.set_ccie(channel.raw(), enable));
605 }
606 fn set_input_capture_prescaler(&mut self, channel: Channel, factor: u8) {
607 use crate::timer::sealed::AdvancedControlInstance;
608 let raw_channel = channel.raw();
609 Self::regs_advanced()
610 .ccmr_input(raw_channel / 2)
611 .modify(|r| r.set_icpsc(raw_channel % 2, factor));
612 }
613 fn set_input_ti_selection(&mut self, channel: Channel, tisel: InputTISelection) {
614 use crate::timer::sealed::AdvancedControlInstance;
615 let raw_channel = channel.raw();
616 Self::regs_advanced()
617 .ccmr_input(raw_channel / 2)
618 .modify(|r| r.set_ccs(raw_channel % 2, tisel.into()));
619 }
620 fn set_input_capture_mode(&mut self, channel: Channel, mode: InputCaptureMode) {
621 use crate::timer::sealed::AdvancedControlInstance;
622 Self::regs_advanced().ccer().modify(|r| match mode {
623 InputCaptureMode::Rising => {
624 r.set_ccnp(channel.raw(), false);
625 r.set_ccp(channel.raw(), false);
626 }
627 InputCaptureMode::Falling => {
628 r.set_ccnp(channel.raw(), false);
629 r.set_ccp(channel.raw(), true);
630 }
631 InputCaptureMode::BothEdges => {
632 r.set_ccnp(channel.raw(), true);
633 r.set_ccp(channel.raw(), true);
634 }
635 });
636 }
411 fn enable_outputs(&mut self, enable: bool) { 637 fn enable_outputs(&mut self, enable: bool) {
412 use crate::timer::sealed::AdvancedControlInstance; 638 use crate::timer::sealed::AdvancedControlInstance;
413 let r = Self::regs_advanced(); 639 let r = Self::regs_advanced();
@@ -440,6 +666,11 @@ foreach_interrupt! {
440 .modify(|w| w.set_cce(channel.raw(), enable)); 666 .modify(|w| w.set_cce(channel.raw(), enable));
441 } 667 }
442 668
669 fn get_capture_value(&mut self, channel: Channel) -> u16 {
670 use crate::timer::sealed::AdvancedControlInstance;
671 Self::regs_advanced().ccr(channel.raw()).read().ccr()
672 }
673
443 fn set_compare_value(&mut self, channel: Channel, value: u16) { 674 fn set_compare_value(&mut self, channel: Channel, value: u16) {
444 use crate::timer::sealed::AdvancedControlInstance; 675 use crate::timer::sealed::AdvancedControlInstance;
445 Self::regs_advanced() 676 Self::regs_advanced()