@@ -13,10 +13,14 @@ use cast::u8;
13
13
#[ derive( Debug ) ]
14
14
#[ non_exhaustive]
15
15
pub enum Error {
16
- /// Bus error
17
- Bus ,
18
16
/// Arbitration loss
19
17
Arbitration ,
18
+ /// Bus error
19
+ Bus ,
20
+ /// Bus busy
21
+ Busy ,
22
+ /// Not Acknowledge received
23
+ Nack ,
20
24
// Overrun, // slave mode only
21
25
// Pec, // SMBUS mode only
22
26
// Timeout, // SMBUS mode only
@@ -57,15 +61,21 @@ macro_rules! busy_wait {
57
61
( $i2c: expr, $flag: ident, $variant: ident) => {
58
62
loop {
59
63
let isr = $i2c. isr. read( ) ;
64
+ let icr = & $i2c. icr;
60
65
61
- if isr. $flag( ) . $variant( ) {
62
- break ;
66
+ if isr. arlo( ) . is_lost( ) {
67
+ icr. write( |w| w. arlocf( ) . clear( ) ) ;
68
+ return Err ( Error :: Arbitration ) ;
63
69
} else if isr. berr( ) . is_error( ) {
70
+ icr. write( |w| w. berrcf( ) . clear( ) ) ;
64
71
return Err ( Error :: Bus ) ;
65
- } else if isr. arlo( ) . is_lost( ) {
66
- return Err ( Error :: Arbitration ) ;
67
- } else {
68
- // try again
72
+ } else if isr. nackf( ) . is_nack( ) {
73
+ while $i2c. isr. read( ) . stopf( ) . is_no_stop( ) { }
74
+ icr. write( |w| w. nackcf( ) . clear( ) ) ;
75
+ icr. write( |w| w. stopcf( ) . clear( ) ) ;
76
+ return Err ( Error :: Nack ) ;
77
+ } else if isr. $flag( ) . $variant( ) {
78
+ break ;
69
79
}
70
80
}
71
81
} ;
@@ -184,8 +194,10 @@ macro_rules! hal {
184
194
// TODO support transfers of more than 255 bytes
185
195
assert!( buffer. len( ) < 256 && buffer. len( ) > 0 ) ;
186
196
187
- // TODO do we have to explicitly wait here if the bus is busy (e.g. another
188
- // master is communicating)?
197
+ // Detect Bus busy
198
+ if self . i2c. isr. read( ) . busy( ) . is_busy( ) {
199
+ return Err ( Error :: Busy ) ;
200
+ }
189
201
190
202
// START and prepare to receive `bytes`
191
203
self . i2c. cr2. write( |w| {
@@ -209,6 +221,10 @@ macro_rules! hal {
209
221
}
210
222
211
223
// automatic STOP
224
+ // Wait until the last transmission is finished
225
+ busy_wait!( self . i2c, stopf, is_stop) ;
226
+
227
+ self . i2c. icr. write( |w| w. stopcf( ) . clear( ) ) ;
212
228
213
229
Ok ( ( ) )
214
230
}
@@ -221,6 +237,11 @@ macro_rules! hal {
221
237
// TODO support transfers of more than 255 bytes
222
238
assert!( bytes. len( ) < 256 && bytes. len( ) > 0 ) ;
223
239
240
+ // Detect Bus busy
241
+ if self . i2c. isr. read( ) . busy( ) . is_busy( ) {
242
+ return Err ( Error :: Busy ) ;
243
+ }
244
+
224
245
// START and prepare to send `bytes`
225
246
self . i2c. cr2. modify( |_, w| {
226
247
w. sadd( )
@@ -245,10 +266,11 @@ macro_rules! hal {
245
266
self . i2c. txdr. write( |w| w. txdata( ) . bits( * byte) ) ;
246
267
}
247
268
248
- // Wait until the last transmission is finished ???
249
- // busy_wait!(self.i2c, busy);
250
-
251
269
// automatic STOP
270
+ // Wait until the last transmission is finished
271
+ busy_wait!( self . i2c, stopf, is_stop) ;
272
+
273
+ self . i2c. icr. write( |w| w. stopcf( ) . clear( ) ) ;
252
274
253
275
Ok ( ( ) )
254
276
}
@@ -267,8 +289,10 @@ macro_rules! hal {
267
289
assert!( bytes. len( ) < 256 && bytes. len( ) > 0 ) ;
268
290
assert!( buffer. len( ) < 256 && buffer. len( ) > 0 ) ;
269
291
270
- // TODO do we have to explicitly wait here if the bus is busy (e.g. another
271
- // master is communicating)?
292
+ // Detect Bus busy
293
+ if self . i2c. isr. read( ) . busy( ) . is_busy( ) {
294
+ return Err ( Error :: Busy ) ;
295
+ }
272
296
273
297
// START and prepare to send `bytes`
274
298
self . i2c. cr2. modify( |_, w| {
@@ -319,6 +343,10 @@ macro_rules! hal {
319
343
}
320
344
321
345
// automatic STOP
346
+ // Wait until the last transmission is finished
347
+ busy_wait!( self . i2c, stopf, is_stop) ;
348
+
349
+ self . i2c. icr. write( |w| w. stopcf( ) . clear( ) ) ;
322
350
323
351
Ok ( ( ) )
324
352
}
0 commit comments