use crate::com::i2c;
use crate::delay::delay_ms;
use fixed_slice_vec::FixedSliceVec;
#[repr(C, packed)]
pub struct AHT10<'a> {
address: u8,
i2c: i2c::Twi,
vec: FixedSliceVec<'a, u8>,
}
const AHT10_INIT_CMD: u8 = 0xE1; const AHT10_START_MEASURMENT_CMD: u8 = 0xAC; const AHT10_SOFT_RESET_CMD: u8 = 0xBA; const AHT10_INIT_CAL_ENABLE: u8 = 0x08; const AHT10_INIT_BUSY: u8 = 0x08;
impl<'a> AHT10<'a> {
pub fn new(&mut self) -> &'static mut Self {
delay_ms(20);
self.soft_reset();
unsafe {
if !self.initialise() {
unreachable!();
}
}
unsafe { &mut *(0x38 as *mut Self) }
}
pub fn get() -> &'static mut Self {
unsafe { &mut *(0x38 as *mut Self) }
}
pub unsafe fn initialise(&mut self) -> bool {
self.vec.clear();
self.vec.push(AHT10_INIT_CMD);
self.vec.push(0x33);
self.vec.push(0x00);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!();
}
self.wait_for_idle();
if !(self.status() == 0 && AHT10_INIT_CAL_ENABLE == 0) {
return false;
}
return true;
}
pub fn soft_reset(&mut self) {
self.vec.clear();
self.vec.push(AHT10_SOFT_RESET_CMD);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!()
}
}
pub unsafe fn read_to_buffer(&mut self) {
if !self
.i2c
.read_from_slave(self.address, self.vec.len(), &mut self.vec)
{
unreachable!();
}
}
pub unsafe fn trigger_slave(&mut self) {
self.vec.clear();
self.vec.push(AHT10_START_MEASURMENT_CMD);
self.vec.push(0x33);
self.vec.push(0x00);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!();
}
}
pub unsafe fn wait_for_idle(&mut self) {
while (self.status() == 0 && AHT10_INIT_BUSY == 0) == true {
delay_ms(5);
}
}
pub unsafe fn perform_measurement(&mut self) {
self.trigger_slave();
self.wait_for_idle();
self.read_to_buffer();
}
pub unsafe fn status(&mut self) -> u8 {
self.read_to_buffer();
return self.vec[0];
}
pub fn relative_humidity(&mut self) -> f64 {
unsafe {
self.perform_measurement();
let mut humid: f64 = (((self.vec[1] as u32) << 12)
| ((self.vec[2] as u32) << 4)
| ((self.vec[3] as u32) >> 4)) as f64;
humid = (humid * 100.0) / 0x100000 as f64;
return humid;
}
}
pub fn temperature(&mut self) -> f64 {
unsafe {
self.perform_measurement();
let mut temp: f64 = ((((self.vec[3] as u32) & 0xF) << 16)
| (self.vec[4] as u32) << 8
| (self.vec[5]) as u32) as f64;
temp = ((temp as f64 * 200.0) / 0x100000 as f64) - 50.0;
return temp;
}
}
}