#![cfg_attr(not(test), no_std)]
use embedded_hal_async::i2c::I2c;
const DEVICE_ADDRESS: u8 = 0x54;
#[derive(Debug)]
pub enum Error<I> {
I2c(I),
Conn,
Address,
Port,
}
impl<I> From<I> for Error<I> {
fn from(error: I) -> Self {
Error::I2c(error)
}
}
pub struct Is31Fl3218<I2C> {
i2c: I2C,
cmd_buf: [u8; 23],
}
impl<I2C, E> Is31Fl3218<I2C>
where
I2C: I2c<Error = E>,
E: Into<Error<E>>,
{
pub fn new(i2c: I2C) -> Self {
Self {
i2c,
cmd_buf: [0; 23],
}
}
async fn write_raw(&mut self, len: usize) -> Result<(), Error<E>> {
self.i2c.write(DEVICE_ADDRESS, &self.cmd_buf[..=len]).await?;
Ok(())
}
async fn write(&mut self, register: u8, values: &[u8]) -> Result<(), Error<E>> {
let len = values.len();
if len > 23 {
return Err(Error::Address);
}
self.cmd_buf[0x0] = register;
self.cmd_buf[0x1..=len].copy_from_slice(values);
self.write_raw(len).await?;
Ok(())
}
pub async fn enable_device(&mut self) -> Result<(), Error<E>> {
self.write(0x0, &[0x1]).await?;
Ok(())
}
pub async fn shutdown_device(&mut self) -> Result<(), Error<E>> {
self.write(0x0, &[0]).await?;
Ok(())
}
pub async fn enable_channel(&mut self, led: usize) -> Result<(), Error<E>> {
if led > 0x11 {
return Err(Error::Address);
}
let register: u8 = 0x13 + led as u8 / 6;
let bit: u8 = (led as u8 - 1) % 6;
self.write(register, &[1 << bit]).await?;
self.write(0x16, &[0]).await?;
Ok(())
}
pub async fn enable_all(&mut self) -> Result<(), Error<E>> {
self.write(0x13, &[0x3f; 3]).await?;
self.write(0x16, &[0]).await?;
Ok(())
}
pub async fn set(&mut self, led: usize, brightness: u8) -> Result<(), Error<E>> {
if led > 0x11 {
return Err(Error::Address);
}
self.write(0x1 + led as u8, &[brightness]).await?;
self.write(0x16, &[0]).await?;
Ok(())
}
pub async fn set_many(&mut self, start_led: usize, values: &[u8]) -> Result<(), Error<E>> {
let len = values.len();
if start_led + len > 0x12 {
return Err(Error::Address);
}
self.write(0x1 + start_led as u8, values).await?;
self.write(0x16, &[0]).await?;
Ok(())
}
pub async fn set_all(&mut self, values: &[u8; 18]) -> Result<(), Error<E>> {
self.cmd_buf[0] = 0x1;
self.cmd_buf[0x1..=0x12].copy_from_slice(values);
self.cmd_buf[0x13..=0x15].copy_from_slice(&[0x3f; 3]);
self.cmd_buf[0x16] = 0x0;
self.write_raw(22).await?;
Ok(())
}
pub async fn reset(&mut self) -> Result<(), Error<E>> {
self.write(0x17, &[0]).await?;
Ok(())
}
}