103 lines
3.1 KiB
Rust
103 lines
3.1 KiB
Rust
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,
|
|
f64::{ElectricPotential, ElectricCurrent},
|
|
};
|
|
|
|
use crate::laser_diode::max5719::{self, Dac};
|
|
use crate::laser_diode::ld_drive::transimpedance_unit;
|
|
|
|
pub trait ChannelPins {
|
|
type PdMonPin;
|
|
type CurrentSourceLdoEn: OutputPin;
|
|
type CurrentSourceShort: OutputPin;
|
|
type Max5719Load: OutputPin;
|
|
type Max5719Cs: OutputPin;
|
|
type Max5719Spi: Transfer<u8>;
|
|
}
|
|
|
|
pub struct CurrentSourcePhy<C: ChannelPins> {
|
|
pub dac: Dac<C::Max5719Spi, C::Max5719Cs, C::Max5719Load>,
|
|
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<Analog>;
|
|
type CurrentSourceLdoEn = PD9<Output<PushPull>>;
|
|
type CurrentSourceShort = PA4<Output<PushPull>>;
|
|
type Max5719Load = DacLoad;
|
|
type Max5719Cs = DacCs;
|
|
type Max5719Spi = DacSpi;
|
|
}
|
|
|
|
type DacSpi = Spi<SPI2, (PB10<Alternate<5>>, NoMiso, PB15<Alternate<5>>), TransferModeNormal>;
|
|
type DacCs = PD8<Output<PushPull>>;
|
|
type DacLoad = PB14<Output<PushPull>>;
|
|
|
|
|
|
pub struct CurrentSource{
|
|
pub phy: CurrentSourcePhy<Channel0>,
|
|
pub pins_adc: Adc<ADC2>
|
|
}
|
|
|
|
impl CurrentSource {
|
|
pub fn new(phy_ch0: CurrentSourcePhy<Channel0>, 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);
|
|
|
|
CurrentSource {
|
|
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 set_dac(&mut self, voltage: ElectricPotential, dac_out_v_max: ElectricPotential) -> ElectricPotential {
|
|
let value = ((voltage / dac_out_v_max).get::<ratio>()
|
|
* (max5719::MAX_VALUE as f64)) as u32;
|
|
self.phy.dac.set(value).unwrap();
|
|
voltage
|
|
}
|
|
|
|
pub fn set_i(&mut self, current: ElectricCurrent, transimpedance: transimpedance_unit, dac_out_v_max: ElectricPotential) -> ElectricCurrent {
|
|
let v = current * transimpedance;
|
|
self.set_dac(current * transimpedance, dac_out_v_max) / transimpedance
|
|
}
|
|
} |