Skip to content

Commit 42acde3

Browse files
committed
alternative to stm32-rs#176
1 parent 8b52514 commit 42acde3

File tree

1 file changed

+136
-12
lines changed

1 file changed

+136
-12
lines changed

src/pwm.rs

Lines changed: 136 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ use crate::afio::MAPR;
7272
use crate::bb;
7373
use crate::gpio::{self, Alternate, PushPull};
7474
use crate::time::Hertz;
75+
use crate::time::U32Ext;
7576
use crate::timer::Timer;
7677

7778
pub trait Pins<REMAP, P> {
@@ -93,7 +94,7 @@ macro_rules! pins_impl {
9394
$($PINX: $TRAIT<REMAP> + gpio::Mode<Alternate<PushPull>>,)+
9495
{
9596
$(const $ENCHX: bool = true;)+
96-
type Channels = ($(Pwm<TIM, $ENCHX>),+);
97+
type Channels = ($(PwmChannel<TIM, $ENCHX>),+);
9798
}
9899
)+
99100
};
@@ -128,7 +129,7 @@ impl Timer<TIM1> {
128129
_pins: PINS,
129130
mapr: &mut MAPR,
130131
freq: T,
131-
) -> PINS::Channels
132+
) -> Pwm<TIM1, REMAP, P, PINS>
132133
where
133134
REMAP: Remap<Periph = TIM1>,
134135
PINS: Pins<REMAP, P>,
@@ -147,7 +148,7 @@ impl Timer<TIM2> {
147148
_pins: PINS,
148149
mapr: &mut MAPR,
149150
freq: T,
150-
) -> PINS::Channels
151+
) -> Pwm<TIM2, REMAP, P, PINS>
151152
where
152153
REMAP: Remap<Periph = TIM2>,
153154
PINS: Pins<REMAP, P>,
@@ -166,7 +167,7 @@ impl Timer<TIM3> {
166167
_pins: PINS,
167168
mapr: &mut MAPR,
168169
freq: T,
169-
) -> PINS::Channels
170+
) -> Pwm<TIM3, REMAP, P, PINS>
170171
where
171172
REMAP: Remap<Periph = TIM3>,
172173
PINS: Pins<REMAP, P>,
@@ -186,7 +187,7 @@ impl Timer<TIM4> {
186187
_pins: PINS,
187188
mapr: &mut MAPR,
188189
freq: T,
189-
) -> PINS::Channels
190+
) -> Pwm<TIM4, REMAP, P, PINS>
190191
where
191192
REMAP: Remap<Periph = TIM4>,
192193
PINS: Pins<REMAP, P>,
@@ -199,7 +200,26 @@ impl Timer<TIM4> {
199200
}
200201
}
201202

202-
pub struct Pwm<TIM, CHANNEL> {
203+
pub struct Pwm<TIM, REMAP, P, PINS>
204+
where
205+
REMAP: Remap<Periph = TIM>,
206+
PINS: Pins<REMAP, P>
207+
{
208+
clk: Hertz,
209+
_pins: PhantomData<(TIM, REMAP, P, PINS)>,
210+
}
211+
212+
impl<TIM, REMAP, P, PINS> Pwm<TIM, REMAP, P, PINS>
213+
where
214+
REMAP: Remap<Periph = TIM>,
215+
PINS: Pins<REMAP, P>
216+
{
217+
pub fn split() -> PINS::Channels {
218+
unsafe { mem::MaybeUninit::uninit().assume_init() }
219+
}
220+
}
221+
222+
pub struct PwmChannel<TIM, CHANNEL> {
203223
_channel: PhantomData<CHANNEL>,
204224
_tim: PhantomData<TIM>,
205225
}
@@ -217,7 +237,7 @@ macro_rules! hal {
217237
_pins: PINS,
218238
freq: Hertz,
219239
clk: Hertz,
220-
) -> PINS::Channels
240+
) -> Pwm<$TIMX, REMAP, P, PINS>
221241
where
222242
REMAP: Remap<Periph = $TIMX>,
223243
PINS: Pins<REMAP, P>,
@@ -258,10 +278,114 @@ macro_rules! hal {
258278
.set_bit()
259279
);
260280

