Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

init channels after Pwm #517

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Temporary replace `stm32f1` with `stm32f1-staging` [#503]
- `Spi` now takes `Option<PIN>` for `SCK`, `MISO`, `MOSI` [#514]
- move `Qei` mod inside `pwm_input` mod [#516]
- move pin connecting to timer channels after `Pwm` initialization

### Changed

Expand Down
83 changes: 29 additions & 54 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ use panic_halt as _;

use cortex_m::asm;
use cortex_m_rt::entry;
use stm32f1xx_hal::{
pac,
prelude::*,
time::ms,
timer::{Channel, Tim2NoRemap},
};
use stm32f1xx_hal::{pac, prelude::*, time::ms};

#[entry]
fn main() -> ! {
Expand All @@ -25,90 +20,70 @@ fn main() -> ! {

let clocks = rcc.cfgr.freeze(&mut flash.acr);

let mut afio = p.AFIO.constrain();

let mut gpioa = p.GPIOA.split();
// let mut gpiob = p.GPIOB.split();
let gpioa = p.GPIOA.split();
// let gpiob = p.GPIOB.split();

// TIM2
let c1 = gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl);
let c2 = gpioa.pa1.into_alternate_push_pull(&mut gpioa.crl);
let c3 = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl);
let c1 = gpioa.pa0;
let c2 = gpioa.pa1;
let c3 = gpioa.pa2;
// If you don't want to use all channels, just leave some out
// let c4 = gpioa.pa3.into_alternate_push_pull(&mut gpioa.crl);
let pins = (c1, c2, c3);
// let c4 = gpioa.pa3;

// TIM3
// let c1 = gpioa.pa6.into_alternate_push_pull(&mut gpioa.crl);
// let c2 = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
// let c3 = gpiob.pb0.into_alternate_push_pull(&mut gpiob.crl);
// let c4 = gpiob.pb1.into_alternate_push_pull(&mut gpiob.crl);
// let c1 = gpioa.pa6;
// let c2 = gpioa.pa7;
// let c3 = gpiob.pb0;
// let c4 = gpiob.pb1;

// TIM4 (Only available with the "medium" density feature)
// let c1 = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl);
// let c2 = gpiob.pb7.into_alternate_push_pull(&mut gpiob.crl);
// let c3 = gpiob.pb8.into_alternate_push_pull(&mut gpiob.crh);
// let c4 = gpiob.pb9.into_alternate_push_pull(&mut gpiob.crh);
// let c1 = gpiob.pb6;
// let c2 = gpiob.pb7;
// let c3 = gpiob.pb8;
// let c4 = gpiob.pb9;

//let mut pwm =
// Timer::new(p.TIM2, &clocks).pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz());
// Timer::new(p.TIM2, &clocks).pwm_hz(pins, 1.kHz());
// or
let mut pwm = p
.TIM2
.pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz(), &clocks);
let (mut pwm_mgr, (pwm_c1, pwm_c2, pwm_c3, ..)) = p.TIM2.pwm_hz(1.kHz(), &clocks);

// Enable clock on each of the channels
pwm.enable(Channel::C1);
pwm.enable(Channel::C2);
pwm.enable(Channel::C3);
let mut c1 = pwm_c1.with(c1);
c1.enable();
let mut c2 = pwm_c2.with(c2);
c2.enable();
let mut c3 = pwm_c3.with(c3);
c3.enable();

//// Operations affecting all defined channels on the Timer

// Adjust period to 0.5 seconds
pwm.set_period(ms(500).into_rate());
pwm_mgr.set_period(ms(500).into_rate());

asm::bkpt();

// Return to the original frequency
pwm.set_period(1.kHz());
pwm_mgr.set_period(1.kHz());

asm::bkpt();

let max = pwm.get_max_duty();
let max = pwm_mgr.get_max_duty();

//// Operations affecting single channels can be accessed through
//// the Pwm object or via dereferencing to the pin.

// Use the Pwm object to set C3 to full strength
pwm.set_duty(Channel::C3, max);
c3.set_duty(max);

asm::bkpt();

// Use the Pwm object to set C3 to be dim
pwm.set_duty(Channel::C3, max / 4);
c3.set_duty(max / 4);

asm::bkpt();

// Use the Pwm object to set C3 to be zero
pwm.set_duty(Channel::C3, 0);

asm::bkpt();

// Extract the PwmChannel for C3
let mut pwm_channel = pwm.split().2;

// Use the PwmChannel object to set C3 to be full strength
pwm_channel.set_duty(max);

asm::bkpt();

// Use the PwmChannel object to set C3 to be dim
pwm_channel.set_duty(max / 4);

asm::bkpt();

// Use the PwmChannel object to set C3 to be zero
pwm_channel.set_duty(0);
c3.set_duty(0);

asm::bkpt();

Expand Down
21 changes: 11 additions & 10 deletions examples/pwm_custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use panic_halt as _;

use cortex_m::asm;
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
use stm32f1xx_hal::{pac, prelude::*};

use cortex_m_rt::entry;

Expand All @@ -30,30 +30,31 @@ fn main() -> ! {
let p0 = pb4.into_alternate_push_pull(&mut gpiob.crl);
let p1 = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl);

let pwm = Timer::new(p.TIM3, &clocks).pwm_hz((p0, p1), &mut afio.mapr, 1.kHz());
let (pwm, pwm_channels) = p.TIM3.remap(&mut afio.mapr).pwm_hz(1.kHz(), &clocks);

let max = pwm.get_max_duty();

let mut pwm_channels = pwm.split();
let mut c1 = pwm_channels.0.with(p0);
let mut c2 = pwm_channels.1.with(p1);

// Enable the individual channels
pwm_channels.0.enable();
pwm_channels.1.enable();
c1.enable();
c2.enable();

// full
pwm_channels.0.set_duty(max);
pwm_channels.1.set_duty(max);
c1.set_duty(max);
c2.set_duty(max);

asm::bkpt();

// dim
pwm_channels.1.set_duty(max / 4);
c2.set_duty(max / 4);

asm::bkpt();

// zero
pwm_channels.0.set_duty(0);
pwm_channels.1.set_duty(0);
c1.set_duty(0);
c2.set_duty(0);

asm::bkpt();

Expand Down
17 changes: 17 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,20 @@ mod sealed {
pub trait Sealed {}
}
use sealed::Sealed;

pub trait Steal {
/// Steal an instance of this peripheral
///
/// # Safety
///
/// Ensure that the new instance of the peripheral cannot be used in a way
/// that may race with any existing instances, for example by only
/// accessing read-only or write-only registers, or by consuming the
/// original peripheral and using critical sections to coordinate
/// access between multiple new instances.
///
/// Additionally the HAL may rely on only one
/// peripheral instance existing to ensure memory safety; ensure
/// no stolen instances are passed to such software.
unsafe fn steal() -> Self;
}
Loading
Loading