#![allow(clippy::unusual_byte_groupings)]
use crate::{types::u24, ConversionRate};
pub trait ReadReg<R>
where
Self: Sized,
{
const ADDR: u8;
fn from_reg(reg: R) -> Self;
}
pub trait WriteReg<R>: ReadReg<R> {
fn to_reg(self) -> R;
}
macro_rules! register {
(@impl_read_reg $Reg:ident : $addr:literal : $RegTy:ty) => {
impl ReadReg<$RegTy> for $Reg {
const ADDR: u8 = $addr;
#[inline]
fn from_reg(reg: $RegTy) -> Self {
$Reg::from_bits_truncate(reg)
}
}
};
(@impl_write_reg $Reg:ident : $addr:literal : $RegTy:ty) => {
impl WriteReg<$RegTy> for $Reg {
fn to_reg(self) -> $RegTy {
self.bits()
}
}
};
(
#[doc = $name:expr]
$vis:vis struct $Reg:ident($RegTy:ty): $addr:literal;
) => {
#[doc = concat!($name, " register (`", stringify!($addr), "`)")]
$vis struct $Reg(pub $RegTy);
impl $Reg {
const fn from_bits_truncate(bits: $RegTy) -> Self {
Self(bits)
}
}
register!(@impl_read_reg $Reg: $addr: $RegTy);
};
(
#[doc = $name:expr]
$vis:vis struct $Reg:ident : $addr:literal : $RegTy:ty {
$(
$(#[$inner:ident $($args:tt)*])*
const $const_name:ident = $const_value:expr;
)*
}
) => {
::bitflags::bitflags! {
#[doc = concat!($name, " register (`", stringify!($addr), "`)")]
$vis struct $Reg: $RegTy {
$(
$(#[$inner $($args)*])*
const $const_name = $const_value;
)*
}
}
register!(@impl_read_reg $Reg: $addr: $RegTy);
register!(@impl_write_reg $Reg: $addr: $RegTy);
};
}
register! {
pub struct Stat: 0x0: u16 {
const INRESET = 0b10000000_00000000;
const ERROR = 0b01000000_00000000;
const PDSTAT1 = 0b00001000_00000000;
const PDSTAT0 = 0b00000100_00000000;
const RDERR = 0b00000010_00000000;
const AOR = 0b00000001_00000000;
const RATE3 = 0b00000000_10000000;
const RATE2 = 0b00000000_01000000;
const RATE1 = 0b00000000_00100000;
const RATE0 = 0b00000000_00010000;
const SYSGOR = 0b00000000_00001000;
const DOR = 0b00000000_00000100;
const MSTAT = 0b00000000_00000010;
const RDY = 0b00000000_00000001;
const PDSTAT = Self::PDSTAT1.bits() | Self::PDSTAT0.bits();
const RATE = Self::RATE3.bits() | Self::RATE2.bits() | Self::RATE1.bits() | Self::RATE0.bits();
}
}
impl Stat {
pub const fn rate(self) -> ConversionRate {
match self.intersection(Self::RATE).bits() >> 4 {
0b0000 => ConversionRate::Hz0_95,
0b0001 => ConversionRate::Hz1_9,
0b0010 => ConversionRate::Hz3_9,
0b0011 => ConversionRate::Hz7_8,
0b0100 => ConversionRate::Hz15_6,
0b0101 => ConversionRate::Hz31_25,
0b0110 => ConversionRate::Hz62_5,
0b0111 => ConversionRate::Hz125,
0b1000 => ConversionRate::Hz250,
0b1001 => ConversionRate::Hz500,
0b1010 => ConversionRate::Hz1000,
0b1011 => ConversionRate::Hz2000,
0b1100 => ConversionRate::Hz4000,
0b1101 => ConversionRate::Hz8000,
0b1110 => ConversionRate::Hz16000,
0b1111 => ConversionRate::Hz32000,
_ => unreachable!(),
}
}
}
register! {
pub struct Ctrl1: 0x1: u8 {
const CONTSC = 0b00000001;
const SCYCLE = 0b00000010;
const FORMAT = 0b00000100;
const UB = 0b00001000;
const PD0 = 0b00010000;
const PD1 = 0b00100000;
const SYNC = 0b01000000;
const EXTCK = 0b10000000;
}
}
register! {
pub struct Ctrl2: 0x2: u8 {
const DGAIN1 = 0b10000000;
const DGAIN0 = 0b01000000;
const BUFEN = 0b00100000;
const LPMODE = 0b00010000;
const PGAEN = 0b00001000;
const PGAG2 = 0b00000100;
const PGAG1 = 0b00000010;
const PGAG0 = 0b00000001;
const DGAIN = Self::DGAIN1.bits() | Self::DGAIN0.bits();
const PGAG = Self::PGAG2.bits() | Self::PGAG1.bits() | Self::PGAG0.bits();
}
}
register! {
pub struct Ctrl3: 0x3: u8 {
const ENMSYNC = 0b00100000;
const MODBITS = 0b00010000;
const DATA32 = 0b00001000;
const PHASE = 0b00000100;
const FILT1 = 0b00000010;
const FILT0 = 0b00000001;
}
}
register! {
pub struct Ctrl4: 0x4: u8 {
const DIR3 = 0b01000000;
const DIR2 = 0b00100000;
const DIR1 = 0b00010000;
const DIO3 = 0b00000100;
const DIO2 = 0b00000010;
const DIO1 = 0b00000001;
}
}
register! {
pub struct Ctrl5: 0x5: u8 {
const CAL1 = 0b10000000;
const CAL0 = 0b01000000;
const NOSYSG = 0b00001000;
const NOSYSO = 0b00000100;
const NOSCG = 0b00000010;
const NOSCO = 0b00000001;
const CAL = Self::CAL1.bits() | Self::CAL0.bits();
}
}
register! {
pub struct Data32(u32): 0x6;
}
register! {
pub struct Data24(u24): 0x6;
}
register! {
pub struct SocSpi(u24): 0x7;
}
register! {
pub struct SgcSpi(u24): 0x8;
}
register! {
pub struct ScocSpi(u24): 0x9;
}
register! {
pub struct ScgcSpi(u24): 0xA;
}
register! {
pub struct Hpf(u16): 0xB;
}
register! {
pub struct SocAdc(u24): 0x15;
}
register! {
pub struct SgcAdc(u24): 0x16;
}
register! {
pub struct ScocAdc(u24): 0x17;
}
register! {
pub struct ScgcAdc(u24): 0x18;
}