1#![no_std]
5
6use core::marker::PhantomData;
7
8use embedded_hal::spi::SpiDevice;
9
10pub enum Normal {}
12
13pub enum Standby {}
15
16pub enum Shutdown {}
18
19const fn command_bytes(control_bits: u8, mut data_bits: u16) -> [u8; 2] {
20 if data_bits > 0b1111_1111_1111 {
21 data_bits = 0b1111_1111_1111
22 }
23
24 [(control_bits << 4) | ((data_bits >> 8) as u8 & 0xf), data_bits as u8]
25}
26
27const fn vref_command_bytes(control_bits: u8, vref: Vref) -> [u8; 2] {
28 [(control_bits << 4) | ((vref as u8) << 2), 0]
29}
30
31macro_rules! impl_into_mode {
32 ($desc:expr, Max5532, Standby, $fn_name:ident, $control_bits:expr) => {
33 };
35 ($desc:expr, Max5533, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
36 impl_into_mode!(@with_vref $desc, Max5533, $mode_ty, $fn_name, $control_bits);
37 };
38 ($desc:expr, Max5534, Standby, $fn_name:ident, $control_bits:expr) => {
39 };
41 ($desc:expr, Max5535, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
42 impl_into_mode!(@with_vref $desc, Max5535, $mode_ty, $fn_name, $control_bits);
43 };
44 ($desc:expr, $max_ty:ident, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
45 #[doc = $desc]
47 pub fn $fn_name(mut self) -> Result<$max_ty<SPI, $mode_ty>, SPI::Error> {
49 self.spi.write(&command_bytes($control_bits, 0))?;
50 Ok($max_ty { spi: self.spi, _mode: PhantomData })
51 }
52 };
53 (@with_vref $desc:expr, $max_ty:ident, $mode_ty:ident, $fn_name:ident, $control_bits:expr) => {
54 #[doc = $desc]
56 pub fn $fn_name(mut self, vref: Vref) -> Result<$max_ty<SPI, $mode_ty>, SPI::Error> {
58 self.spi.write(&vref_command_bytes($control_bits, vref))?;
59 Ok($max_ty { spi: self.spi, _mode: PhantomData })
60 }
61 };
62}
63
64macro_rules! doc_imports {
65 (Max5533) => {
66 "max553x::{Max5533, Vref}"
67 };
68 (Max5535) => {
69 "max553x::{Max5535, Vref}"
70 };
71 ($max_ty:ident) => {
72 concat!("max553x::", stringify!($max_ty))
73 };
74}
75
76macro_rules! doc_vref_value {
77 (Max5533) => {
78 0b0100
79 };
80 (Max5535) => {
81 0b0100
82 };
83 ($max_ty:ident) => {
84 0b0000
85 };
86}
87
88macro_rules! doc_vref {
89 (Max5533) => {
90 "Vref::M1940"
91 };
92 (Max5535) => {
93 "Vref::M1940"
94 };
95 ($max_ty:ident) => {
96 ""
97 };
98}
99
100macro_rules! impl_standby_shutdown {
101 (Max5533) => {
102 impl_standby_shutdown!(@inner Max5533, Standby);
103 impl_standby_shutdown!(@inner Max5533, Shutdown);
104 };
105 (Max5535) => {
106 impl_standby_shutdown!(@inner Max5535, Standby);
107 impl_standby_shutdown!(@inner Max5535, Shutdown);
108 };
109 ($max_ty:ident) => {
110 impl_standby_shutdown!(@inner $max_ty, Shutdown);
111 };
112 (@inner $max_ty:ident, $mode_ty:ident) => {
113 impl<SPI> $max_ty<SPI, $mode_ty>
114 where
115 SPI: SpiDevice<u8>
116 {
117 #[inline]
120 pub fn dac_ab(self) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
121 let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
122 max_553x.dac_ab()?;
123 Ok(max_553x)
124 }
125
126 pub fn input_a_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
130 let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
131 max_553x.input_a_dac_ab(value)?;
132 Ok(max_553x)
133 }
134
135 pub fn input_b_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
139 let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
140 max_553x.input_b_dac_ab(value)?;
141 Ok(max_553x)
142 }
143
144 pub fn input_ab_dac_ab(self, value: u16) -> Result<$max_ty<SPI, Normal>, SPI::Error> {
147 let mut max_553x: $max_ty<SPI, Normal> = $max_ty { spi: self.spi, _mode: PhantomData };
148 max_553x.input_ab_dac_ab(value)?;
149 Ok(max_553x)
150 }
151 }
152 }
153}
154
155macro_rules! impl_max {
156 ($(#[$attr:meta]),* $max_ty:ident) => {
157 $(
158 #[$attr]
159 )*
160 #[doc = concat!("use ", doc_imports!($max_ty), ";")]
166 #[doc = concat!("# SpiTransaction::write_vec(vec![0b1101_0000 | ", doc_vref_value!($max_ty), ", 0b00000000]), // Into normal mode.")]
170 #[doc = concat!("# SpiTransaction::write_vec(vec![0b1110_0000 | ", doc_vref_value!($max_ty), ", 0b00000000]), // Into shutdown mode.")]
188 #[doc = concat!("let dac = ", stringify!($max_ty), "::new(spi);")]
192 #[doc = concat!("let mut dac = dac.into_normal(", doc_vref!($max_ty), ")?;")]
195 #[doc = concat!("let dac = dac.into_shutdown(", doc_vref!($max_ty), ")?;")]
213 #[derive(Debug)]
223 pub struct $max_ty<SPI, MODE> {
224 spi: SPI,
225 _mode: PhantomData<MODE>,
226 }
227
228 impl<SPI> $max_ty<SPI, Shutdown> {
229 pub const fn new(spi: SPI) -> $max_ty<SPI, Shutdown> {
231 $max_ty { spi, _mode: PhantomData }
232 }
233
234 pub fn release(self) -> SPI {
236 self.spi
237 }
238 }
239
240 impl<SPI, MODE> $max_ty<SPI, MODE>
241 where
242 SPI: SpiDevice<u8>
243 {
244 #[inline]
246 pub fn input_a(&mut self, value: u16) -> Result<(), SPI::Error> {
247 self.spi.write(&command_bytes(0b0001, value))
248 }
249
250 #[inline]
252 pub fn input_b(&mut self, value: u16) -> Result<(), SPI::Error> {
253 self.spi.write(&command_bytes(0b0010, value))
254 }
255
256 impl_into_mode!("normal operation", $max_ty, Normal, into_normal, 0b1101);
257 impl_into_mode!("shutdown", $max_ty, Shutdown, into_shutdown, 0b1110);
258 }
259
260 impl<SPI> $max_ty<SPI, Normal>
261 where
262 SPI: SpiDevice<u8>
263 {
264 #[inline]
267 pub fn dac_ab(&mut self) -> Result<(), SPI::Error> {
268 self.spi.write(&command_bytes(0b1000, 0))
269 }
270
271 pub fn input_a_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
274 self.spi.write(&command_bytes(0b1001, value))
275 }
276
277 pub fn input_b_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
280 self.spi.write(&command_bytes(0b1010, value))
281 }
282
283 pub fn input_ab_dac_ab(&mut self, value: u16) -> Result<(), SPI::Error> {
285 self.spi.write(&command_bytes(0b1111, value))
286 }
287
288 impl_into_mode!("standby", $max_ty, Standby, into_standby, 0b1100);
289 }
290
291 impl_standby_shutdown!($max_ty);
292 }
293}
294
295impl_max!(
296 Max5532
298);
299impl_max!(
300 Max5533
302);
303impl_max!(
304 Max5534
306);
307impl_max!(
308 Max5535
310);
311
312#[derive(Debug, Clone, Copy)]
314pub enum Vref {
315 M1214 = 0b00,
317 M1940 = 0b01,
319 M2425 = 0b10,
321 M3885 = 0b11,
323}