ld_pwr_exc_protector: cal volt offset for pd mon

- hw change: A voltage offset is added onto the pd mon pin
This commit is contained in:
linuswck 2024-06-12 18:16:44 +08:00
parent f35546b070
commit d1660c6090
1 changed files with 26 additions and 5 deletions

View File

@ -1,6 +1,8 @@
use stm32f4xx_hal::{gpio::{gpioa::PA3, gpiod::PD9, Analog, Output, PushPull}, use stm32f4xx_hal::{adc::{config::{self, AdcConfig},
Adc},
gpio::{gpioa::PA3, gpiod::PD9, Analog, Output, PushPull},
interrupt, pac, interrupt, pac,
pac::{ADC3, NVIC}, pac::{Peripherals, ADC3, NVIC},
rcc::Enable}; rcc::Enable};
use uom::si::{electric_potential::millivolt, f32::ElectricPotential, ratio::ratio}; use uom::si::{electric_potential::millivolt, f32::ElectricPotential, ratio::ratio};
@ -42,6 +44,7 @@ pub struct LdPwrExcProtector {
phy: LdPwrExcProtectorPhy, phy: LdPwrExcProtectorPhy,
alarm_status: Status, alarm_status: Status,
calibrated_vdda: u32, calibrated_vdda: u32,
offset: u32,
} }
impl LdPwrExcProtector { impl LdPwrExcProtector {
@ -49,6 +52,20 @@ impl LdPwrExcProtector {
/// 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: ADC3, mut phy: LdPwrExcProtectorPhy) { pub fn setup(pac_adc: ADC3, mut phy: LdPwrExcProtectorPhy) {
let mut offset = 0;
unsafe {
let adc_config = AdcConfig::default()
.clock(config::Clock::Pclk2_div_8)
.default_sample_time(config::SampleTime::Cycles_480);
let mut tmp_adc = Adc::adc3(Peripherals::steal().ADC3, false, adc_config);
for _ in (0..1024).rev() {
offset += tmp_adc.convert(&phy._pd_mon_ch0, stm32f4xx_hal::adc::config::SampleTime::Cycles_480) as u32;
}
offset /= 1024 as u32
}
// Do not set reset RCCs as it causes other ADCs' clock to be disabled
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.
@ -125,6 +142,7 @@ impl LdPwrExcProtector {
phy: phy, phy: phy,
alarm_status: Status::default(), alarm_status: Status::default(),
calibrated_vdda: 3300, calibrated_vdda: 3300,
offset: offset,
}); });
} }
} }
@ -136,7 +154,8 @@ impl LdPwrExcProtector {
fn convert_sample_to_volt(sample: u16) -> ElectricPotential { fn convert_sample_to_volt(sample: u16) -> ElectricPotential {
if let Some(ref mut wdg) = LdPwrExcProtector::get() { if let Some(ref mut wdg) = LdPwrExcProtector::get() {
return ElectricPotential::new::<millivolt>( return ElectricPotential::new::<millivolt>(
((u32::from(sample) * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE)) as f32, (((i32::from(sample) - wdg.offset as i32).max(0) as u32 * wdg.calibrated_vdda) / u32::from(MAX_SAMPLE))
as f32,
); );
} }
ElectricPotential::new::<millivolt>(0.0) ElectricPotential::new::<millivolt>(0.0)
@ -144,8 +163,10 @@ impl LdPwrExcProtector {
pub fn set_trigger_threshold_v(htr: ElectricPotential) { pub fn set_trigger_threshold_v(htr: ElectricPotential) {
if let Some(ref mut wdg) = LdPwrExcProtector::get() { if let Some(ref mut wdg) = LdPwrExcProtector::get() {
let code: u32 = ((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f32))).get::<ratio>() let code: u32 = ((((htr / (ElectricPotential::new::<millivolt>(wdg.calibrated_vdda as f32))).get::<ratio>()
* (MAX_SAMPLE as f32)) as u32; * (MAX_SAMPLE as f32)) as u32)
+ wdg.offset)
.min(MAX_SAMPLE as u32);
wdg.pac.htr.write(|w| unsafe { w.bits(code) }); wdg.pac.htr.write(|w| unsafe { w.bits(code) });
} }
} }