@@ -160,6 +160,41 @@ where
160160 Ok ( ( ) )
161161 }
162162
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+
163198 /// Write to an I2C slave.
164199 ///
165200 /// The buffer must have a length of at most 255 bytes on the nRF52832
@@ -177,37 +212,26 @@ where
177212 // Set up the DMA write.
178213 unsafe { self . set_tx_buffer ( buffer) ? } ;
179214
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 ( ) ;
182220
183221 // Start write operation.
222+ self . 0 . shorts . write ( |w| w. lasttx_stop ( ) . enabled ( ) ) ;
184223 self . 0 . tasks_starttx . write ( |w|
185224 // `1` is a valid value to write to task registers.
186225 unsafe { w. bits ( 1 ) } ) ;
187226
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 ( ) ;
202228
203229 // Conservative compiler fence to prevent optimizations that do not
204230 // take in to account actions by DMA. The fence has been placed here,
205231 // after all possible DMA actions have completed.
206232 compiler_fence ( SeqCst ) ;
207233
208- if self . 0 . errorsrc . read ( ) . anack ( ) . is_received ( ) {
209- return Err ( Error :: AddressNack ) ;
210- }
234+ self . read_errorsrc ( ) ?;
211235
212236 if self . 0 . txd . amount . read ( ) . bits ( ) != buffer. len ( ) as u32 {
213237 return Err ( Error :: Transmit ) ;
@@ -233,37 +257,25 @@ where
233257 // Set up the DMA read.
234258 unsafe { self . set_rx_buffer ( buffer) ? } ;
235259
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 ( ) ;
238264
239265 // Start read operation.
266+ self . 0 . shorts . write ( |w| w. lastrx_stop ( ) . enabled ( ) ) ;
240267 self . 0 . tasks_startrx . write ( |w|
241268 // `1` is a valid value to write to task registers.
242269 unsafe { w. bits ( 1 ) } ) ;
243270
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 ( ) ;
258272
259273 // Conservative compiler fence to prevent optimizations that do not
260274 // take in to account actions by DMA. The fence has been placed here,
261275 // after all possible DMA actions have completed.
262276 compiler_fence ( SeqCst ) ;
263277
264- if self . 0 . errorsrc . read ( ) . anack ( ) . is_received ( ) {
265- return Err ( Error :: AddressNack ) ;
266- }
278+ self . read_errorsrc ( ) ?;
267279
268280 if self . 0 . rxd . amount . read ( ) . bits ( ) != buffer. len ( ) as u32 {
269281 return Err ( Error :: Receive ) ;
@@ -298,53 +310,29 @@ where
298310 self . set_rx_buffer ( rd_buffer) ?;
299311 }
300312
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 ( ) ;
303317
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+ } ) ;
305324 // `1` is a valid value to write to task registers.
306325 self . 0 . tasks_starttx . write ( |w| unsafe { w. bits ( 1 ) } ) ;
307326
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 ( ) ;
342328
343329 // Conservative compiler fence to prevent optimizations that do not
344330 // take in to account actions by DMA. The fence has been placed here,
345331 // after all possible DMA actions have completed.
346332 compiler_fence ( SeqCst ) ;
347333
334+ self . read_errorsrc ( ) ?;
335+
348336 let bad_write = self . 0 . txd . amount . read ( ) . bits ( ) != wr_buffer. len ( ) as u32 ;
349337 let bad_read = self . 0 . rxd . amount . read ( ) . bits ( ) != rd_buffer. len ( ) as u32 ;
350338
@@ -398,7 +386,7 @@ where
398386
399387 // Wait until write operation is about to end.
400388 while self . 0 . events_lasttx . read ( ) . bits ( ) == 0 { }
401- self . 0 . events_lasttx . write ( |w| w ) ; // reset event
389+ self . 0 . events_lasttx . reset ( ) ;
402390
403391 // Check for bad writes.
404392 if self . 0 . txd . amount . read ( ) . bits ( ) != wr_buffer. len ( ) as u32 {
@@ -413,7 +401,7 @@ where
413401
414402 // Wait until read operation is about to end.
415403 while self . 0 . events_lastrx . read ( ) . bits ( ) == 0 { }
416- self . 0 . events_lastrx . write ( |w| w ) ; // reset event
404+ self . 0 . events_lastrx . reset ( ) ;
417405
418406 // Stop read operation.
419407 self . 0 . tasks_stop . write ( |w|
@@ -422,7 +410,7 @@ where
422410
423411 // Wait until total operation has ended.
424412 while self . 0 . events_stopped . read ( ) . bits ( ) == 0 { }
425- self . 0 . events_stopped . write ( |w| w ) ; // reset event
413+ self . 0 . events_stopped . reset ( ) ;
426414
427415 // Conservative compiler fence to prevent optimizations that do not
428416 // take in to account actions by DMA. The fence has been placed here,
@@ -515,6 +503,8 @@ pub enum Error {
515503 Receive ,
516504 DMABufferNotInDataMemory ,
517505 AddressNack ,
506+ DataNack ,
507+ Overrun ,
518508}
519509
520510/// Implemented by all TWIM instances
0 commit comments