use alloc::sync::Arc;
use embedded_hal::i2c::{I2c, SevenBitAddress};
use spin::Mutex;
use crate::{errors::AfeError, RegisterWritable};
pub(crate) struct Register<I2C, BF> {
_p: core::marker::PhantomData<BF>,
reg_addr: u8,
phy_addr: SevenBitAddress,
i2c: Arc<Mutex<I2C>>,
}
impl<I2C, BF> Register<I2C, BF>
where
I2C: I2c,
BF: RegisterWritable,
{
pub(crate) fn new(reg_addr: u8, phy_addr: SevenBitAddress, i2c: Arc<Mutex<I2C>>) -> Self {
Self {
_p: core::marker::PhantomData::default(),
reg_addr,
phy_addr,
i2c,
}
}
pub(crate) fn read(&mut self) -> Result<BF, AfeError<I2C::Error>> {
if self.reg_addr < 0x2a || (self.reg_addr > 0x2f && self.reg_addr < 0x3f) {
self.i2c
.lock()
.write(self.phy_addr, [0, 0, 0, 1].as_slice())?;
}
let output_buffer = [self.reg_addr];
let mut receive_buffer: [u8; 3] = [0, 0, 0];
self.i2c.lock().write(self.phy_addr, &output_buffer)?;
self.i2c.lock().read(self.phy_addr, &mut receive_buffer)?;
if self.reg_addr < 0x2a || (self.reg_addr > 0x2f && self.reg_addr < 0x3f) {
self.i2c
.lock()
.write(self.phy_addr, [0, 0, 0, 0].as_slice())?;
}
Ok(BF::from_reg_bytes(receive_buffer))
}
pub(crate) fn write(&mut self, value: BF) -> Result<(), AfeError<I2C::Error>> {
let mut buffer: [u8; 4] = [self.reg_addr, 0, 0, 0];
buffer[1..=3].copy_from_slice(&value.into_reg_bytes());
self.i2c.lock().write(self.phy_addr, buffer.as_slice())?;
Ok(())
}
}