@@ -13,6 +13,24 @@ mod hal_1;
13
13
14
14
pub mod dma;
15
15
16
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
17
+ pub enum Address {
18
+ Seven ( u8 ) ,
19
+ Ten ( u16 ) ,
20
+ }
21
+
22
+ impl From < u8 > for Address {
23
+ fn from ( value : u8 ) -> Self {
24
+ Self :: Seven ( value)
25
+ }
26
+ }
27
+
28
+ impl From < u16 > for Address {
29
+ fn from ( value : u16 ) -> Self {
30
+ Self :: Ten ( value)
31
+ }
32
+ }
33
+
16
34
#[ derive( Debug , Eq , PartialEq ) ]
17
35
pub enum DutyCycle {
18
36
Ratio2to1 ,
@@ -286,9 +304,41 @@ impl<I2C: Instance> I2c<I2C> {
286
304
Ok ( sr1)
287
305
}
288
306
307
+ /// Set up current address, we're trying to talk to
308
+ #[ inline( always) ]
309
+ fn set_address ( & self , addr : Address , read : bool , first_transaction : bool ) {
310
+ match addr {
311
+ Address :: Seven ( addr) => {
312
+ self . i2c . dr ( ) . write ( |w| unsafe {
313
+ w. bits ( {
314
+ let addr = u32:: from ( addr) << 1 ;
315
+ if read {
316
+ addr & 1
317
+ } else {
318
+ addr
319
+ }
320
+ } )
321
+ } ) ;
322
+ }
323
+ Address :: Ten ( addr) => {
324
+ let [ msbs, lsbs] = addr. to_be_bytes ( ) ;
325
+ let msbs = ( ( msbs & 0b11 ) << 1 ) & 0b11110000 ;
326
+ let dr = self . i2c . dr ( ) ;
327
+ if first_transaction {
328
+ dr. write ( |w| unsafe { w. bits ( u32:: from ( msbs) ) } ) ;
329
+ dr. write ( |w| unsafe { w. bits ( u32:: from ( lsbs) ) } ) ;
330
+ }
331
+ if read {
332
+ self . i2c . cr1 ( ) . modify ( |_, w| w. start ( ) . set_bit ( ) ) ;
333
+ dr. write ( |w| unsafe { w. bits ( u32:: from ( msbs & 1 ) ) } ) ;
334
+ }
335
+ }
336
+ }
337
+ }
338
+
289
339
/// Sends START and Address for writing
290
340
#[ inline( always) ]
291
- fn prepare_write ( & self , addr : u8 ) -> Result < ( ) , Error > {
341
+ fn prepare_write ( & self , addr : Address , first_transaction : bool ) -> Result < ( ) , Error > {
292
342
// Wait until a previous STOP condition finishes. When the previous
293
343
// STOP was generated inside an ISR (e.g. DMA interrupt handler),
294
344
// the ISR returns without waiting for the STOP condition to finish.
@@ -313,10 +363,7 @@ impl<I2C: Instance> I2c<I2C> {
313
363
}
314
364
}
315
365
316
- // Set up current address, we're trying to talk to
317
- self . i2c
318
- . dr ( )
319
- . write ( |w| unsafe { w. bits ( u32:: from ( addr) << 1 ) } ) ;
366
+ self . set_address ( addr, false , first_transaction) ;
320
367
321
368
// Wait until address was sent
322
369
loop {
@@ -338,7 +385,7 @@ impl<I2C: Instance> I2c<I2C> {
338
385
}
339
386
340
387
/// Sends START and Address for reading
341
- fn prepare_read ( & self , addr : u8 ) -> Result < ( ) , Error > {
388
+ fn prepare_read ( & self , addr : Address , first_transaction : bool ) -> Result < ( ) , Error > {
342
389
// Wait until a previous STOP condition finishes. When the previous
343
390
// STOP was generated inside an ISR (e.g. DMA interrupt handler),
344
391
// the ISR returns without waiting for the STOP condition to finish.
@@ -361,10 +408,7 @@ impl<I2C: Instance> I2c<I2C> {
361
408
sr2. msl ( ) . bit_is_clear ( ) && sr2. busy ( ) . bit_is_clear ( )
362
409
} { }
363
410
364
- // Set up current address, we're trying to talk to
365
- self . i2c
366
- . dr ( )
367
- . write ( |w| unsafe { w. bits ( ( u32:: from ( addr) << 1 ) + 1 ) } ) ;
411
+ self . set_address ( addr, true , first_transaction) ;
368
412
369
413
// Wait until address was sent
370
414
loop {
@@ -440,12 +484,22 @@ impl<I2C: Instance> I2c<I2C> {
440
484
Ok ( ( ) )
441
485
}
442
486
443
- pub fn read ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
487
+ pub fn read ( & mut self , addr : impl Into < Address > , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
488
+ self . read_inner ( addr. into ( ) , buffer, true )
489
+ }
490
+
491
+ #[ inline( always) ]
492
+ fn read_inner (
493
+ & mut self ,
494
+ addr : Address ,
495
+ buffer : & mut [ u8 ] ,
496
+ first_transaction : bool ,
497
+ ) -> Result < ( ) , Error > {
444
498
if buffer. is_empty ( ) {
445
499
return Err ( Error :: Overrun ) ;
446
500
}
447
501
448
- self . prepare_read ( addr) ?;
502
+ self . prepare_read ( addr. into ( ) , first_transaction ) ?;
449
503
self . read_wo_prepare ( buffer)
450
504
}
451
505
@@ -477,8 +531,8 @@ impl<I2C: Instance> I2c<I2C> {
477
531
}
478
532
}
479
533
480
- pub fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
481
- self . prepare_write ( addr) ?;
534
+ pub fn write ( & mut self , addr : impl Into < Address > , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
535
+ self . prepare_write ( addr. into ( ) , true ) ?;
482
536
self . write_wo_prepare ( bytes)
483
537
}
484
538
@@ -500,11 +554,11 @@ impl<I2C: Instance> I2c<I2C> {
500
554
Ok ( ( ) )
501
555
}
502
556
503
- pub fn write_iter < B > ( & mut self , addr : u8 , bytes : B ) -> Result < ( ) , Error >
557
+ pub fn write_iter < B > ( & mut self , addr : impl Into < Address > , bytes : B ) -> Result < ( ) , Error >
504
558
where
505
559
B : IntoIterator < Item = u8 > ,
506
560
{
507
- self . prepare_write ( addr) ?;
561
+ self . prepare_write ( addr. into ( ) , true ) ?;
508
562
self . write_bytes ( bytes. into_iter ( ) ) ?;
509
563
510
564
// Send a STOP condition
@@ -521,31 +575,44 @@ impl<I2C: Instance> I2c<I2C> {
521
575
Ok ( ( ) )
522
576
}
523
577
524
- pub fn write_read ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
525
- self . prepare_write ( addr) ?;
578
+ pub fn write_read (
579
+ & mut self ,
580
+ addr : impl Into < Address > ,
581
+ bytes : & [ u8 ] ,
582
+ buffer : & mut [ u8 ] ,
583
+ ) -> Result < ( ) , Error > {
584
+ let addr = addr. into ( ) ;
585
+ self . prepare_write ( addr, true ) ?;
526
586
self . write_bytes ( bytes. iter ( ) . cloned ( ) ) ?;
527
- self . read ( addr, buffer)
587
+ self . read_inner ( addr, buffer, false )
528
588
}
529
589
530
- pub fn write_iter_read < B > ( & mut self , addr : u8 , bytes : B , buffer : & mut [ u8 ] ) -> Result < ( ) , Error >
590
+ pub fn write_iter_read < B > (
591
+ & mut self ,
592
+ addr : impl Into < Address > ,
593
+ bytes : B ,
594
+ buffer : & mut [ u8 ] ,
595
+ ) -> Result < ( ) , Error >
531
596
where
532
597
B : IntoIterator < Item = u8 > ,
533
598
{
534
- self . prepare_write ( addr) ?;
599
+ let addr = addr. into ( ) ;
600
+ self . prepare_write ( addr, true ) ?;
535
601
self . write_bytes ( bytes. into_iter ( ) ) ?;
536
- self . read ( addr, buffer)
602
+ self . read_inner ( addr, buffer, false )
537
603
}
538
604
539
605
pub fn transaction < ' a > (
540
606
& mut self ,
541
- addr : u8 ,
607
+ addr : impl Into < Address > ,
542
608
mut ops : impl Iterator < Item = Hal1Operation < ' a > > ,
543
609
) -> Result < ( ) , Error > {
610
+ let addr = addr. into ( ) ;
544
611
if let Some ( mut prev_op) = ops. next ( ) {
545
612
// 1. Generate Start for operation
546
613
match & prev_op {
547
- Hal1Operation :: Read ( _) => self . prepare_read ( addr) ?,
548
- Hal1Operation :: Write ( _) => self . prepare_write ( addr) ?,
614
+ Hal1Operation :: Read ( _) => self . prepare_read ( addr, true ) ?,
615
+ Hal1Operation :: Write ( _) => self . prepare_write ( addr, true ) ?,
549
616
} ;
550
617
551
618
for op in ops {
@@ -557,9 +624,11 @@ impl<I2C: Instance> I2c<I2C> {
557
624
// 3. If operation changes type we must generate new start
558
625
match ( & prev_op, & op) {
559
626
( Hal1Operation :: Read ( _) , Hal1Operation :: Write ( _) ) => {
560
- self . prepare_write ( addr) ?
627
+ self . prepare_write ( addr, false ) ?
628
+ }
629
+ ( Hal1Operation :: Write ( _) , Hal1Operation :: Read ( _) ) => {
630
+ self . prepare_read ( addr, false ) ?
561
631
}
562
- ( Hal1Operation :: Write ( _) , Hal1Operation :: Read ( _) ) => self . prepare_read ( addr) ?,
563
632
_ => { } // No changes if operation have not changed
564
633
}
565
634
@@ -579,19 +648,21 @@ impl<I2C: Instance> I2c<I2C> {
579
648
580
649
pub fn transaction_slice (
581
650
& mut self ,
582
- addr : u8 ,
651
+ addr : impl Into < Address > ,
583
652
ops_slice : & mut [ Hal1Operation < ' _ > ] ,
584
653
) -> Result < ( ) , Error > {
654
+ let addr = addr. into ( ) ;
585
655
transaction_impl ! ( self , addr, ops_slice, Hal1Operation ) ;
586
656
// Fallthrough is success
587
657
Ok ( ( ) )
588
658
}
589
659
590
660
fn transaction_slice_hal_02 (
591
661
& mut self ,
592
- addr : u8 ,
662
+ addr : impl Into < Address > ,
593
663
ops_slice : & mut [ Hal02Operation < ' _ > ] ,
594
664
) -> Result < ( ) , Error > {
665
+ let addr = addr. into ( ) ;
595
666
transaction_impl ! ( self , addr, ops_slice, Hal02Operation ) ;
596
667
// Fallthrough is success
597
668
Ok ( ( ) )
@@ -607,8 +678,8 @@ macro_rules! transaction_impl {
607
678
if let Some ( mut prev_op) = ops. next( ) {
608
679
// 1. Generate Start for operation
609
680
match & prev_op {
610
- $Operation:: Read ( _) => i2c. prepare_read( addr) ?,
611
- $Operation:: Write ( _) => i2c. prepare_write( addr) ?,
681
+ $Operation:: Read ( _) => i2c. prepare_read( addr, true ) ?,
682
+ $Operation:: Write ( _) => i2c. prepare_write( addr, true ) ?,
612
683
} ;
613
684
614
685
for op in ops {
@@ -619,8 +690,10 @@ macro_rules! transaction_impl {
619
690
} ;
620
691
// 3. If operation changes type we must generate new start
621
692
match ( & prev_op, & op) {
622
- ( $Operation:: Read ( _) , $Operation:: Write ( _) ) => i2c. prepare_write( addr) ?,
623
- ( $Operation:: Write ( _) , $Operation:: Read ( _) ) => i2c. prepare_read( addr) ?,
693
+ ( $Operation:: Read ( _) , $Operation:: Write ( _) ) => {
694
+ i2c. prepare_write( addr, false ) ?
695
+ }
696
+ ( $Operation:: Write ( _) , $Operation:: Read ( _) ) => i2c. prepare_read( addr, false ) ?,
624
697
_ => { } // No changes if operation have not changed
625
698
}
626
699
0 commit comments