Improve the VREF calibration routine #132

Merged
sb10q merged 1 commits from atse/thermostat:calibration-fix into master 2024-09-19 10:06:25 +08:00
2 changed files with 5 additions and 14 deletions

View File

@ -22,6 +22,7 @@ use crate::{
pins::{self, Channel0VRef, Channel1VRef}, pins::{self, Channel0VRef, Channel1VRef},
steinhart_hart, steinhart_hart,
}; };
use crate::timer::sleep;
pub enum PinsAdcReadTarget { pub enum PinsAdcReadTarget {
VREF, VREF,
@ -269,17 +270,6 @@ impl Channels {
} }
} }
pub fn read_dac_feedback_until_stable(&mut self, channel: usize, tolerance: ElectricPotential) -> ElectricPotential {
let mut prev = self.adc_read(channel, PinsAdcReadTarget::DacVfb, 1);
loop {
let current = self.adc_read(channel, PinsAdcReadTarget::DacVfb, 1);
if (current - prev).abs() < tolerance {
return current;
}
prev = current;
}
}
/// Calibrates the DAC output to match vref of the MAX driver to reduce zero-current offset of the MAX driver output. /// Calibrates the DAC output to match vref of the MAX driver to reduce zero-current offset of the MAX driver output.
/// ///
/// The thermostat DAC applies a control voltage signal to the CTLI pin of MAX driver chip to control its output current. /// The thermostat DAC applies a control voltage signal to the CTLI pin of MAX driver chip to control its output current.
@ -306,7 +296,7 @@ impl Channels {
let mut start_value = 1; let mut start_value = 1;
let mut best_error = ElectricPotential::new::<volt>(100.0); let mut best_error = ElectricPotential::new::<volt>(100.0);
for step in (0..18).rev() { for step in (5..18).rev() {
let mut prev_value = start_value; let mut prev_value = start_value;
for value in (start_value..=ad5680::MAX_VALUE).step_by(1 << step) { for value in (start_value..=ad5680::MAX_VALUE).step_by(1 << step) {
match channel { match channel {
@ -318,8 +308,9 @@ impl Channels {
} }
_ => unreachable!(), _ => unreachable!(),
} }
sleep(10);
let dac_feedback = self.read_dac_feedback_until_stable(channel, ElectricPotential::new::<volt>(0.001)); let dac_feedback = self.adc_read(channel, PinsAdcReadTarget::DacVfb, 64);
let error = target_voltage - dac_feedback; let error = target_voltage - dac_feedback;
if error < ElectricPotential::new::<volt>(0.0) { if error < ElectricPotential::new::<volt>(0.0) {
break; break;

View File

@ -58,7 +58,7 @@ mod hw_rev;
const HSE: MegaHertz = MegaHertz(8); const HSE: MegaHertz = MegaHertz(8);
#[cfg(not(feature = "semihosting"))] #[cfg(not(feature = "semihosting"))]
const WATCHDOG_INTERVAL: u32 = 1_000; const WATCHDOG_INTERVAL: u32 = 2_000;
Review

Did the change caused the watchdog to trigger?

Did the change caused the watchdog to trigger?
Review

Yes. It takes longer time and causes the watchdog to trigger.
1.5s does not work.
1.75s works.
We chose 2.0s to leave some more margin.

Yes. It takes longer time and causes the watchdog to trigger. 1.5s does not work. 1.75s works. We chose 2.0s to leave some more margin.
#[cfg(feature = "semihosting")] #[cfg(feature = "semihosting")]
const WATCHDOG_INTERVAL: u32 = 30_000; const WATCHDOG_INTERVAL: u32 = 30_000;