Rename Analog_Wdg -> LdPwrExcProtector

This commit is contained in:
linuswck 2024-01-26 11:43:53 +08:00
parent 9ae867cd88
commit f50505feaf
4 changed files with 49 additions and 48 deletions

View File

@ -1,6 +1,6 @@
use crate::laser_diode::ld_ctrl::{self, LdCtrlPhy}; use crate::laser_diode::ld_ctrl::{self, LdCtrlPhy};
use crate::laser_diode::max5719; use crate::laser_diode::max5719;
use crate::laser_diode::analog_wdg::LdAnalogWdgPhy; use crate::laser_diode::ld_pwr_exc_protector::LdPwrExcProtectorPhy;
use crate::thermostat::ad5680; use crate::thermostat::ad5680;
use crate::thermostat::max1968::{self, MAX1968PinSet, MAX1968Phy, PWM_FREQ_KHZ}; use crate::thermostat::max1968::{self, MAX1968PinSet, MAX1968Phy, PWM_FREQ_KHZ};
use crate::thermostat::ad7172; use crate::thermostat::ad7172;
@ -40,7 +40,7 @@ pub fn setup(
LdCtrlPhy<ld_ctrl::Channel0>, LdCtrlPhy<ld_ctrl::Channel0>,
ad7172::AdcPhy, ad7172::AdcPhy,
MAX1968Phy<max1968::Channel0>, MAX1968Phy<max1968::Channel0>,
LdAnalogWdgPhy LdPwrExcProtectorPhy
) { ) {
let gpioa = gpioa.split(); let gpioa = gpioa.split();
let gpiob = gpiob.split(); let gpiob = gpiob.split();
@ -84,7 +84,7 @@ pub fn setup(
current_source_short_pin: gpioa.pa4.into_push_pull_output(), current_source_short_pin: gpioa.pa4.into_push_pull_output(),
}; };
let pd_mon_phy = LdAnalogWdgPhy { let pd_mon_phy = LdPwrExcProtectorPhy {
_pd_mon_ch0: gpioa.pa3.into_analog(), _pd_mon_ch0: gpioa.pa3.into_analog(),
pwr_en_ch0: gpiod.pd9.into_push_pull_output(), pwr_en_ch0: gpiod.pd9.into_push_pull_output(),
}; };

View File

