channels: fix dac calibration

This commit is contained in:
Astro 2020-09-06 19:08:09 +02:00
parent 50dcee0c8a
commit 9a912392be
2 changed files with 22 additions and 23 deletions

View File

@ -207,50 +207,49 @@ impl Channels {
} }
} }
/// for i_set /// Calibrate the I_SET DAC using the DAC_FB ADC pin.
///
/// These loops perform a width-first search for the DAC setting
/// that will produce a `target_voltage`.
pub fn calibrate_dac_value(&mut self, channel: usize) { pub fn calibrate_dac_value(&mut self, channel: usize) {
let vref = self.read_vref(channel); let target_voltage = Volts(2.5);
let value = self.calibrate_dac_value_for_voltage(channel, vref); let mut start_value = 1;
info!("best dac value for {}: {}", vref, value);
let dac_factor = value as f64 / vref.0;
match channel {
0 => self.channel0.dac_factor = dac_factor,
1 => self.channel1.dac_factor = dac_factor,
_ => unreachable!(),
}
}
fn calibrate_dac_value_for_voltage(&mut self, channel: usize, voltage: Volts) -> u32 {
let mut best_value = 0;
let mut best_error = Volts(100.0); let mut best_error = Volts(100.0);
for step in (1..=12).rev() { for step in (0..18).rev() {
for value in (best_value..=ad5680::MAX_VALUE).step_by(2usize.pow(step)) { let mut prev_value = start_value;
for value in (start_value..=ad5680::MAX_VALUE).step_by(1 << step) {
match channel { match channel {
0 => { 0 => {
self.channel0.dac.set(value).unwrap(); self.channel0.dac.set(value).unwrap();
// self.channel0.shdn.set_high().unwrap();
} }
1 => { 1 => {
self.channel1.dac.set(value).unwrap(); self.channel1.dac.set(value).unwrap();
// self.channel1.shdn.set_high().unwrap();
} }
_ => unreachable!(), _ => unreachable!(),
} }
let dac_feedback = self.read_dac_feedback_until_stable(channel, 0.001); let dac_feedback = self.read_dac_feedback_until_stable(channel, 0.001);
let error = voltage - dac_feedback; let error = target_voltage - dac_feedback;
if error < Volts(0.0) { if error < Volts(0.0) {
break; break;
} else if error < best_error { } else if error < best_error {
best_value = value;
best_error = error; best_error = error;
start_value = prev_value;
let dac_factor = value as f64 / dac_feedback.0;
match channel {
0 => self.channel0.dac_factor = dac_factor,
1 => self.channel1.dac_factor = dac_factor,
_ => unreachable!(),
}
} }
prev_value = value;
} }
} }
// Reset
self.set_dac(channel, Volts(0.0)); self.set_dac(channel, Volts(0.0));
best_value
} }
} }

View File

@ -97,7 +97,7 @@ fn main() -> ! {
); );
let mut channels = Channels::new(pins); let mut channels = Channels::new(pins);
channels.calibrate_dac_value(0); channels.calibrate_dac_value(0);
channels.calibrate_dac_value(1);
#[cfg(not(feature = "generate-hwaddr"))] #[cfg(not(feature = "generate-hwaddr"))]
let hwaddr = EthernetAddress(NET_HWADDR); let hwaddr = EthernetAddress(NET_HWADDR);