Skip to content

Commit 8d5fa95

Browse files
committed
both embedded-hals for I2C
1 parent 81202b8 commit 8d5fa95

File tree

4 files changed

+309
-0
lines changed

4 files changed

+309
-0
lines changed

src/fmpi2c.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::rcc::{Enable, Reset};
77
use crate::time::{Hertz, U32Ext};
88

99
mod hal_02;
10+
mod hal_1;
1011

1112
/// I2C FastMode+ abstraction
1213
pub struct FMPI2c<I2C, PINS> {

src/fmpi2c/hal_1.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
mod blocking {
2+
use super::super::{fmpi2c1, Error, FMPI2c};
3+
use core::ops::Deref;
4+
use embedded_hal_one::i2c::blocking::{Read, Write, WriteRead};
5+
6+
impl<I2C, PINS> WriteRead for FMPI2c<I2C, PINS>
7+
where
8+
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
9+
{
10+
type Error = Error;
11+
12+
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
13+
// Set up current slave address for writing and disable autoending
14+
self.i2c.cr2.modify(|_, w| {
15+
w.sadd()
16+
.bits(u16::from(addr) << 1)
17+
.nbytes()
18+
.bits(bytes.len() as u8)
19+
.rd_wrn()
20+
.clear_bit()
21+
.autoend()
22+
.clear_bit()
23+
});
24+
25+
// Send a START condition
26+
self.i2c.cr2.modify(|_, w| w.start().set_bit());
27+
28+
// Wait until the transmit buffer is empty and there hasn't been any error condition
29+
while {
30+
let isr = self.i2c.isr.read();
31+
self.check_and_clear_error_flags(&isr)?;
32+
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
33+
} {}
34+
35+
// Send out all individual bytes
36+
for c in bytes {
37+
self.send_byte(*c)?;
38+
}
39+
40+
// Wait until data was sent
41+
while {
42+
let isr = self.i2c.isr.read();
43+
self.check_and_clear_error_flags(&isr)?;
44+
isr.tc().bit_is_clear()
45+
} {}
46+
47+
// Set up current address for reading
48+
self.i2c.cr2.modify(|_, w| {
49+
w.sadd()
50+
.bits(u16::from(addr) << 1)
51+
.nbytes()
52+
.bits(buffer.len() as u8)
53+
.rd_wrn()
54+
.set_bit()
55+
});
56+
57+
// Send another START condition
58+
self.i2c.cr2.modify(|_, w| w.start().set_bit());
59+
60+
// Send the autoend after setting the start to get a restart
61+
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());
62+
63+
// Now read in all bytes
64+
for c in buffer.iter_mut() {
65+
*c = self.recv_byte()?;
66+
}
67+
68+
// Check and clear flags if they somehow ended up set
69+
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
70+
71+
Ok(())
72+
}
73+
}
74+
75+
impl<I2C, PINS> Read for FMPI2c<I2C, PINS>
76+
where
77+
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
78+
{
79+
type Error = Error;
80+
81+
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
82+
// Set up current address for reading
83+
self.i2c.cr2.modify(|_, w| {
84+
w.sadd()
85+
.bits(u16::from(addr) << 1)
86+
.nbytes()
87+
.bits(buffer.len() as u8)
88+
.rd_wrn()
89+
.set_bit()
90+
});
91+
92+
// Send a START condition
93+
self.i2c.cr2.modify(|_, w| w.start().set_bit());
94+
95+
// Send the autoend after setting the start to get a restart
96+
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());
97+
98+
// Now read in all bytes
99+
for c in buffer.iter_mut() {
100+
*c = self.recv_byte()?;
101+
}
102+
103+
// Check and clear flags if they somehow ended up set
104+
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
105+
106+
Ok(())
107+
}
108+
}
109+
110+
impl<I2C, PINS> Write for FMPI2c<I2C, PINS>
111+
where
112+
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
113+
{
114+
type Error = Error;
115+
116+
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
117+
// Set up current slave address for writing and enable autoending
118+
self.i2c.cr2.modify(|_, w| {
119+
w.sadd()
120+
.bits(u16::from(addr) << 1)
121+
.nbytes()
122+
.bits(bytes.len() as u8)
123+
.rd_wrn()
124+
.clear_bit()
125+
.autoend()
126+
.set_bit()
127+
});
128+
129+
// Send a START condition
130+
self.i2c.cr2.modify(|_, w| w.start().set_bit());
131+
132+
// Send out all individual bytes
133+
for c in bytes {
134+
self.send_byte(*c)?;
135+
}
136+
137+
// Check and clear flags if they somehow ended up set
138+
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
139+
140+
Ok(())
141+
}
142+
}
143+
}

src/i2c.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::rcc::Clocks;
1818
use crate::time::{Hertz, U32Ext};
1919

2020
mod hal_02;
21+
mod hal_1;
2122