@ -1,7 +1,7 @@
use miniconf::Miniconf; use miniconf::Miniconf;
use stm32f4xx_hal::pac::ADC2; use stm32f4xx_hal::pac::ADC2;
use crate::laser_diode::ld_ctrl::LdCtrl; use crate::laser_diode::ld_ctrl::LdCtrl;
use crate::laser_diode::analog_wdg::{LdAnalogWdg, self}; use crate::laser_diode::ld_pwr_exc_protector::{LdPwrExcProtector, self};
use core::{marker::PhantomData, f64::NAN}; use core::{marker::PhantomData, f64::NAN};
use uom::si::{ use uom::si::{
@ -62,8 +62,8 @@ pub struct LdDrive{
} }
impl LdDrive{ impl LdDrive{
pub fn new(current_source: LdCtrl, pins_adc: ADC2, phy: analog_wdg::LdAnalogWdgPhy)-> Self { pub fn new(current_source: LdCtrl, pins_adc: ADC2, phy: ld_pwr_exc_protector::LdPwrExcProtectorPhy)-> Self {
LdAnalogWdg::setup(pins_adc, phy); LdPwrExcProtector::setup(pins_adc, phy);
LdDrive { LdDrive {
ctrl: current_source, ctrl: current_source,
@ -72,7 +72,7 @@ impl LdDrive{
} }
pub fn setup(&mut self) { pub fn setup(&mut self) {
LdAnalogWdg::pwr_off(); LdPwrExcProtector::pwr_off();
self.ld_set_i(ElectricCurrent::new::<milliampere>(0.0)); self.ld_set_i(ElectricCurrent::new::<milliampere>(0.0));
self.ld_short(); self.ld_short();
} }
@ -94,15 +94,15 @@ impl LdDrive{
} }
pub fn power_up(&mut self){ pub fn power_up(&mut self){
LdAnalogWdg::pwr_on_and_arm_protection(); LdPwrExcProtector::pwr_on_and_arm_protection();
} }
pub fn power_down(&mut self){ pub fn power_down(&mut self){
LdAnalogWdg::pwr_off(); LdPwrExcProtector::pwr_off();
} }
pub fn get_pd_i(&mut self) -> ElectricCurrent { pub fn get_pd_i(&mut self) -> ElectricCurrent {
LdAnalogWdg::get_status().v * Settings::PD_MON_TRANSCONDUCTANCE LdPwrExcProtector::get_status().v * Settings::PD_MON_TRANSCONDUCTANCE
} }
pub fn ld_set_i(&mut self, i: ElectricCurrent) -> ElectricCurrent { pub fn ld_set_i(&mut self, i: ElectricCurrent) -> ElectricCurrent {
@ -114,27 +114,27 @@ impl LdDrive{
// Set the calibrated VDDA value obtained from ADC1 calibration // Set the calibrated VDDA value obtained from ADC1 calibration
pub fn set_pd_mon_calibrated_vdda(&mut self, val_cal: u32) { pub fn set_pd_mon_calibrated_vdda(&mut self, val_cal: u32) {
LdAnalogWdg::set_calibrated_vdda(val_cal) LdPwrExcProtector::set_calibrated_vdda(val_cal)
} }
pub fn pd_mon_status(&mut self) -> analog_wdg::Status { pub fn pd_mon_status(&mut self) -> ld_pwr_exc_protector::Status {
LdAnalogWdg::get_status() LdPwrExcProtector::get_status()
} }
pub fn pd_mon_clear_alarm(&mut self) { pub fn pd_mon_clear_alarm(&mut self) {
LdAnalogWdg::clear_alarm_status(); LdPwrExcProtector::clear_alarm_status();
} }
pub fn set_ld_power_limit(&mut self, pwr_limit: Power){ pub fn set_ld_power_limit(&mut self, pwr_limit: Power){
// LdAnalogWdg::set_trigger_threshold_v(convert pwr_limit to raw adc code) // LdPwrExcProtector::set_trigger_threshold_v(convert pwr_limit to raw adc code)
unimplemented!() unimplemented!()
} }
pub fn set_pd_i_limit(&mut self, i: ElectricCurrent){ pub fn set_pd_i_limit(&mut self, i: ElectricCurrent){
LdAnalogWdg::set_trigger_threshold_v(i / Settings::PD_MON_TRANSCONDUCTANCE); LdPwrExcProtector::set_trigger_threshold_v(i / Settings::PD_MON_TRANSCONDUCTANCE);
} }
pub fn set_pd_v_limit(&mut self, v: ElectricPotential){ pub fn set_pd_v_limit(&mut self, v: ElectricPotential){
LdAnalogWdg::set_trigger_threshold_v(v); LdPwrExcProtector::set_trigger_threshold_v(v);
} }
} }

View File

@ -18,9 +18,9 @@ pub type LdPwrEnPinType = PD9<Output<PushPull>>;
pub type PdMonAdcPinType = PA3<Analog>; pub type PdMonAdcPinType = PA3<Analog>;
const PD_MON_ADC_CH_ID: u8 = 0x03; const PD_MON_ADC_CH_ID: u8 = 0x03;
static mut ANALOG_WDG: Option<LdAnalogWdg> = None; static mut LD_PWR_EXC_PROTECTOR: Option<LdPwrExcProtector> = None;
pub struct LdAnalogWdgPhy { pub struct LdPwrExcProtectorPhy {
// To make sure Pd Mon Pin is configured to Analog mode // To make sure Pd Mon Pin is configured to Analog mode
pub _pd_mon_ch0: PdMonAdcPinType, pub _pd_mon_ch0: PdMonAdcPinType,
pub pwr_en_ch0: LdPwrEnPinType, pub pwr_en_ch0: LdPwrEnPinType,
@ -44,20 +44,21 @@ impl Default for Status {
} }
} }
} }
// power excursion protection
pub struct LdAnalogWdg { // LdPwrExcProtector
pub struct LdPwrExcProtector {
pac: ADC2, pac: ADC2,
phy: LdAnalogWdgPhy, phy: LdPwrExcProtectorPhy,
alarm_status: Status, alarm_status: Status,
//Calibrated VDDA in millivolt from Adc<ADC1>.calibrate() //Calibrated VDDA in millivolt from Adc<ADC1>.calibrate()
calibrated_vdda: u32, calibrated_vdda: u32,
} }
impl LdAnalogWdg { impl LdPwrExcProtector {
/// ADC Analog Watchdog is configured to guard a single regular Adc channel on Pd Mon Pin. /// ADC Analog Watchdog is configured to guard a single regular Adc channel on Pd Mon Pin.
/// ADC is configured to start continuous conversion without using DMA immediately. /// ADC is configured to start continuous conversion without using DMA immediately.
/// Interrupt is disabled by default. /// Interrupt is disabled by default.
pub fn setup(pac_adc: ADC2, mut phy: LdAnalogWdgPhy){ pub fn setup(pac_adc: ADC2, mut phy: LdPwrExcProtectorPhy){
unsafe { unsafe {
// All ADCs share the same reset interface. // All ADCs share the same reset interface.
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects. // NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
@ -120,8 +121,8 @@ impl LdAnalogWdg {
phy.pwr_en_ch0.set_low(); phy.pwr_en_ch0.set_low();
unsafe { unsafe {
ANALOG_WDG = Some( LD_PWR_EXC_PROTECTOR = Some(
LdAnalogWdg { LdPwrExcProtector {
pac: pac_adc, pac: pac_adc,
phy: phy, phy: phy,
alarm_status: Status::default(), alarm_status: Status::default(),
@ -132,18 +133,18 @@ impl LdAnalogWdg {
} }
fn get() -> Option<&'static mut Self> { fn get() -> Option<&'static mut Self> {
unsafe { ANALOG_WDG.as_mut() } unsafe { LD_PWR_EXC_PROTECTOR.as_mut() }
} }
fn convert_sample_to_volt(sample :u16) -> ElectricPotential { fn convert_sample_to_volt(sample :u16) -> ElectricPotential {
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
return ElectricPotential::new::<millivolt>(((u32::from(sample) * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE)) as f64) return ElectricPotential::new::<millivolt>(((u32::from(sample) * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE)) as f64)
} }
ElectricPotential::new::<millivolt>(0.0) ElectricPotential::new::<millivolt>(0.0)
} }
pub fn set_trigger_threshold_v(htr: ElectricPotential){ pub fn set_trigger_threshold_v(htr: ElectricPotential){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
let code: u32 = ((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f64))).get::<ratio>() * (MAX_SAMPLE as f64)) as u32; let code: u32 = ((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f64))).get::<ratio>() * (MAX_SAMPLE as f64)) as u32;
wdg.pac.htr.write(|w| unsafe {w.bits(code)}); wdg.pac.htr.write(|w| unsafe {w.bits(code)});
info!("trigger_threshold_v: {:?}", code); info!("trigger_threshold_v: {:?}", code);
@ -151,38 +152,38 @@ impl LdAnalogWdg {
} }
pub fn set_calibrated_vdda(val: u32) { pub fn set_calibrated_vdda(val: u32) {
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.calibrated_vdda = val; wdg.calibrated_vdda = val;
} }
} }
pub fn get_status() -> Status { pub fn get_status() -> Status {
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.alarm_status.v = LdAnalogWdg::convert_sample_to_volt(wdg.pac.dr.read().data().bits()); wdg.alarm_status.v = LdPwrExcProtector::convert_sample_to_volt(wdg.pac.dr.read().data().bits());
return wdg.alarm_status.clone() return wdg.alarm_status.clone()
} }
Status::default() Status::default()
} }
pub fn pwr_on_and_arm_protection(){ pub fn pwr_on_and_arm_protection(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.alarm_status = Status::default(); wdg.alarm_status = Status::default();
LdAnalogWdg::pwr_on(); LdPwrExcProtector::pwr_on();
// Interrupt should be enabled after power on to tackle the following edge case: // Interrupt should be enabled after power on to tackle the following edge case:
// Pd_Mon pin voltage has already exceed threshold before LD Power is on. // Pd_Mon pin voltage has already exceed threshold before LD Power is on.
LdAnalogWdg::enable_watchdog_interrupt(); LdPwrExcProtector::enable_watchdog_interrupt();
} }
} }
pub fn clear_alarm_status(){ pub fn clear_alarm_status(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.alarm_status.pwr_excursion = false; wdg.alarm_status.pwr_excursion = false;
wdg.alarm_status.v_tripped = ElectricPotential::new::<millivolt>(0.0); wdg.alarm_status.v_tripped = ElectricPotential::new::<millivolt>(0.0);
} }
} }
fn enable_watchdog_interrupt(){ fn enable_watchdog_interrupt(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.pac.cr1.modify(|_, w| w wdg.pac.cr1.modify(|_, w| w
.awdie().set_bit() .awdie().set_bit()
); );
@ -190,7 +191,7 @@ impl LdAnalogWdg {
} }
fn disable_watchdog_interrupt(){ fn disable_watchdog_interrupt(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.pac.cr1.modify(|_, w| w wdg.pac.cr1.modify(|_, w| w
.awdie().clear_bit() .awdie().clear_bit()
); );
@ -198,7 +199,7 @@ impl LdAnalogWdg {
} }
fn clear_interrupt_bit(){ fn clear_interrupt_bit(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.pac.sr.modify(|_, w| w wdg.pac.sr.modify(|_, w| w
.awd().clear_bit() .awd().clear_bit()
); );
@ -206,25 +207,25 @@ impl LdAnalogWdg {
} }
fn pwr_on(){ fn pwr_on(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.alarm_status.pwr_engaged = true; wdg.alarm_status.pwr_engaged = true;
wdg.phy.pwr_en_ch0.set_high() wdg.phy.pwr_en_ch0.set_high()
} }
} }
pub fn pwr_off(){ pub fn pwr_off(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
wdg.alarm_status.pwr_engaged = false; wdg.alarm_status.pwr_engaged = false;
wdg.phy.pwr_en_ch0.set_low() wdg.phy.pwr_en_ch0.set_low()
} }
} }
fn power_excursion_handler(){ fn power_excursion_handler(){
if let Some(ref mut wdg ) = LdAnalogWdg::get() { if let Some(ref mut wdg ) = LdPwrExcProtector::get() {
let sample = wdg.pac.dr.read().data().bits(); let sample = wdg.pac.dr.read().data().bits();
LdAnalogWdg::pwr_off(); LdPwrExcProtector::pwr_off();
wdg.alarm_status.pwr_excursion = true; wdg.alarm_status.pwr_excursion = true;
wdg.alarm_status.v_tripped = LdAnalogWdg::convert_sample_to_volt(sample); wdg.alarm_status.v_tripped = LdPwrExcProtector::convert_sample_to_volt(sample);
} }
} }
} }
@ -232,10 +233,10 @@ impl LdAnalogWdg {
#[interrupt] #[interrupt]
fn ADC(){ fn ADC(){
cortex_m::interrupt::free(|_| { cortex_m::interrupt::free(|_| {
LdAnalogWdg::power_excursion_handler(); LdPwrExcProtector::power_excursion_handler();
// Disable interrupt to avoid getting stuck in infinite interrupt loop // Disable interrupt to avoid getting stuck in infinite interrupt loop
LdAnalogWdg::disable_watchdog_interrupt(); LdPwrExcProtector::disable_watchdog_interrupt();
LdAnalogWdg::clear_interrupt_bit(); LdPwrExcProtector::clear_interrupt_bit();
} }
) )
} }

View File

@ -2,4 +2,4 @@ pub mod ld_ctrl;
pub mod max5719; pub mod max5719;
pub mod laser_diode; pub mod laser_diode;
pub mod pd_mon; pub mod pd_mon;
pub mod analog_wdg; pub mod ld_pwr_exc_protector;