Skip to content

Commit 461b136

Browse files
committed
improve pwm
- dead time - fix typo - update changelog
1 parent eed06fb commit 461b136

File tree

3 files changed

+41
-50
lines changed

3 files changed

+41
-50
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616
- Provide getters to serial status flags idle/txe/rxne/tc.
1717
- Provide ability to reset timer UIF interrupt flag
1818
- PWM complementary output capability for TIM1 with new example to demonstrate
19+
- Very simple dead time control of complementary PWM channels
1920

2021
### Fixed
2122

2223
- Wrong mode when using PWM channel 2 of a two-channel timer
2324
- `adc_values` example conversion error
25+
- Fixed typo in setup of complementary channels
2426

2527
## [v0.18.0] - 2021-11-14
2628

examples/pwm_complementary.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ use cortex_m_rt::entry;
1010

1111
use stm32f0xx_hal as hal;
1212

13-
use hal::{delay::Delay, pac, prelude::*, pwm};
13+
use hal::{
14+
delay::Delay,
15+
pac,
16+
prelude::*,
17+
pwm::{self, DTInterval::*, *},
18+
};
1419

1520
#[entry]
1621
fn main() -> ! {
@@ -31,6 +36,8 @@ fn main() -> ! {
3136
let max_duty = ch1.get_max_duty();
3237
ch1.set_duty(max_duty / 2);
3338
ch1.enable();
39+
40+
ch1n.set_dead_time(DT_2);
3441
ch1n.enable();
3542

3643
// simple duty sweep

src/pwm.rs

+31-49
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ pub struct C3;
3232
pub struct C3N;
3333
pub struct C4;
3434

35+
pub enum DTInterval {
36+
DT_0 = 0,
37+
DT_1 = 1,
38+
DT_2 = 2,
39+
DT_3 = 3,
40+
DT_4 = 4,
41+
DT_5 = 5,
42+
DT_6 = 6,
43+
DT_7 = 7,
44+
}
45+
46+
pub trait ComplementaryPwm {
47+
fn disable(&mut self);
48+
fn enable(&mut self);
49+
50+
fn set_dead_time(&mut self, duration: DTInterval);
51+
}
52+
3553
pub struct PwmChannels<TIM, CHANNELS> {
3654
_channel: PhantomData<CHANNELS>,
3755
_tim: PhantomData<TIM>,
@@ -321,7 +339,7 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
321339
rcc.regs.$apbrstr.modify(|_, w| w.$timXrst().set_bit());
322340
rcc.regs.$apbrstr.modify(|_, w| w.$timXrst().clear_bit());
323341

324-
if PINS::C1N | PINS::C1N | PINS::C1N {
342+
if PINS::C1N | PINS::C2N | PINS::C3N {
325343
tim.bdtr.modify(|_, w| w.ossr().set_bit());
326344
}
327345
if PINS::C1 {
@@ -406,9 +424,7 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
406424
}
407425
}
408426

409-
impl hal::PwmPin for PwmChannels<$TIMX, C1N> {
410-
type Duty = u16;
411-
427+
impl ComplementaryPwm for PwmChannels<$TIMX, C1N> {
412428
//NOTE(unsafe) atomic write with no side effects
413429
fn disable(&mut self) {
414430
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc1ne().clear_bit()) };
@@ -419,19 +435,9 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
419435
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc1ne().set_bit()) };
420436
}
421437

422-
//NOTE(unsafe) atomic read with no side effects
423-
fn get_duty(&self) -> u16 {
424-
unsafe { (*$TIMX::ptr()).ccr1.read().ccr().bits() as u16 }
425-
}
426-
427-
//NOTE(unsafe) atomic read with no side effects
428-
fn get_max_duty(&self) -> u16 {
429-
unsafe { (*$TIMX::ptr()).arr.read().arr().bits() as u16 }
430-
}
431-
432-
//NOTE(unsafe) atomic write with no side effects
433-
fn set_duty(&mut self, duty: u16) {
434-
unsafe { (*$TIMX::ptr()).ccr1.write(|w| w.ccr().bits(duty.into())) }
438+
// NOTE: dead time insertion is per timer not per channel
439+
fn set_dead_time(&mut self, duration: DTInterval) {
440+
unsafe { (*($TIMX::ptr())).bdtr.modify(|_, w| w.dtg().bits(duration as u8)) };
435441
}
436442
}
437443

@@ -464,9 +470,7 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
464470
}
465471
}
466472

467-
impl hal::PwmPin for PwmChannels<$TIMX, C2N> {
468-
type Duty = u16;
469-
473+
impl ComplementaryPwm for PwmChannels<$TIMX, C2N> {
470474
//NOTE(unsafe) atomic write with no side effects
471475
fn disable(&mut self) {
472476
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc2ne().clear_bit()) };
@@ -477,19 +481,9 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
477481
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc2ne().set_bit()) };
478482
}
479483

480-
//NOTE(unsafe) atomic read with no side effects
481-
fn get_duty(&self) -> u16 {
482-
unsafe { (*$TIMX::ptr()).ccr2.read().ccr().bits() as u16 }
483-
}
484-
485-
//NOTE(unsafe) atomic read with no side effects
486-
fn get_max_duty(&self) -> u16 {
487-
unsafe { (*$TIMX::ptr()).arr.read().arr().bits() as u16 }
488-
}
489-
490-
//NOTE(unsafe) atomic write with no side effects
491-
fn set_duty(&mut self, duty: u16) {
492-
unsafe { (*$TIMX::ptr()).ccr2.write(|w| w.ccr().bits(duty.into())) }
484+
// NOTE: dead time insertion is per timer not per channel
485+
fn set_dead_time(&mut self, duration: DTInterval) {
486+
unsafe { (*($TIMX::ptr())).bdtr.modify(|_, w| w.dtg().bits(duration as u8)) };
493487
}
494488
}
495489

@@ -522,9 +516,7 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
522516
}
523517
}
524518

525-
impl hal::PwmPin for PwmChannels<$TIMX, C3N> {
526-
type Duty = u16;
527-
519+
impl ComplementaryPwm for PwmChannels<$TIMX, C3N> {
528520
//NOTE(unsafe) atomic write with no side effects
529521
fn disable(&mut self) {
530522
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc3ne().clear_bit()) };
@@ -535,19 +527,9 @@ macro_rules! pwm_4_channels_with_3_complementary_outputs {
535527
unsafe { (*($TIMX::ptr())).ccer.modify(|_, w| w.cc3ne().set_bit()) };
536528
}
537529

538-
//NOTE(unsafe) atomic read with no side effects
539-
fn get_duty(&self) -> u16 {
540-
unsafe { (*$TIMX::ptr()).ccr3.read().ccr().bits() as u16 }
541-
}
542-
543-
//NOTE(unsafe) atomic read with no side effects
544-
fn get_max_duty(&self) -> u16 {
545-
unsafe { (*$TIMX::ptr()).arr.read().arr().bits() as u16 }
546-
}
547-
548-
//NOTE(unsafe) atomic write with no side effects
549-
fn set_duty(&mut self, duty: u16) {
550-
unsafe { (*$TIMX::ptr()).ccr3.write(|w| w.ccr().bits(duty.into())) }
530+
// NOTE: dead time insertion is per timer not per channel
531+
fn set_dead_time(&mut self, duration: DTInterval) {
532+
unsafe { (*($TIMX::ptr())).bdtr.modify(|_, w| w.dtg().bits(duration as u8)) };
551533
}
552534
}
553535

0 commit comments

Comments
 (0)