use hal::blocking::i2c;
use {
register::{Config2, Enable, Status},
Apds9960, BitFlags, Error, LightData, Register,
};
impl<I2C, E> Apds9960<I2C>
where
I2C: i2c::Write<Error = E> + i2c::WriteRead<Error = E>,
{
pub fn enable_light(&mut self) -> Result<(), Error<E>> {
self.set_flag_enable(Enable::AEN, true)
}
pub fn disable_light(&mut self) -> Result<(), Error<E>> {
self.set_flag_enable(Enable::AEN, false)
}
pub fn set_light_integration_time(&mut self, value: u8) -> Result<(), Error<E>> {
self.write_register(Register::ATIME, value)
}
pub fn enable_light_interrupts(&mut self) -> Result<(), Error<E>> {
self.set_flag_enable(Enable::AIEN, true)
}
pub fn disable_light_interrupts(&mut self) -> Result<(), Error<E>> {
self.set_flag_enable(Enable::AIEN, false)
}
pub fn enable_light_saturation_interrupts(&mut self) -> Result<(), Error<E>> {
self.set_flag_config2(Config2::CPSIEN, true)
}
pub fn disable_light_saturation_interrupts(&mut self) -> Result<(), Error<E>> {
self.set_flag_config2(Config2::CPSIEN, false)
}
pub fn set_light_low_threshold(&mut self, threshold: u16) -> Result<(), Error<E>> {
self.write_double_register(Register::AILTL, threshold)
}
pub fn set_light_high_threshold(&mut self, threshold: u16) -> Result<(), Error<E>> {
self.write_double_register(Register::AIHTL, threshold)
}
pub fn clear_light_interrupt(&mut self) -> Result<(), Error<E>> {
self.touch_register(Register::CICLEAR)
}
pub fn read_light(&mut self) -> nb::Result<LightData, Error<E>> {
if !self.is_light_data_valid().map_err(nb::Error::Other)? {
return Err(nb::Error::WouldBlock);
}
let mut data = [0; 8];
self.read_data(Register::CDATAL, &mut data)
.map_err(nb::Error::Other)?;
Ok(LightData {
clear: (u16::from(data[1]) << 8) | u16::from(data[0]),
red: (u16::from(data[3]) << 8) | u16::from(data[2]),
green: (u16::from(data[5]) << 8) | u16::from(data[4]),
blue: (u16::from(data[7]) << 8) | u16::from(data[6]),
})
}
pub fn read_light_clear(&mut self) -> nb::Result<u16, Error<E>> {
self.read_light_channel(Register::CDATAL)
}
pub fn read_light_red(&mut self) -> nb::Result<u16, Error<E>> {
self.read_light_channel(Register::RDATAL)
}
pub fn read_light_green(&mut self) -> nb::Result<u16, Error<E>> {
self.read_light_channel(Register::GDATAL)
}
pub fn read_light_blue(&mut self) -> nb::Result<u16, Error<E>> {
self.read_light_channel(Register::BDATAL)
}
#[allow(clippy::wrong_self_convention)]
pub fn is_light_data_valid(&mut self) -> Result<bool, Error<E>> {
let status = self.read_register(Register::STATUS)?;
Ok(Status::new(status).is(Status::AVALID, true))
}
fn read_light_channel(&mut self, register: u8) -> nb::Result<u16, Error<E>> {
if !self.is_light_data_valid().map_err(nb::Error::Other)? {
return Err(nb::Error::WouldBlock);
}
let mut data = [0; 2];
self.read_data(register, &mut data)
.map_err(nb::Error::Other)?;
Ok((u16::from(data[1]) << 8) | u16::from(data[0]))
}
}