Skip to content

Commit ee0a4dd

Browse files
committed
init channels after Pwm
1 parent bfba917 commit ee0a4dd

File tree

9 files changed

+539
-599
lines changed

9 files changed

+539
-599
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Breaking changes
11+
12+
- move pin connecting to timer channels after `Pwm` initialization [#517]
13+
14+
[#517]: https://github.com/stm32-rs/stm32f1xx-hal/pull/517
15+
1016
## [v0.11.0] - 2025-09-09
1117

1218
### Breaking changes

examples/pwm.rs

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,103 +9,78 @@ use panic_halt as _;
99

1010
use cortex_m::asm;
1111
use cortex_m_rt::entry;
12-
use stm32f1xx_hal::{
13-
pac,
14-
prelude::*,
15-
time::ms,
16-
timer::{Channel, Tim2NoRemap},
17-
};
12+
use stm32f1xx_hal::{pac, prelude::*, time::ms};
1813

1914
#[entry]
2015
fn main() -> ! {
2116
let p = pac::Peripherals::take().unwrap();
2217

2318
let mut rcc = p.RCC.constrain();
2419

25-
let mut afio = p.AFIO.constrain(&mut rcc);
26-
27-
let mut gpioa = p.GPIOA.split(&mut rcc);
20+
let gpioa = p.GPIOA.split(&mut rcc);
2821
// let mut gpiob = p.GPIOB.split(&mut rcc);
2922

3023
// TIM2
31-
let c1 = gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl);
32-
let c2 = gpioa.pa1.into_alternate_push_pull(&mut gpioa.crl);
33-
let c3 = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl);
24+
let c1 = gpioa.pa0;
25+
let c2 = gpioa.pa1;
26+
let c3 = gpioa.pa2;
3427
// If you don't want to use all channels, just leave some out
35-
// let c4 = gpioa.pa3.into_alternate_push_pull(&mut gpioa.crl);
36-
let pins = (c1, c2, c3);
28+
// let c4 = gpioa.pa3;
3729

3830
// TIM3
39-
// let c1 = gpioa.pa6.into_alternate_push_pull(&mut gpioa.crl);
40-
// let c2 = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
41-
// let c3 = gpiob.pb0.into_alternate_push_pull(&mut gpiob.crl);
42-
// let c4 = gpiob.pb1.into_alternate_push_pull(&mut gpiob.crl);
31+
// let c1 = gpioa.pa6;
32+
// let c2 = gpioa.pa7;
33+
// let c3 = gpiob.pb0;
34+
// let c4 = gpiob.pb1;
4335

4436
// TIM4 (Only available with the "medium" density feature)
45-
// let c1 = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl);
46-
// let c2 = gpiob.pb7.into_alternate_push_pull(&mut gpiob.crl);
47-
// let c3 = gpiob.pb8.into_alternate_push_pull(&mut gpiob.crh);
48-
// let c4 = gpiob.pb9.into_alternate_push_pull(&mut gpiob.crh);
37+
// let c1 = gpiob.pb6;
38+
// let c2 = gpiob.pb7;
39+
// let c3 = gpiob.pb8;
40+
// let c4 = gpiob.pb9;
4941

5042
//let mut pwm =
51-
// Timer::new(p.TIM2, &mut rcc).pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz());
43+
// Timer::new(p.TIM2, &mut rcc).pwm_hz(pins, 1.kHz());
5244
// or
53-
let mut pwm = p
54-
.TIM2
55-
.pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz(), &mut rcc);
45+
let (mut pwm_mgr, (pwm_c1, pwm_c2, pwm_c3, ..)) = p.TIM2.pwm_hz(1.kHz(), &mut rcc);
5646

5747
// Enable clock on each of the channels
58-
pwm.enable(Channel::C1);
59-
pwm.enable(Channel::C2);
60-
pwm.enable(Channel::C3);
48+
let mut c1 = pwm_c1.with(c1);
49+
c1.enable();
50+
let mut c2 = pwm_c2.with(c2);
51+
c2.enable();
52+
let mut c3 = pwm_c3.with(c3);
53+
c3.enable();
6154

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

6457
// Adjust period to 0.5 seconds
65-
pwm.set_period(ms(500).into_rate());
58+
pwm_mgr.set_period(ms(500).into_rate());
6659

6760
asm::bkpt();
6861

6962
// Return to the original frequency
70-
pwm.set_period(1.kHz());
63+
pwm_mgr.set_period(1.kHz());
7164

7265
asm::bkpt();
7366

74-
let max = pwm.get_max_duty();
67+
let max = pwm_mgr.get_max_duty();
7568

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

7972
// Use the Pwm object to set C3 to full strength
80-
pwm.set_duty(Channel::C3, max);
73+
c3.set_duty(max);
8174

8275
asm::bkpt();
8376

8477
// Use the Pwm object to set C3 to be dim
85-
pwm.set_duty(Channel::C3, max / 4);
78+
c3.set_duty(max / 4);
8679

8780
asm::bkpt();
8881

