Skip to content

Commit 3e703b6

Browse files
bors[bot]burrbull
andauthored
Merge #571
571: Pwm complementary r=therealprof a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents bb41956 + 1dbbf40 commit 3e703b6

File tree

5 files changed

+267
-145
lines changed

5 files changed

+267
-145
lines changed

CHANGELOG.md

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

1212
- Bump `synopsys-usb-otg` to 0.3.2 (bug fix)
1313
- Update readme, clippy fixes
14+
- Added possibility to pass complementary pins to `Pwm` and change pwm channel polarity [#571]
1415

1516
### Added
1617

@@ -22,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2223
- Fix alternate function pin definitions for FMPI2C1 [#572]
2324

2425
[#426]: https://github.com/stm32-rs/stm32f4xx-hal/pull/426
26+
[#571]: https://github.com/stm32-rs/stm32f4xx-hal/pull/571
2527
[#572]: https://github.com/stm32-rs/stm32f4xx-hal/pull/572
2628

2729

src/gpio/alt.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -766,22 +766,7 @@ pin! {
766766
<serial::RxPin, USART6> for [PA12<8>]
767767
}
768768

769-
#[cfg(any(
770-
feature = "stm32f405",
771-
feature = "stm32f407",
772-
feature = "stm32f412",
773-
feature = "stm32f413",
774-
feature = "stm32f415",
775-
feature = "stm32f417",
776-
feature = "stm32f423",
777-
feature = "stm32f427",
778-
feature = "stm32f429",
779-
feature = "stm32f437",
780-
feature = "stm32f439",
781-
feature = "stm32f446",
782-
feature = "stm32f469",
783-
feature = "stm32f479"
784-
))]
769+
#[cfg(feature = "gpiog")]
785770
pin! {
786771
<serial::TxPin, USART6> for [PG14<8>],
787772
<serial::RxPin, USART6> for [PG9<8>]

src/timer.rs

Lines changed: 96 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ pub enum Channel {
5757
C4 = 3,
5858
}
5959

60+
/// Enum for IO polarity
61+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
62+
pub enum Polarity {
63+
ActiveHigh,
64+
ActiveLow,
65+
}
66+
6067
/// Interrupt events
6168
#[derive(Clone, Copy, PartialEq, Eq)]
6269
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -232,7 +239,7 @@ pub type CCR4<T> = CCR<T, 3>;
232239
pub struct DMAR<T>(T);
233240

234241
mod sealed {
235-
use super::{Channel, Event, Ocm};
242+
use super::{Channel, Event, Ocm, Polarity};
236243
pub trait General {
237244
type Width: Into<u32> + From<u16>;
238245
fn max_auto_reload() -> u32;
@@ -257,21 +264,30 @@ mod sealed {
257264
fn cnt_reset(&mut self);
258265
}
259266

260-
pub trait WithPwm: General {
267+
pub trait WithPwmCommon: General {
261268
const CH_NUMBER: u8;
262269
fn read_cc_value(channel: u8) -> u32;
263270
fn set_cc_value(channel: u8, value: u32);
271+
fn enable_channel(channel: u8, b: bool);
272+
fn set_channel_polarity(channel: u8, p: Polarity);
273+
fn set_nchannel_polarity(channel: u8, p: Polarity);
274+
}
275+
276+
pub trait Advanced: WithPwmCommon {
277+
fn enable_nchannel(channel: u8, b: bool);
278+
}
279+
280+
pub trait WithPwm: WithPwmCommon {
264281
fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm);
265282
fn start_pwm(&mut self);
266-
fn enable_channel(channel: u8, b: bool);
267283
}
268284

269285
pub trait MasterTimer: General {
270286
type Mms;
271287
fn master_mode(&mut self, mode: Self::Mms);
272288
}
273289
}
274-
pub(crate) use sealed::{General, MasterTimer, WithPwm};
290+
pub(crate) use sealed::{Advanced, General, MasterTimer, WithPwm, WithPwmCommon};
275291

276292
pub trait Instance:
277293
crate::Sealed + rcc::Enable + rcc::Reset + rcc::BusTimerClock + General
@@ -283,7 +299,7 @@ macro_rules! hal {
283299
$Timer:ident,
284300
$bits:ty,
285301
$(dmar: $memsize:ty,)?
286-
$(c: ($cnum:ident $(, $aoe:ident)?),)?
302+
$(c: ($CNUM:ident, $cnum:literal $(, $aoe:ident)?),)?
287303
$(m: $timbase:ident,)?
288304
],)+) => {
289305
$(
@@ -391,7 +407,66 @@ macro_rules! hal {
391407
$(with_dmar!($TIM, $memsize);)?
392408

393409
$(
394-
with_pwm!($TIM: $cnum $(, $aoe)?);
410+
impl WithPwmCommon for $TIM {
411+
const CH_NUMBER: u8 = $cnum;
412+
413+
#[inline(always)]
414+
fn read_cc_value(c: u8) -> u32 {
415+
let tim = unsafe { &*<$TIM>::ptr() };
416+
if c < Self::CH_NUMBER {
417+
tim.ccr[c as usize].read().bits()
418+
} else {
419+
0
420+
}
421+
}
422+
423+
#[inline(always)]
424+
fn set_cc_value(c: u8, value: u32) {
425+
let tim = unsafe { &*<$TIM>::ptr() };
426+
if c < Self::CH_NUMBER {
427+
#[allow(unused_unsafe)]
428+
tim.ccr[c as usize].write(|w| unsafe { w.bits(value) })
429+
}
430+
}
431+
432+
#[inline(always)]
433+
fn enable_channel(c: u8, b: bool) {
434+
let tim = unsafe { &*<$TIM>::ptr() };
435+
if c < Self::CH_NUMBER {
436+
unsafe { bb::write(&tim.ccer, c*4, b); }
437+
}
438+
}
439+
440+
#[inline(always)]
441+
fn set_channel_polarity(c: u8, p: Polarity) {
442+
let tim = unsafe { &*<$TIM>::ptr() };
443+
if c < Self::CH_NUMBER {
444+
unsafe { bb::write(&tim.ccer, c*4 + 1, p == Polarity::ActiveLow); }
445+
}
446+
}
447+
448+
#[inline(always)]
449+
fn set_nchannel_polarity(c: u8, p: Polarity) {
450+
let tim = unsafe { &*<$TIM>::ptr() };
451+
if c < Self::CH_NUMBER {
452+
unsafe { bb::write(&tim.ccer, c*4 + 3, p == Polarity::ActiveLow); }
453+
}
454+
}
455+
}
456+
457+
$(
458+
impl Advanced for $TIM {
459+
fn enable_nchannel(c: u8, b: bool) {
460+
let $aoe = ();
461+
let tim = unsafe { &*<$TIM>::ptr() };
462+
if c < Self::CH_NUMBER {
463+
unsafe { bb::write(&tim.ccer, c*4 + 2, b); }
464+
}
465+
}
466+
}
467+
)?
468+
469+
with_pwm!($TIM: $CNUM $(, $aoe)?);
395470
unsafe impl<const C: u8> PeriAddress for CCR<$TIM, C> {
396471
#[inline(always)]
397472
fn address(&self) -> u32 {
@@ -428,21 +503,6 @@ macro_rules! with_dmar {
428503
macro_rules! with_pwm {
429504
($TIM:ty: CH1) => {
430505
impl WithPwm for $TIM {
431-
const CH_NUMBER: u8 = 1;
432-
433-
#[inline(always)]
434-
fn read_cc_value(channel: u8) -> u32 {
435-
let tim = unsafe { &*<$TIM>::ptr() };
436-
tim.ccr[channel as usize].read().bits()
437-
}
438-
439-
#[inline(always)]
440-
fn set_cc_value(channel: u8, value: u32) {
441-
let tim = unsafe { &*<$TIM>::ptr() };
442-
#[allow(unused_unsafe)]
443-
tim.ccr[channel as usize].write(|w| unsafe { w.bits(value) })
444-
}
445-
446506
#[inline(always)]
447507
fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
448508
match channel {
@@ -458,33 +518,10 @@ macro_rules! with_pwm {
458518
fn start_pwm(&mut self) {
459519
self.cr1.modify(|_, w| w.cen().set_bit());
460520
}
461-
462-
#[inline(always)]
463-
fn enable_channel(c: u8, b: bool) {
464-
let tim = unsafe { &*<$TIM>::ptr() };
465-
if c < Self::CH_NUMBER {
466-
unsafe { bb::write(&tim.ccer, c*4, b); }
467-
}
468-
}
469521
}
470522
};
471523
($TIM:ty: CH2) => {
472524
impl WithPwm for $TIM {
473-
const CH_NUMBER: u8 = 2;
474-
475-
#[inline(always)]
476-
fn read_cc_value(channel: u8) -> u32 {
477-
let tim = unsafe { &*<$TIM>::ptr() };
478-
tim.ccr[channel as usize].read().bits()
479-
}
480-
481-
#[inline(always)]
482-
fn set_cc_value(channel: u8, value: u32) {
483-
let tim = unsafe { &*<$TIM>::ptr() };
484-
#[allow(unused_unsafe)]
485-
tim.ccr[channel as usize].write(|w| unsafe { w.bits(value) });
486-
}
487-
488525
#[inline(always)]
489526
fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
490527
match channel {
@@ -504,33 +541,10 @@ macro_rules! with_pwm {
504541
fn start_pwm(&mut self) {
505542
self.cr1.modify(|_, w| w.cen().set_bit());
506543
}
507-
508-
#[inline(always)]
509-
fn enable_channel(c: u8, b: bool) {
510-
let tim = unsafe { &*<$TIM>::ptr() };
511-
if c < Self::CH_NUMBER {
512-
unsafe { bb::write(&tim.ccer, c*4, b); }
513-
}
514-
}
515544
}
516545
};
517546
($TIM:ty: CH4 $(, $aoe:ident)?) => {
518547
impl WithPwm for $TIM {
519-
const CH_NUMBER: u8 = 4;
520-
521-
#[inline(always)]
522-
fn read_cc_value(channel: u8) -> u32 {
523-
let tim = unsafe { &*<$TIM>::ptr() };
524-
tim.ccr[channel as usize].read().bits()
525-
}
526-
527-
#[inline(always)]
528-
fn set_cc_value(channel: u8, value: u32) {
529-
let tim = unsafe { &*<$TIM>::ptr() };
530-
#[allow(unused_unsafe)]
531-
tim.ccr[channel as usize].write(|w| unsafe { w.bits(value) })
532-
}
533-
534548
#[inline(always)]
535549
fn preload_output_channel_in_mode(&mut self, channel: Channel, mode: Ocm) {
536550
match channel {
@@ -558,16 +572,8 @@ macro_rules! with_pwm {
558572
$(let $aoe = self.bdtr.modify(|_, w| w.aoe().set_bit());)?
559573
self.cr1.modify(|_, w| w.cen().set_bit());
560574
}
561-
562-
#[inline(always)]
563-
fn enable_channel(c: u8, b: bool) {
564-
let tim = unsafe { &*<$TIM>::ptr() };
565-
if c < Self::CH_NUMBER {
566-
unsafe { bb::write(&tim.ccer, c*4, b); }
567-
}
568-
}
569575
}
570-
}
576+
};
571577
}
572578

573579
impl<TIM: Instance> Timer<TIM> {
@@ -723,26 +729,26 @@ pub(crate) const fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u32) {
723729

724730
// All F4xx parts have these timers.
725731
hal!(
726-
pac::TIM9: [Timer9, u16, c: (CH2),],
727-
pac::TIM11: [Timer11, u16, c: (CH1),],
732+
pac::TIM9: [Timer9, u16, c: (CH2, 2),],
733+
pac::TIM11: [Timer11, u16, c: (CH1, 1),],
728734
);
729735

730736
// All parts except for F410 add these timers.
731737
#[cfg(not(feature = "stm32f410"))]
732738
hal!(
733-
pac::TIM1: [Timer1, u16, dmar: u32, c: (CH4, _aoe), m: tim1,],
734-
pac::TIM5: [Timer5, u32, dmar: u16, c: (CH4), m: tim5,],
735-
pac::TIM2: [Timer2, u32, dmar: u16, c: (CH4), m: tim2,],
736-
pac::TIM3: [Timer3, u16, dmar: u16, c: (CH4), m: tim3,],
737-
pac::TIM4: [Timer4, u16, dmar: u16, c: (CH4), m: tim3,],
738-
pac::TIM10: [Timer10, u16, c: (CH1),],
739+
pac::TIM1: [Timer1, u16, dmar: u32, c: (CH4, 4, _aoe), m: tim1,],
740+
pac::TIM5: [Timer5, u32, dmar: u16, c: (CH4, 4), m: tim5,],
741+
pac::TIM2: [Timer2, u32, dmar: u16, c: (CH4, 4), m: tim2,],
742+
pac::TIM3: [Timer3, u16, dmar: u16, c: (CH4, 4), m: tim3,],
743+
pac::TIM4: [Timer4, u16, dmar: u16, c: (CH4, 4), m: tim3,],
744+
pac::TIM10: [Timer10, u16, c: (CH1, 1),],
739745
);
740746

741747
// TIM5 on F410 is 16-bit
742748
#[cfg(feature = "stm32f410")]
743749
hal!(
744-
pac::TIM1: [Timer1, u16, dmar: u16, c: (CH4, _aoe), m: tim1,],
745-
pac::TIM5: [Timer5, u16, dmar: u16, c: (CH4), m: tim5,],
750+
pac::TIM1: [Timer1, u16, dmar: u16, c: (CH4, 4, _aoe), m: tim1,],
751+
pac::TIM5: [Timer5, u16, dmar: u16, c: (CH4, 4), m: tim5,],
746752
);
747753

748754
// All parts except F401 and F411.
@@ -753,8 +759,8 @@ hal!(pac::TIM6: [Timer6, u16, m: tim6,],);
753759
#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411",)))]
754760
hal!(
755761
pac::TIM7: [Timer7, u16, m: tim7,],
756-
pac::TIM8: [Timer8, u16, dmar: u32, c: (CH4, _aoe), m: tim8,],
757-
pac::TIM12: [Timer12, u16, c: (CH2),],
758-
pac::TIM13: [Timer13, u16, c: (CH1),],
759-
pac::TIM14: [Timer14, u16, c: (CH1),],
762+
pac::TIM8: [Timer8, u16, dmar: u32, c: (CH4, 4, _aoe), m: tim8,],
763+
pac::TIM12: [Timer12, u16, c: (CH2, 2),],
764+
pac::TIM13: [Timer13, u16, c: (CH1, 1),],
765+
pac::TIM14: [Timer14, u16, c: (CH1, 1),],
760766
);

src/timer/pins.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub trait EtrPin<TIM> {}
1010
pub trait BkinPin<TIM> {}
1111

1212
/// Channel wrapper
13-
pub struct Ch<const C: u8>;
13+
pub struct Ch<const C: u8, const COMP: bool>;
1414
pub const C1: u8 = 0;
1515
pub const C2: u8 = 1;
1616
pub const C3: u8 = 2;

0 commit comments

Comments
 (0)