Skip to content

Commit 6d71da4

Browse files
committed
Added RefCell blanket implementation for I2C to allow sharing, see rust-embedded#35
Signed-off-by: Daniel Egger <[email protected]>
1 parent 53cf9ab commit 6d71da4

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

src/blocking/i2c.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Blocking I2C API
22
3+
use core::cell::RefCell;
4+
35
/// Blocking read
46
pub trait Read {
57
/// Error type
@@ -84,3 +86,93 @@ pub trait WriteRead {
8486
buffer: &mut [u8],
8587
) -> Result<(), Self::Error>;
8688
}
89+
90+
/// Blanket implementations to enable I2C bus sharing via RefCell
91+
92+
/// # Example usage
93+
///
94+
/// ``` ignore
95+
/// let mut i2c = hal::I2c::i2c (...);
96+
///
97+
/// // Stash i2c instance into a RefCell for sharing
98+
/// let shared_i2c = RefCell::new(i2c);
99+
///
100+
/// // Pass it on to one or more drivers for devices on the same bus
101+
/// let mut driver_a = DriverA::new(&mut &shared_i2c);
102+
///
103+
/// // Use the shared bus with the drivers
104+
/// driver_a.do_stuff();
105+
///
106+
/// // Use it independently of a driver for direct bus interaction
107+
/// let mut data = [0; 2];
108+
/// shared_i2c.borrow_mut().read(0x11, &mut data);
109+
/// ```
110+
impl<'a, I> ::blocking::i2c::Read for &'a RefCell<I>
111+
where
112+
I: ::blocking::i2c::Read,
113+
{
114+
type Error = <I as Read>::Error;
115+
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
116+
self.borrow_mut().read(address, buffer)
117+
}
118+
}
119+
120+
/// # Example usage
121+
///
122+
/// ``` ignore
123+
/// let mut i2c = hal::I2c::i2c (...);
124+
///
125+
/// // Stash i2c instance into a RefCell for sharing
126+
/// let shared_i2c = RefCell::new(i2c);
127+
///
128+
/// // Pass it on to one or more drivers for devices on the same bus
129+
/// let mut driver_a = DriverA::new(&mut &shared_i2c);
130+
///
131+
/// // Use the shared bus with the drivers
132+
/// driver_a.do_stuff();
133+
///
134+
/// // Use it independently of a driver for direct bus interaction
135+
/// shared_i2c.borrow_mut().write(0x33, &[0x01, 0x02]);
136+
/// ```
137+
impl<'a, I> ::blocking::i2c::Write for &'a RefCell<I>
138+
where
139+
I: ::blocking::i2c::Write,
140+
{
141+
type Error = <I as Write>::Error;
142+
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
143+
self.borrow_mut().write(addr, bytes)
144+
}
145+
}
146+
147+
/// # Example usage
148+
///
149+
/// ``` ignore
150+
/// let mut i2c = hal::I2c::i2c (...);
151+
///
152+
/// // Stash i2c instance into a RefCell for sharing
153+
/// let shared_i2c = RefCell::new(i2c);
154+
///
155+
/// // Pass it on to one or more drivers for devices on the same bus
156+
/// let mut driver_a = DriverA::new(&mut &shared_i2c);
157+
///
158+
/// // Use the shared bus with the drivers
159+
/// driver_a.do_stuff();
160+
///
161+
/// // Use it independently of a driver for direct bus interaction
162+
/// let mut data = [0; 2];
163+
/// shared_i2c.borrow_mut().write_read(0x22, &[0x00], &mut data);
164+
/// ```
165+
impl<'a, I> ::blocking::i2c::WriteRead for &'a RefCell<I>
166+
where
167+
I: ::blocking::i2c::WriteRead,
168+
{
169+
type Error = <I as WriteRead>::Error;
170+
fn write_read(
171+
&mut self,
172+
address: u8,
173+
bytes: &[u8],
174+
buffer: &mut [u8],
175+
) -> Result<(), Self::Error> {
176+
self.borrow_mut().write_read(address, bytes, buffer)
177+
}
178+
}

0 commit comments

Comments
 (0)