7
7
//! extern crate embedded_hal_mock;
8
8
//!
9
9
//! use embedded_hal::i2c::ErrorKind;
10
- //! use embedded_hal::i2c::blocking::{Read, Write, WriteRead};
10
+ //! use embedded_hal::i2c::blocking::I2c;
11
+ //! use embedded_hal::i2c::blocking::Operation;
11
12
//! use embedded_hal_mock::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
12
13
//!
13
14
//! // Configure expectations
46
47
//! ```
47
48
//! # extern crate embedded_hal;
48
49
//! # extern crate embedded_hal_mock;
49
- //! # use embedded_hal::i2c::blocking::{Read, Write, WriteRead} ;
50
+ //! # use embedded_hal::i2c::blocking::I2c ;
50
51
//! # use embedded_hal::i2c::ErrorKind;
51
52
//! # use embedded_hal_mock::i2c::{Mock as I2cMock, Transaction as I2cTransaction};
52
53
//!
71
72
72
73
use embedded_hal:: i2c:: blocking as i2c;
73
74
use embedded_hal:: i2c:: ErrorKind ;
75
+ use embedded_hal:: i2c:: ErrorType ;
74
76
75
77
use crate :: common:: Generic ;
76
78
@@ -83,6 +85,10 @@ pub enum Mode {
83
85
Read ,
84
86
/// Write and read transaction
85
87
WriteRead ,
88
+ /// Mark the start of a transaction
89
+ TransactionStart ,
90
+ /// Mark the end of a transaction
91
+ TransactionEnd ,
86
92
}
87
93
88
94
/// I2C Transaction type
@@ -135,6 +141,28 @@ impl Transaction {
135
141
}
136
142
}
137
143
144
+ /// Create nested transactions
145
+ pub fn transaction_start ( addr : u8 ) -> Transaction {
146
+ Transaction {
147
+ expected_mode : Mode :: TransactionStart ,
148
+ expected_addr : addr,
149
+ expected_data : Vec :: new ( ) ,
150
+ response_data : Vec :: new ( ) ,
151
+ expected_err : None ,
152
+ }
153
+ }
154
+
155
+ /// Create nested transactions
156
+ pub fn transaction_end ( addr : u8 ) -> Transaction {
157
+ Transaction {
158
+ expected_mode : Mode :: TransactionEnd ,
159
+ expected_addr : addr,
160
+ expected_data : Vec :: new ( ) ,
161
+ response_data : Vec :: new ( ) ,
162
+ expected_err : None ,
163
+ }
164
+ }
165
+
138
166
/// Add an error return to a transaction
139
167
///
140
168
/// This is used to mock failure behaviours.
@@ -153,9 +181,11 @@ impl Transaction {
153
181
/// Mismatches between expectations will cause runtime assertions to assist in locating the source of the fault.
154
182
pub type Mock = Generic < Transaction > ;
155
183
156
- impl i2c :: Read for Mock {
184
+ impl ErrorType for Mock {
157
185
type Error = ErrorKind ;
186
+ }
158
187
188
+ impl i2c:: I2c for Mock {
159
189
fn read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
160
190
let e = self
161
191
. next ( )
@@ -178,10 +208,6 @@ impl i2c::Read for Mock {
178
208
}
179
209
}
180
210
}
181
- }
182
-
183
- impl i2c:: Write for Mock {
184
- type Error = ErrorKind ;
185
211
186
212
fn write ( & mut self , address : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
187
213
let e = self
@@ -200,10 +226,31 @@ impl i2c::Write for Mock {
200
226
None => Ok ( ( ) ) ,
201
227
}
202
228
}
203
- }
204
229
205
- impl i2c:: WriteRead for Mock {
206
- type Error = ErrorKind ;
230
+ fn write_iter < B > ( & mut self , address : u8 , bytes : B ) -> Result < ( ) , Self :: Error >
231
+ where
232
+ B : IntoIterator < Item = u8 > ,
233
+ {
234
+ let w = self
235
+ . next ( )
236
+ . expect ( "no pending expectation for i2c::write call" ) ;
237
+
238
+ assert_eq ! (
239
+ w. expected_mode,
240
+ Mode :: Write ,
241
+ "i2c::write_iter unexpected mode"
242
+ ) ;
243
+ assert_eq ! ( w. expected_addr, address, "i2c::write_iter address mismatch" ) ;
244
+ assert ! (
245
+ bytes. into_iter( ) . eq( w. expected_data) ,
246
+ "i2c::write_iter data does not match expectation"
247
+ ) ;
248
+
249
+ match w. expected_err {
250
+ Some ( err) => Err ( err) ,
251
+ None => Ok ( ( ) ) ,
252
+ }
253
+ }
207
254
208
255
fn write_read (
209
256
& mut self ,
@@ -240,10 +287,6 @@ impl i2c::WriteRead for Mock {
240
287
}
241
288
}
242
289
}
243
- }
244
-
245
- impl i2c:: WriteIterRead for Mock {
246
- type Error = ErrorKind ;
247
290
248
291
fn write_iter_read < B > (
249
292
& mut self ,
@@ -254,24 +297,108 @@ impl i2c::WriteIterRead for Mock {
254
297
where
255
298
B : IntoIterator < Item = u8 > ,
256
299
{
257
- // Just collect the bytes and pass them on to the WriteRead::write_read implementation
258
- use embedded_hal:: i2c:: blocking:: WriteRead ;
259
- let bytes: Vec < _ > = bytes. into_iter ( ) . collect ( ) ;
260
- self . write_read ( address, bytes. as_slice ( ) , buffer)
300
+ let w = self
301
+ . next ( )
302
+ . expect ( "no pending expectation for i2c::write_read call" ) ;
303
+
304
+ assert_eq ! (
305
+ w. expected_mode,
306
+ Mode :: WriteRead ,
307
+ "i2c::write_iter_read unexpected mode"
308
+ ) ;
309
+ assert_eq ! (
310
+ w. expected_addr, address,
311
+ "i2c::write_iter_read address mismatch"
312
+ ) ;
313
+ assert ! (
314
+ bytes. into_iter( ) . eq( w. expected_data) ,
315
+ "i2c::write_iter_read write data does not match expectation"
316
+ ) ;
317
+
318
+ assert_eq ! (
319
+ buffer. len( ) ,
320
+ w. response_data. len( ) ,
321
+ "i2c::write_iter_read mismatched response length"
322
+ ) ;
323
+
324
+ match w. expected_err {
325
+ Some ( err) => Err ( err) ,
326
+ None => {
327
+ buffer. copy_from_slice ( & w. response_data ) ;
328
+ Ok ( ( ) )
329
+ }
330
+ }
261
331
}
262
- }
263
332
264
- impl i2c:: WriteIter for Mock {
265
- type Error = ErrorKind ;
333
+ fn transaction < ' a > (
334
+ & mut self ,
335
+ address : u8 ,
336
+ operations : & mut [ i2c:: Operation < ' a > ] ,
337
+ ) -> Result < ( ) , Self :: Error > {
338
+ let w = self
339
+ . next ( )
340
+ . expect ( "no pending expectation for i2c::transaction call" ) ;
266
341
267
- fn write_iter < B > ( & mut self , address : u8 , bytes : B ) -> Result < ( ) , Self :: Error >
342
+ assert_eq ! (
343
+ w. expected_mode,
344
+ Mode :: TransactionStart ,
345
+ "i2c::transaction_start unexpected mode"
346
+ ) ;
347
+
348
+ for op in operations {
349
+ match op {
350
+ i2c:: Operation :: Read ( r) => self . read ( address, r) ,
351
+ i2c:: Operation :: Write ( w) => self . write ( address, w) ,
352
+ }
353
+ . unwrap ( ) ;
354
+ }
355
+
356
+ let w = self
357
+ . next ( )
358
+ . expect ( "no pending expectation for i2c::transaction call" ) ;
359
+
360
+ assert_eq ! (
361
+ w. expected_mode,
362
+ Mode :: TransactionEnd ,
363
+ "i2c::transaction_end unexpected mode"
364
+ ) ;
365
+
366
+ Ok ( ( ) )
367
+ }
368
+
369
+ fn transaction_iter < ' a , O > ( & mut self , address : u8 , operations : O ) -> Result < ( ) , Self :: Error >
268
370
where
269
- B : IntoIterator < Item = u8 > ,
371
+ O : IntoIterator < Item = i2c :: Operation < ' a > > ,
270
372
{
271
- // Just collect the bytes and pass them on to the Write::write implementation
272
- use embedded_hal:: i2c:: blocking:: Write ;
273
- let bytes: Vec < _ > = bytes. into_iter ( ) . collect ( ) ;
274
- Write :: write ( self , address, bytes. as_slice ( ) )
373
+ let w = self
374
+ . next ( )
375
+ . expect ( "no pending expectation for i2c::transaction call" ) ;
376
+
377
+ assert_eq ! (
378
+ w. expected_mode,
379
+ Mode :: TransactionStart ,
380
+ "i2c::transaction_start unexpected mode"
381
+ ) ;
382
+
383
+ for op in operations {
384
+ match op {
385
+ i2c:: Operation :: Read ( r) => self . read ( address, r) ,
386
+ i2c:: Operation :: Write ( w) => self . write ( address, w) ,
387
+ }
388
+ . unwrap ( ) ;
389
+ }
390
+
391
+ let w = self
392
+ . next ( )
393
+ . expect ( "no pending expectation for i2c::transaction call" ) ;
394
+
395
+ assert_eq ! (
396
+ w. expected_mode,
397
+ Mode :: TransactionEnd ,
398
+ "i2c::transaction_end unexpected mode"
399
+ ) ;
400
+
401
+ Ok ( ( ) )
275
402
}
276
403
}
277
404
@@ -281,7 +408,7 @@ mod test {
281
408
282
409
use std:: time:: SystemTime ;
283
410
284
- use embedded_hal:: i2c:: blocking:: { Read , Write , WriteRead } ;
411
+ use embedded_hal:: i2c:: blocking:: I2c ;
285
412
286
413
#[ test]
287
414
fn write ( ) {
@@ -293,6 +420,16 @@ mod test {
293
420
i2c. done ( ) ;
294
421
}
295
422
423
+ #[ test]
424
+ fn write_iter ( ) {
425
+ let expectations = [ Transaction :: write ( 0xaa , vec ! [ 10 , 12 ] ) ] ;
426
+ let mut i2c = Mock :: new ( & expectations) ;
427
+
428
+ i2c. write_iter ( 0xaa , vec ! [ 10 , 12 ] ) . unwrap ( ) ;
429
+
430
+ i2c. done ( ) ;
431
+ }
432
+
296
433
#[ test]
297
434
fn read ( ) {
298
435
let expectations = [ Transaction :: read ( 0xaa , vec ! [ 1 , 2 ] ) ] ;
@@ -318,6 +455,19 @@ mod test {
318
455
i2c. done ( ) ;
319
456
}
320
457
458
+ #[ test]
459
+ fn write_iter_read ( ) {
460
+ let expectations = [ Transaction :: write_read ( 0xaa , vec ! [ 1 , 2 ] , vec ! [ 3 , 4 ] ) ] ;
461
+ let mut i2c = Mock :: new ( & expectations) ;
462
+
463
+ let v = vec ! [ 1 , 2 ] ;
464
+ let mut buff = vec ! [ 0u8 ; 2 ] ;
465
+ i2c. write_iter_read ( 0xaa , v, & mut buff) . unwrap ( ) ;
466
+ assert_eq ! ( vec![ 3 , 4 ] , buff) ;
467
+
468
+ i2c. done ( ) ;
469
+ }
470
+
321
471
#[ test]
322
472
fn multiple_transactions ( ) {
323
473
let expectations = [
@@ -336,6 +486,56 @@ mod test {
336
486
i2c. done ( ) ;
337
487
}
338
488
489
+ #[ test]
490
+ fn test_i2c_mock_multiple_transaction ( ) {
491
+ let expectations = [
492
+ Transaction :: transaction_start ( 0xaa ) ,
493
+ Transaction :: write ( 0xaa , vec ! [ 1 , 2 ] ) ,
494
+ Transaction :: read ( 0xaa , vec ! [ 3 , 4 ] ) ,
495
+ Transaction :: transaction_end ( 0xaa ) ,
496
+ ] ;
497
+ let mut i2c = Mock :: new ( & expectations) ;
498
+
499
+ let mut v = vec ! [ 0u8 ; 2 ] ;
500
+ i2c. transaction (
501
+ 0xaa ,
502
+ & mut [
503
+ i2c:: Operation :: Write ( & vec ! [ 1 , 2 ] ) ,
504
+ i2c:: Operation :: Read ( & mut v) ,
505
+ ] ,
506
+ )
507
+ . unwrap ( ) ;
508
+
509
+ assert_eq ! ( v, vec![ 3 , 4 ] ) ;
510
+
511
+ i2c. done ( ) ;
512
+ }
513
+
514
+ #[ test]
515
+ fn test_i2c_mock_multiple_transaction_iter ( ) {
516
+ let expectations = [
517
+ Transaction :: transaction_start ( 0xaa ) ,
518
+ Transaction :: write ( 0xaa , vec ! [ 1 , 2 ] ) ,
519
+ Transaction :: read ( 0xaa , vec ! [ 3 , 4 ] ) ,
520
+ Transaction :: transaction_end ( 0xaa ) ,
521
+ ] ;
522
+ let mut i2c = Mock :: new ( & expectations) ;
523
+
524
+ let mut v = vec ! [ 0u8 ; 2 ] ;
525
+ i2c. transaction_iter (
526
+ 0xaa ,
527
+ [
528
+ i2c:: Operation :: Write ( & vec ! [ 1 , 2 ] ) ,
529
+ i2c:: Operation :: Read ( & mut v) ,
530
+ ] ,
531
+ )
532
+ . unwrap ( ) ;
533
+
534
+ assert_eq ! ( v, vec![ 3 , 4 ] ) ;
535
+
536
+ i2c. done ( ) ;
537
+ }
538
+
339
539
#[ test]
340
540
#[ should_panic]
341
541
fn write_data_mismatch ( ) {
0 commit comments