#![no_std]
#![warn(missing_debug_implementations, missing_docs)]
mod encode;
mod status;
use core::fmt::Debug;
use embedded_hal::blocking::i2c::{Read, Write};
use encode::{encode_address, encode_command, encode_fast_command};
pub use status::DacStatus;
#[derive(Debug)]
pub struct MCP4725<I2C>
where
I2C: Read + Write,
{
i2c: I2C,
address: u8,
}
impl<I2C, E> MCP4725<I2C>
where
I2C: Read<Error = E> + Write<Error = E>,
{
pub fn new(i2c: I2C, user_address: u8) -> Self {
MCP4725 {
i2c,
address: encode_address(user_address),
}
}
pub fn set_dac(&mut self, power: PowerDown, data: u16) -> Result<(), E> {
let bytes = encode_command(CommandType::WriteDac, power, data);
self.i2c.write(self.address, &bytes)
}
pub fn set_dac_and_eeprom(&mut self, power: PowerDown, data: u16) -> Result<(), E> {
let bytes = encode_command(CommandType::WriteDacAndEEPROM, power, data);
self.i2c.write(self.address, &bytes)
}
pub fn set_dac_fast(&mut self, power: PowerDown, data: u16) -> Result<(), E> {
let bytes = encode_fast_command(power, data);
self.i2c.write(self.address, &bytes)
}
pub fn read(&mut self) -> Result<DacStatus, E> {
let mut buffer: [u8; 5] = [0; 5];
self.i2c.read(self.address, &mut buffer)?;
Ok(buffer.into())
}
pub fn wake_up(&mut self) -> Result<(), E> {
self.i2c.write(0x00, &[0x06u8])?;
Ok(())
}
pub fn reset(&mut self) -> Result<(), E> {
self.i2c.write(0x00, &[0x09u8])?;
Ok(())
}
pub fn destroy(self) -> I2C {
self.i2c
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(u8)]
pub enum PowerDown {
Normal = 0b00,
Resistor1kOhm = 0b01,
Resistor100kOhm = 0b10,
Resistor500kOhm = 0b11,
}
impl From<u8> for PowerDown {
fn from(mode: u8) -> Self {
match mode {
0b00 => PowerDown::Normal,
0b01 => PowerDown::Resistor1kOhm,
0b10 => PowerDown::Resistor100kOhm,
0b11 => PowerDown::Resistor500kOhm,
_ => panic!("Invalid powerdown value"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(u8)]
pub enum CommandType {
WriteDac = 0x40,
WriteDacAndEEPROM = 0x60,
}
#[derive(Debug, Eq, PartialEq)]
pub struct Command {
command_byte: u8,
data_byte_0: u8,
data_byte_1: u8,
}
impl Default for Command {
fn default() -> Self {
Self {
command_byte: CommandType::WriteDac as u8,
data_byte_0: 0,
data_byte_1: 0,
}
}
}