@@ -7,6 +7,7 @@ use crate::gpio::{Const, OpenDrain, PinA, SetAlternate};
7
7
use crate :: pac:: RCC ;
8
8
9
9
use crate :: rcc:: Clocks ;
10
+ use embedded_hal_one:: i2c:: blocking:: Operation ;
10
11
use fugit:: { HertzU32 as Hertz , RateExtU32 } ;
11
12
12
13
mod hal_02;
@@ -313,7 +314,9 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
313
314
Ok ( sr1)
314
315
}
315
316
316
- fn write_bytes ( & mut self , addr : u8 , bytes : impl Iterator < Item = u8 > ) -> Result < ( ) , Error > {
317
+ /// Sends START and Address for writing
318
+ #[ inline( always) ]
319
+ fn prepare_write ( & self , addr : u8 ) -> Result < ( ) , Error > {
317
320
// Send a START condition
318
321
self . i2c . cr1 . modify ( |_, w| w. start ( ) . set_bit ( ) ) ;
319
322
@@ -351,6 +354,46 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
351
354
// Clear condition by reading SR2
352
355
self . i2c . sr2 . read ( ) ;
353
356
357
+ Ok ( ( ) )
358
+ }
359
+
360
+ /// Sends START and Address for reading
361
+ fn prepare_read ( & self , addr : u8 ) -> Result < ( ) , Error > {
362
+ // Send a START condition and set ACK bit
363
+ self . i2c
364
+ . cr1
365
+ . modify ( |_, w| w. start ( ) . set_bit ( ) . ack ( ) . set_bit ( ) ) ;
366
+
367
+ // Wait until START condition was generated
368
+ while self . i2c . sr1 . read ( ) . sb ( ) . bit_is_clear ( ) { }
369
+
370
+ // Also wait until signalled we're master and everything is waiting for us
371
+ while {
372
+ let sr2 = self . i2c . sr2 . read ( ) ;
373
+ sr2. msl ( ) . bit_is_clear ( ) && sr2. busy ( ) . bit_is_clear ( )
374
+ } { }
375
+
376
+ // Set up current address, we're trying to talk to
377
+ self . i2c
378
+ . dr
379
+ . write ( |w| unsafe { w. bits ( ( u32:: from ( addr) << 1 ) + 1 ) } ) ;
380
+
381
+ // Wait until address was sent
382
+ loop {
383
+ self . check_and_clear_error_flags ( )
384
+ . map_err ( Error :: nack_addr) ?;
385
+ if self . i2c . sr1 . read ( ) . addr ( ) . bit_is_set ( ) {
386
+ break ;
387
+ }
388
+ }
389
+
390
+ // Clear condition by reading SR2
391
+ self . i2c . sr2 . read ( ) ;
392
+
393
+ Ok ( ( ) )
394
+ }
395
+
396
+ fn write_bytes ( & mut self , bytes : impl Iterator < Item = u8 > ) -> Result < ( ) , Error > {
354
397
// Send bytes
355
398
for c in bytes {
356
399
self . send_byte ( c) ?;
@@ -400,43 +443,29 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
400
443
Ok ( value)
401
444
}
402
445
403
- pub fn read ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
404
- if let Some ( ( last, buffer) ) = buffer. split_last_mut ( ) {
405
- // Send a START condition and set ACK bit
406
- self . i2c
407
- . cr1
408
- . modify ( |_, w| w. start ( ) . set_bit ( ) . ack ( ) . set_bit ( ) ) ;
409
-
410
- // Wait until START condition was generated
411
- while self . i2c . sr1 . read ( ) . sb ( ) . bit_is_clear ( ) { }
446
+ fn read_bytes ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
447
+ // Receive bytes into buffer
448
+ for c in buffer {
449
+ * c = self . recv_byte ( ) ?;
450
+ }
412
451
413
- // Also wait until signalled we're master and everything is waiting for us
414
- while {
415
- let sr2 = self . i2c . sr2 . read ( ) ;
416
- sr2. msl ( ) . bit_is_clear ( ) && sr2. busy ( ) . bit_is_clear ( )
417
- } { }
452
+ Ok ( ( ) )
453
+ }
418
454
419
- // Set up current address, we're trying to talk to
420
- self . i2c
421
- . dr
422
- . write ( |w| unsafe { w. bits ( ( u32:: from ( addr) << 1 ) + 1 ) } ) ;
423
-
424
- // Wait until address was sent
425
- loop {
426
- self . check_and_clear_error_flags ( )
427
- . map_err ( Error :: nack_addr) ?;
428
- if self . i2c . sr1 . read ( ) . addr ( ) . bit_is_set ( ) {
429
- break ;
430
- }
431
- }
455
+ pub fn read ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
456
+ if buffer. is_empty ( ) {
457
+ return Err ( Error :: Overrun ) ;
458
+ }
432
459
433
- // Clear condition by reading SR2
434
- self . i2c . sr2 . read ( ) ;
460
+ self . prepare_read ( addr) ?;
461
+ self . read_wo_prepare ( buffer)
462
+ }
435
463
436
- // Receive bytes into buffer
437
- for c in buffer {
438
- * c = self . recv_byte ( ) ?;
439
- }
464
+ /// Reads like normal but does'n genereate start and don't send address
465
+ fn read_wo_prepare ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
466
+ if let Some ( ( last, buffer) ) = buffer. split_last_mut ( ) {
467
+ // Read all bytes but not last
468
+ self . read_bytes ( buffer) ?;
440
469
441
470
// Prepare to send NACK then STOP after next byte
442
471
self . i2c
@@ -457,7 +486,13 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
457
486
}
458
487
459
488
pub fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
460
- self . write_bytes ( addr, bytes. iter ( ) . cloned ( ) ) ?;
489
+ self . prepare_write ( addr) ?;
490
+ self . write_wo_prepare ( bytes)
491
+ }
492
+
493
+ /// Writes like normal but does'n genereate start and don't send address
494
+ fn write_wo_prepare ( & mut self , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
495
+ self . write_bytes ( bytes. iter ( ) . cloned ( ) ) ?;
461
496
462
497
// Send a STOP condition
463
498
self . i2c . cr1 . modify ( |_, w| w. stop ( ) . set_bit ( ) ) ;
@@ -473,7 +508,8 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
473
508
where
474
509
B : IntoIterator < Item = u8 > ,
475
510
{
476
- self . write_bytes ( addr, bytes. into_iter ( ) ) ?;
511
+ self . prepare_write ( addr) ?;
512
+ self . write_bytes ( bytes. into_iter ( ) ) ?;
477
513
478
514
// Send a STOP condition
479
515
self . i2c . cr1 . modify ( |_, w| w. stop ( ) . set_bit ( ) ) ;
@@ -486,15 +522,97 @@ impl<I2C: Instance, PINS> I2c<I2C, PINS> {
486
522
}
487
523
488
524
pub fn write_read ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
489
- self . write_bytes ( addr, bytes. iter ( ) . cloned ( ) ) ?;
525
+ self . prepare_write ( addr) ?;
526
+ self . write_bytes ( bytes. iter ( ) . cloned ( ) ) ?;
490
527
self . read ( addr, buffer)
491
528
}
492
529
493
530
pub fn write_iter_read < B > ( & mut self , addr : u8 , bytes : B , buffer : & mut [ u8 ] ) -> Result < ( ) , Error >
494
531
where
495
532
B : IntoIterator < Item = u8 > ,
496
533
{
497
- self . write_bytes ( addr, bytes. into_iter ( ) ) ?;
534
+ self . prepare_write ( addr) ?;
535
+ self . write_bytes ( bytes. into_iter ( ) ) ?;
498
536
self . read ( addr, buffer)
499
537
}
538
+
539
+ pub fn transaction < ' a > (
540
+ & mut self ,
541
+ addr : u8 ,
542
+ mut ops : impl Iterator < Item = Operation < ' a > > ,
543
+ ) -> Result < ( ) , Error > {
544
+ if let Some ( mut prev_op) = ops. next ( ) {
545
+ // 1. Generate Start for operation
546
+ match & prev_op {
547
+ Operation :: Read ( _) => self . prepare_read ( addr) ?,
548
+ Operation :: Write ( _) => self . prepare_write ( addr) ?,
549
+ } ;
550
+
551
+ for op in ops {
552
+ // 2. Execute previous operations.
553
+ match & mut prev_op {
554
+ Operation :: Read ( rb) => self . read_bytes ( * rb) ?,
555
+ Operation :: Write ( wb) => self . write_bytes ( wb. iter ( ) . cloned ( ) ) ?,
556
+ } ;
557
+ // 3. If operation changes type we must generate new start
558
+ match ( & prev_op, & op) {
559
+ ( Operation :: Read ( _) , Operation :: Write ( _) ) => self . prepare_write ( addr) ?,
560
+ ( Operation :: Write ( _) , Operation :: Read ( _) ) => self . prepare_read ( addr) ?,
561
+ _ => { } // No changes if operation have not changed
562
+ }
563
+
564
+ prev_op = op;
565
+ }
566
+
567
+ // 4. Now, prev_op is last command use methods variations that will generate stop
568
+ match prev_op {
569
+ Operation :: Read ( rb) => self . read_wo_prepare ( rb) ?,
570
+ Operation :: Write ( wb) => self . write_wo_prepare ( wb) ?,
571
+ } ;
572
+ }
573
+
574
+ // Fallthrough is success
575
+ Ok ( ( ) )
576
+ }
577
+
578
+ pub fn transaction_slice < ' a > (
579
+ & mut self ,
580
+ addr : u8 ,
581
+ ops_slice : & mut [ Operation < ' a > ] ,
582
+ ) -> Result < ( ) , Error > {
583
+ let mut ops = ops_slice. iter_mut ( ) ;
584
+
585
+ if let Some ( mut prev_op) = ops. next ( ) {
586
+ // 1. Generate Start for operation
587
+ match & prev_op {
588
+ Operation :: Read ( _) => self . prepare_read ( addr) ?,
589
+ Operation :: Write ( _) => self . prepare_write ( addr) ?,
590
+ } ;
591
+
592
+ for op in ops {
593
+ // 2. Execute previous operations.
594
+ match & mut prev_op {
595
+ Operation :: Read ( rb) => self . read_bytes ( * rb) ?,
596
+ Operation :: Write ( wb) => self . write_bytes ( wb. iter ( ) . cloned ( ) ) ?,
597
+ } ;
598
+ // 3. If operation changes type we must generate new start
599
+ match ( & prev_op, & op) {
600
+ ( Operation :: Read ( _) , Operation :: Write ( _) ) => self . prepare_write ( addr) ?,
601
+ ( Operation :: Write ( _) , Operation :: Read ( _) ) => self . prepare_read ( addr) ?,
602
+ _ => { } // No changes if operation have not changed
603
+ }
604
+
605
+ prev_op = op;
606
+ }
607
+
608
+ // 4. Now, prev_op is last command use methods variations that will generate stop
609
+ match prev_op {
610
+ Operation :: Read ( rb) => self . read_wo_prepare ( rb) ?,
611
+ Operation :: Write ( wb) => self . write_wo_prepare ( wb) ?,
612
+ } ;
613
+ }
614
+
615
+ // Fallthrough is success
616
+ Ok ( ( ) )
617
+ }
500
618
}
0 commit comments