2223
#[derive(Debug, Eq, PartialEq)]
2324
pub enum DutyCycle {

src/i2c/hal_1.rs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
use embedded_hal_one::i2c::{Error, ErrorKind, NoAcknowledgeSource};
2+
3+
impl Error for super::Error {
4+
fn kind(&self) -> ErrorKind {
5+
match self {
6+
Self::OVERRUN => ErrorKind::Overrun,
7+
Self::BUS => ErrorKind::Bus,
8+
Self::ARBITRATION => ErrorKind::ArbitrationLoss,
9+
Self::NACK => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown),
10+
Self::CRC | Self::TIMEOUT => ErrorKind::Other,
11+
}
12+
}
13+
}
14+
15+
mod blocking {
16+
use super::super::{Error, I2c, I2cCommon, Instance};
17+
use embedded_hal_one::i2c::blocking::{Read, Write, WriteIter, WriteIterRead, WriteRead};
18+
19+
impl<I2C, PINS> WriteRead for I2c<I2C, PINS>
20+
where
21+
I2C: Instance,
22+
{
23+
type Error = Error;
24+
25+
fn write_read(
26+
&mut self,
27+
addr: u8,
28+
bytes: &[u8],
29+
buffer: &mut [u8],
30+
) -> Result<(), Self::Error> {
31+
self.write_bytes(addr, bytes.iter().cloned())?;
32+
self.read(addr, buffer)?;
33+
34+
Ok(())
35+
}
36+
}
37+
38+
impl<I2C, PINS> WriteIterRead for I2c<I2C, PINS>
39+
where
40+
I2C: Instance,
41+
{
42+
type Error = Error;
43+
44+
fn write_iter_read<B>(
45+
&mut self,
46+
addr: u8,
47+
bytes: B,
48+
buffer: &mut [u8],
49+
) -> Result<(), Self::Error>
50+
where
51+
B: IntoIterator<Item = u8>,
52+
{
53+
self.write_bytes(addr, bytes.into_iter())?;
54+
self.read(addr, buffer)?;
55+
56+
Ok(())
57+
}
58+
}
59+
60+
impl<I2C, PINS> Write for I2c<I2C, PINS>
61+
where
62+
I2C: Instance,
63+
{
64+
type Error = Error;
65+
66+
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
67+
self.write_bytes(addr, bytes.iter().cloned())?;
68+
69+
// Send a STOP condition
70+
self.i2c.cr1.modify(|_, w| w.stop().set_bit());
71+
72+
// Wait for STOP condition to transmit.
73+
while self.i2c.cr1.read().stop().bit_is_set() {}
74+
75+
// Fallthrough is success
76+
Ok(())
77+
}
78+
}
79+
80+
impl<I2C, PINS> WriteIter for I2c<I2C, PINS>
81+
where
82+
I2C: Instance,
83+
{
84+
type Error = Error;
85+
86+
fn write_iter<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
87+
where
88+
B: IntoIterator<Item = u8>,
89+
{
90+
self.write_bytes(addr, bytes.into_iter())?;
91+
92+
// Send a STOP condition
93+
self.i2c.cr1.modify(|_, w| w.stop().set_bit());
94+
95+
// Wait for STOP condition to transmit.
96+
while self.i2c.cr1.read().stop().bit_is_set() {}
97+
98+
// Fallthrough is success
99+
Ok(())
100+
}
101+
}
102+
103+
impl<I2C, PINS> Read for I2c<I2C, PINS>
104+
where
105+
I2C: Instance,
106+
{
107+
type Error = Error;
108+
109+
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
110+
if let Some((last, buffer)) = buffer.split_last_mut() {
111+
// Send a START condition and set ACK bit
112+
self.i2c
113+
.cr1
114+
.modify(|_, w| w.start().set_bit().ack().set_bit());
115+
116+
// Wait until START condition was generated
117+
while self.i2c.sr1.read().sb().bit_is_clear() {}
118+
119+
// Also wait until signalled we're master and everything is waiting for us
120+
while {
121+
let sr2 = self.i2c.sr2.read();
122+
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
123+
} {}
124+
125+
// Set up current address, we're trying to talk to
126+
self.i2c
127+
.dr
128+
.write(|w| unsafe { w.bits((u32::from(addr) << 1) + 1) });
129+
130+
// Wait until address was sent
131+
loop {
132+
self.check_and_clear_error_flags()?;
133+
if self.i2c.sr1.read().addr().bit_is_set() {
134+
break;
135+
}
136+
}
137+
138+
// Clear condition by reading SR2
139+
self.i2c.sr2.read();
140+
141+
// Receive bytes into buffer
142+
for c in buffer {
143+
*c = self.recv_byte()?;
144+
}
145+
146+
// Prepare to send NACK then STOP after next byte
147+
self.i2c
148+
.cr1
149+
.modify(|_, w| w.ack().clear_bit().stop().set_bit());
150+
151+
// Receive last byte
152+
*last = self.recv_byte()?;
153+
154+
// Wait for the STOP to be sent.
155+
while self.i2c.cr1.read().stop().bit_is_set() {}
156+
157+
// Fallthrough is success
158+
Ok(())
159+
} else {
160+
Err(Error::OVERRUN)
161+
}
162+
}
163+
}
164+
}

0 commit comments

Comments
 (0)