Skip to content

Commit

Permalink
WithPwm
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Feb 1, 2022
1 parent 69357c0 commit dddfcb4
Show file tree
Hide file tree
Showing 15 changed files with 678 additions and 670 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed

- Timer impls with time based on `fugit` moved to `fugit` module, added `Pwm` and `fugit-timer` impls [#423]
- Add channel events, make Event use bitflags (simplify interrupt handling) [#425]

### Fixed

- Incorrect values of autoreload in `CountDown::start`, `Pwm::new`, `Delay` and prescaler in `Delay` [#422]

### Added

- `WithPwm` trait implemented for timers with channels (internals) [#425]
- `Pwm` struct with `split` method and implementation of embedded-hal::Pwm (similar to f1xx-hal) [#425]
- VSCode setting file
- Add CAN1 PB8/PB9 and SPI3 MOSI PC1 pin mappings for F446 [#421]

[#421]: https://github.com/stm32-rs/stm32f4xx-hal/pull/421
[#422]: https://github.com/stm32-rs/stm32f4xx-hal/pull/422
[#423]: https://github.com/stm32-rs/stm32f4xx-hal/pull/423
[#425]: https://github.com/stm32-rs/stm32f4xx-hal/pull/425

### Changed

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ display-interface = { version = "0.4.1", optional = true }
fugit = "0.3.3"
fugit-timer = "0.1.3"
rtic-monotonic = { version = "1.0", optional = true }
bitflags = "1.3.2"

[dependencies.stm32_i2s_v12x]
version = "0.2.0"
Expand Down
4 changes: 2 additions & 2 deletions examples/analog-stopwatch-with-spi-ssd1306.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fn main() -> ! {
// Create a 1ms periodic interrupt from TIM2
let mut timer = Timer::new(dp.TIM2, &clocks).counter();
timer.start(1.secs()).unwrap();
timer.listen(Event::TimeOut);
timer.listen(Event::Update);

free(|cs| {
TIMER_TIM2.borrow(cs).replace(Some(timer));
Expand Down Expand Up @@ -263,7 +263,7 @@ fn EXTI0() {
fn TIM2() {
free(|cs| {
if let Some(ref mut tim2) = TIMER_TIM2.borrow(cs).borrow_mut().deref_mut() {
tim2.clear_interrupt(Event::TimeOut);
tim2.clear_interrupt(Event::Update);
}

let cell = ELAPSED_MS.borrow(cs);
Expand Down
2 changes: 1 addition & 1 deletion examples/blinky-timer-irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn main() -> ! {
timer.start(1.secs()).unwrap();

// Generate an interrupt when the timer expires
timer.listen(Event::TimeOut);
timer.listen(Event::Update);

// Move the timer into our global storage
cortex_m::interrupt::free(|cs| *G_TIM.borrow(cs).borrow_mut() = Some(timer));
Expand Down
6 changes: 3 additions & 3 deletions examples/delay-timer-blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ fn main() -> ! {
let mut delay = dp.TIM5.delay_us(&clocks);

loop {
// On for 1s, off for 1s.
// On for 1s, off for 3s.
led.set_high();
delay.delay_ms(1_000_u32);
delay.delay(1.secs()).unwrap();
led.set_low();
delay.delay_us(1_000_000_u32);
delay.delay(3.secs()).unwrap();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/pwm-input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main() -> ! {
let channels = (gpioa.pa8.into_alternate(), gpioa.pa9.into_alternate());
// configure tim1 as a PWM output of known frequency.
let pwm = Timer::new(dp.TIM1, &clocks).pwm(channels, 501u32.hz());
let (mut ch1, _ch2) = pwm;
let (mut ch1, _ch2) = pwm.split();
let max_duty = ch1.get_max_duty();
ch1.set_duty(max_duty / 2);
ch1.enable();
Expand Down
74 changes: 24 additions & 50 deletions examples/pwm-sinus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,7 @@ use panic_halt as _;
use core::f32::consts::FRAC_PI_2;
use cortex_m_rt::entry;
use micromath::F32Ext;
use stm32f4xx_hal::{pac, prelude::*};

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Quadrant {
Q1,
Q2,
Q3,
Q4,
}
impl Quadrant {
pub fn next_cw(&mut self) {
*self = match self {
Self::Q1 => Self::Q2,
Self::Q2 => Self::Q3,
Self::Q3 => Self::Q4,
Self::Q4 => Self::Q1,
};
}
}
use stm32f4xx_hal::{fugit::Channel, pac, prelude::*};

#[entry]
fn main() -> ! {
Expand All @@ -37,12 +19,10 @@ fn main() -> ! {

let gpioa = dp.GPIOA.split();
let channels = (gpioa.pa8.into_alternate(), gpioa.pa9.into_alternate());
let mut quad = Quadrant::Q1;

let pwm = dp.TIM1.pwm_us(&clocks, channels, 100.micros());
let mut pwm = dp.TIM1.pwm_us(&clocks, channels, 100.micros());
let mut counter = dp.TIM2.counter_us(&clocks);
let (mut ch1, mut ch2) = pwm;
let max_duty = ch1.get_max_duty();
let max_duty = pwm.get_max_duty();

const N: usize = 50;
let mut sin_a = [0_u16; N + 1];
Expand All @@ -54,36 +34,30 @@ fn main() -> ! {
}

counter.start(100.micros()).unwrap();
ch1.enable();
ch2.enable();
let mut clos = |quad, duty| {
match quad {
Quadrant::Q1 | Quadrant::Q2 => {
ch1.set_duty(duty);
ch2.set_duty(0);
}
Quadrant::Q3 | Quadrant::Q4 => {
ch1.set_duty(0);
ch2.set_duty(duty);
}
pwm.enable(Channel::C1);
pwm.enable(Channel::C2);
let mut i = 0;
loop {
if i == 0 {
pwm.set_duty(Channel::C2, 0);
}
if i == 2 * N {
pwm.set_duty(Channel::C1, 0);
}
if i < N {
pwm.set_duty(Channel::C1, sin_a[i]);
} else if i < 2 * N {
pwm.set_duty(Channel::C1, sin_a[2 * N - i]);
} else if i < 3 * N {
pwm.set_duty(Channel::C2, sin_a[i - 2 * N]);
} else {
pwm.set_duty(Channel::C2, sin_a[4 * N - i]);
}
nb::block!(counter.wait()).unwrap();
};
loop {
match quad {
Quadrant::Q1 | Quadrant::Q3 => {
for &duty in sin_a.iter().take(N) {
clos(quad, duty);
}
}
Quadrant::Q2 | Quadrant::Q4 => {
for &duty in sin_a.iter().rev().take(N) {
clos(quad, duty);
}
}
i += 1;
if i == 4 * N {
i -= 4 * N;
}

quad.next_cw();
}
}

Expand Down
4 changes: 3 additions & 1 deletion examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ fn main() -> ! {
let gpioa = dp.GPIOA.split();
let channels = (gpioa.pa8.into_alternate(), gpioa.pa9.into_alternate());

let pwm = Timer::new(dp.TIM1, &clocks).pwm(channels, 20u32.khz());
let pwm = Timer::new(dp.TIM1, &clocks)
.pwm(channels, 20u32.khz())
.split();
let (mut ch1, _ch2) = pwm;
let max_duty = ch1.get_max_duty();
ch1.set_duty(max_duty / 2);
Expand Down
4 changes: 2 additions & 2 deletions examples/stopwatch-with-ssd1306-and-interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn main() -> ! {
// Create a 1ms periodic interrupt from TIM2
let mut timer = Timer::new(dp.TIM2, &clocks).counter();
timer.start(1.secs()).unwrap();
timer.listen(Event::TimeOut);
timer.listen(Event::Update);

free(|cs| {
TIMER_TIM2.borrow(cs).replace(Some(timer));
Expand Down Expand Up @@ -155,7 +155,7 @@ fn main() -> ! {
fn TIM2() {
free(|cs| {
if let Some(ref mut tim2) = TIMER_TIM2.borrow(cs).borrow_mut().deref_mut() {
tim2.clear_interrupt(Event::TimeOut);
tim2.clear_interrupt(Event::Update);
}

let cell = ELAPSED_MS.borrow(cs);
Expand Down
10 changes: 5 additions & 5 deletions src/fugit/counter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Error, Instance, Timer};
use super::{Error, Event, Instance, Timer};

use core::ops::{Deref, DerefMut};
use fugit::{TimerDurationU32, TimerInstantU32};
Expand Down Expand Up @@ -57,11 +57,11 @@ impl<TIM: Instance, const FREQ: u32> Counter<TIM, FREQ> {
}

pub fn wait(&mut self) -> nb::Result<(), Error> {
if self.tim.get_update_interrupt_flag() {
Err(nb::Error::WouldBlock)
} else {
self.tim.clear_update_interrupt_flag();
if self.tim.get_interrupt_flag().contains(Event::Update) {
self.tim.clear_interrupt_flag(Event::Update);
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}

Expand Down
29 changes: 9 additions & 20 deletions src/fugit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use crate::pac::RCC;
use crate::rcc::Clocks;
use crate::timer::General;
pub use crate::timer::{Error, Event, Instance};
use crate::timer::WithPwm;
pub use crate::timer::{Channel, Error, Event, Instance, Ocm, SysEvent};
use cast::u16;

pub mod delay;
Expand Down Expand Up @@ -128,34 +128,23 @@ impl<TIM: Instance, const FREQ: u32> Timer<TIM, FREQ> {
/// Note, you will also have to enable the TIM2 interrupt in the NVIC to start
/// receiving events.
pub fn listen(&mut self, event: Event) {
match event {
Event::TimeOut => {
// Enable update event interrupt
self.tim.listen_update_interrupt(true);
}
}
self.tim.listen_interrupt(event, true);
}

/// Clears interrupt associated with `event`.
///
/// If the interrupt is not cleared, it will immediately retrigger after
/// the ISR has finished.
pub fn clear_interrupt(&mut self, event: Event) {
match event {
Event::TimeOut => {
// Clear interrupt flag
self.tim.clear_update_interrupt_flag();
}
}
self.tim.clear_interrupt_flag(event);
}

pub fn get_interrupt(&mut self) -> Event {
self.tim.get_interrupt_flag()
}

/// Stops listening for an `event`
pub fn unlisten(&mut self, event: Event) {
match event {
Event::TimeOut => {
// Disable update event interrupt
self.tim.listen_update_interrupt(false);
}
}
self.tim.listen_interrupt(event, false);
}
}
Loading

0 comments on commit dddfcb4

Please sign in to comment.