261-
unsafe { mem::MaybeUninit::uninit().assume_init() }
281+
Pwm {
282+
clk,
283+
_pins: PhantomData,
284+
}
285+
}
286+
287+
impl<REMAP, P, PINS> hal::Pwm for Pwm<$TIMX, REMAP, P, PINS> where
288+
REMAP: Remap<Periph = $TIMX>,
289+
PINS: Pins<REMAP, P>,
290+
{
291+
type Channel = u8;
292+
type Duty = u16;
293+
type Time = Hertz;
294+
295+
fn enable(&mut self, channel: Self::Channel) {
296+
if channel == 1 && PINS::C1 {
297+
unsafe { bb::set(&(*$TIMX::ptr()).ccer, 0) }
298+
}
299+
if channel == 2 && PINS::C2 {
300+
unsafe { bb::set(&(*$TIMX::ptr()).ccer, 4) }
301+
}
302+
if channel == 3 && PINS::C3 {
303+
unsafe { bb::set(&(*$TIMX::ptr()).ccer, 8) }
304+
}
305+
if channel == 4 && PINS::C4 {
306+
unsafe { bb::set(&(*$TIMX::ptr()).ccer, 12) }
307+
}
308+
}
309+
310+
fn disable(&mut self, channel: Self::Channel) {
311+
if PINS::C1 {
312+
unsafe { bb::clear(&(*$TIMX::ptr()).ccer, 0) }
313+
}
314+
if PINS::C2 {
315+
unsafe { bb::clear(&(*$TIMX::ptr()).ccer, 4) }
316+
}
317+
if PINS::C3 {
318+
unsafe { bb::clear(&(*$TIMX::ptr()).ccer, 8) }
319+
}
320+
if PINS::C4 {
321+
unsafe { bb::clear(&(*$TIMX::ptr()).ccer, 12) }
322+
}
323+
}
324+
325+
fn get_duty(&self, channel: Self::Channel) -> Self::Duty {
326+
if channel == 1 && PINS::C1 {
327+
unsafe { (*$TIMX::ptr()).ccr1.read().ccr().bits() }
328+
} else if channel == 2 && PINS::C2 {
329+
unsafe { (*$TIMX::ptr()).ccr2.read().ccr().bits() }
330+
} else if channel == 3 && PINS::C3 {
331+
unsafe { (*$TIMX::ptr()).ccr3.read().ccr().bits() }
332+
} else if channel == 4 && PINS::C4 {
333+
unsafe { (*$TIMX::ptr()).ccr4.read().ccr().bits() }
334+
} else {
335+
0
336+
}
337+
}
338+
339+
fn set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) {
340+
if PINS::C1 {
341+
unsafe { (*$TIMX::ptr()).ccr1.write(|w| w.ccr().bits(duty)) }
342+
}
343+
if PINS::C2 {
344+
unsafe { (*$TIMX::ptr()).ccr2.write(|w| w.ccr().bits(duty)) }
345+
}
346+
if PINS::C3 {
347+
unsafe { (*$TIMX::ptr()).ccr3.write(|w| w.ccr().bits(duty)) }
348+
}
349+
if PINS::C4 {
350+
unsafe { (*$TIMX::ptr()).ccr4.write(|w| w.ccr().bits(duty)) }
351+
}
352+
}
353+
354+
fn get_max_duty(&self) -> Self::Duty {
355+
unsafe { (*$TIMX::ptr()).arr.read().arr().bits() }
356+
}
357+
358+
fn get_period(&self) -> Self::Time {
359+
let clk = self.clk;
360+
let mut psc: u16 = 0;
361+
let mut arr: u16 = 0;
362+
unsafe {
363+
psc = (*$TIMX::ptr()).psc.read().psc().bits();
364+
arr = (*$TIMX::ptr()).arr.read().arr().bits();
365+
}
366+
367+
// Length in ms of an internal clock pulse
368+
(clk.0 / u32(psc * arr)).hz()
369+
// (((psc as u32) / clk.0) * (1_000_000 as u32) * (arr as u32)).ms()
370+
}
371+
372+
fn set_period<T>(&mut self, period: T) where
373+
T: Into<Self::Time> {
374+
let clk = self.clk;
375+
376+
// let freq = u16(1 / period.into());
377+
378+
let ticks = clk.0 / period.into().0;
379+
let psc = u16(ticks / (1 << 16)).unwrap();
380+
let arr = u16(ticks / u32(psc + 1)).unwrap();
381+
unsafe {
382+
(*$TIMX::ptr()).psc.write(|w| w.psc().bits(psc));
383+
(*$TIMX::ptr()).arr.write(|w| w.arr().bits(arr));
384+
}
385+
}
262386
}
263387

264-
impl hal::PwmPin for Pwm<$TIMX, C1> {
388+
impl hal::PwmPin for PwmChannel<$TIMX, C1> {
265389
type Duty = u16;
266390

267391
fn disable(&mut self) {
@@ -285,7 +409,7 @@ macro_rules! hal {
285409
}
286410
}
287411

288-
impl hal::PwmPin for Pwm<$TIMX, C2> {
412+
impl hal::PwmPin for PwmChannel<$TIMX, C2> {
289413
type Duty = u16;
290414

291415
fn disable(&mut self) {
@@ -309,7 +433,7 @@ macro_rules! hal {
309433
}
310434
}
311435

312-
impl hal::PwmPin for Pwm<$TIMX, C3> {
436+
impl hal::PwmPin for PwmChannel<$TIMX, C3> {
313437
type Duty = u16;
314438

315439
fn disable(&mut self) {
@@ -333,7 +457,7 @@ macro_rules! hal {
333457
}
334458
}
335459

336-
impl hal::PwmPin for Pwm<$TIMX, C4> {
460+
impl hal::PwmPin for PwmChannel<$TIMX, C4> {
337461
type Duty = u16;
338462

339463
fn disable(&mut self) {

0 commit comments

Comments
 (0)