diff options
Diffstat (limited to 'examples/stm32h7/src/bin/low_level_timer_api.rs')
| -rw-r--r-- | examples/stm32h7/src/bin/low_level_timer_api.rs | 80 |
1 files changed, 47 insertions, 33 deletions
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index e0be495d1..a95b44b74 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | 3 | ||
| 5 | use defmt::*; | 4 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::gpio::low_level::AFType; | 6 | use embassy_stm32::gpio::{AFType, Flex, Pull, Speed}; |
| 8 | use embassy_stm32::gpio::Speed; | ||
| 9 | use embassy_stm32::time::{khz, Hertz}; | 7 | use embassy_stm32::time::{khz, Hertz}; |
| 10 | use embassy_stm32::timer::*; | 8 | use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; |
| 11 | use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; | 9 | use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; |
| 10 | use embassy_stm32::{into_ref, Config, Peripheral}; | ||
| 12 | use embassy_time::Timer; | 11 | use embassy_time::Timer; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 13 | ||
| @@ -57,11 +56,15 @@ async fn main(_spawner: Spawner) { | |||
| 57 | Timer::after_millis(300).await; | 56 | Timer::after_millis(300).await; |
| 58 | } | 57 | } |
| 59 | } | 58 | } |
| 60 | pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { | 59 | pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> { |
| 61 | inner: PeripheralRef<'d, T>, | 60 | tim: LLTimer<'d, T>, |
| 61 | _ch1: Flex<'d>, | ||
| 62 | _ch2: Flex<'d>, | ||
| 63 | _ch3: Flex<'d>, | ||
| 64 | _ch4: Flex<'d>, | ||
| 62 | } | 65 | } |
| 63 | 66 | ||
| 64 | impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | 67 | impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { |
| 65 | pub fn new( | 68 | pub fn new( |
| 66 | tim: impl Peripheral<P = T> + 'd, | 69 | tim: impl Peripheral<P = T> + 'd, |
| 67 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | 70 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, |
| @@ -70,25 +73,33 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 70 | ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, | 73 | ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, |
| 71 | freq: Hertz, | 74 | freq: Hertz, |
| 72 | ) -> Self { | 75 | ) -> Self { |
| 73 | into_ref!(tim, ch1, ch2, ch3, ch4); | 76 | into_ref!(ch1, ch2, ch3, ch4); |
| 74 | 77 | ||
| 75 | T::enable_and_reset(); | 78 | let af1 = ch1.af_num(); |
| 76 | 79 | let af2 = ch2.af_num(); | |
| 77 | ch1.set_speed(Speed::VeryHigh); | 80 | let af3 = ch3.af_num(); |
| 78 | ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 81 | let af4 = ch4.af_num(); |
| 79 | ch2.set_speed(Speed::VeryHigh); | 82 | let mut ch1 = Flex::new(ch1); |
| 80 | ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 83 | let mut ch2 = Flex::new(ch2); |
| 81 | ch3.set_speed(Speed::VeryHigh); | 84 | let mut ch3 = Flex::new(ch3); |
| 82 | ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 85 | let mut ch4 = Flex::new(ch4); |
| 83 | ch4.set_speed(Speed::VeryHigh); | 86 | ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 84 | ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 87 | ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 85 | 88 | ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); | |
| 86 | let mut this = Self { inner: tim }; | 89 | ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh); |
| 87 | 90 | ||
| 88 | this.set_freq(freq); | 91 | let mut this = Self { |
| 89 | this.inner.start(); | 92 | tim: LLTimer::new(tim), |
| 90 | 93 | _ch1: ch1, | |
| 91 | let r = T::regs_gp32(); | 94 | _ch2: ch2, |
| 95 | _ch3: ch3, | ||
| 96 | _ch4: ch4, | ||
| 97 | }; | ||
| 98 | |||
| 99 | this.set_frequency(freq); | ||
| 100 | this.tim.start(); | ||
| 101 | |||
| 102 | let r = this.tim.regs_gp32(); | ||
| 92 | r.ccmr_output(0) | 103 | r.ccmr_output(0) |
| 93 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | 104 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); |
| 94 | r.ccmr_output(0) | 105 | r.ccmr_output(0) |
| @@ -102,23 +113,26 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 102 | } | 113 | } |
| 103 | 114 | ||
| 104 | pub fn enable(&mut self, channel: Channel) { | 115 | pub fn enable(&mut self, channel: Channel) { |
| 105 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), true)); | 116 | self.tim.regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true)); |
| 106 | } | 117 | } |
| 107 | 118 | ||
| 108 | pub fn disable(&mut self, channel: Channel) { | 119 | pub fn disable(&mut self, channel: Channel) { |
| 109 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), false)); | 120 | self.tim |
| 121 | .regs_gp32() | ||
| 122 | .ccer() | ||
| 123 | .modify(|w| w.set_cce(channel.index(), false)); | ||
| 110 | } | 124 | } |
| 111 | 125 | ||
| 112 | pub fn set_freq(&mut self, freq: Hertz) { | 126 | pub fn set_frequency(&mut self, freq: Hertz) { |
| 113 | <T as embassy_stm32::timer::low_level::GeneralPurpose32bitInstance>::set_frequency(&mut self.inner, freq); | 127 | self.tim.set_frequency(freq); |
| 114 | } | 128 | } |
| 115 | 129 | ||
| 116 | pub fn get_max_duty(&self) -> u32 { | 130 | pub fn get_max_duty(&self) -> u32 { |
| 117 | T::regs_gp32().arr().read().arr() | 131 | self.tim.regs_gp32().arr().read() |
| 118 | } | 132 | } |
| 119 | 133 | ||
| 120 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | 134 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { |
| 121 | defmt::assert!(duty < self.get_max_duty()); | 135 | defmt::assert!(duty < self.get_max_duty()); |
| 122 | T::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(duty)) | 136 | self.tim.regs_gp32().ccr(channel.index()).write_value(duty) |
| 123 | } | 137 | } |
| 124 | } | 138 | } |
