Skip to content

Commit 017ad89

Browse files
committed
i2c: add timeouts (hardcoded for now)
Inspired by f1 hal
1 parent 723a425 commit 017ad89

File tree

1 file changed

+117
-56
lines changed

1 file changed

+117
-56
lines changed

src/i2c.rs

Lines changed: 117 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ use crate::prelude::*;
77
use crate::rcc::Rcc;
88
use crate::stm32::{I2C1, I2C2};
99
use crate::time::Hertz;
10+
use cortex_m::peripheral::DWT;
1011

1112
/// I2C abstraction
1213
pub struct I2c<I2C, PINS> {
1314
i2c: I2C,
1415
pins: PINS,
16+
speed: Hertz,
17+
clock: u32,
1518
}
1619

1720
pub trait Pins<I2c> {
@@ -39,10 +42,56 @@ impl Pins<I2C2> for (PB10<Output<OpenDrain>>, PB11<Output<OpenDrain>>) {
3942
}
4043
}
4144

42-
#[derive(Debug)]
45+
#[derive(Debug, PartialEq)]
4346
pub enum Error {
44-
OVERRUN,
45-
NACK,
47+
Bus,
48+
Arbitration,
49+
Acknowledge,
50+
Overrun,
51+
Timeout,
52+
}
53+
54+
macro_rules! wait_for_flag {
55+
($i2c:expr, $flag:ident) => {{
56+
let sr1 = $i2c.sr1.read();
57+
58+
if sr1.berr().bit_is_set() {
59+
$i2c.sr1.write(|w| w.berr().clear_bit());
60+
Err(Error::Bus)
61+
} else if sr1.arlo().bit_is_set() {
62+
$i2c.sr1.write(|w| w.arlo().clear_bit());
63+
Err(Error::Arbitration)
64+
} else if sr1.af().bit_is_set() {
65+
$i2c.sr1.write(|w| w.af().clear_bit());
66+
Err(Error::Acknowledge)
67+
} else if sr1.ovr().bit_is_set() {
68+
$i2c.sr1.write(|w| w.ovr().clear_bit());
69+
Err(Error::Overrun)
70+
} else {
71+
Ok(sr1.$flag().bit_is_set())
72+
}
73+
}};
74+
}
75+
76+
macro_rules! busy_wait {
77+
($nb_expr:expr, $exit_cond:expr) => {{
78+
loop {
79+
match $nb_expr {
80+
Err(e) => break Err(e),
81+
Ok(true) => break Ok(()),
82+
Ok(false) if $exit_cond => break Err(Error::Timeout),
83+
Ok(false) => {}
84+
}
85+
}
86+
}};
87+
}
88+
89+
macro_rules! busy_wait_cycles {
90+
($nb_expr:expr, $cycles:expr) => {{
91+
let started = DWT::cycle_count();
92+
let cycles = $cycles;
93+
busy_wait!($nb_expr, DWT::cycle_count().wrapping_sub(started) >= cycles)
94+
}};
4695
}
4796

