You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.4 KiB
Rust
129 lines
3.4 KiB
Rust
use core::fmt;
|
|
use crate::board::pwm::{self, PwmChannel, PwmPeripheral};
|
|
use crate::board::gpio::{Gpio, GpioOutput, PP2, PP3, PK1, PQ4};
|
|
use embedded_hal::digital::v2::OutputPin;
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub enum TecPin {
|
|
ISet,
|
|
MaxIPos,
|
|
MaxINeg,
|
|
MaxV,
|
|
}
|
|
|
|
impl TecPin {
|
|
pub const VALID_VALUES: &'static [TecPin] = &[
|
|
TecPin::ISet,
|
|
TecPin::MaxIPos,
|
|
TecPin::MaxINeg,
|
|
TecPin::MaxV,
|
|
];
|
|
}
|
|
|
|
impl fmt::Display for TecPin {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
match self {
|
|
TecPin::ISet =>
|
|
"i_set".fmt(fmt),
|
|
TecPin::MaxIPos =>
|
|
"max_i_pos".fmt(fmt),
|
|
TecPin::MaxINeg =>
|
|
"max_i_neg".fmt(fmt),
|
|
TecPin::MaxV =>
|
|
"max_v".fmt(fmt),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn setup_shdn<G>(gpio: G) -> GpioOutput<G>
|
|
where
|
|
G: Gpio,
|
|
GpioOutput<G>: OutputPin,
|
|
{
|
|
let mut pin = gpio.into_output();
|
|
// keep off until first use
|
|
let _ = pin.set_low();
|
|
pin
|
|
}
|
|
|
|
fn setup_freq<G>(gpio: G)
|
|
where
|
|
G: Gpio,
|
|
GpioOutput<G>: OutputPin,
|
|
{
|
|
let mut pin = gpio.into_output();
|
|
// Switching Frequency Select
|
|
// high: 1 MHz, low: 500 kHz
|
|
let _ = pin.set_high();
|
|
}
|
|
|
|
/// Thermo-Electric Cooling device controlled through four PWM
|
|
/// channels
|
|
pub struct Tec<MaxIPos: PwmChannel, MaxINeg: PwmChannel, ISet: PwmChannel, MaxV: PwmChannel, SHDN: OutputPin> {
|
|
max_i_pos: MaxIPos,
|
|
max_i_neg: MaxINeg,
|
|
i_set: ISet,
|
|
max_v: MaxV,
|
|
shdn: SHDN,
|
|
}
|
|
|
|
impl Tec<pwm::T2CCP0, pwm::T2CCP1, pwm::T3CCP0, pwm::T3CCP1, GpioOutput<PP2>> {
|
|
pub fn tec0() -> Self {
|
|
let (max_i_pos, max_i_neg) = tm4c129x::TIMER2::split();
|
|
let (i_set, max_v) = tm4c129x::TIMER3::split();
|
|
let shdn = setup_shdn(PP2);
|
|
setup_freq(PK1);
|
|
Tec { max_i_pos, max_i_neg, i_set, max_v, shdn }
|
|
}
|
|
}
|
|
|
|
impl Tec<pwm::T4CCP0, pwm::T4CCP1, pwm::T5CCP0, pwm::T5CCP1, GpioOutput<PP3>> {
|
|
pub fn tec1() -> Self {
|
|
let (max_i_pos, max_i_neg) = tm4c129x::TIMER4::split();
|
|
let (i_set, max_v) = tm4c129x::TIMER5::split();
|
|
let shdn = setup_shdn(PP3);
|
|
setup_freq(PQ4);
|
|
Tec { max_i_pos, max_i_neg, i_set, max_v, shdn }
|
|
}
|
|
}
|
|
|
|
|
|
impl<MaxIPos: PwmChannel, MaxINeg: PwmChannel, ISet: PwmChannel, MaxV: PwmChannel, SHDN: OutputPin> Tec<MaxIPos, MaxINeg, ISet, MaxV, SHDN> {
|
|
pub fn setup(mut self, iset_width: u16, max: u16) -> Self {
|
|
self.max_i_pos.set(max, max);
|
|
self.max_i_neg.set(max, max);
|
|
self.max_v.set(max, max);
|
|
self.i_set.set(iset_width, max);
|
|
self
|
|
}
|
|
|
|
pub fn get(&mut self, pin: TecPin) -> (u16, u16) {
|
|
match pin {
|
|
TecPin::MaxIPos =>
|
|
self.max_i_pos.get(),
|
|
TecPin::MaxINeg =>
|
|
self.max_i_neg.get(),
|
|
TecPin::ISet =>
|
|
self.i_set.get(),
|
|
TecPin::MaxV =>
|
|
self.max_v.get(),
|
|
}
|
|
}
|
|
|
|
pub fn set(&mut self, pin: TecPin, width: u16, total: u16) {
|
|
match pin {
|
|
TecPin::MaxIPos =>
|
|
self.max_i_pos.set(width, total),
|
|
TecPin::MaxINeg =>
|
|
self.max_i_neg.set(width, total),
|
|
TecPin::ISet => {
|
|
self.i_set.set(width, total);
|
|
// enable on first use
|
|
let _ = self.shdn.set_high();
|
|
}
|
|
TecPin::MaxV =>
|
|
self.max_v.set(width, total),
|
|
}
|
|
}
|
|
}
|