diff --git a/pykirdy/driver/kirdy_async.py b/pykirdy/driver/kirdy_async.py index b081bc1..6260685 100644 --- a/pykirdy/driver/kirdy_async.py +++ b/pykirdy/driver/kirdy_async.py @@ -132,6 +132,22 @@ class Device: """ return await self._send_cmd(TARGET_DEVICE, "SetActiveReportMode", on) + async def set_pd_mon_fin_gain(self, gain): + """ + Configure the photodiode monitor transconductance + - gain: unitless + """ + print("set_pd_mon_fin_gain") + return await self._send_cmd(TARGET_DEVICE, "SetPdFinGain", gain) + + async def set_pd_mon_transconductance(self, transconductance): + """ + Configure the photodiode monitor transconductance + - transconductance: 1/Ohm + """ + print("set_pd_mon_transconductance") + return await self._send_cmd(TARGET_DEVICE, "SetPdTransconductance", transconductance) + async def get_status_report(self): """ Get status of all peripherals in a json object @@ -541,6 +557,8 @@ class Kirdy: self._cmd_list = { TARGET_DEVICE: { "SetIPSettings": IP_SETTINGS, + "SetPdFinGain": DATA_F32, + "SetPdTransconductance": DATA_F32, "SetActiveReportMode": DATA_BOOL, "GetStatusReport": None, "GetSettingsSummary": None, diff --git a/src/laser_diode/laser_diode.rs b/src/laser_diode/laser_diode.rs index 81a64ca..b91fd46 100644 --- a/src/laser_diode/laser_diode.rs +++ b/src/laser_diode/laser_diode.rs @@ -1,14 +1,13 @@ use core::marker::PhantomData; +use log::info; use miniconf::Tree; use serde::{Deserialize, Serialize}; use stm32f4xx_hal::{pac::{ADC3, TIM2}, timer::CounterUs}; -use uom::{si::{electric_current::{ampere, milliampere}, - f32::{ElectricCurrent, ElectricPotential, Power}, - power::milliwatt, - Quantity, ISQ, SI}, - typenum::*}; +use uom::si::{electric_current::{ampere, milliampere}, + f32::{ElectricCurrent, ElectricPotential, ElectricalConductance, ElectricalResistance, Power}, + power::milliwatt}; use crate::{device::sys_timer::sleep, laser_diode::{ld_ctrl::{Impedance, LdCtrl}, @@ -16,11 +15,6 @@ use crate::{device::sys_timer::sleep, ld_pwr_exc_protector::{self, LdPwrExcProtector}, pd_mon_params}}; -// Volt / Ampere -pub type TransimpedanceUnit = Quantity, SI, f32>; -// Ampere / Volt -type TransconductanceUnit = Quantity, SI, f32>; - impl Settings { pub const LD_CURRENT_MAX: ElectricCurrent = ElectricCurrent { dimension: PhantomData, @@ -33,14 +27,7 @@ impl Settings { value: 4.096, }; - // Unit: A/V - const PD_MON_TRANSCONDUCTANCE: TransconductanceUnit = TransconductanceUnit { - dimension: PhantomData, - units: PhantomData, - value: 0.001, - }; - - const LD_DRIVE_TRANSIMPEDANCE: TransimpedanceUnit = TransimpedanceUnit { + const LD_DRIVE_TRANSIMPEDANCE: ElectricalResistance = ElectricalResistance { dimension: PhantomData, units: PhantomData, value: 10.0 / 0.75, @@ -152,13 +139,17 @@ impl LdDrive { } pub fn get_pd_i(&mut self) -> ElectricCurrent { - LdPwrExcProtector::get_status().v * Settings::PD_MON_TRANSCONDUCTANCE + self.settings + .pd_mon_params + .get_pd_i_from_pd_v(LdPwrExcProtector::get_status().v) } pub fn get_pd_pwr(&mut self) -> Power { - self.settings - .pd_mon_params - .get_ld_pwr_from_ld_i(LdPwrExcProtector::get_status().v * Settings::PD_MON_TRANSCONDUCTANCE) + self.settings.pd_mon_params.get_ld_pwr_from_ld_i( + self.settings + .pd_mon_params + .get_pd_i_from_pd_v(LdPwrExcProtector::get_status().v), + ) } pub fn ld_set_i(&mut self, i: ElectricCurrent) { @@ -188,6 +179,10 @@ impl LdDrive { LdPwrExcProtector::clear_alarm_status(); } + pub fn set_pd_transconductance(&mut self, transconductance: ElectricalConductance) { + self.settings.pd_mon_params.set_transconductance(transconductance) + } + pub fn set_pd_responsitivity(&mut self, responsitivity: pd_mon_params::ResponsitivityUnit) { self.settings.pd_mon_params.set(responsitivity); } @@ -198,13 +193,13 @@ impl LdDrive { pub fn set_ld_power_limit(&mut self, pwr_limit: Power) { LdPwrExcProtector::set_trigger_threshold_v( - self.settings.pd_mon_params.get_ld_i_from_ld_pwr(pwr_limit) / Settings::PD_MON_TRANSCONDUCTANCE, + self.settings.pd_mon_params.get_pd_i_from_ld_pwr(pwr_limit) / self.settings.pd_mon_params.transconductance, ); self.settings.ld_pwr_limit = pwr_limit; } pub fn set_pd_i_limit(&mut self, i: ElectricCurrent) { - LdPwrExcProtector::set_trigger_threshold_v(i / Settings::PD_MON_TRANSCONDUCTANCE); + LdPwrExcProtector::set_trigger_threshold_v(i / self.settings.pd_mon_params.transconductance); } pub fn set_default_pwr_on(&mut self, pwr_on: bool) { diff --git a/src/laser_diode/ld_ctrl.rs b/src/laser_diode/ld_ctrl.rs index 788a5e6..270ce55 100644 --- a/src/laser_diode/ld_ctrl.rs +++ b/src/laser_diode/ld_ctrl.rs @@ -5,11 +5,10 @@ use stm32f4xx_hal::{gpio::{gpioa::*, gpiob::*, gpiod::*, Input, Output, PushPull pac::SPI2, spi::Spi}; use uom::si::{electric_current::ampere, - f32::{ElectricCurrent, ElectricPotential}, + f32::{ElectricCurrent, ElectricPotential, ElectricalResistance}, ratio::ratio}; -use crate::laser_diode::{laser_diode::TransimpedanceUnit, - max5719::{self, Dac}}; +use crate::laser_diode::max5719::{self, Dac}; #[derive(Deserialize, Serialize, Debug, Clone, Copy)] pub enum Impedance { @@ -84,7 +83,7 @@ impl LdCtrl { pub fn set_i( &mut self, current: ElectricCurrent, - transimpedance: TransimpedanceUnit, + transimpedance: ElectricalResistance, dac_out_v_max: ElectricPotential, ) -> ElectricCurrent { self.i_set = self.set_dac(current * transimpedance, dac_out_v_max) / transimpedance; diff --git a/src/laser_diode/pd_mon_params.rs b/src/laser_diode/pd_mon_params.rs index 3d576e6..12ffd9a 100644 --- a/src/laser_diode/pd_mon_params.rs +++ b/src/laser_diode/pd_mon_params.rs @@ -1,9 +1,10 @@ use core::{f32::NAN, marker::PhantomData}; use miniconf::Tree; +use num_traits::Zero; use serde::{Deserialize, Serialize}; use uom::{si::{electric_current::microampere, - f32::{ElectricCurrent, Power}, + f32::{ElectricCurrent, ElectricPotential, ElectricalConductance, Power}, Quantity, ISQ, SI}, typenum::*}; @@ -12,6 +13,7 @@ pub type ResponsitivityUnit = Quantity, SI, #[derive(Deserialize, Serialize, Clone, Copy, Debug, PartialEq, Tree)] pub struct Parameters { + pub transconductance: ElectricalConductance, responsitivity: ResponsitivityUnit, i_dark: ElectricCurrent, } @@ -22,11 +24,15 @@ impl Parameters { ld_power } - pub fn get_ld_i_from_ld_pwr(&self, pwr: Power) -> ElectricCurrent { + pub fn get_pd_i_from_ld_pwr(&self, pwr: Power) -> ElectricCurrent { let ld_i = pwr * self.responsitivity + self.i_dark; ld_i } + pub fn get_pd_i_from_pd_v(&self, v: ElectricPotential) -> ElectricCurrent { + (v * self.transconductance).max(ElectricCurrent::zero()) + } + pub fn set(&mut self, responsitivity: ResponsitivityUnit) { self.responsitivity = responsitivity; } @@ -34,11 +40,20 @@ impl Parameters { pub fn set_i_dark(&mut self, i_dark: ElectricCurrent) { self.i_dark = i_dark; } + + pub fn set_transconductance(&mut self, transconductance: ElectricalConductance) { + self.transconductance = transconductance; + } } impl Default for Parameters { fn default() -> Self { Parameters { + transconductance: ElectricalConductance { + dimension: PhantomData, + units: PhantomData, + value: 1.0 / 1000.0, + }, responsitivity: ResponsitivityUnit { dimension: PhantomData, units: PhantomData, diff --git a/src/main.rs b/src/main.rs index fd6fe87..dee2807 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ #![cfg_attr(not(test), no_main)] #![cfg_attr(not(test), no_std)] +use core::marker::PhantomData; + use cortex_m_rt::entry; use log::{debug, info}; use stm32f4xx_hal::pac::{CorePeripherals, Peripherals}; +use uom::si::f32::ElectricalConductance; mod device; mod laser_diode; mod net; @@ -35,6 +38,8 @@ static mut ETH_DATA_BUFFER: [u8; 1024] = [0; 1024]; #[derive(Deserialize, Serialize, Clone, Copy, Debug)] pub struct DeviceSettings { ip_settings: IpSettings, + pd_mon_fin_gain: f32, + pd_mon_transconductance: ElectricalConductance, } const CONFIG_KEY: [&str; 3] = ["Device", "Laser_0", "Thermostat_0"]; @@ -63,6 +68,12 @@ fn main() -> ! { let mut device_settings = DeviceSettings { ip_settings: IpSettings::default(), + pd_mon_fin_gain: 1.0, + pd_mon_transconductance: ElectricalConductance { + dimension: PhantomData, + units: PhantomData, + value: 1.0 / 1000.0, + }, }; let mut active_report: [bool; net::net::NUM_OF_SOCKETS] = [false; net::net::NUM_OF_SOCKETS]; @@ -88,6 +99,7 @@ fn main() -> ! { match flash_store.read_value(CONFIG_KEY[0]) { Ok(Some(config)) => { device_settings_flash = config; + laser.set_pd_transconductance(config.pd_mon_fin_gain * config.pd_mon_transconductance); debug!("Found Device Settings"); } Ok(None) => { diff --git a/src/net/cmd_handler.rs b/src/net/cmd_handler.rs index 455a59b..9a1da1a 100644 --- a/src/net/cmd_handler.rs +++ b/src/net/cmd_handler.rs @@ -6,13 +6,14 @@ use serde::{Deserialize, Serialize}; use smoltcp::iface::SocketHandle; use uom::si::{electric_current::{ampere, ElectricCurrent}, electric_potential::{volt, ElectricPotential}, + electrical_conductance::{siemens, ElectricalConductance}, electrical_resistance::{ohm, ElectricalResistance}, power::{watt, Power}, thermodynamic_temperature::{degree_celsius, ThermodynamicTemperature}}; use crate::{device::{dfu, sys_timer}, laser_diode::{laser_diode::{LdDrive, LdSettingsSummary, StatusReport as LdStatusReport}, - pd_mon_params::ResponsitivityUnit}, + pd_mon_params::{self, ResponsitivityUnit}}, net::net, thermostat::{ad7172::FilterType, pid_state::PidSettings::*, @@ -61,6 +62,8 @@ enum DeviceCmd { Reserved, SetIPSettings, SetActiveReportMode, + SetPdFinGain, + SetPdTransconductance, GetStatusReport, GetSettingsSummary, Dfu, @@ -311,6 +314,42 @@ pub fn execute_cmd( ); } }, + Some(DeviceCmd::SetPdFinGain) => match cmd.json.data_f32 { + Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); + device_settings.pd_mon_fin_gain = val; + laser.set_pd_transconductance( + device_settings.pd_mon_fin_gain * device_settings.pd_mon_transconductance, + ); + *state = State::SaveDeviceSettings; + } + None => { + send_response( + buffer, + ResponseEnum::InvalidDatatype, + Some(ERR_MSG_MISSING_DATA_F32), + socket, + ); + } + }, + Some(DeviceCmd::SetPdTransconductance) => match cmd.json.data_f32 { + Some(val) => { + send_response(buffer, ResponseEnum::Acknowledge, None, socket); + device_settings.pd_mon_transconductance = ElectricalConductance::new::(val); + laser.set_pd_transconductance( + device_settings.pd_mon_fin_gain * device_settings.pd_mon_transconductance, + ); + *state = State::SaveDeviceSettings; + } + None => { + send_response( + buffer, + ResponseEnum::InvalidDatatype, + Some(ERR_MSG_MISSING_DATA_F32), + socket, + ); + } + }, Some(DeviceCmd::GetStatusReport) => { send_status_report(buffer, laser, thermostat, socket); }