@@ -160,6 +160,41 @@ where
160
160
Ok ( ( ) )
161
161
}
162
162
163
+ fn clear_errorsrc ( & mut self ) {
164
+ self . 0
165
+ . errorsrc
166
+ . write ( |w| w. anack ( ) . bit ( true ) . dnack ( ) . bit ( true ) . overrun ( ) . bit ( true ) ) ;
167
+ }
168
+
169
+ /// Get Error instance, if any occurred.
170
+ fn read_errorsrc ( & self ) -> Result < ( ) , Error > {
171
+ let err = self . 0 . errorsrc . read ( ) ;
172
+ if err. anack ( ) . is_received ( ) {
173
+ return Err ( Error :: AddressNack ) ;
174
+ }
175
+ if err. dnack ( ) . is_received ( ) {
176
+ return Err ( Error :: DataNack ) ;
177
+ }
178
+ if err. overrun ( ) . is_received ( ) {
179
+ return Err ( Error :: DataNack ) ;
180
+ }
181
+ Ok ( ( ) )
182
+ }
183
+
184
+ /// Wait for stop or error
185
+ fn wait ( & mut self ) {
186
+ loop {
187
+ if self . 0 . events_stopped . read ( ) . bits ( ) != 0 {
188
+ self . 0 . events_stopped . reset ( ) ;
189
+ break ;
190
+ }
191
+ if self . 0 . events_error . read ( ) . bits ( ) != 0 {
192
+ self . 0 . events_error . reset ( ) ;
193
+ self . 0 . tasks_stop . write ( |w| unsafe { w. bits ( 1 ) } ) ;
194
+ }
195
+ }
196
+ }
197
+
163
198
/// Write to an I2C slave.
164
199
///
165
200
/// The buffer must have a length of at most 255 bytes on the nRF52832
@@ -177,37 +212,26 @@ where
177
212
// Set up the DMA write.
178
213
unsafe { self . set_tx_buffer ( buffer) ? } ;
179
214
180
- // Clear address NACK.
181
- self . 0 . errorsrc . write ( |w| w. anack ( ) . bit ( true ) ) ;
215
+ // Clear events
216
+ self . 0 . events_stopped . reset ( ) ;
217
+ self . 0 . events_error . reset ( ) ;
218
+ self . 0 . events_lasttx . reset ( ) ;
219
+ self . clear_errorsrc ( ) ;
182
220
183
221
// Start write operation.
222
+ self . 0 . shorts . write ( |w| w. lasttx_stop ( ) . enabled ( ) ) ;
184
223
self . 0 . tasks_starttx . write ( |w|
185
224
// `1` is a valid value to write to task registers.
186
225
unsafe { w. bits ( 1 ) } ) ;
187
226
188
- // Wait until write operation is about to end.
189
- while self . 0 . events_lasttx . read ( ) . bits ( ) == 0
190
- && self . 0 . errorsrc . read ( ) . anack ( ) . is_not_received ( )
191
- { }
192
- self . 0 . events_lasttx . write ( |w| w) ; // reset event
193
-
194
- // Stop write operation.
195
- self . 0 . tasks_stop . write ( |w|
196
- // `1` is a valid value to write to task registers.
197
- unsafe { w. bits ( 1 ) } ) ;
198
-
199
- // Wait until write operation has ended.
200
- while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
201
- self . 0 . events_stopped . write ( |w| w) ; // reset event
227
+ self . wait ( ) ;
202
228
203
229
// Conservative compiler fence to prevent optimizations that do not
204
230
// take in to account actions by DMA. The fence has been placed here,
205
231
// after all possible DMA actions have completed.
206
232
compiler_fence ( SeqCst ) ;
207
233
208
- if self . 0 . errorsrc . read ( ) . anack ( ) . is_received ( ) {
209
- return Err ( Error :: AddressNack ) ;
210
- }
234
+ self . read_errorsrc ( ) ?;
211
235
212
236
if self . 0 . txd . amount . read ( ) . bits ( ) != buffer. len ( ) as u32 {
213
237
return Err ( Error :: Transmit ) ;
@@ -233,37 +257,25 @@ where
233
257
// Set up the DMA read.
234
258
unsafe { self . set_rx_buffer ( buffer) ? } ;
235
259
236
- // Clear address NACK.
237
- self . 0 . errorsrc . write ( |w| w. anack ( ) . bit ( true ) ) ;
260
+ // Clear events
261
+ self . 0 . events_stopped . reset ( ) ;
262
+ self . 0 . events_error . reset ( ) ;
263
+ self . clear_errorsrc ( ) ;
238
264
239
265
// Start read operation.
266
+ self . 0 . shorts . write ( |w| w. lastrx_stop ( ) . enabled ( ) ) ;
240
267
self . 0 . tasks_startrx . write ( |w|
241
268
// `1` is a valid value to write to task registers.
242
269
unsafe { w. bits ( 1 ) } ) ;
243
270
244
- // Wait until read operation is about to end.
245
- while self . 0 . events_lastrx . read ( ) . bits ( ) == 0
246
- && self . 0 . errorsrc . read ( ) . anack ( ) . is_not_received ( )
247
- { }
248
- self . 0 . events_lastrx . write ( |w| w) ; // reset event
249
-
250
- // Stop read operation.
251
- self . 0 . tasks_stop . write ( |w|
252
- // `1` is a valid value to write to task registers.
253
- unsafe { w. bits ( 1 ) } ) ;
254
-
255
- // Wait until read operation has ended.
256
- while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
257
- self . 0 . events_stopped . write ( |w| w) ; // reset event
271
+ self . wait ( ) ;
258
272
259
273
// Conservative compiler fence to prevent optimizations that do not
260
274
// take in to account actions by DMA. The fence has been placed here,
261
275
// after all possible DMA actions have completed.
262
276
compiler_fence ( SeqCst ) ;
263
277
264
- if self . 0 . errorsrc . read ( ) . anack ( ) . is_received ( ) {
265
- return Err ( Error :: AddressNack ) ;
266
- }
278
+ self . read_errorsrc ( ) ?;
267
279
268
280
if self . 0 . rxd . amount . read ( ) . bits ( ) != buffer. len ( ) as u32 {
269
281
return Err ( Error :: Receive ) ;
@@ -298,53 +310,29 @@ where
298
310
self . set_rx_buffer ( rd_buffer) ?;
299
311
}
300
312
301
- // Clear address NACK.
302
- self . 0 . errorsrc . write ( |w| w. anack ( ) . bit ( true ) ) ;
313
+ // Clear events
314
+ self . 0 . events_stopped . reset ( ) ;
315
+ self . 0 . events_error . reset ( ) ;
316
+ self . clear_errorsrc ( ) ;
303
317
304
- // Start write operation.
318
+ // Start write+read operation.
319
+ self . 0 . shorts . write ( |w| {
320
+ w. lasttx_startrx ( ) . enabled ( ) ;
321
+ w. lastrx_stop ( ) . enabled ( ) ;
322
+ w
323
+ } ) ;
305
324
// `1` is a valid value to write to task registers.
306
325
self . 0 . tasks_starttx . write ( |w| unsafe { w. bits ( 1 ) } ) ;
307
326
308
- // Wait until write operation is about to end.
309
- while self . 0 . events_lasttx . read ( ) . bits ( ) == 0
310
- && self . 0 . errorsrc . read ( ) . anack ( ) . is_not_received ( )
311
- { }
312
- self . 0 . events_lasttx . write ( |w| w) ; // reset event
313
-
314
- // Stop operation if address is NACK.
315
- if self . 0 . errorsrc . read ( ) . anack ( ) . is_received ( ) {
316
- // `1` is a valid value to write to task registers.
317
- self . 0 . tasks_stop . write ( |w| unsafe { w. bits ( 1 ) } ) ;
318
- // Wait until operation is stopped
319
- while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
320
- self . 0 . events_stopped . write ( |w| w) ; // reset event
321
- return Err ( Error :: AddressNack ) ;
322
- }
323
-
324
- // Start read operation.
325
- // `1` is a valid value to write to task registers.
326
- self . 0 . tasks_startrx . write ( |w| unsafe { w. bits ( 1 ) } ) ;
327
-
328
- // Wait until read operation is about to end.
329
- while self . 0 . events_lastrx . read ( ) . bits ( ) == 0 { }
330
- self . 0 . events_lastrx . write ( |w| w) ; // reset event
331
-
332
- // Stop read operation.
333
- // `1` is a valid value to write to task registers.
334
- self . 0 . tasks_stop . write ( |w| unsafe { w. bits ( 1 ) } ) ;
335
-
336
- // Wait until total operation has ended.
337
- while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
338
-
339
- self . 0 . events_lasttx . write ( |w| w) ; // reset event
340
- self . 0 . events_lastrx . write ( |w| w) ; // reset event
341
- self . 0 . events_stopped . write ( |w| w) ; // reset event
327
+ self . wait ( ) ;
342
328
343
329
// Conservative compiler fence to prevent optimizations that do not
344
330
// take in to account actions by DMA. The fence has been placed here,
345
331
// after all possible DMA actions have completed.
346
332
compiler_fence ( SeqCst ) ;
347
333
334
+ self . read_errorsrc ( ) ?;
335
+
348
336
let bad_write = self . 0 . txd . amount . read ( ) . bits ( ) != wr_buffer. len ( ) as u32 ;
349
337
let bad_read = self . 0 . rxd . amount . read ( ) . bits ( ) != rd_buffer. len ( ) as u32 ;
350
338
@@ -398,7 +386,7 @@ where
398
386
399
387
// Wait until write operation is about to end.
400
388
while self . 0 . events_lasttx . read ( ) . bits ( ) == 0 { }
401
- self . 0 . events_lasttx . write ( |w| w ) ; // reset event
389
+ self . 0 . events_lasttx . reset ( ) ;
402
390
403
391
// Check for bad writes.
404
392
if self . 0 . txd . amount . read ( ) . bits ( ) != wr_buffer. len ( ) as u32 {
@@ -413,7 +401,7 @@ where
413
401
414
402
// Wait until read operation is about to end.
415
403
while self . 0 . events_lastrx . read ( ) . bits ( ) == 0 { }
416
- self . 0 . events_lastrx . write ( |w| w ) ; // reset event
404
+ self . 0 . events_lastrx . reset ( ) ;
417
405
418
406
// Stop read operation.
419
407
self . 0 . tasks_stop . write ( |w|
@@ -422,7 +410,7 @@ where
422
410
423
411
// Wait until total operation has ended.
424
412
while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
425
- self . 0 . events_stopped . write ( |w| w ) ; // reset event
413
+ self . 0 . events_stopped . reset ( ) ;
426
414
427
415
// Conservative compiler fence to prevent optimizations that do not
428
416
// take in to account actions by DMA. The fence has been placed here,
@@ -515,6 +503,8 @@ pub enum Error {
515
503
Receive ,
516
504
DMABufferNotInDataMemory ,
517
505
AddressNack ,
506
+ DataNack ,
507
+ Overrun ,
518
508
}
519
509
520
510
/// Implemented by all TWIM instances
0 commit comments