126 lines
3.7 KiB
Rust
126 lines
3.7 KiB
Rust
|
use tm4c129x::{
|
||
|
TIMER2, TIMER3, TIMER4, TIMER5,
|
||
|
};
|
||
|
|
||
|
pub struct T2CCP0;
|
||
|
pub struct T2CCP1;
|
||
|
pub struct T3CCP0;
|
||
|
pub struct T3CCP1;
|
||
|
pub struct T4CCP0;
|
||
|
pub struct T4CCP1;
|
||
|
pub struct T5CCP0;
|
||
|
pub struct T5CCP1;
|
||
|
|
||
|
pub trait PwmPeripheral {
|
||
|
type ChannelA: PwmChannel;
|
||
|
type ChannelB: PwmChannel;
|
||
|
fn split_16bit_ab() -> (Self::ChannelA, Self::ChannelB);
|
||
|
}
|
||
|
|
||
|
macro_rules! pwm_peripheral {
|
||
|
($TIMER: ty, $A: tt, $B: tt) => {
|
||
|
impl PwmPeripheral for $TIMER {
|
||
|
type ChannelA = $A;
|
||
|
type ChannelB = $B;
|
||
|
fn split_16bit_ab() -> (Self::ChannelA, Self::ChannelB) {
|
||
|
let regs = unsafe { &*Self::ptr() };
|
||
|
regs.cfg.write(|w| unsafe { w.bits(4) });
|
||
|
|
||
|
let mut a = $A;
|
||
|
a.configure();
|
||
|
let mut b = $B;
|
||
|
b.configure();
|
||
|
(a, b)
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
pwm_peripheral!(TIMER2, T2CCP0, T2CCP1);
|
||
|
pwm_peripheral!(TIMER3, T3CCP0, T3CCP1);
|
||
|
pwm_peripheral!(TIMER4, T4CCP0, T4CCP1);
|
||
|
pwm_peripheral!(TIMER5, T5CCP0, T5CCP1);
|
||
|
|
||
|
|
||
|
pub trait PwmChannel {
|
||
|
fn configure(&mut self);
|
||
|
fn set(&mut self, width: u16, total: u16);
|
||
|
}
|
||
|
|
||
|
macro_rules! pwm_channel_a {
|
||
|
($CHANNEL: ty, $TIMER: tt) => {
|
||
|
impl PwmChannel for $CHANNEL {
|
||
|
fn configure(&mut self) {
|
||
|
let timer = unsafe { &*tm4c129x::$TIMER::ptr() };
|
||
|
timer.tamr.modify(|_, w| unsafe {
|
||
|
w
|
||
|
.taams().bit(true)
|
||
|
.tacmr().bit(false)
|
||
|
.tamr().bits(2)
|
||
|
});
|
||
|
timer.ctl.modify(|_, w| {
|
||
|
w
|
||
|
.tapwml().bit(false)
|
||
|
});
|
||
|
// no prescaler
|
||
|
// no interrupts
|
||
|
timer.tailr.write(|w| unsafe { w.bits(0xFFFF) });
|
||
|
timer.tamatchr.write(|w| unsafe { w.bits(0x0) });
|
||
|
timer.ctl.modify(|_, w| {
|
||
|
w
|
||
|
.taen().bit(true)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn set(&mut self, width: u16, total: u16) {
|
||
|
let timer = unsafe { &*tm4c129x::$TIMER::ptr() };
|
||
|
timer.tamatchr.write(|w| unsafe { w.bits(width.into()) });
|
||
|
timer.tailr.write(|w| unsafe { w.bits(total.into()) });
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
macro_rules! pwm_channel_b {
|
||
|
($CHANNEL: ty, $TIMER: tt) => {
|
||
|
impl PwmChannel for $CHANNEL {
|
||
|
fn configure(&mut self) {
|
||
|
let timer = unsafe { &*tm4c129x::$TIMER::ptr() };
|
||
|
timer.tbmr.modify(|_, w| unsafe {
|
||
|
w
|
||
|
.tbams().bit(true)
|
||
|
.tbcmr().bit(false)
|
||
|
.tbmr().bits(2)
|
||
|
});
|
||
|
timer.ctl.modify(|_, w| {
|
||
|
w
|
||
|
.tbpwml().bit(false)
|
||
|
});
|
||
|
// no prescaler
|
||
|
// no interrupts
|
||
|
timer.tbilr.write(|w| unsafe { w.bits(0xFFFF) });
|
||
|
timer.tbmatchr.write(|w| unsafe { w.bits(0x0) });
|
||
|
timer.ctl.modify(|_, w| {
|
||
|
w
|
||
|
.tben().bit(true)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn set(&mut self, width: u16, total: u16) {
|
||
|
let timer = unsafe { &*tm4c129x::$TIMER::ptr() };
|
||
|
timer.tbmatchr.write(|w| unsafe { w.bits(width.into()) });
|
||
|
timer.tbilr.write(|w| unsafe { w.bits(total.into()) });
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
pwm_channel_a!(T2CCP0, TIMER2);
|
||
|
pwm_channel_b!(T2CCP1, TIMER2);
|
||
|
pwm_channel_a!(T3CCP0, TIMER3);
|
||
|
pwm_channel_b!(T3CCP1, TIMER3);
|
||
|
pwm_channel_a!(T4CCP0, TIMER4);
|
||
|
pwm_channel_b!(T4CCP1, TIMER4);
|
||
|
pwm_channel_a!(T5CCP0, TIMER5);
|
||
|
pwm_channel_b!(T5CCP1, TIMER5);
|