forked from M-Labs/thermostat
ad7172: add calibrate_offset()
This commit is contained in:
parent
63cc1d2fe1
commit
1cba8e56c9
@ -2,11 +2,10 @@ use core::fmt;
|
|||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
use embedded_hal::blocking::spi::Transfer;
|
use embedded_hal::blocking::spi::Transfer;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use super::checksum::{ChecksumMode, Checksum};
|
|
||||||
use super::AdcError;
|
|
||||||
use super::{
|
use super::{
|
||||||
regs::{self, Register, RegisterData},
|
regs::{self, Register, RegisterData},
|
||||||
Input, RefSource, PostFilter, DigitalFilterOrder,
|
checksum::{ChecksumMode, Checksum},
|
||||||
|
AdcError, Mode, Input, RefSource, PostFilter, DigitalFilterOrder,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// AD7172-2 implementation
|
/// AD7172-2 implementation
|
||||||
@ -42,6 +41,7 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
|
|||||||
|
|
||||||
let mut adc_mode = <regs::AdcMode as Register>::Data::empty();
|
let mut adc_mode = <regs::AdcMode as Register>::Data::empty();
|
||||||
adc_mode.set_ref_en(true);
|
adc_mode.set_ref_en(true);
|
||||||
|
adc_mode.set_mode(Mode::ContinuousConversion);
|
||||||
adc.write_reg(®s::AdcMode, &mut adc_mode)?;
|
adc.write_reg(®s::AdcMode, &mut adc_mode)?;
|
||||||
|
|
||||||
Ok(adc)
|
Ok(adc)
|
||||||
@ -85,9 +85,6 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
|
|||||||
data.set_enh_filt(PostFilter::F16SPS);
|
data.set_enh_filt(PostFilter::F16SPS);
|
||||||
data.set_order(DigitalFilterOrder::Sinc5Sinc1);
|
data.set_order(DigitalFilterOrder::Sinc5Sinc1);
|
||||||
})?;
|
})?;
|
||||||
let mut offset = <regs::Offset as regs::Register>::Data::empty();
|
|
||||||
offset.set_offset(0);
|
|
||||||
self.write_reg(®s::Offset { index }, &mut offset)?;
|
|
||||||
self.update_reg(®s::Channel { index }, |data| {
|
self.update_reg(®s::Channel { index }, |data| {
|
||||||
data.set_setup(index);
|
data.set_setup(index);
|
||||||
data.set_enabled(true);
|
data.set_enabled(true);
|
||||||
@ -97,6 +94,20 @@ impl<SPI: Transfer<u8, Error = E>, NSS: OutputPin, E: fmt::Debug> Adc<SPI, NSS>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calibrates offset registers
|
||||||
|
pub fn calibrate_offset(&mut self) -> Result<(), AdcError<SPI::Error>> {
|
||||||
|
self.update_reg(®s::AdcMode, |adc_mode| {
|
||||||
|
adc_mode.set_mode(Mode::SystemOffsetCalibration);
|
||||||
|
})?;
|
||||||
|
while ! self.read_reg(®s::Status)?.ready() {}
|
||||||
|
|
||||||
|
self.update_reg(®s::AdcMode, |adc_mode| {
|
||||||
|
adc_mode.set_mode(Mode::ContinuousConversion);
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_postfilter(&mut self, index: u8) -> Result<Option<PostFilter>, AdcError<SPI::Error>> {
|
pub fn get_postfilter(&mut self, index: u8) -> Result<Option<PostFilter>, AdcError<SPI::Error>> {
|
||||||
self.read_reg(®s::FiltCon { index })
|
self.read_reg(®s::FiltCon { index })
|
||||||
.map(|data| {
|
.map(|data| {
|
||||||
|
@ -33,6 +33,37 @@ impl<SPI> From<SPI> for AdcError<SPI> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Mode {
|
||||||
|
ContinuousConversion = 0b000,
|
||||||
|
SingleConversion = 0b001,
|
||||||
|
Standby = 0b010,
|
||||||
|
PowerDown = 0b011,
|
||||||
|
InternalOffsetCalibration = 0b100,
|
||||||
|
Invalid,
|
||||||
|
SystemOffsetCalibration = 0b110,
|
||||||
|
SystemGainCalibration = 0b111,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Mode {
|
||||||
|
fn from(x: u8) -> Self {
|
||||||
|
use Mode::*;
|
||||||
|
match x {
|
||||||
|
0b000 => ContinuousConversion,
|
||||||
|
0b001 => SingleConversion,
|
||||||
|
0b010 => Standby,
|
||||||
|
0b011 => PowerDown,
|
||||||
|
0b100 => InternalOffsetCalibration,
|
||||||
|
0b110 => SystemOffsetCalibration,
|
||||||
|
0b111 => SystemGainCalibration,
|
||||||
|
_ => Invalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
|
@ -158,12 +158,12 @@ impl status::Data {
|
|||||||
|
|
||||||
def_reg!(AdcMode, adc_mode, 0x01, 2);
|
def_reg!(AdcMode, adc_mode, 0x01, 2);
|
||||||
impl adc_mode::Data {
|
impl adc_mode::Data {
|
||||||
reg_bits!(clockset, set_clocksel, 1, 2..3, "Clock source");
|
reg_bits!(delay, set_delay, 0, 0..=2, "Delay after channel switch");
|
||||||
reg_bits!(mode, set_mode, 1, 4..6, "Operating mode");
|
reg_bit!(sing_cyc, set_sing_cyc, 0, 5, "Can only used with single channel");
|
||||||
reg_bits!(delay, set_delay, 0, 0..2, "Delay after channel switch");
|
reg_bit!(hide_delay, set_hide_delay, 0, 6, "Hide delay");
|
||||||
reg_bit!(sing_cyc, set_sing_cyc, 1, 5, "Can only used with single channel");
|
|
||||||
reg_bit!(hide_delay, set_hide_delay, 1, 6, "Hide delay");
|
|
||||||
reg_bit!(ref_en, set_ref_en, 0, 7, "Enable internal reference, output buffered 2.5 V to REFOUT");
|
reg_bit!(ref_en, set_ref_en, 0, 7, "Enable internal reference, output buffered 2.5 V to REFOUT");
|
||||||
|
reg_bits!(clockset, set_clocksel, 1, 2..=3, "Clock source");
|
||||||
|
reg_bits!(mode, set_mode, 1, 4..=6, Mode, "Operating mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
def_reg!(IfMode, if_mode, 0x02, 2);
|
def_reg!(IfMode, if_mode, 0x02, 2);
|
||||||
|
@ -94,6 +94,7 @@ fn main() -> ! {
|
|||||||
let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
|
let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
|
||||||
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.calibrate_offset().unwrap();
|
||||||
let mut dac0 = ad5680::Dac::new(pins.dac0_spi, pins.dac0_sync);
|
let mut dac0 = ad5680::Dac::new(pins.dac0_spi, pins.dac0_sync);
|
||||||
dac0.set(0).unwrap();
|
dac0.set(0).unwrap();
|
||||||
let mut dac1 = ad5680::Dac::new(pins.dac1_spi, pins.dac1_sync);
|
let mut dac1 = ad5680::Dac::new(pins.dac1_spi, pins.dac1_sync);
|
||||||
|
Loading…
Reference in New Issue
Block a user