8982
// Use the Pwm object to set C3 to be zero
90-
pwm.set_duty(Channel::C3, 0);
91-
92-
asm::bkpt();
93-
94-
// Extract the PwmChannel for C3
95-
let mut pwm_channel = pwm.split().2;
96-
97-
// Use the PwmChannel object to set C3 to be full strength
98-
pwm_channel.set_duty(max);
99-
100-
asm::bkpt();
101-
102-
// Use the PwmChannel object to set C3 to be dim
103-
pwm_channel.set_duty(max / 4);
104-
105-
asm::bkpt();
106-
107-
// Use the PwmChannel object to set C3 to be zero
108-
pwm_channel.set_duty(0);
83+
c3.set_duty(0);
10984

11085
asm::bkpt();
11186

examples/pwm_custom.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use panic_halt as _;
99

1010
use cortex_m::asm;
11-
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
11+
use stm32f1xx_hal::{pac, prelude::*};
1212

1313
use cortex_m_rt::entry;
1414

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

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

3232
let max = pwm.get_max_duty();
3333

34-
let mut pwm_channels = pwm.split();
34+
let mut c1 = pwm_channels.0.with(p0);
35+
let mut c2 = pwm_channels.1.with(p1);
3536

3637
// Enable the individual channels
37-
pwm_channels.0.enable();
38-
pwm_channels.1.enable();
38+
c1.enable();
39+
c2.enable();
3940

4041
// full
41-
pwm_channels.0.set_duty(max);
42-
pwm_channels.1.set_duty(max);
42+
c1.set_duty(max);
43+
c2.set_duty(max);
4344

4445
asm::bkpt();
4546

4647
// dim
47-
pwm_channels.1.set_duty(max / 4);
48+
c2.set_duty(max / 4);
4849

4950
asm::bkpt();
5051

5152
// zero
52-
pwm_channels.0.set_duty(0);
53-
pwm_channels.1.set_duty(0);
53+
c1.set_duty(0);
54+
c2.set_duty(0);
5455

5556
asm::bkpt();
5657

src/rcc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ impl Rcc {
207207
/// let clocks = rcc.freeze(rcc::Config::default(), &mut flash.acr);
208208
/// ```
209209
#[inline(always)]
210+
#[allow(unused)]
210211
pub fn freeze(self, cfg: impl Into<RawConfig>, acr: &mut ACR) -> Self {
211212
let cfg = cfg.into();
212213
let clocks = cfg.get_clocks();

src/timer.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
*/
4949
#![allow(non_upper_case_globals)]
5050

51+
use crate::afio::Rmp;
5152
use crate::bb;
5253
use crate::pac::{self, DBGMCU as DBG};
5354

@@ -62,10 +63,8 @@ use crate::time::Hertz;
6263
pub mod monotonic;
6364
#[cfg(feature = "rtic")]
6465
pub use monotonic::*;
65-
pub(crate) mod pins;
66-
pub mod pwm_input;
67-
pub use pins::*;
6866
pub mod delay;
67+
pub mod pwm_input;
6968
pub use delay::*;
7069
pub mod counter;
7170
pub use counter::*;
@@ -90,6 +89,15 @@ pub enum Channel {
9089
C4 = 3,
9190
}
9291

92+
pub use crate::afio::{TimC, TimNC};
93+
94+
/// Channel wrapper
95+
pub struct Ch<const C: u8, const COMP: bool>;
96+
pub const C1: u8 = 0;
97+
pub const C2: u8 = 1;
98+
pub const C3: u8 = 2;
99+
pub const C4: u8 = 3;
100+
93101
/// Enum for IO polarity
94102
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
95103
pub enum Polarity {
@@ -329,6 +337,11 @@ mod sealed {
329337
type Mms;
330338
fn master_mode(&mut self, mode: Self::Mms);
331339
}
340+
341+
pub trait Split {
342+
type Channels;
343+
fn split() -> Self::Channels;
344+
}
332345
}
333346
pub(crate) use sealed::{Advanced, General, MasterTimer, WithPwm, WithPwmCommon};
334347

@@ -337,6 +350,33 @@ pub trait Instance:
337350
{
338351
}
339352

353+
use sealed::Split;
354+
macro_rules! split {
355+
($TIM:ty: 1) => {
356+
split!($TIM, C1);
357+
};
358+
($TIM:ty: 2) => {
359+
split!($TIM, C1, C2);
360+
};
361+
($TIM:ty: 4) => {
362+
split!($TIM, C1, C2, C3, C4);
363+
};
364+
($TIM:ty, $($C:ident),+) => {
365+
impl Split for $TIM {
366+
type Channels = ($(PwmChannelDisabled<$TIM, $C, 0>,)+);
367+
fn split() -> Self::Channels {
368+
($(PwmChannelDisabled::<_, $C, 0>::new(),)+)
369+
}
370+
}
371+
impl<const R: u8> Split for Rmp<$TIM, R> {
372+
type Channels = ($(PwmChannelDisabled<$TIM, $C, R>,)+);
373+
fn split() -> Self::Channels {
374+
($(PwmChannelDisabled::<_, $C, R>::new(),)+)
375+
}
376+
}
377+
};
378+
}
379+
340380
macro_rules! hal {
341381
($TIM:ty: [
342382
$Timer:ident,
@@ -531,6 +571,7 @@ macro_rules! hal {
531571
)?
532572

533573
with_pwm!($TIM: $cnum $(, $aoe)?);
574+
split!($TIM: $cnum);
534575
)?
535576

536577
$(impl MasterTimer for $TIM {

0 commit comments

Comments
 (0)