Skip to content

Commit 0ad1ca6

Browse files
committed
Implement blocking Read for I2C
1 parent d4732de commit 0ad1ca6

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/i2c.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::gpio::gpiob::{PB6, PB7, PB8, PB9};
2222
use crate::gpio::gpiof::PF6;
2323
use crate::gpio::gpiof::{PF0, PF1};
2424
use crate::gpio::AF4;
25-
use crate::hal::blocking::i2c::{Write, WriteRead};
25+
use crate::hal::blocking::i2c::{Read, Write, WriteRead};
2626
use crate::rcc::{Clocks, APB1};
2727
use crate::time::Hertz;
2828

@@ -207,6 +207,42 @@ macro_rules! hal {
207207
}
208208
}
209209

210+
impl<PINS> Read for I2c<$I2CX, PINS> {
211+
type Error = Error;
212+
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
213+
// TODO support transfers of more than 255 bytes
214+
assert!(buffer.len() < 256 && buffer.len() > 0);
215+
216+
// TODO do we have to explicitly wait here if the bus is busy (e.g. another
217+
// master is communicating)?
218+
219+
// START and prepare to receive `bytes`
220+
self.i2c.cr2.write(|w| {
221+
w.sadd()
222+
.bits(u16::from(addr << 1))
223+
.rd_wrn()
224+
.read()
225+
.nbytes()
226+
.bits(buffer.len() as u8)
227+
.start()
228+
.start()
229+
.autoend()
230+
.software()
231+
});
232+
233+
for byte in buffer {
234+
// Wait until we have received something
235+
busy_wait!(self.i2c, rxne, is_not_empty);
236+
237+
*byte = self.i2c.rxdr.read().rxdata().bits();
238+
}
239+
240+
// automatic STOP
241+
242+
Ok(())
243+
}
244+
}
245+
210246
impl<PINS> Write for I2c<$I2CX, PINS> {
211247
type Error = Error;
212248

0 commit comments

Comments
 (0)