From 1cba8e56c946e08e9ff74efd75f163d396fe9735 Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 20 Mar 2020 23:51:19 +0100 Subject: [PATCH] ad7172: add calibrate_offset() --- src/ad7172/adc.rs | 23 +++++++++++++++++------ src/ad7172/mod.rs | 31 +++++++++++++++++++++++++++++++ src/ad7172/regs.rs | 10 +++++----- src/main.rs | 1 + 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/ad7172/adc.rs b/src/ad7172/adc.rs index ec1a6dc..c240f1e 100644 --- a/src/ad7172/adc.rs +++ b/src/ad7172/adc.rs @@ -2,11 +2,10 @@ use core::fmt; use embedded_hal::digital::v2::OutputPin; use embedded_hal::blocking::spi::Transfer; use log::{info, warn}; -use super::checksum::{ChecksumMode, Checksum}; -use super::AdcError; use super::{ regs::{self, Register, RegisterData}, - Input, RefSource, PostFilter, DigitalFilterOrder, + checksum::{ChecksumMode, Checksum}, + AdcError, Mode, Input, RefSource, PostFilter, DigitalFilterOrder, }; /// AD7172-2 implementation @@ -42,6 +41,7 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc let mut adc_mode = ::Data::empty(); adc_mode.set_ref_en(true); + adc_mode.set_mode(Mode::ContinuousConversion); adc.write_reg(®s::AdcMode, &mut adc_mode)?; Ok(adc) @@ -85,9 +85,6 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc data.set_enh_filt(PostFilter::F16SPS); data.set_order(DigitalFilterOrder::Sinc5Sinc1); })?; - let mut offset = ::Data::empty(); - offset.set_offset(0); - self.write_reg(®s::Offset { index }, &mut offset)?; self.update_reg(®s::Channel { index }, |data| { data.set_setup(index); data.set_enabled(true); @@ -97,6 +94,20 @@ impl, NSS: OutputPin, E: fmt::Debug> Adc Ok(()) } + /// Calibrates offset registers + pub fn calibrate_offset(&mut self) -> Result<(), AdcError> { + 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, AdcError> { self.read_reg(®s::FiltCon { index }) .map(|data| { diff --git a/src/ad7172/mod.rs b/src/ad7172/mod.rs index ea0ac93..53f4c11 100644 --- a/src/ad7172/mod.rs +++ b/src/ad7172/mod.rs @@ -33,6 +33,37 @@ impl From for AdcError { } } + + +#[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 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)] #[repr(u8)] pub enum Input { diff --git a/src/ad7172/regs.rs b/src/ad7172/regs.rs index 5f730d5..5b8c9d5 100644 --- a/src/ad7172/regs.rs +++ b/src/ad7172/regs.rs @@ -158,12 +158,12 @@ impl status::Data { def_reg!(AdcMode, adc_mode, 0x01, 2); impl adc_mode::Data { - reg_bits!(clockset, set_clocksel, 1, 2..3, "Clock source"); - reg_bits!(mode, set_mode, 1, 4..6, "Operating mode"); - reg_bits!(delay, set_delay, 0, 0..2, "Delay after channel switch"); - 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_bits!(delay, set_delay, 0, 0..=2, "Delay after channel switch"); + reg_bit!(sing_cyc, set_sing_cyc, 0, 5, "Can only used with single channel"); + reg_bit!(hide_delay, set_hide_delay, 0, 6, "Hide delay"); 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); diff --git a/src/main.rs b/src/main.rs index 5214b1c..192a884 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,6 +94,7 @@ fn main() -> ! { 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(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap(); + adc.calibrate_offset().unwrap(); let mut dac0 = ad5680::Dac::new(pins.dac0_spi, pins.dac0_sync); dac0.set(0).unwrap(); let mut dac1 = ad5680::Dac::new(pins.dac1_spi, pins.dac1_sync);