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}