dac7571/lib.rs
1//! Driver for the DAC7571 digital-to-analog converter.
2//!
3//! # Note
4//! This driver does not support any low-power operation modes.
5#![no_std]
6
7use embedded_hal::i2c::{ErrorType, I2c};
8
9/// A driver for the DAC7571 digital to analog converter.
10pub struct Dac7571<I2C> {
11 i2c: I2C,
12 address: u8,
13 supply_voltage: f32,
14}
15
16/// Represents errors that can be generated by the DAC driver.
17#[derive(Debug)]
18pub enum Error<E> {
19 Bounds,
20 Interface(E),
21}
22
23impl<E> From<E> for Error<E> {
24 fn from(err: E) -> Error<E> {
25 Error::Interface(err)
26 }
27}
28
29impl<I2C> Dac7571<I2C>
30where
31 I2C: I2c,
32{
33 /// Construct a new DAC7571 driver.
34 ///
35 /// # Args
36 /// * `i2c` - The I2C interface to use to communicate with the DAC.
37 /// * `address` - The I2C address of the device.
38 /// * `vdd` - The VDD supplied to the DAC in volts.
39 pub fn new(i2c: I2C, address: u8, vdd: f32) -> Self {
40 Dac7571 {
41 i2c,
42 address,
43 supply_voltage: vdd,
44 }
45 }
46
47 /// Construct a default DAC7571.
48 ///
49 /// # Note
50 /// A default configuration assumes 3.3V VDD and the address bit held low.
51 ///
52 /// # Args
53 /// * `i2c` - The I2C interface to use to communicate with the DAC.
54 pub fn default(i2c: I2C) -> Self {
55 Dac7571::new(i2c, 0x4C, 3.3)
56 }
57
58 /// Configure the DAC output voltage.
59 ///
60 /// # Args
61 /// * `voltage` - The desired DAC output voltage.
62 ///
63 /// # Returns
64 /// The voltage nominal DAC output voltage.
65 pub fn set_voltage(&mut self, voltage: f32) -> Result<f32, Error<<I2C as ErrorType>::Error>> {
66 if voltage >= self.supply_voltage || voltage < 0.0 {
67 return Err(Error::Bounds);
68 }
69
70 let dac_code = (voltage / self.supply_voltage * 4096.0) as u16 & 0xFFF;
71 self.i2c.write(self.address, &dac_code.to_be_bytes())?;
72
73 let dac_output = dac_code as f32 / 4096.0 * self.supply_voltage;
74 Ok(dac_output)
75 }
76}