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(gpio: G) -> GpioOutput where G: Gpio, GpioOutput: OutputPin, { let mut pin = gpio.into_output(); // keep off until first use let _ = pin.set_low(); pin } fn setup_freq(gpio: G) where G: Gpio, GpioOutput: 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 { max_i_pos: MaxIPos, max_i_neg: MaxINeg, i_set: ISet, max_v: MaxV, shdn: SHDN, } impl Tec> { 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> { 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 Tec { 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), } } }