forked from M-Labs/thermostat
adc: don't calibrate but convert using ChannelCalibration
This commit is contained in:
parent
2617895460
commit
c11b71cc0d
|
@ -114,27 +114,11 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calibrates offset registers
|
pub fn get_calibration(&mut self, index: u8) -> Result<ChannelCalibration, SPI::Error> {
|
||||||
pub fn calibrate(&mut self) -> Result<(), SPI::Error> {
|
let offset = self.read_reg(®s::Offset { index })?.offset();
|
||||||
// internal offset calibration
|
let gain = self.read_reg(®s::Gain { index })?.gain();
|
||||||
self.update_reg(®s::AdcMode, |adc_mode| {
|
let bipolar = self.read_reg(®s::SetupCon { index })?.bipolar();
|
||||||
adc_mode.set_mode(Mode::InternalOffsetCalibration);
|
Ok(ChannelCalibration { offset, gain, bipolar })
|
||||||
})?;
|
|
||||||
while ! self.read_reg(®s::Status)?.ready() {}
|
|
||||||
|
|
||||||
// system offset calibration
|
|
||||||
self.update_reg(®s::AdcMode, |adc_mode| {
|
|
||||||
adc_mode.set_mode(Mode::SystemOffsetCalibration);
|
|
||||||
})?;
|
|
||||||
while ! self.read_reg(®s::Status)?.ready() {}
|
|
||||||
|
|
||||||
// system gain calibration
|
|
||||||
self.update_reg(®s::AdcMode, |adc_mode| {
|
|
||||||
adc_mode.set_mode(Mode::SystemGainCalibration);
|
|
||||||
})?;
|
|
||||||
while ! self.read_reg(®s::Status)?.ready() {}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_continuous_conversion(&mut self) -> Result<(), SPI::Error> {
|
pub fn start_continuous_conversion(&mut self) -> Result<(), SPI::Error> {
|
||||||
|
@ -279,3 +263,26 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ChannelCalibration {
|
||||||
|
offset: u32,
|
||||||
|
gain: u32,
|
||||||
|
bipolar: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChannelCalibration {
|
||||||
|
pub fn convert_data(&self, data: u32) -> f64 {
|
||||||
|
let data = if self.bipolar {
|
||||||
|
(data as i32 - 0x80_0000) as f64
|
||||||
|
} else {
|
||||||
|
data as f64 / 2.0
|
||||||
|
};
|
||||||
|
let data = data / (self.gain as f64 / (0x40_0000 as f64));
|
||||||
|
let data = data + (self.offset as i32 - 0x80_0000) as f64;
|
||||||
|
let data = data / (2 << 23) as f64;
|
||||||
|
|
||||||
|
const V_REF: f64 = 3.0;
|
||||||
|
data * V_REF / 0.75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,23 +32,16 @@ impl Channels {
|
||||||
// Feature not used
|
// Feature not used
|
||||||
adc.set_sync_enable(false).unwrap();
|
adc.set_sync_enable(false).unwrap();
|
||||||
|
|
||||||
// Calibrate ADC channels individually
|
|
||||||
adc.disable_all_channels().unwrap();
|
|
||||||
|
|
||||||
adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap();
|
|
||||||
adc.calibrate().unwrap();
|
|
||||||
adc.disable_channel(0).unwrap();
|
|
||||||
|
|
||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
|
||||||
adc.calibrate().unwrap();
|
|
||||||
adc.disable_channel(1).unwrap();
|
|
||||||
|
|
||||||
// Setup channels and start ADC
|
// Setup channels and start ADC
|
||||||
adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap();
|
adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap();
|
||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
||||||
adc.start_continuous_conversion().unwrap();
|
adc.start_continuous_conversion().unwrap();
|
||||||
|
|
||||||
Channels { channel0, channel1, adc, pins_adc, pwm }
|
let mut channels = Channels { channel0, channel1, adc, pins_adc, pwm };
|
||||||
|
for channel in 0..CHANNELS {
|
||||||
|
channels.calibrate_dac_value(channel);
|
||||||
|
}
|
||||||
|
channels
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn channel_state<I: Into<usize>>(&mut self, channel: I) -> &mut ChannelState {
|
pub fn channel_state<I: Into<usize>>(&mut self, channel: I) -> &mut ChannelState {
|
||||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -102,8 +102,10 @@ fn main() -> ! {
|
||||||
leds.g4.off();
|
leds.g4.off();
|
||||||
|
|
||||||
let mut channels = Channels::new(pins);
|
let mut channels = Channels::new(pins);
|
||||||
channels.calibrate_dac_value(0);
|
let adc_calibration = [
|
||||||
channels.calibrate_dac_value(1);
|
channels.adc.get_calibration(0).unwrap(),
|
||||||
|
channels.adc.get_calibration(1).unwrap(),
|
||||||
|
];
|
||||||
|
|
||||||
#[cfg(not(feature = "generate-hwaddr"))]
|
#[cfg(not(feature = "generate-hwaddr"))]
|
||||||
let hwaddr = EthernetAddress(NET_HWADDR);
|
let hwaddr = EthernetAddress(NET_HWADDR);
|
||||||
|
@ -162,12 +164,16 @@ fn main() -> ! {
|
||||||
|
|
||||||
let state = channels.channel_state(channel);
|
let state = channels.channel_state(channel);
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
socket, "t={} adc_raw{}=0x{:06X} vref={} dac_feedback={} itec={} tec={} tec_u_meas={}",
|
socket, "channel {}: t={} adc_raw{}=0x{:06X} adc{}={:.3}V vref={} dac_feedback={} itec={} tec={} tec_u_meas={}",
|
||||||
|
channel,
|
||||||
state.adc_time, channel, adc_data,
|
state.adc_time, channel, adc_data,
|
||||||
|
channel, adc_calibration[channel].convert_data(adc_data),
|
||||||
vref, dac_feedback,
|
vref, dac_feedback,
|
||||||
itec, tec_i,
|
itec, tec_i,
|
||||||
tec_u_meas,
|
tec_u_meas,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
let _ = writeln!(socket, "channel {}: no adc input", channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,9 +379,11 @@ fn main() -> ! {
|
||||||
} else if socket.can_send() && socket.send_capacity() - socket.send_queue() > 256 {
|
} else if socket.can_send() && socket.send_capacity() - socket.send_queue() > 256 {
|
||||||
while let Some(channel) = session.is_report_pending() {
|
while let Some(channel) = session.is_report_pending() {
|
||||||
let state = &mut channels.channel_state(usize::from(channel));
|
let state = &mut channels.channel_state(usize::from(channel));
|
||||||
|
let adc_data = state.adc_data.unwrap_or(0);
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
socket, "t={} raw{}=0x{:06X}",
|
socket, "t={} raw{}=0x{:06X} value={:.3}V",
|
||||||
state.adc_time, channel, state.adc_data.unwrap_or(0)
|
state.adc_time, channel, adc_data,
|
||||||
|
adc_calibration[channel].convert_data(adc_data),
|
||||||
).map(|_| {
|
).map(|_| {
|
||||||
session.mark_report_sent(channel);
|
session.mark_report_sent(channel);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue