2019-09-09 03:34:38 +08:00
use byteorder ::{ BigEndian , ByteOrder } ;
use bit_field ::BitField ;
use super ::* ;
pub trait Register {
type Data : RegisterData ;
fn address ( & self ) -> u8 ;
}
pub trait RegisterData {
fn empty ( ) -> Self ;
fn as_mut ( & mut self ) -> & mut [ u8 ] ;
}
macro_rules ! def_reg {
( $Reg : ident , $reg : ident , $addr : expr , $size : expr ) = > {
2019-09-10 22:21:51 +08:00
/// AD7172 register
2019-09-09 03:34:38 +08:00
pub struct $Reg ;
impl Register for $Reg {
2019-09-10 22:21:51 +08:00
/// Register contents
2019-09-09 03:34:38 +08:00
type Data = $reg ::Data ;
2019-09-10 22:21:51 +08:00
/// Register address
2019-09-09 03:34:38 +08:00
fn address ( & self ) -> u8 {
$addr
}
}
mod $reg {
2019-09-10 22:21:51 +08:00
/// Register contents
2019-09-09 03:34:38 +08:00
pub struct Data ( pub [ u8 ; $size ] ) ;
impl super ::RegisterData for Data {
2019-09-10 22:21:51 +08:00
/// Generate zeroed register contents
2019-09-09 03:34:38 +08:00
fn empty ( ) -> Self {
Data ( [ 0 ; $size ] )
}
2019-09-10 22:21:51 +08:00
/// Borrow for SPI transfer
2019-09-09 03:34:38 +08:00
fn as_mut ( & mut self ) -> & mut [ u8 ] {
& mut self . 0
}
}
}
} ;
2019-09-14 08:19:18 +08:00
( $Reg : ident , u8 , $reg : ident , $addr : expr , $size : expr ) = > {
pub struct $Reg { pub index : u8 , }
2019-09-09 03:34:38 +08:00
impl Register for $Reg {
type Data = $reg ::Data ;
fn address ( & self ) -> u8 {
2019-09-14 08:19:18 +08:00
$addr + self . index
2019-09-09 03:34:38 +08:00
}
}
mod $reg {
pub struct Data ( pub [ u8 ; $size ] ) ;
impl super ::RegisterData for Data {
fn empty ( ) -> Self {
Data ( [ 0 ; $size ] )
}
fn as_mut ( & mut self ) -> & mut [ u8 ] {
& mut self . 0
}
}
}
}
}
2019-09-09 22:20:15 +08:00
macro_rules ! reg_bit {
( $getter : ident , $byte : expr , $bit : expr , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> bool {
self . 0 [ $byte ] . get_bit ( $bit )
}
} ;
( $getter : ident , $setter : ident , $byte : expr , $bit : expr , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> bool {
self . 0 [ $byte ] . get_bit ( $bit )
}
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $setter ( & mut self , value : bool ) {
self . 0 [ $byte ] . set_bit ( $bit , value ) ;
}
} ;
}
macro_rules ! reg_bits {
( $getter : ident , $byte : expr , $bits : expr , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> u8 {
self . 0 [ $byte ] . get_bits ( $bits )
}
} ;
( $getter : ident , $setter : ident , $byte : expr , $bits : expr , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> u8 {
self . 0 [ $byte ] . get_bits ( $bits )
}
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $setter ( & mut self , value : u8 ) {
self . 0 [ $byte ] . set_bits ( $bits , value ) ;
}
} ;
( $getter : ident , $byte : expr , $bits : expr , $ty : ty , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> $ty {
self . 0 [ $byte ] . get_bits ( $bits ) as $ty
}
} ;
( $getter : ident , $setter : ident , $byte : expr , $bits : expr , $ty : ty , $doc : expr ) = > {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $getter ( & self ) -> $ty {
self . 0 [ $byte ] . get_bits ( $bits ) . into ( )
}
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
#[ doc = $doc ]
pub fn $setter ( & mut self , value : $ty ) {
self . 0 [ $byte ] . set_bits ( $bits , value as u8 ) ;
}
} ;
}
2019-09-09 03:34:38 +08:00
def_reg! ( Status , status , 0x00 , 1 ) ;
impl status ::Data {
/// Is there new data to read?
pub fn ready ( & self ) -> bool {
2019-09-09 22:20:15 +08:00
! self . not_ready ( )
2019-09-09 03:34:38 +08:00
}
2019-09-09 22:20:15 +08:00
reg_bit! ( not_ready , 0 , 7 , " No data ready indicator " ) ;
reg_bits! ( channel , 0 , 0 ..= 1 , " Channel for which data is ready " ) ;
reg_bit! ( adc_error , 0 , 6 , " ADC error " ) ;
reg_bit! ( crc_error , 0 , 5 , " SPI CRC error " ) ;
reg_bit! ( reg_error , 0 , 4 , " Register error " ) ;
2019-09-09 03:34:38 +08:00
}
def_reg! ( IfMode , if_mode , 0x02 , 2 ) ;
impl if_mode ::Data {
2019-09-09 22:20:15 +08:00
reg_bits! ( crc , set_crc , 1 , 2 ..= 3 , ChecksumMode , " SPI checksum mode " ) ;
2019-09-09 03:34:38 +08:00
}
def_reg! ( Data , data , 0x04 , 3 ) ;
impl data ::Data {
2019-10-03 03:27:35 +08:00
pub fn data ( & self ) -> i32 {
let raw =
( u32 ::from ( self . 0 [ 0 ] ) < < 16 ) |
( u32 ::from ( self . 0 [ 1 ] ) < < 8 ) |
u32 ::from ( self . 0 [ 2 ] ) ;
if raw & 0x80_0000 ! = 0 {
( ( raw & 0x7F_FFFF ) | 0x8000_0000 ) as i32
} else {
raw as i32
}
2019-09-09 03:34:38 +08:00
}
}
2019-09-17 06:13:46 +08:00
def_reg! ( GpioCon , gpio_con , 0x06 , 2 ) ;
impl gpio_con ::Data {
reg_bit! ( sync_en , set_sync_en , 0 , 3 , " Enables the SYNC/ERROR pin as a sync input " ) ;
}
2019-09-09 03:34:38 +08:00
def_reg! ( Id , id , 0x07 , 2 ) ;
impl id ::Data {
pub fn id ( & self ) -> u16 {
BigEndian ::read_u16 ( & self . 0 )
}
}
def_reg! ( Channel , u8 , channel , 0x10 , 2 ) ;
impl channel ::Data {
2019-09-09 22:20:15 +08:00
reg_bit! ( enabled , set_enabled , 0 , 7 , " Channel enabled " ) ;
reg_bits! ( setup , set_setup , 0 , 4 ..= 5 , " Setup number " ) ;
2019-09-09 03:34:38 +08:00
2019-09-09 22:20:15 +08:00
/// Which input is connected to positive input of this channel
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
pub fn a_in_pos ( & self ) -> Input {
( ( self . 0 [ 0 ] . get_bits ( 0 ..= 1 ) < < 3 ) |
self . 0 [ 1 ] . get_bits ( 5 ..= 7 ) ) . into ( )
2019-09-09 03:34:38 +08:00
}
2019-09-09 22:20:15 +08:00
/// Set which input is connected to positive input of this channel
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-09 22:20:15 +08:00
pub fn set_a_in_pos ( & mut self , value : Input ) {
let value = value as u8 ;
self . 0 [ 0 ] . set_bits ( 0 ..= 1 , value > > 3 ) ;
self . 0 [ 1 ] . set_bits ( 5 ..= 7 , value & 0x7 ) ;
}
reg_bits! ( a_in_neg , set_a_in_neg , 1 , 0 ..= 4 , Input ,
" Which input is connected to negative input of this channel " ) ;
// const PROPS: &'static [Property<Self>] = &[
// Property::named("enable")
// .readable(&|self_: &Self| self_.enabled().into())
// .writebale(&|self_: &mut Self, value| self_.set_enabled(value != 0)),
// Property::named("setup")
// .readable(&|self_: &Self| self_.0[0].get_bits(4..=5).into())
// .writeable(&|self_: &mut Self, value| {
// self_.0[0].set_bits(4..=5, value as u8);
// }),
// ];
// pub fn props() -> &'static [Property<Self>] {
// Self::PROPS
// }
2019-09-09 03:34:38 +08:00
}
def_reg! ( SetupCon , u8 , setup_con , 0x20 , 2 ) ;
2019-09-09 22:20:15 +08:00
impl setup_con ::Data {
2019-09-19 04:45:29 +08:00
reg_bit! ( bipolar , set_bipolar , 0 , 4 , " Unipolar (`false`) or bipolar (`true`) coded output " ) ;
reg_bit! ( refbuf_pos , set_refbuf_pos , 0 , 3 , " Enable REF+ input buffer " ) ;
reg_bit! ( refbuf_neg , set_refbuf_neg , 0 , 2 , " Enable REF- input buffer " ) ;
reg_bit! ( ainbuf_pos , set_ainbuf_pos , 0 , 1 , " Enable AIN+ input buffer " ) ;
reg_bit! ( ainbuf_neg , set_ainbuf_neg , 0 , 0 , " Enable AIN- input buffer " ) ;
2019-09-09 22:20:15 +08:00
reg_bit! ( burnout_en , 1 , 7 , " enables a 10 µA current source on the positive analog input selected and a 10 µA current sink on the negative analog input selected " ) ;
reg_bits! ( ref_sel , set_ref_sel , 1 , 4 ..= 5 , RefSource , " Select reference source for conversion " ) ;
}
2019-09-09 03:34:38 +08:00
2019-09-10 22:21:51 +08:00
def_reg! ( FiltCon , u8 , filt_con , 0x28 , 2 ) ;
2019-09-09 22:20:15 +08:00
impl filt_con ::Data {
reg_bit! ( sinc3_map , 0 , 7 , " If set, mapping of filter register changes to directly program the decimation rate of the sinc3 filter " ) ;
reg_bit! ( enh_filt_en , set_enh_filt_en , 0 , 3 , " Enable postfilters for enhanced 50Hz and 60Hz rejection " ) ;
reg_bits! ( enh_filt , set_enh_filt , 0 , 0 ..= 2 , PostFilter , " Select postfilters for enhanced 50Hz and 60Hz rejection " ) ;
reg_bits! ( order , set_order , 1 , 5 ..= 6 , DigitalFilterOrder , " order of the digital filter that processes the modulator data " ) ;
reg_bits! ( odr , set_odr , 1 , 0 ..= 4 , " Output data rate " ) ;
}
2019-09-10 22:21:51 +08:00
def_reg! ( Offset , u8 , offset , 0x30 , 3 ) ;
impl offset ::Data {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-10 22:21:51 +08:00
pub fn offset ( & self ) -> u32 {
( u32 ::from ( self . 0 [ 0 ] ) < < 16 ) |
( u32 ::from ( self . 0 [ 1 ] ) < < 8 ) |
u32 ::from ( self . 0 [ 2 ] )
}
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-10 22:21:51 +08:00
pub fn set_offset ( & mut self , value : u32 ) {
self . 0 [ 0 ] = ( value > > 16 ) as u8 ;
self . 0 [ 1 ] = ( value > > 8 ) as u8 ;
self . 0 [ 2 ] = value as u8 ;
}
}
def_reg! ( Gain , u8 , gain , 0x38 , 3 ) ;
impl gain ::Data {
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-10 22:21:51 +08:00
pub fn gain ( & self ) -> u32 {
( u32 ::from ( self . 0 [ 0 ] ) < < 16 ) |
( u32 ::from ( self . 0 [ 1 ] ) < < 8 ) |
u32 ::from ( self . 0 [ 2 ] )
}
2019-09-15 03:40:49 +08:00
#[ allow(unused) ]
2019-09-10 22:21:51 +08:00
pub fn set_gain ( & mut self , value : u32 ) {
self . 0 [ 0 ] = ( value > > 16 ) as u8 ;
self . 0 [ 1 ] = ( value > > 8 ) as u8 ;
self . 0 [ 2 ] = value as u8 ;
}
}