Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added RefCell blanket implementation for I2C to allow sharing, see #35 #55

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions src/blocking/i2c.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Blocking I2C API

use core::cell::RefCell;

/// Blocking read
pub trait Read {
/// Error type
Expand Down Expand Up @@ -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<I>
where
I: ::blocking::i2c::Read,
{
type Error = <I as Read>::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<I>
where
I: ::blocking::i2c::Write,
{
type Error = <I as Write>::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<I>
where
I: ::blocking::i2c::WriteRead,
{
type Error = <I as WriteRead>::Error;
fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.borrow_mut().write_read(address, bytes, buffer)
}
}