use serde::{Deserialize, Serialize}; use stm32f4xx_hal::{ gpio::{gpioa::*, gpiob::*, gpiod::*, Input, Output, PushPull}, hal::{spi::SpiBus, digital::{OutputPin, InputPin}}, pac::SPI2, spi::Spi, }; use uom::si::{ ratio::ratio, f32::{ElectricPotential, ElectricCurrent}, electric_current::ampere, }; use crate::laser_diode::max5719::{self, Dac}; use crate::laser_diode::laser_diode::TransimpedanceUnit; #[derive(Deserialize, Serialize, Debug, Clone, Copy)] pub enum Impedance { Is50Ohm, Not50Ohm, } pub trait ChannelPins { type CurrentSourceShort: OutputPin; type TerminationStatus: InputPin; type Max5719Load: OutputPin; type Max5719Cs: OutputPin; type Max5719Spi: SpiBus; } pub struct LdCtrlPhy { pub dac: Dac, pub current_source_short_pin: C::CurrentSourceShort, pub termination_status_pin: C::TerminationStatus } pub struct Channel0; impl ChannelPins for Channel0 { type CurrentSourceShort = PA4>; type TerminationStatus = PD7; type Max5719Load = DacLoad; type Max5719Cs = DacCs; type Max5719Spi = DacSpi; } type DacSpi = Spi; type DacCs = PD8>; type DacLoad = PB14>; pub struct LdCtrl{ pub phy: LdCtrlPhy, i_set: ElectricCurrent, } impl LdCtrl { pub fn new(phy_ch0: LdCtrlPhy) -> Self { LdCtrl { phy: phy_ch0, i_set: ElectricCurrent::new::(0.0) } } // LD Terminals are shorted together pub fn ld_short_enable(&mut self) { self.phy.current_source_short_pin.set_low(); } // LD Current flows from anode to cathode pub fn ld_short_disable(&mut self) { self.phy.current_source_short_pin.set_high(); } pub fn get_lf_mod_in_impedance(&mut self)-> Impedance { if self.phy.termination_status_pin.is_high() { Impedance::Is50Ohm } else { Impedance::Not50Ohm } } pub fn set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential { let value = ((voltage / dac_out_v_max).get::() * (max5719::MAX_VALUE as f32)) as u32; self.phy.dac.set(value).unwrap(); value as f32 * dac_out_v_max / max5719::MAX_VALUE as f32 } pub fn set_i(&mut self, current: ElectricCurrent, transimpedance: TransimpedanceUnit, dac_out_v_max: ElectricPotential) -> ElectricCurrent { self.i_set = self.set_dac(current * transimpedance, dac_out_v_max) / transimpedance; self.i_set } pub fn get_i_set(&mut self) -> ElectricCurrent{ self.i_set } }