diff options
| -rw-r--r-- | examples/stm32g4/src/bin/pwm.rs | 4 | ||||
| -rw-r--r-- | examples/stm32h7/Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/low_level_timer_api.rs | 147 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/pwm.rs | 48 |
4 files changed, 199 insertions, 3 deletions
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 1aa7b85f3..3dd45318d 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs | |||
| @@ -7,7 +7,7 @@ mod example_common; | |||
| 7 | use embassy::executor::Spawner; | 7 | use embassy::executor::Spawner; |
| 8 | use embassy::time::{Duration, Timer}; | 8 | use embassy::time::{Duration, Timer}; |
| 9 | use embassy_stm32::gpio::NoPin; | 9 | use embassy_stm32::gpio::NoPin; |
| 10 | use embassy_stm32::pwm::{Channel, Pwm}; | 10 | use embassy_stm32::pwm::{simple_pwm::SimplePwm, Channel}; |
| 11 | use embassy_stm32::time::U32Ext; | 11 | use embassy_stm32::time::U32Ext; |
| 12 | use embassy_stm32::Peripherals; | 12 | use embassy_stm32::Peripherals; |
| 13 | use example_common::*; | 13 | use example_common::*; |
| @@ -16,7 +16,7 @@ use example_common::*; | |||
| 16 | async fn main(_spawner: Spawner, p: Peripherals) { | 16 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 17 | info!("Hello World!"); | 17 | info!("Hello World!"); |
| 18 | 18 | ||
| 19 | let mut pwm = Pwm::new(p.TIM2, p.PA5, NoPin, NoPin, NoPin, 10000.hz()); | 19 | let mut pwm = SimplePwm::new(p.TIM2, p.PA5, NoPin, NoPin, NoPin, 10000.hz()); |
| 20 | let max = pwm.get_max_duty(); | 20 | let max = pwm.get_max_duty(); |
| 21 | pwm.enable(Channel::Ch1); | 21 | pwm.enable(Channel::Ch1); |
| 22 | 22 | ||
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index a34ac6ad9..de294318f 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -10,8 +10,9 @@ resolver = "2" | |||
| 10 | [dependencies] | 10 | [dependencies] |
| 11 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } | 11 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } |
| 12 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } | 12 | embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } |
| 13 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-tim2", "exti"] } | 13 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-tim2", "exti", "unstable-pac"] } |
| 14 | embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } | 14 | embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } |
| 15 | embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] } | ||
| 15 | 16 | ||
| 16 | defmt = "0.3" | 17 | defmt = "0.3" |
| 17 | defmt-rtt = "0.3" | 18 | defmt-rtt = "0.3" |
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs new file mode 100644 index 000000000..2640f249d --- /dev/null +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use core::marker::PhantomData; | ||
| 8 | |||
| 9 | use embassy::executor::Spawner; | ||
| 10 | use embassy::time::{Duration, Timer}; | ||
| 11 | use embassy::util::Unborrow; | ||
| 12 | use embassy_hal_common::unborrow; | ||
| 13 | use embassy_stm32::gpio::NoPin; | ||
| 14 | use embassy_stm32::pwm::{pins::*, Channel, OutputCompareMode}; | ||
| 15 | use embassy_stm32::time::{Hertz, U32Ext}; | ||
| 16 | use embassy_stm32::timer::GeneralPurpose32bitInstance; | ||
| 17 | use embassy_stm32::{Config, Peripherals}; | ||
| 18 | use example_common::*; | ||
| 19 | |||
| 20 | pub fn config() -> Config { | ||
| 21 | let mut config = Config::default(); | ||
| 22 | config.rcc.sys_ck = Some(400.mhz().into()); | ||
| 23 | config.rcc.hclk = Some(400.mhz().into()); | ||
| 24 | config.rcc.pll1.q_ck = Some(100.mhz().into()); | ||
| 25 | config.rcc.pclk1 = Some(100.mhz().into()); | ||
| 26 | config.rcc.pclk2 = Some(100.mhz().into()); | ||
| 27 | config.rcc.pclk3 = Some(100.mhz().into()); | ||
| 28 | config.rcc.pclk4 = Some(100.mhz().into()); | ||
| 29 | config | ||
| 30 | } | ||
| 31 | |||
| 32 | #[embassy::main(config = "config()")] | ||
| 33 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 34 | info!("Hello World!"); | ||
| 35 | |||
| 36 | let mut pwm = SimplePwm32::new(p.TIM5, p.PA0, NoPin, NoPin, NoPin, 10000.hz()); | ||
| 37 | let max = pwm.get_max_duty(); | ||
| 38 | pwm.enable(Channel::Ch1); | ||
| 39 | |||
| 40 | info!("PWM initialized"); | ||
| 41 | info!("PWM max duty {}", max); | ||
| 42 | |||
| 43 | loop { | ||
| 44 | pwm.set_duty(Channel::Ch1, 0); | ||
| 45 | Timer::after(Duration::from_millis(300)).await; | ||
| 46 | pwm.set_duty(Channel::Ch1, max / 4); | ||
| 47 | Timer::after(Duration::from_millis(300)).await; | ||
| 48 | pwm.set_duty(Channel::Ch1, max / 2); | ||
| 49 | Timer::after(Duration::from_millis(300)).await; | ||
| 50 | pwm.set_duty(Channel::Ch1, max - 1); | ||
| 51 | Timer::after(Duration::from_millis(300)).await; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | pub struct SimplePwm32<'d, T: GeneralPurpose32bitInstance> { | ||
| 55 | phantom: PhantomData<&'d mut T>, | ||
| 56 | inner: T, | ||
| 57 | } | ||
| 58 | |||
| 59 | impl<'d, T: GeneralPurpose32bitInstance> SimplePwm32<'d, T> { | ||
| 60 | pub fn new<F: Into<Hertz>>( | ||
| 61 | tim: impl Unborrow<Target = T> + 'd, | ||
| 62 | ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, | ||
| 63 | ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, | ||
| 64 | ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, | ||
| 65 | ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd, | ||
| 66 | freq: F, | ||
| 67 | ) -> Self { | ||
| 68 | unborrow!(tim, ch1, ch2, ch3, ch4); | ||
| 69 | |||
| 70 | T::enable(); | ||
| 71 | <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset(); | ||
| 72 | |||
| 73 | unsafe { | ||
| 74 | ch1.configure(); | ||
| 75 | ch2.configure(); | ||
| 76 | ch3.configure(); | ||
| 77 | ch4.configure(); | ||
| 78 | } | ||
| 79 | |||
| 80 | let mut this = Self { | ||
| 81 | inner: tim, | ||
| 82 | phantom: PhantomData, | ||
| 83 | }; | ||
| 84 | |||
| 85 | this.set_freq(freq); | ||
| 86 | this.inner.start(); | ||
| 87 | |||
| 88 | unsafe { | ||
| 89 | this.inner | ||
| 90 | .regs_gp32() | ||
| 91 | .ccmr_output(0) | ||
| 92 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | ||
| 93 | this.inner | ||
| 94 | .regs_gp32() | ||
| 95 | .ccmr_output(0) | ||
| 96 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); | ||
| 97 | this.inner | ||
| 98 | .regs_gp32() | ||
| 99 | .ccmr_output(1) | ||
| 100 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | ||
| 101 | this.inner | ||
| 102 | .regs_gp32() | ||
| 103 | .ccmr_output(1) | ||
| 104 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); | ||
| 105 | } | ||
| 106 | this | ||
| 107 | } | ||
| 108 | |||
| 109 | pub fn enable(&mut self, channel: Channel) { | ||
| 110 | unsafe { | ||
| 111 | self.inner | ||
| 112 | .regs_gp32() | ||
| 113 | .ccer() | ||
| 114 | .modify(|w| w.set_cce(channel.raw(), true)); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | pub fn disable(&mut self, channel: Channel) { | ||
| 119 | unsafe { | ||
| 120 | self.inner | ||
| 121 | .regs_gp32() | ||
| 122 | .ccer() | ||
| 123 | .modify(|w| w.set_cce(channel.raw(), false)); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | pub fn set_freq<F: Into<Hertz>>(&mut self, freq: F) { | ||
| 128 | <T as embassy_stm32::timer::low_level::GeneralPurpose32bitInstance>::set_frequency( | ||
| 129 | &mut self.inner, | ||
| 130 | freq, | ||
| 131 | ); | ||
| 132 | } | ||
| 133 | |||
| 134 | pub fn get_max_duty(&self) -> u32 { | ||
| 135 | unsafe { self.inner.regs_gp32().arr().read().arr() } | ||
| 136 | } | ||
| 137 | |||
| 138 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | ||
| 139 | defmt::assert!(duty < self.get_max_duty()); | ||
| 140 | unsafe { | ||
| 141 | self.inner | ||
| 142 | .regs_gp32() | ||
| 143 | .ccr(channel.raw()) | ||
| 144 | .modify(|w| w.set_ccr(duty)) | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs new file mode 100644 index 000000000..020150a39 --- /dev/null +++ b/examples/stm32h7/src/bin/pwm.rs | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | #[path = "../example_common.rs"] | ||
| 6 | mod example_common; | ||
| 7 | use embassy::executor::Spawner; | ||
| 8 | use embassy::time::{Duration, Timer}; | ||
| 9 | use embassy_stm32::gpio::NoPin; | ||
| 10 | use embassy_stm32::pwm::{simple_pwm::SimplePwm, Channel}; | ||
| 11 | use embassy_stm32::time::U32Ext; | ||
| 12 | use embassy_stm32::{Config, Peripherals}; | ||
| 13 | use example_common::*; | ||
| 14 | |||
| 15 | pub fn config() -> Config { | ||
| 16 | let mut config = Config::default(); | ||
| 17 | config.rcc.sys_ck = Some(400.mhz().into()); | ||
| 18 | config.rcc.hclk = Some(400.mhz().into()); | ||
| 19 | config.rcc.pll1.q_ck = Some(100.mhz().into()); | ||
| 20 | config.rcc.pclk1 = Some(100.mhz().into()); | ||
| 21 | config.rcc.pclk2 = Some(100.mhz().into()); | ||
| 22 | config.rcc.pclk3 = Some(100.mhz().into()); | ||
| 23 | config.rcc.pclk4 = Some(100.mhz().into()); | ||
| 24 | config | ||
| 25 | } | ||
| 26 | |||
| 27 | #[embassy::main(config = "config()")] | ||
| 28 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 29 | info!("Hello World!"); | ||
| 30 | |||
| 31 | let mut pwm = SimplePwm::new(p.TIM3, p.PA6, NoPin, NoPin, NoPin, 10000.hz()); | ||
| 32 | let max = pwm.get_max_duty(); | ||
| 33 | pwm.enable(Channel::Ch1); | ||
| 34 | |||
| 35 | info!("PWM initialized"); | ||
| 36 | info!("PWM max duty {}", max); | ||
| 37 | |||
| 38 | loop { | ||
| 39 | pwm.set_duty(Channel::Ch1, 0); | ||
| 40 | Timer::after(Duration::from_millis(300)).await; | ||
| 41 | pwm.set_duty(Channel::Ch1, max / 4); | ||
| 42 | Timer::after(Duration::from_millis(300)).await; | ||
| 43 | pwm.set_duty(Channel::Ch1, max / 2); | ||
| 44 | Timer::after(Duration::from_millis(300)).await; | ||
| 45 | pwm.set_duty(Channel::Ch1, max - 1); | ||
| 46 | Timer::after(Duration::from_millis(300)).await; | ||
| 47 | } | ||
| 48 | } | ||
