Skip to content

Commit 18c8fc1

Browse files
techmccatusbalbin
authored andcommitted
pwm: implement SetDutyCycle from embedded-hal 1
1 parent 1720ce6 commit 18c8fc1

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/pwm.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ use crate::gpio::AF14;
216216
use crate::gpio::{gpioa::*, gpiob::*, gpioc::*, gpiod::*, gpioe::*, gpiof::*};
217217
use crate::gpio::{Alternate, AF1, AF10, AF11, AF12, AF2, AF3, AF4, AF5, AF6, AF9};
218218

219+
use core::mem::size_of;
220+
219221
// This trait marks that a GPIO pin can be used with a specific timer channel
220222
// TIM is the timer being used
221223
// CHANNEL is a marker struct for the channel (or multi channels for tuples)
@@ -1540,8 +1542,7 @@ macro_rules! tim_pin_hal {
15401542
// In that case, 100% duty cycle is not possible, only 65535/65536
15411543
if arr == Self::Duty::MAX {
15421544
arr
1543-
}
1544-
else {
1545+
} else {
15451546
arr + 1
15461547
}
15471548
}
@@ -1553,6 +1554,31 @@ macro_rules! tim_pin_hal {
15531554
}
15541555
}
15551556

1557+
impl<COMP, POL, NPOL> embedded_hal_one::pwm::ErrorType for Pwm<$TIMX, $CH, COMP, POL, NPOL>
1558+
where Pwm<$TIMX, $CH, COMP, POL, NPOL>: PwmPinEnable {
1559+
type Error = core::convert::Infallible;
1560+
}
1561+
impl<COMP, POL, NPOL> embedded_hal_one::pwm::SetDutyCycle for Pwm<$TIMX, $CH, COMP, POL, NPOL>
1562+
where Pwm<$TIMX, $CH, COMP, POL, NPOL>: PwmPinEnable {
1563+
fn max_duty_cycle(&self) -> u16 {
1564+
let tim = unsafe { &*$TIMX::ptr() };
1565+
let arr = tim.arr.read().arr().bits() as $typ;
1566+
let arr = (arr >> (8*(size_of::<$typ>() - size_of::<u16>()))) as u16;
1567+
// see note above
1568+
if arr == u16::MAX {
1569+
arr
1570+
} else {
1571+
arr + 1
1572+
}
1573+
}
1574+
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
1575+
// hal trait always has 16 bit resolution
1576+
let duty = (duty as $typ) << (8*(size_of::<$typ>() - size_of::<u16>()));
1577+
let tim = unsafe { &*$TIMX::ptr() };
1578+
Ok(tim.$ccrx().write(|w| unsafe { w.ccr().bits(duty.into()) }))
1579+
}
1580+
}
1581+
15561582
// Enable implementation for ComplementaryImpossible
15571583
impl<POL, NPOL> PwmPinEnable for Pwm<$TIMX, $CH, ComplementaryImpossible, POL, NPOL> {
15581584
fn ccer_enable(&mut self) {
@@ -1863,6 +1889,23 @@ macro_rules! lptim_hal {
18631889
tim.icr.write(|w| w.cmpokcf().set_bit());
18641890
}
18651891
}
1892+
1893+
impl embedded_hal_one::pwm::ErrorType for Pwm<$TIMX, C1, ComplementaryImpossible, ActiveHigh, ActiveHigh> {
1894+
type Error = core::convert::Infallible;
1895+
}
1896+
impl embedded_hal_one::pwm::SetDutyCycle for Pwm<$TIMX, C1, ComplementaryImpossible, ActiveHigh, ActiveHigh> {
1897+
fn max_duty_cycle(&self) -> u16 {
1898+
let tim = unsafe { &*$TIMX::ptr() };
1899+
tim.arr.read().arr().bits()
1900+
}
1901+
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
1902+
let tim = unsafe { &*$TIMX::ptr() };
1903+
1904+
tim.cmp.write(|w| unsafe { w.cmp().bits(duty) });
1905+
while !tim.isr.read().cmpok().bit_is_set() {}
1906+
Ok(tim.icr.write(|w| w.cmpokcf().set_bit()))
1907+
}
1908+
}
18661909
)+
18671910
}
18681911
}

0 commit comments

Comments
 (0)