4897
macro_rules! i2c {
@@ -62,14 +111,30 @@ macro_rules! i2c {
62111
rcc.rb.apb1rstr.modify(|_, w| w.$i2crst().set_bit());
63112
rcc.rb.apb1rstr.modify(|_, w| w.$i2crst().clear_bit());
64113

65-
// Make sure the I2C unit is disabled so we can configure it
66-
i2c.cr1.modify(|_, w| w.pe().clear_bit());
67-
68114
// Calculate settings for I2C speed modes
69115
let clock = rcc.clocks.apb1_clk().0;
70116
let freq = clock / 1_000_000;
71117
assert!(freq >= 2 && freq <= 50);
72118

119+
let mut i2c = I2c {
120+
i2c,
121+
pins,
122+
speed,
123+
clock,
124+
};
125+
i2c.init();
126+
i2c
127+
}
128+
129+
fn init(&mut self) {
130+
let i2c = &mut self.i2c;
131+
let speed = self.speed;
132+
let clock = self.clock;
133+
let freq = clock / 1_000_000;
134+
135+
// Make sure the I2C unit is disabled so we can configure it
136+
i2c.cr1.modify(|_, w| w.pe().clear_bit());
137+
73138
// Configure bus frequency into I2C peripheral
74139
i2c.cr2.write(|w| unsafe { w.freq().bits(freq as u8) });
75140

@@ -125,40 +190,54 @@ macro_rules! i2c {
125190

126191
// Enable the I2C processing
127192
i2c.cr1.modify(|_, w| w.pe().set_bit());
128-
129-
I2c { i2c, pins }
130193
}
131194

132195
pub fn release(self) -> ($I2CX, PINS) {
133196
(self.i2c, self.pins)
134197
}
135198

136-
fn write_bytes(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
137-
// Send a START condition
138-
self.i2c.cr1.modify(|_, w| w.start().set_bit());
199+
fn send_start(&mut self) -> Result<(), Error> {
200+
let mut retries_left = 10;
201+
let mut last_err = Err(Error::Timeout);
202+
while retries_left > 0 {
203+
// Send a START condition
204+
self.i2c.cr1.modify(|_, w| w.start().set_bit());
205+
206+
// Wait until START condition was generated
207+
last_err = busy_wait_cycles!(wait_for_flag!(self.i2c, sb), 24_0000);
208+
209+
if last_err.is_err() {
210+
self.i2c.cr1.write(|w| w.pe().set_bit().swrst().set_bit());
211+
self.i2c.cr1.reset();
212+
self.init();
213+
} else {
214+
break;
215+
}
216+
217+
retries_left -= 1;
218+
}
219+
last_err
220+
}
139221

140-
// Wait until START condition was generated
141-
while {
142-
let sr1 = self.i2c.sr1.read();
143-
sr1.sb().bit_is_clear()
144-
} {}
222+
fn write_bytes(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
223+
self.send_start()?;
145224

146225
// Also wait until signalled we're master and everything is waiting for us
147-
while {
148-
let sr2 = self.i2c.sr2.read();
149-
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
150-
} {}
226+
busy_wait_cycles!(
227+
{
228+
let sr2 = self.i2c.sr2.read();
229+
Ok(sr2.msl().bit_is_set() && sr2.busy().bit_is_set())
230+
},
231+
24_0000
232+
)?;
151233

152234
// Set up current address, we're trying to talk to
153235
self.i2c
154236
.dr
155237
.write(|w| unsafe { w.bits(u32::from(addr) << 1) });
156238

157239
// Wait until address was sent
158-
while {
159-
let sr1 = self.i2c.sr1.read();
160-
sr1.addr().bit_is_clear()
161-
} {}
240+
busy_wait_cycles!(wait_for_flag!(self.i2c, addr), 24_0000)?;
162241

163242
// Clear condition by reading SR2
164243
self.i2c.sr2.read();
@@ -174,28 +253,19 @@ macro_rules! i2c {
174253

175254
fn send_byte(&self, byte: u8) -> Result<(), Error> {
176255
// Wait until we're ready for sending
177-
while self.i2c.sr1.read().tx_e().bit_is_clear() {}
256+
busy_wait_cycles!(wait_for_flag!(self.i2c, tx_e), 24_0000)?;
178257

179258
// Push out a byte of data
180259
self.i2c.dr.write(|w| unsafe { w.bits(u32::from(byte)) });
181260

182-
// While until byte is transferred
183-
while {
184-
let sr1 = self.i2c.sr1.read();
185-
186-
// If we received a NACK, then this is an error
187-
if sr1.af().bit_is_set() {
188-
return Err(Error::NACK);
189-
}
190-
191-
sr1.btf().bit_is_clear()
192-
} {}
261+
// Wait until byte is transferred
262+
busy_wait_cycles!(wait_for_flag!(self.i2c, btf), 24_0000)?;
193263

194264
Ok(())
195265
}
196266

197267
fn recv_byte(&self) -> Result<u8, Error> {
198-
while self.i2c.sr1.read().rx_ne().bit_is_clear() {}
268+
busy_wait_cycles!(wait_for_flag!(self.i2c, rx_ne), 24_0000)?;
199269
let value = self.i2c.dr.read().bits() as u8;
200270
Ok(value)
201271
}
@@ -243,33 +313,24 @@ macro_rules! i2c {
243313

244314
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
245315
if let Some((last, buffer)) = buffer.split_last_mut() {
246-
// Send a START condition and set ACK bit
247-
self.i2c
248-
.cr1
249-
.modify(|_, w| w.start().set_bit().ack().set_bit());
250-
251-
// Wait until START condition was generated
252-
while {
253-
let sr1 = self.i2c.sr1.read();
254-
sr1.sb().bit_is_clear()
255-
} {}
316+
self.send_start()?;
256317

257318
// Also wait until signalled we're master and everything is waiting for us
258-
while {
259-
let sr2 = self.i2c.sr2.read();
260-
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
261-
} {}
319+
busy_wait_cycles!(
320+
{
321+
let sr2 = self.i2c.sr2.read();
322+
Ok(sr2.msl().bit_is_set() && sr2.busy().bit_is_set())
323+
},
324+
24_0000
325+
)?;
262326

263327
// Set up current address, we're trying to talk to
264328
self.i2c
265329
.dr
266330
.write(|w| unsafe { w.bits((u32::from(addr) << 1) + 1) });
267331

268332
// Wait until address was sent
269-
while {
270-
let sr1 = self.i2c.sr1.read();
271-
sr1.addr().bit_is_clear()
272-
} {}
333+
busy_wait_cycles!(wait_for_flag!(self.i2c, addr), 24_0000)?;
273334

274335
// Clear condition by reading SR2
275336
self.i2c.sr2.read();
@@ -290,7 +351,7 @@ macro_rules! i2c {
290351
// Fallthrough is success
291352
Ok(())
292353
} else {
293-
Err(Error::OVERRUN)
354+
Err(Error::Overrun)
294355
}
295356
}
296357
}

0 commit comments

Comments
 (0)