@@ -13,6 +13,24 @@ mod hal_1;
1313
1414pub mod dma;
1515
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+
1634#[ derive( Debug , Eq , PartialEq ) ]
1735pub enum DutyCycle {
1836 Ratio2to1 ,
@@ -286,9 +304,41 @@ impl<I2C: Instance> I2c<I2C> {
286304 Ok ( sr1)
287305 }
288306
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+
289339 /// Sends START and Address for writing
290340 #[ inline( always) ]
291- fn prepare_write ( & self , addr : u8 ) -> Result < ( ) , Error > {
341+ fn prepare_write ( & self , addr : Address , first_transaction : bool ) -> Result < ( ) , Error > {
292342 // Wait until a previous STOP condition finishes. When the previous
293343 // STOP was generated inside an ISR (e.g. DMA interrupt handler),
294344 // the ISR returns without waiting for the STOP condition to finish.
@@ -313,10 +363,7 @@ impl<I2C: Instance> I2c<I2C> {
313363 }
314364 }
315365
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) ;
320367
321368 // Wait until address was sent
322369 loop {
@@ -338,7 +385,7 @@ impl<I2C: Instance> I2c<I2C> {
338385 }
339386
340387 /// 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 > {
342389 // Wait until a previous STOP condition finishes. When the previous
343390 // STOP was generated inside an ISR (e.g. DMA interrupt handler),
344391 // the ISR returns without waiting for the STOP condition to finish.
@@ -361,10 +408,7 @@ impl<I2C: Instance> I2c<I2C> {
361408 sr2. msl ( ) . bit_is_clear ( ) && sr2. busy ( ) . bit_is_clear ( )
362409 } { }
363410
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) ;
368412
369413 // Wait until address was sent
370414 loop {
@@ -440,12 +484,22 @@ impl<I2C: Instance> I2c<I2C> {
440484 Ok ( ( ) )
441485 }
442486
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 > {
444498 if buffer. is_empty ( ) {
445499 return Err ( Error :: Overrun ) ;
446500 }
447501
448- self . prepare_read ( addr) ?;
502+ self . prepare_read ( addr. into ( ) , first_transaction ) ?;
449503 self . read_wo_prepare ( buffer)
450504 }
451505
@@ -477,8 +531,8 @@ impl<I2C: Instance> I2c<I2C> {
477531 }
478532 }
479533
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 ) ?;
482536 self . write_wo_prepare ( bytes)
483537 }
484538
@@ -500,11 +554,11 @@ impl<I2C: Instance> I2c<I2C> {
500554 Ok ( ( ) )
501555 }
502556
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 >
504558 where
505559 B : IntoIterator < Item = u8 > ,
506560 {
507- self . prepare_write ( addr) ?;
561+ self . prepare_write ( addr. into ( ) , true ) ?;
508562 self . write_bytes ( bytes. into_iter ( ) ) ?;
509563
510564 // Send a STOP condition
@@ -521,31 +575,44 @@ impl<I2C: Instance> I2c<I2C> {
521575 Ok ( ( ) )
522576 }
523577
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 ) ?;
526586 self . write_bytes ( bytes. iter ( ) . cloned ( ) ) ?;
527- self . read ( addr, buffer)
587+ self . read_inner ( addr, buffer, false )
528588 }
529589
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 >
531596 where
532597 B : IntoIterator < Item = u8 > ,
533598 {
534- self . prepare_write ( addr) ?;
599+ let addr = addr. into ( ) ;
600+ self . prepare_write ( addr, true ) ?;
535601 self . write_bytes ( bytes. into_iter ( ) ) ?;
536- self . read ( addr, buffer)
602+ self . read_inner ( addr, buffer, false )
537603 }
538604
539605 pub fn transaction < ' a > (
540606 & mut self ,
541- addr : u8 ,
607+ addr : impl Into < Address > ,
542608 mut ops : impl Iterator < Item = Hal1Operation < ' a > > ,
543609 ) -> Result < ( ) , Error > {
610+ let addr = addr. into ( ) ;
544611 if let Some ( mut prev_op) = ops. next ( ) {
545612 // 1. Generate Start for operation
546613 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 ) ?,
549616 } ;
550617
551618 for op in ops {
@@ -557,9 +624,11 @@ impl<I2C: Instance> I2c<I2C> {
557624 // 3. If operation changes type we must generate new start
558625 match ( & prev_op, & op) {
559626 ( 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 ) ?
561631 }
562- ( Hal1Operation :: Write ( _) , Hal1Operation :: Read ( _) ) => self . prepare_read ( addr) ?,
563632 _ => { } // No changes if operation have not changed
564633 }
565634
@@ -579,19 +648,21 @@ impl<I2C: Instance> I2c<I2C> {
579648
580649 pub fn transaction_slice (
581650 & mut self ,
582- addr : u8 ,
651+ addr : impl Into < Address > ,
583652 ops_slice : & mut [ Hal1Operation < ' _ > ] ,
584653 ) -> Result < ( ) , Error > {
654+ let addr = addr. into ( ) ;
585655 transaction_impl ! ( self , addr, ops_slice, Hal1Operation ) ;
586656 // Fallthrough is success
587657 Ok ( ( ) )
588658 }
589659
590660 fn transaction_slice_hal_02 (
591661 & mut self ,
592- addr : u8 ,
662+ addr : impl Into < Address > ,
593663 ops_slice : & mut [ Hal02Operation < ' _ > ] ,
594664 ) -> Result < ( ) , Error > {
665+ let addr = addr. into ( ) ;
595666 transaction_impl ! ( self , addr, ops_slice, Hal02Operation ) ;
596667 // Fallthrough is success
597668 Ok ( ( ) )
@@ -607,8 +678,8 @@ macro_rules! transaction_impl {
607678 if let Some ( mut prev_op) = ops. next( ) {
608679 // 1. Generate Start for operation
609680 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 ) ?,
612683 } ;
613684
614685 for op in ops {
@@ -619,8 +690,10 @@ macro_rules! transaction_impl {
619690 } ;
620691 // 3. If operation changes type we must generate new start
621692 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 ) ?,
624697 _ => { } // No changes if operation have not changed
625698 }
626699
0 commit comments