forked from M-Labs/kirdy
Rename Analog_Wdg -> LdPwrExcProtector
This commit is contained in:
parent
9ae867cd88
commit
f50505feaf
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -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;
|
Loading…
Reference in New Issue