1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
#![allow(clippy::unusual_byte_groupings)] // FIXME: https://github.com/rust-lang/rust-clippy/issues/9183
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(crate) $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), "`)")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
$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! {
/// STAT
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! {
/// Control 1 Register (`CTRL1`)
pub struct Ctrl1: 0x1: u8 {
/// Continuous single-cycle bit.
///
/// - 0 A single conversion.
/// - 1 Continuous conversions.
const CONTSC = 0b00000001;
/// Single-cycle control bit.
///
/// - 0 Continuous conversion mode.
/// - 1 Single-cycle mode. The MAX11214 completes one no-latency conversion and then powers down into a leakage-only state.
const SCYCLE = 0b00000010;
/// Bipolar range format bit.
///
/// When reading bipolar data:
/// - 0 Use two’s complement.
/// - 1 Use offset binary.
///
/// The data from unipolar range is always formatted in offset binary format.
const FORMAT = 0b00000100;
/// U/B: Unipolar/bipolar bit.
///
/// - 0 Bipolar input range (±VREF).
/// - 1 Unipolar input range (0 to VREF). S
const UB = 0b00001000;
/// Power mode bits.
///
/// - 00 Normal power-up state: This is the default state.
/// - 01 Sleep mode: Powers down the subregulator and the entire digital circuitry. Upon resumption of power to the digital the PD[1:0] reverts to the default state of ‘00’.
/// - 10 Standby power: Powers down the analog blocks leaving the subregulator powered up.
/// - 11 Resets all registers to POR state leaving the subregulator powered. The `PD[1:0]` bits are reset to ‘00’. The operation of this state is identical to the RSTB pin.
const PD0 = 0b00010000;
const PD1 = 0b00100000;
/// Synchronization bit.
///
/// - 0 Pulse synchronization mode.
/// - 1 Continuous synchronization mode.
const SYNC = 0b01000000;
/// External clock bit.
///
/// - 0 Use internal oscillator as the system clock.
/// - 1 Use external clock as the system clock.
const EXTCK = 0b10000000;
}
}
register! {
/// Control 2 Register (`CTRL2`)
pub struct Ctrl2: 0x2: u8 {
const DGAIN1 = 0b10000000;
const DGAIN0 = 0b01000000;
/// Analog input buffer enable bit.
///
/// - 0 Disable the analog input buffers.
/// - 1 Enable the analog input buffers.
const BUFEN = 0b00100000;
/// PGA Low Power mode bit.
///
/// - 0 Standard power.
/// - 1 Low power.
const LPMODE = 0b00010000;
/// PGA Enable bit.
///
/// - 0 Disable the PGA.
/// - 1 Enable the PGA.
const PGAEN = 0b00001000;
const PGAG2 = 0b00000100;
const PGAG1 = 0b00000010;
const PGAG0 = 0b00000001;
/// Modulator Digital Gain bits.
///
/// - 00 x1
/// - 01 x2
/// - 10 x4
/// - 11 x8
const DGAIN = Self::DGAIN1.bits() | Self::DGAIN0.bits();
/// PGA Gain-Setting bits.
///
/// - 000 x1
/// - 001 x2
/// - 010 x4
/// - 011 x8
/// - 100 x16
/// - 101 x32
/// - 110 x64
/// - 111 x128
const PGAG = Self::PGAG2.bits() | Self::PGAG1.bits() | Self::PGAG0.bits();
}
}
register! {
/// Control 3 Register (`CTRL3`)
pub struct Ctrl3: 0x3: u8 {
const ENMSYNC = 0b00100000;
const MODBITS = 0b00010000;
const DATA32 = 0b00001000;
const PHASE = 0b00000100;
const FILT1 = 0b00000010;
const FILT0 = 0b00000001;
}
}
register! {
/// Control 4 Register (`CTRL4`)
pub struct Ctrl4: 0x4: u8 {
const DIR3 = 0b01000000;
const DIR2 = 0b00100000;
const DIR1 = 0b00010000;
const DIO3 = 0b00000100;
const DIO2 = 0b00000010;
const DIO1 = 0b00000001;
}
}
register! {
/// Control 5 Register (`CTRL5`)
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! {
/// 32-bit Data Register (`DATA`)
pub struct Data32(u32): 0x6;
}
register! {
/// 24-bit Data Register (`DATA`)
pub struct Data24(u24): 0x6;
}
register! {
/// SPI System Offset Calibration Register (`SOC_SPI`)
pub struct SocSpi(u24): 0x7;
}
register! {
/// SPI System Gain Calibration Register (`SGC_SPI`)
pub struct SgcSpi(u24): 0x8;
}
register! {
/// SPI Self-Cal Offset Calibration Register (`SCOC_SPI`)
pub struct ScocSpi(u24): 0x9;
}
register! {
/// SPI Self-Cal Gain Calibration Register (`SCGC_SPI`)
pub struct ScgcSpi(u24): 0xA;
}
register! {
/// Highpass Filter Register (`HPF`)
pub struct Hpf(u16): 0xB;
}
register! {
/// ADC System Offset Calibration Register (`SOC_ADC`)
pub struct SocAdc(u24): 0x15;
}
register! {
/// ADC System Gain Calibration Register (`SGC_ADC`)
pub struct SgcAdc(u24): 0x16;
}
register! {
/// ADC Self-Cal Offset Calibration Register (`SCOC_ADC`)
pub struct ScocAdc(u24): 0x17;
}
register! {
/// ADC Self-Cal Gain Calibration Register (`SCGC_ADC`)
pub struct ScgcAdc(u24): 0x18;
}