#![no_std]
#![deny(warnings)]
use bit_field::BitField;
use embedded_hal::i2c::{ErrorType, I2c};
#[allow(dead_code)]
#[doc(hidden)]
enum Command {
ReadLocalTemperature = 0x00,
ReadRemoteTemperature = 0x01,
ReadStatusByte = 0x02,
ReadConfigurationByte = 0x03,
ReadLocalHighLimit = 0x05,
ReadRemoteHighLimit = 0x07,
WriteConfigurationByte = 0x09,
WriteLocalHighLimit = 0x0b,
WriteRemoteHighLimit = 0x0d,
SingleShot = 0x0f,
ReadRemoteExtendedTemperature = 0x10,
ReadInternalExtendedTemperature = 0x11,
ReadManufacturerId = 0xfe,
}
impl Command {
fn is_writable(&self) -> bool {
match self {
Command::WriteConfigurationByte
| Command::WriteLocalHighLimit
| Command::WriteRemoteHighLimit
| Command::SingleShot => true,
_ => false,
}
}
}
#[derive(Debug)]
pub enum Error<E> {
Interface(E),
DiodeFault,
InvalidCommand,
}
impl<E> From<E> for Error<E> {
fn from(err: E) -> Error<E> {
Error::Interface(err)
}
}
pub struct Max6642<I2C> {
i2c: I2C,
address: u8,
}
impl<I2C> Max6642<I2C>
where
I2C: I2c,
<I2C as ErrorType>::Error: Into<<I2C as ErrorType>::Error>,
{
pub fn att94(i2c: I2C) -> Self {
Max6642::new(i2c, 0x4A)
}
pub fn new(i2c: I2C, address: u8) -> Self {
Max6642 { i2c, address }
}
fn read(&mut self, command: Command) -> Result<u8, Error<<I2C as ErrorType>::Error>> {
let mut result: [u8; 1] = [0; 1];
self.i2c
.write_read(self.address, &[command as u8], &mut result)?;
Ok(result[0])
}
#[allow(dead_code)]
fn write(
&mut self,
command: Command,
value: u8,
) -> Result<(), Error<<I2C as ErrorType>::Error>> {
if !command.is_writable() {
return Err(Error::InvalidCommand);
}
self.i2c.write(self.address, &[command as u8, value])?;
Ok(())
}
pub fn get_remote_temperature(&mut self) -> Result<f32, Error<<I2C as ErrorType>::Error>> {
let temp_c = self.read(Command::ReadRemoteTemperature)?;
if temp_c > 130 {
return Err(Error::DiodeFault);
}
let temp_c_4ths = self
.read(Command::ReadRemoteExtendedTemperature)?
.get_bits(6..8);
let temp_c = (temp_c as f32) + (temp_c_4ths as f32) * 0.25;
Ok(temp_c)
}
}