#![deny(missing_docs)]
#![deny(warnings)]
#![no_std]
extern crate embedded_hal as hal;
use hal::blocking::i2c;
use core::marker::PhantomData;
pub struct Tsl2561<I2C> {
i2c: PhantomData<I2C>,
address: u8,
}
impl<I2C, E> Tsl2561<I2C>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
{
pub fn new(_i2c: &I2C, address: u8) -> Result<Self, E> {
let tsl2561 = Tsl2561 {
i2c: PhantomData,
address,
};
Ok(tsl2561)
}
pub fn power_on(&self, i2c: &mut I2C) -> Result<(), E> {
let command = Command::new(Register::CONTROL).value();
let power_on = 0x03;
i2c.write(self.address, &[command, power_on])
}
pub fn power_off(&self, i2c: &mut I2C) -> Result<(), E> {
let command = Command::new(Register::CONTROL).value();
let power_on = 0x00;
i2c.write(self.address, &[command, power_on])
}
pub fn visible_and_ir_raw(&self, i2c: &mut I2C) -> Result<u16, E> {
let command = Command::new(Register::DATA0LOW)
.enable_word_protocol().value();
let mut buffer : [u8;2] = [0;2];
i2c.write_read(self.address, &[command], &mut buffer)?;
let result = ((buffer[1] as u16) << 8) | buffer[0] as u16;
Ok(result)
}
pub fn ir_raw(&self, i2c: &mut I2C) -> Result<u16, E> {
let command = Command::new(Register::DATA1LOW)
.enable_word_protocol().value();
let mut buffer : [u8;2] = [0;2];
i2c.write_read(self.address, &[command], &mut buffer)?;
let result = ((buffer[1] as u16) << 8) | buffer[0] as u16;
Ok(result)
}
pub fn config_time_gain(&self, i2c: &mut I2C, integration_time: IntegrationTime, gain: Gain)
-> Result<(), E>
{
let command = Command::new(Register::TIMING).value();
let setting = (*&integration_time as u8) | ((*&gain as u8) << 4);
i2c.write(self.address, &[command, setting])
}
}
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
enum Register {
CONTROL = 0x0,
TIMING = 0x1,
THRESHLOWLOW = 0x2,
THRESHLOWHIGH = 0x3,
THRESHHIGHLOW = 0x4,
THRESHHIGHHIGH = 0x5,
INTERRUPT = 0x6,
CRC = 0x8,
ID = 0xA,
DATA0LOW = 0xC,
DATA0HIGH = 0xD,
DATA1LOW = 0xE,
DATA1HIGH = 0xF,
}
impl Register {
pub fn addr(&self) -> u8 {
*self as u8
}
}
struct Command {
cmd: bool,
clear: bool,
word: bool,
block: bool,
register: Register,
}
impl Command {
fn new(register: Register) -> Self {
Self {
cmd: true,
clear: false,
word: false,
block: false,
register,
}
}
fn enable_word_protocol(mut self) -> Self {
self.word = true;
self
}
fn value(self) -> u8 {
self.register.addr() |
((self.cmd as u8) << 7) |
((self.clear as u8) << 6) |
((self.word as u8) << 5) |
((self.block as u8) << 4)
}
}
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum SlaveAddr {
ADDR_0x39 = 0x39,
ADDR_0x29 = 0x29,
ADDR_0x49 = 0x49,
}
impl Default for SlaveAddr {
fn default() -> Self {
SlaveAddr::ADDR_0x39
}
}
impl SlaveAddr {
pub fn addr(&self) -> u8 {
*self as u8
}
}
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum IntegrationTime {
ms_13 = 0,
ms_101 = 1,
ms_402 = 2,
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Gain {
Low = 0,
High = 1,
}