use stm32f4xx_hal::{ adc::{ config::{self, AdcConfig}, Adc, }, gpio::{gpioa::*, gpiob::*, gpiod::*, Alternate, Output, PushPull, Analog, PD9}, hal::{blocking::spi::Transfer, digital::v2::OutputPin}, pac::{SPI2, ADC2}, spi::{NoMiso, Spi, TransferModeNormal}, }; use uom::si::{ ratio::ratio, electric_potential::millivolt, f64::{ElectricPotential, ElectricCurrent}, }; use crate::laser_diode::max5719::{self, Dac}; use crate::laser_diode::laser_diode::TransimpedanceUnit; pub trait ChannelPins { type PdMonPin; type CurrentSourceLdoEn: OutputPin; type CurrentSourceShort: OutputPin; type Max5719Load: OutputPin; type Max5719Cs: OutputPin; type Max5719Spi: Transfer; } pub struct LdCtrlPhy { pub dac: Dac, pub current_source_ldo_en_pin: C::CurrentSourceLdoEn, pub current_source_short_pin: C::CurrentSourceShort, pub pd_mon_pin : C::PdMonPin, } pub struct Channel0; impl ChannelPins for Channel0 { type PdMonPin = PA3; type CurrentSourceLdoEn = PD9>; type CurrentSourceShort = PA4>; type Max5719Load = DacLoad; type Max5719Cs = DacCs; type Max5719Spi = DacSpi; } type DacSpi = Spi>, NoMiso, PB15>), TransferModeNormal>; type DacCs = PD8>; type DacLoad = PB14>; pub struct LdCtrl{ pub phy: LdCtrlPhy, pub pins_adc: Adc } impl LdCtrl { pub fn new(phy_ch0: LdCtrlPhy, adc2: ADC2) -> Self { let config = AdcConfig::default() .clock(config::Clock::Pclk2_div_2) .default_sample_time(config::SampleTime::Cycles_480); let pins_adc = Adc::adc2(adc2, true, config); LdCtrl { phy: phy_ch0, pins_adc: pins_adc, } } pub fn power_up(&mut self) { self.phy.current_source_ldo_en_pin.set_high(); } #[deprecated(note= "To be removed when rev0_3 has arrived Rev0_2 has hardware connection bug for LD_EN. LD_EN will always be enabled.")] pub fn power_down(&mut self) { self.phy.current_source_ldo_en_pin.set_low(); } // 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_pd_mon_v(&mut self) -> ElectricPotential{ let sample = self.pins_adc.convert( &self.phy.pd_mon_pin, stm32f4xx_hal::adc::config::SampleTime::Cycles_480, ); let mv = self.pins_adc.sample_to_millivolts(sample as u16); ElectricPotential::new::(mv as f64) } 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 f64)) as u32; self.phy.dac.set(value).unwrap(); voltage } pub fn set_i(&mut self, current: ElectricCurrent, transimpedance: TransimpedanceUnit, dac_out_v_max: ElectricPotential) -> ElectricCurrent { self.set_dac(current * transimpedance, dac_out_v_max) / transimpedance } }