From 6d71da46553c4306d507783873362762c8b8ed8c Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Mon, 5 Mar 2018 19:20:17 +0100 Subject: [PATCH] Added RefCell blanket implementation for I2C to allow sharing, see #35 Signed-off-by: Daniel Egger --- src/blocking/i2c.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/blocking/i2c.rs b/src/blocking/i2c.rs index 7a8ea3f3d..4cc3a6a7a 100644 --- a/src/blocking/i2c.rs +++ b/src/blocking/i2c.rs @@ -1,5 +1,7 @@ //! Blocking I2C API +use core::cell::RefCell; + /// Blocking read pub trait Read { /// Error type @@ -84,3 +86,93 @@ pub trait WriteRead { buffer: &mut [u8], ) -> Result<(), Self::Error>; } + +/// Blanket implementations to enable I2C bus sharing via RefCell + +/// # Example usage +/// +/// ``` ignore +/// let mut i2c = hal::I2c::i2c (...); +/// +/// // Stash i2c instance into a RefCell for sharing +/// let shared_i2c = RefCell::new(i2c); +/// +/// // Pass it on to one or more drivers for devices on the same bus +/// let mut driver_a = DriverA::new(&mut &shared_i2c); +/// +/// // Use the shared bus with the drivers +/// driver_a.do_stuff(); +/// +/// // Use it independently of a driver for direct bus interaction +/// let mut data = [0; 2]; +/// shared_i2c.borrow_mut().read(0x11, &mut data); +/// ``` +impl<'a, I> ::blocking::i2c::Read for &'a RefCell +where + I: ::blocking::i2c::Read, +{ + type Error = ::Error; + fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.borrow_mut().read(address, buffer) + } +} + +/// # Example usage +/// +/// ``` ignore +/// let mut i2c = hal::I2c::i2c (...); +/// +/// // Stash i2c instance into a RefCell for sharing +/// let shared_i2c = RefCell::new(i2c); +/// +/// // Pass it on to one or more drivers for devices on the same bus +/// let mut driver_a = DriverA::new(&mut &shared_i2c); +/// +/// // Use the shared bus with the drivers +/// driver_a.do_stuff(); +/// +/// // Use it independently of a driver for direct bus interaction +/// shared_i2c.borrow_mut().write(0x33, &[0x01, 0x02]); +/// ``` +impl<'a, I> ::blocking::i2c::Write for &'a RefCell +where + I: ::blocking::i2c::Write, +{ + type Error = ::Error; + fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.borrow_mut().write(addr, bytes) + } +} + +/// # Example usage +/// +/// ``` ignore +/// let mut i2c = hal::I2c::i2c (...); +/// +/// // Stash i2c instance into a RefCell for sharing +/// let shared_i2c = RefCell::new(i2c); +/// +/// // Pass it on to one or more drivers for devices on the same bus +/// let mut driver_a = DriverA::new(&mut &shared_i2c); +/// +/// // Use the shared bus with the drivers +/// driver_a.do_stuff(); +/// +/// // Use it independently of a driver for direct bus interaction +/// let mut data = [0; 2]; +/// shared_i2c.borrow_mut().write_read(0x22, &[0x00], &mut data); +/// ``` +impl<'a, I> ::blocking::i2c::WriteRead for &'a RefCell +where + I: ::blocking::i2c::WriteRead, +{ + type Error = ::Error; + fn write_read( + &mut self, + address: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Self::Error> { + self.borrow_mut().write_read(address, bytes, buffer) + } +}