#![no_std]
#![deny(missing_docs)]
extern crate embedded_hal as hal;
#[macro_use]
extern crate bitflags;
use core::fmt::Debug;
use hal::blocking::i2c::{Write, WriteRead};
use hal::digital::OutputPin;
pub mod registers;
use registers as reg;
#[derive(Debug)]
pub enum Error<I> {
NotEnabled,
I2cError(I),
}
#[derive(Copy, Clone)]
pub enum Addr {
_0x32,
_0x33,
_0x34,
_0x35,
}
impl From<Addr> for u8 {
fn from(a: Addr) -> Self {
match a {
Addr::_0x32 => 0x32_u8,
Addr::_0x33 => 0x33_u8,
Addr::_0x34 => 0x34_u8,
Addr::_0x35 => 0x35_u8,
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum D {
D1,
D2,
D3,
D4,
D5,
D6,
D7,
D8,
D9,
}
impl From<D> for u8 {
fn from(d: D) -> Self {
match d {
D::D1 => 0,
D::D2 => 1,
D::D3 => 2,
D::D4 => 3,
D::D5 => 4,
D::D6 => 5,
D::D7 => 6,
D::D8 => 7,
D::D9 => 8,
}
}
}
pub struct Lp55231<I, P> {
i2c: I,
en_pin: Option<P>,
addr: u8,
en: bool,
}
impl<E, I, P> Lp55231<I, P>
where
E: Debug,
I: Write<Error = E> + WriteRead<Error = E>,
P: OutputPin,
{
pub fn new(i2c: I, en_pin: Option<P>, addr: Addr) -> Self {
Lp55231 {
i2c,
en_pin,
addr: u8::from(addr) << 1,
en: false,
}
}
fn send(&mut self, bytes: &[u8]) -> Result<(), Error<E>> {
if self.en {
self.i2c.write(self.addr, bytes).map_err(|e| Error::I2cError(e))
} else {
Err(Error::NotEnabled)
}
}
pub fn enable(&mut self) -> Result<(), Error<E>> {
if let Some(p) = self.en_pin.as_mut() {
p.set_high();
}
self.en = true;
self.send(&[reg::CNTRL1, (reg::Cntrl1::CHIP_EN).bits()])?;
self.send(&[
reg::MISC,
(reg::Misc::INT_CLK_EN
| reg::Misc::CLK_DET_EN
| reg::Misc::CP_MODE_1_5x
| reg::Misc::EN_AUTO_INCR)
.bits(),
])?;
Ok(())
}
pub fn reset(&mut self) -> Result<(), Error<E>> {
self.send(&[reg::Reset::RESET_NOW.bits()])?;
Ok(())
}
pub fn disable(&mut self) {
if let Some(p) = self.en_pin.as_mut() {
p.set_low();
}
self.en = false;
}
pub fn set_pwm(&mut self, d: D, pwm: u8) -> Result<(), Error<E>> {
self.send(&[reg::D_PWM_BASE + u8::from(d), pwm])?;
Ok(())
}
}