use core::cell::RefCell;
use critical_section::{Mutex, with};
use embedded_hal::i2c::I2c;
#[cfg(feature = "async")]
use crate::driver::PinSignal;
use crate::{
access::DriverHandler,
driver::{ReadInputsResult, Xl9555},
error::Xl9555Error,
};
pub struct Xl9555Shared<I: I2c> {
inner: Mutex<RefCell<Xl9555<I>>>,
#[cfg(feature = "async")]
signals: [crate::driver::PinSignal; 16],
}
impl<I> DriverHandler for Xl9555Shared<I>
where
I: I2c,
{
type Error = Xl9555Error<I::Error>;
type I2c = I;
fn new(i2c: Self::I2c, a3: bool, a2: bool, a1: bool) -> Result<Self, Self::Error> {
#[cfg(feature = "async")]
const PIN_SIGNAL: PinSignal = PinSignal::new();
Ok(Xl9555Shared {
inner: Mutex::new(RefCell::new(Xl9555::new(i2c, a3, a2, a1)?)),
#[cfg(feature = "async")]
signals: [PIN_SIGNAL; 16],
})
}
fn read_inputs(&self) -> Result<ReadInputsResult, Self::Error> {
with(|cs| self.inner.borrow(cs).borrow_mut().read_inputs())
}
fn set_direction(
&self,
pin: crate::types::PinId,
direction: crate::types::Direction,
) -> Result<(), Self::Error> {
with(|cs| {
self.inner
.borrow(cs)
.borrow_mut()
.set_direction(pin, direction)
})
}
fn get_direction(
&self,
pin: crate::types::PinId,
) -> Result<crate::types::Direction, Self::Error> {
with(|cs| self.inner.borrow(cs).borrow().get_direction(pin))
}
fn set_level(
&self,
pin: crate::types::PinId,
level: embedded_hal::digital::PinState,
) -> Result<(), Self::Error> {
with(|cs| self.inner.borrow(cs).borrow_mut().set_level(pin, level))
}
fn get_level(
&self,
pin: crate::types::PinId,
) -> Result<embedded_hal::digital::PinState, Self::Error> {
with(|cs| self.inner.borrow(cs).borrow_mut().get_level(pin))
}
fn get_set_level(
&self,
pin: crate::types::PinId,
) -> Result<embedded_hal::digital::PinState, Self::Error> {
with(|cs| self.inner.borrow(cs).borrow().get_set_level(pin))
}
#[cfg(feature = "async")]
fn get_signals(&self) -> &[PinSignal; 16] {
&self.signals
}
}