use core::cell::RefCell;
use critical_section::Mutex;
use embedded_hal::i2c::{ErrorType, I2c};
pub struct CriticalSectionDevice<'a, T> {
bus: &'a Mutex<RefCell<T>>,
}
impl<'a, T> CriticalSectionDevice<'a, T> {
#[inline]
pub fn new(bus: &'a Mutex<RefCell<T>>) -> Self {
Self { bus }
}
}
impl<'a, T> ErrorType for CriticalSectionDevice<'a, T>
where
T: I2c,
{
type Error = T::Error;
}
impl<'a, T> I2c for CriticalSectionDevice<'a, T>
where
T: I2c,
{
#[inline]
fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
critical_section::with(|cs| {
let bus = &mut *self.bus.borrow_ref_mut(cs);
bus.read(address, read)
})
}
#[inline]
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
critical_section::with(|cs| {
let bus = &mut *self.bus.borrow_ref_mut(cs);
bus.write(address, write)
})
}
#[inline]
fn write_read(
&mut self,
address: u8,
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
critical_section::with(|cs| {
let bus = &mut *self.bus.borrow_ref_mut(cs);
bus.write_read(address, write, read)
})
}
#[inline]
fn transaction(
&mut self,
address: u8,
operations: &mut [embedded_hal::i2c::Operation<'_>],
) -> Result<(), Self::Error> {
critical_section::with(|cs| {
let bus = &mut *self.bus.borrow_ref_mut(cs);
bus.transaction(address, operations)
})
}
}