kirdy/src/laser_diode/laser_diode.rs

140 lines
3.8 KiB
Rust
Raw Normal View History

use miniconf::Miniconf;
2024-01-24 12:11:35 +08:00
use stm32f4xx_hal::pac::ADC2;
2024-01-18 16:13:08 +08:00
use crate::laser_diode::ld_ctrl::LdCtrl;
2024-01-24 12:11:35 +08:00
use crate::laser_diode::analog_wdg::{LdAnalogWdg, self};
use core::{marker::PhantomData, f64::NAN};
use uom::si::{
2024-01-09 16:53:34 +08:00
electric_current::milliampere,
f64::{ElectricPotential, ElectricCurrent, Power},
};
use uom::{si::{ISQ, SI, Quantity}, typenum::*};
// Volt / Ampere
2024-01-09 16:53:34 +08:00
pub type TransimpedanceUnit = Quantity<ISQ<P2, P1, N3, N2, Z0, Z0, Z0>, SI<f64>, f64>;
// Ampere / Volt
2024-01-09 16:53:34 +08:00
type TransconductanceUnit = Quantity<ISQ<N2, N1, P3, P2, Z0, Z0, Z0>, SI<f64>, f64>;
// Watt / Ampere
2024-01-09 16:53:34 +08:00
pub type IToPowerUnit = Quantity<ISQ<P2, P1, N3, N1, Z0, Z0, Z0>, SI<f64>, f64>;
impl Settings{
pub const DAC_OUT_V_MAX: ElectricPotential = ElectricPotential {
dimension: PhantomData,
units: PhantomData,
value: 4.096,
};
// Unit: A/V
2024-01-09 16:53:34 +08:00
const PD_MON_TRANSCONDUCTANCE: TransconductanceUnit = TransconductanceUnit {
dimension: PhantomData,
units: PhantomData,
value: 0.001,
};
2024-01-09 16:53:34 +08:00
const LD_DRIVE_TRANSIMPEDANCE: TransimpedanceUnit = TransimpedanceUnit {
dimension: PhantomData,
units: PhantomData,
value: 10.0 / 0.75,
};
}
#[derive(Clone, Debug, Miniconf)]
pub struct Settings {
ld_drive_current: ElectricCurrent,
2024-01-11 12:51:08 +08:00
ld_drive_current_limit: ElectricCurrent,
2024-01-09 16:53:34 +08:00
pd_i_to_out_pwr: IToPowerUnit,
}
impl Default for Settings {
fn default() -> Self {
Self {
ld_drive_current: ElectricCurrent::new::<milliampere>(0.0),
2024-01-11 12:51:08 +08:00
ld_drive_current_limit: ElectricCurrent::new::<milliampere>(0.0),
2024-01-09 16:53:34 +08:00
pd_i_to_out_pwr: IToPowerUnit {dimension: PhantomData, units: PhantomData, value: NAN}
}
}
}
2024-01-09 16:53:34 +08:00
pub struct LdDrive{
2024-01-18 16:13:08 +08:00
ctrl: LdCtrl,
settings: Settings,
}
2024-01-09 16:53:34 +08:00
impl LdDrive{
2024-01-24 12:11:35 +08:00
pub fn new(current_source: LdCtrl, pins_adc: ADC2, phy: analog_wdg::LdAnalogWdgPhy)-> Self {
LdAnalogWdg::setup(pins_adc, phy);
2024-01-09 16:53:34 +08:00
LdDrive {
ctrl: current_source,
settings: Settings::default()
}
}
2024-01-09 16:13:42 +08:00
pub fn setup(&mut self) {
2024-01-24 12:11:35 +08:00
LdAnalogWdg::pwr_disengage();
2024-01-09 16:13:42 +08:00
self.ld_set_i(ElectricCurrent::new::<milliampere>(0.0));
self.ld_short();
}
pub fn get_ld_drive_current(&mut self) -> ElectricCurrent{
self.settings.ld_drive_current
}
2024-01-11 12:51:08 +08:00
pub fn set_ld_drive_current_limit(&mut self, i_limit: ElectricCurrent){
self.settings.ld_drive_current_limit = i_limit;
}
pub fn ld_short(&mut self) {
self.ctrl.ld_short_enable();
}
pub fn ld_open(&mut self) {
self.ctrl.ld_short_disable();
}
2024-01-24 12:11:35 +08:00
pub fn power_up(&mut self){
LdAnalogWdg::pwr_engage();
}
pub fn power_down(&mut self){
LdAnalogWdg::pwr_disengage();
}
pub fn get_pd_i(&mut self) -> ElectricCurrent {
2024-01-24 12:11:35 +08:00
LdAnalogWdg::get_pd_v() * Settings::PD_MON_TRANSCONDUCTANCE
}
pub fn ld_set_i(&mut self, i: ElectricCurrent) -> ElectricCurrent {
2024-01-11 12:51:08 +08:00
let ld_i_set = i.min(self.settings.ld_drive_current_limit);
let ld_i_set = self.ctrl.set_i(ld_i_set, Settings::LD_DRIVE_TRANSIMPEDANCE, Settings::DAC_OUT_V_MAX);
self.settings.ld_drive_current = ld_i_set;
ld_i_set
}
2024-01-24 12:11:35 +08:00
// Set the calibrated VDDA value obtained from ADC1 calibration
pub fn set_pd_mon_calibrated_vdda(val_cal: u32) {
LdAnalogWdg::set_calibrated_vdda(val_cal)
}
pub fn pd_mon_status() -> analog_wdg::AlarmStatus {
LdAnalogWdg::get_alarm_status()
}
pub fn pd_mon_clear_alarm(&mut self) {
LdAnalogWdg::clear_alarm_status();
}
pub fn pd_mon_engage(){
LdAnalogWdg::enable_watchdog_interrupt()
}
pub fn pd_mon_disengage(){
LdAnalogWdg::disable_watchdog_interrupt()
}
pub fn set_ld_power_limit(pwr_limit: Power){
// LdAnalogWdg::set_htr(convert pwr_limit to raw adc code)
unimplemented!()
}
}