xl9555-hal 0.3.0

embedded-hal driver for the XL9555 GPIO expander
Documentation
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
    }
}