#![no_std]
use core::marker::PhantomData;
use embedded_hal::spi::SpiDevice;
pub enum Normal {}
pub enum Standby {}
pub enum Shutdown {}
const fn command_bytes(control_bits: u8, mut data_bits: u16) -> [u8; 2] {
if data_bits > 0b1111_1111_1111 {
data_bits = 0b1111_1111_1111
}
[(control_bits << 4) | ((data_bits >> 8) as u8 & 0xf), data_bits as u8]
}
const fn vref_command_bytes(control_bits: u8, vref: Vref) -> [u8; 2] {
[(control_bits << 4) | ((vref as u8) << 2), 0]
}
macro_rules! impl_into_mode {
($desc:expr, Max5532, Standby, $fn_name:ident, $control_bits:expr) => {
};
($desc:expr, Max5533, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
impl_into_mode!(@with_vref $desc, Max5533, $mode_ty, $fn_name, $control_bits);
};
($desc:expr, Max5534, Standby, $fn_name:ident, $control_bits:expr) => {
};
($desc:expr, Max5535, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
impl_into_mode!(@with_vref $desc, Max5535, $mode_ty, $fn_name, $control_bits);
};
($desc:expr, $max_ty:ident, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
#[doc = $desc]
pub fn $fn_name(mut self) -> Result<$max_ty<SPI, $mode_ty>, SPI::Error> {
self.spi.write(&command_bytes($control_bits, 0))?;
Ok($max_ty { spi: self.spi, _mode: PhantomData })
}
};
(@with_vref $desc:expr, $max_ty:ident, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
#[doc = $desc]
pub fn $fn_name(mut self, vref: Vref) -> Result<$max_ty<SPI, $mode_ty>, SPI::Error> {
self.spi.write(&vref_command_bytes($control_bits, vref))?;
Ok($max_ty { spi: self.spi, _mode: PhantomData })
}
};
}
macro_rules! doc_imports {
(Max5533) => {
"max553x::{Max5533, Vref}"
};
(Max5535) => {
"max553x::{Max5535, Vref}"
};
($max_ty:ident) => {
concat!("max553x::", stringify!($max_ty))
};
}
macro_rules! doc_vref_value {
(Max5533) => {
0b0100
};
(Max5535) => {
0b0100
};
($max_ty:ident) => {
0b0000
};
}
macro_rules! doc_vref {
(Max5533) => {
"Vref::M1940"
};
(Max5535) => {
"Vref::M1940"
};
($max_ty:ident) => {
""
};
}
macro_rules! impl_standby_shutdown {
(Max5533) => {
impl_standby_shutdown!(@inner Max5533, Standby);
impl_standby_shutdown!(@inner Max5533, Shutdown);
};
(Max5535) => {
impl_standby_shutdown!(@inner Max5535, Standby);
impl_standby_shutdown!(@inner Max5535, Shutdown);
};
($max_ty:ident) => {
impl_standby_shutdown!(@inner $max_ty, Shutdown);
};
(@inner $max_ty:ident, $mode_ty:ident) => {
impl<SPI> $max_ty<SPI, $mode_ty>
where
SPI: SpiDevice<u8>
{
#[inline]
pub fn dac_ab(self) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
max_553x.dac_ab()?;
Ok(max_553x)
}
pub fn input_a_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
max_553x.input_a_dac_ab(value)?;
Ok(max_553x)
}
pub fn input_b_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
max_553x.input_b_dac_ab(value)?;
Ok(max_553x)
}
pub fn input_ab_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
max_553x.input_ab_dac_ab(value)?;
Ok(max_553x)
}
}
}
}
macro_rules! impl_max {
($(#[$attr:meta]),* $max_ty:ident) => {
$(
#[$attr]
)*
#[doc = concat!("use ", doc_imports!($max_ty), ";")]
#[doc = concat!("# SpiTransaction::write_vec(vec![0b1101_0000 | ", doc_vref_value!($max_ty), ", 0b00000000]), // Into normal mode.")]
#[doc = concat!("# SpiTransaction::write_vec(vec![0b1110_0000 | ", doc_vref_value!($max_ty), ", 0b00000000]), // Into shutdown mode.")]
#[doc = concat!("let dac = ", stringify!($max_ty), "::new(spi);")]
#[doc = concat!("let mut dac = dac.into_normal(", doc_vref!($max_ty), ")?;")]
#[doc = concat!("let dac = dac.into_shutdown(", doc_vref!($max_ty), ")?;")]
#[derive(Debug)]
pub struct $max_ty<SPI, MODE> {
spi: SPI,
_mode: PhantomData<MODE>,
}
impl<SPI> $max_ty<SPI, Shutdown> {
pub const fn new(spi: SPI) -> $max_ty<SPI, Shutdown> {
$max_ty { spi, _mode: PhantomData }
}
pub fn release(self) -> SPI {
self.spi
}
}
impl<SPI, MODE> $max_ty<SPI, MODE>
where
SPI: SpiDevice<u8>
{
#[inline]
pub fn input_a(&mut self, value: u16) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b0001, value))
}
#[inline]
pub fn input_b(&mut self, value: u16) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b0010, value))
}
impl_into_mode!("normal operation", $max_ty, Normal, into_normal, 0b1101);
impl_into_mode!("shutdown", $max_ty, Shutdown, into_shutdown, 0b1110);
}
impl<SPI> $max_ty<SPI, Normal>
where
SPI: SpiDevice<u8>
{
#[inline]
pub fn dac_ab(&mut self) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b1000, 0))
}
pub fn input_a_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b1001, value))
}
pub fn input_b_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b1010, value))
}
pub fn input_ab_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
self.spi.write(&command_bytes(0b1111, value))
}
impl_into_mode!("standby", $max_ty, Standby, into_standby, 0b1100);
}
impl_standby_shutdown!($max_ty);
}
}
impl_max!(
Max5532
);
impl_max!(
Max5533
);
impl_max!(
Max5534
);
impl_max!(
Max5535
);
#[derive(Debug, Clone, Copy)]
pub enum Vref {
M1214 = 0b00,
M1940 = 0b01,
M2425 = 0b10,
M3885 = 0b11,
}