Compare commits
No commits in common. "9a912392bed5ff6367c420e9cc2f5f9ea3a16a01" and "e5c9ee8ed01c81c5133101e61bca54f1d8c7b03f" have entirely different histories.
9a912392be
...
e5c9ee8ed0
|
@ -46,7 +46,6 @@ impl<SPI: Transfer<u8>, S: OutputPin> Dac<SPI, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, value: u32) -> Result<(), SPI::Error> {
|
pub fn set(&mut self, value: u32) -> Result<(), SPI::Error> {
|
||||||
let value = value.min(MAX_VALUE);
|
|
||||||
let mut buf = [
|
let mut buf = [
|
||||||
(value >> 14) as u8,
|
(value >> 14) as u8,
|
||||||
(value >> 6) as u8,
|
(value >> 6) as u8,
|
||||||
|
|
|
@ -207,37 +207,13 @@ impl Channels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calibrate the I_SET DAC using the DAC_FB ADC pin.
|
/// for i_set
|
||||||
///
|
|
||||||
/// 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 target_voltage = Volts(2.5);
|
let vref = self.read_vref(channel);
|
||||||
let mut start_value = 1;
|
let value = self.calibrate_dac_value_for_voltage(channel, vref);
|
||||||
let mut best_error = Volts(100.0);
|
info!("best dac value for {}: {}", vref, value);
|
||||||
|
|
||||||
for step in (0..18).rev() {
|
let dac_factor = value as f64 / vref.0;
|
||||||
let mut prev_value = start_value;
|
|
||||||
for value in (start_value..=ad5680::MAX_VALUE).step_by(1 << step) {
|
|
||||||
match channel {
|
|
||||||
0 => {
|
|
||||||
self.channel0.dac.set(value).unwrap();
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
self.channel1.dac.set(value).unwrap();
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
let dac_feedback = self.read_dac_feedback_until_stable(channel, 0.001);
|
|
||||||
let error = target_voltage - dac_feedback;
|
|
||||||
if error < Volts(0.0) {
|
|
||||||
break;
|
|
||||||
} else if error < best_error {
|
|
||||||
best_error = error;
|
|
||||||
start_value = prev_value;
|
|
||||||
|
|
||||||
let dac_factor = value as f64 / dac_feedback.0;
|
|
||||||
match channel {
|
match channel {
|
||||||
0 => self.channel0.dac_factor = dac_factor,
|
0 => self.channel0.dac_factor = dac_factor,
|
||||||
1 => self.channel1.dac_factor = dac_factor,
|
1 => self.channel1.dac_factor = dac_factor,
|
||||||
|
@ -245,11 +221,36 @@ impl Channels {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_value = value;
|
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);
|
||||||
|
|
||||||
|
for step in (1..=12).rev() {
|
||||||
|
for value in (best_value..=ad5680::MAX_VALUE).step_by(2usize.pow(step)) {
|
||||||
|
match channel {
|
||||||
|
0 => {
|
||||||
|
self.channel0.dac.set(value).unwrap();
|
||||||
|
// self.channel0.shdn.set_high().unwrap();
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
self.channel1.dac.set(value).unwrap();
|
||||||
|
// self.channel1.shdn.set_high().unwrap();
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let dac_feedback = self.read_dac_feedback_until_stable(channel, 0.001);
|
||||||
|
let error = voltage - dac_feedback;
|
||||||
|
if error < Volts(0.0) {
|
||||||
|
break;
|
||||||
|
} else if error < best_error {
|
||||||
|
best_value = value;
|
||||||
|
best_error = error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset
|
|
||||||
self.set_dac(channel, Volts(0.0));
|
self.set_dac(channel, Volts(0.0));
|
||||||
|
best_value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -206,7 +206,7 @@ impl Pins {
|
||||||
fn setup_dac0<M1, M2, M3>(
|
fn setup_dac0<M1, M2, M3>(
|
||||||
clocks: Clocks, spi4: SPI4,
|
clocks: Clocks, spi4: SPI4,
|
||||||
sclk: PE2<M1>, sync: PE4<M2>, sdin: PE6<M3>
|
sclk: PE2<M1>, sync: PE4<M2>, sdin: PE6<M3>
|
||||||
) -> (Dac0Spi, <Channel0 as ChannelPins>::DacSync) {
|
) -> (Dac0Spi, PE4<Output<PushPull>>) {
|
||||||
let sclk = sclk.into_alternate_af5();
|
let sclk = sclk.into_alternate_af5();
|
||||||
let sdin = sdin.into_alternate_af5();
|
let sdin = sdin.into_alternate_af5();
|
||||||
let spi = Spi::spi4(
|
let spi = Spi::spi4(
|
||||||
|
@ -224,7 +224,7 @@ impl Pins {
|
||||||
fn setup_dac1<M1, M2, M3>(
|
fn setup_dac1<M1, M2, M3>(
|
||||||
clocks: Clocks, spi5: SPI5,
|
clocks: Clocks, spi5: SPI5,
|
||||||
sclk: PF7<M1>, sync: PF6<M2>, sdin: PF9<M3>
|
sclk: PF7<M1>, sync: PF6<M2>, sdin: PF9<M3>
|
||||||
) -> (Dac1Spi, <Channel1 as ChannelPins>::DacSync) {
|
) -> (Dac1Spi, PF6<Output<PushPull>>) {
|
||||||
let sclk = sclk.into_alternate_af5();
|
let sclk = sclk.into_alternate_af5();
|
||||||
let sdin = sdin.into_alternate_af5();
|
let sdin = sdin.into_alternate_af5();
|
||||||
let spi = Spi::spi5(
|
let spi = Spi::spi5(
|
||||||
|
|
Loading…
Reference in New Issue