@@ -8,9 +8,13 @@ use crate::gpio;
88use crate :: rcc:: Clocks ;
99use fugit:: { HertzU32 as Hertz , RateExtU32 } ;
1010
11+ mod common;
1112mod hal_02;
1213mod hal_1;
1314
15+ pub use common:: { Address , Error , NoAcknowledgeSource } ;
16+ use common:: { Hal02Operation , Hal1Operation } ;
17+
1418pub mod dma;
1519
1620#[ derive( Debug , Eq , PartialEq ) ]
@@ -70,39 +74,6 @@ pub struct I2c<I2C: Instance> {
7074 pins : ( I2C :: Scl , I2C :: Sda ) ,
7175}
7276
73- pub use embedded_hal:: i2c:: NoAcknowledgeSource ;
74-
75- #[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
76- #[ non_exhaustive]
77- pub enum Error {
78- Overrun ,
79- NoAcknowledge ( NoAcknowledgeSource ) ,
80- Timeout ,
81- // Note: The Bus error type is not currently returned, but is maintained for compatibility.
82- Bus ,
83- Crc ,
84- ArbitrationLoss ,
85- }
86-
87- impl Error {
88- pub ( crate ) fn nack_addr ( self ) -> Self {
89- match self {
90- Error :: NoAcknowledge ( NoAcknowledgeSource :: Unknown ) => {
91- Error :: NoAcknowledge ( NoAcknowledgeSource :: Address )
92- }
93- e => e,
94- }
95- }
96- pub ( crate ) fn nack_data ( self ) -> Self {
97- match self {
98- Error :: NoAcknowledge ( NoAcknowledgeSource :: Unknown ) => {
99- Error :: NoAcknowledge ( NoAcknowledgeSource :: Data )
100- }
101- e => e,
102- }
103- }
104- }
105-
10677pub trait Instance :
10778 crate :: Sealed
10879 + crate :: Ptr < RB = i2c1:: RegisterBlock >
@@ -155,10 +126,7 @@ impl<I2C: Instance> I2cExt for I2C {
155126 }
156127}
157128
158- impl < I2C > I2c < I2C >
159- where
160- I2C : Instance ,
161- {
129+ impl < I2C : Instance > I2c < I2C > {
162130 pub fn new (
163131 i2c : I2C ,
164132 pins : ( impl Into < I2C :: Scl > , impl Into < I2C :: Sda > ) ,
@@ -287,7 +255,7 @@ impl<I2C: Instance> I2c<I2C> {
287255
288256 /// Sends START and Address for writing
289257 #[ inline( always) ]
290- fn prepare_write ( & self , addr : u8 ) -> Result < ( ) , Error > {
258+ fn prepare_write ( & self , addr : Address ) -> Result < ( ) , Error > {
291259 // Wait until a previous STOP condition finishes. When the previous
292260 // STOP was generated inside an ISR (e.g. DMA interrupt handler),
293261 // the ISR returns without waiting for the STOP condition to finish.
@@ -313,9 +281,20 @@ impl<I2C: Instance> I2c<I2C> {
313281 }
314282
315283 // Set up current address, we're trying to talk to
316- self . i2c
317- . dr ( )
318- . write ( |w| unsafe { w. bits ( u32:: from ( addr) << 1 ) } ) ;
284+ match addr {
285+ Address :: Seven ( addr) => {
286+ self . i2c
287+ . dr ( )
288+ . write ( |w| unsafe { w. bits ( u32:: from ( addr) << 1 ) } ) ;
289+ }
290+ Address :: Ten ( addr) => {
291+ let [ msbs, lsbs] = addr. to_be_bytes ( ) ;
292+ let msbs = ( ( msbs & 0b11 ) << 1 ) & 0b11110000 ;
293+ let dr = self . i2c . dr ( ) ;
294+ dr. write ( |w| unsafe { w. bits ( u32:: from ( msbs) ) } ) ;
295+ dr. write ( |w| unsafe { w. bits ( u32:: from ( lsbs) ) } ) ;
296+ }
297+ }
319298
320299 // Wait until address was sent
321300 loop {
@@ -337,7 +316,7 @@ impl<I2C: Instance> I2c<I2C> {
337316 }
338317
339318 /// Sends START and Address for reading
340- fn prepare_read ( & self , addr : u8 ) -> Result < ( ) , Error > {
319+ fn prepare_read ( & self , addr : Address , first_transaction : bool ) -> Result < ( ) , Error > {
341320 // Wait until a previous STOP condition finishes. When the previous
342321 // STOP was generated inside an ISR (e.g. DMA interrupt handler),
343322 // the ISR returns without waiting for the STOP condition to finish.
@@ -361,9 +340,26 @@ impl<I2C: Instance> I2c<I2C> {
361340 } { }
362341
363342 // Set up current address, we're trying to talk to
364- self . i2c
365- . dr ( )
366- . write ( |w| unsafe { w. bits ( ( u32:: from ( addr) << 1 ) + 1 ) } ) ;
343+ match addr {
344+ Address :: Seven ( addr) => {
345+ self . i2c
346+ . dr ( )
347+ . write ( |w| unsafe { w. bits ( ( u32:: from ( addr) << 1 ) & 1 ) } ) ;
348+ }
349+ Address :: Ten ( addr) => {
350+ let [ msbs, lsbs] = addr. to_be_bytes ( ) ;
351+ let msbs = ( ( msbs & 0b11 ) << 1 ) & 0b11110000 ;
352+ let dr = self . i2c . dr ( ) ;
353+ if first_transaction {
354+ dr. write ( |w| unsafe { w. bits ( u32:: from ( msbs) ) } ) ;
355+ dr. write ( |w| unsafe { w. bits ( u32:: from ( lsbs) ) } ) ;
356+ }
357+ self . i2c . cr1 ( ) . modify ( |_, w| w. start ( ) . set_bit ( ) ) ;
358+ // Wait until START condition was generated
359+ while self . i2c . sr1 ( ) . read ( ) . sb ( ) . bit_is_clear ( ) { }
360+ dr. write ( |w| unsafe { w. bits ( u32:: from ( msbs & 1 ) ) } ) ;
361+ }
362+ }
367363
368364 // Wait until address was sent
369365 loop {
@@ -439,12 +435,22 @@ impl<I2C: Instance> I2c<I2C> {
439435 Ok ( ( ) )
440436 }
441437
442- pub fn read ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
438+ pub fn read ( & mut self , addr : impl Into < Address > , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
439+ self . read_inner ( addr. into ( ) , buffer, true )
440+ }
441+
442+ #[ inline( always) ]
443+ fn read_inner (
444+ & mut self ,
445+ addr : Address ,
446+ buffer : & mut [ u8 ] ,
447+ first_transaction : bool ,
448+ ) -> Result < ( ) , Error > {
443449 if buffer. is_empty ( ) {
444450 return Err ( Error :: Overrun ) ;
445451 }
446452
447- self . prepare_read ( addr) ?;
453+ self . prepare_read ( addr. into ( ) , first_transaction ) ?;
448454 self . read_wo_prepare ( buffer)
449455 }
450456
@@ -476,8 +482,8 @@ impl<I2C: Instance> I2c<I2C> {
476482 }
477483 }
478484
479- pub fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
480- self . prepare_write ( addr) ?;
485+ pub fn write ( & mut self , addr : impl Into < Address > , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
486+ self . prepare_write ( addr. into ( ) ) ?;
481487 self . write_wo_prepare ( bytes)
482488 }
483489
@@ -499,11 +505,11 @@ impl<I2C: Instance> I2c<I2C> {
499505 Ok ( ( ) )
500506 }
501507
502- pub fn write_iter < B > ( & mut self , addr : u8 , bytes : B ) -> Result < ( ) , Error >
508+ pub fn write_iter < B > ( & mut self , addr : impl Into < Address > , bytes : B ) -> Result < ( ) , Error >
503509 where
504510 B : IntoIterator < Item = u8 > ,
505511 {
506- self . prepare_write ( addr) ?;
512+ self . prepare_write ( addr. into ( ) ) ?;
507513 self . write_bytes ( bytes. into_iter ( ) ) ?;
508514
509515 // Send a STOP condition
@@ -520,30 +526,43 @@ impl<I2C: Instance> I2c<I2C> {
520526 Ok ( ( ) )
521527 }
522528
523- pub fn write_read ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
529+ pub fn write_read (
530+ & mut self ,
531+ addr : impl Into < Address > ,
532+ bytes : & [ u8 ] ,
533+ buffer : & mut [ u8 ] ,
534+ ) -> Result < ( ) , Error > {
535+ let addr = addr. into ( ) ;
524536 self . prepare_write ( addr) ?;
525537 self . write_bytes ( bytes. iter ( ) . cloned ( ) ) ?;
526- self . read ( addr, buffer)
538+ self . read_inner ( addr, buffer, false )
527539 }
528540
529- pub fn write_iter_read < B > ( & mut self , addr : u8 , bytes : B , buffer : & mut [ u8 ] ) -> Result < ( ) , Error >
541+ pub fn write_iter_read < B > (
542+ & mut self ,
543+ addr : impl Into < Address > ,
544+ bytes : B ,
545+ buffer : & mut [ u8 ] ,
546+ ) -> Result < ( ) , Error >
530547 where
531548 B : IntoIterator < Item = u8 > ,
532549 {
550+ let addr = addr. into ( ) ;
533551 self . prepare_write ( addr) ?;
534552 self . write_bytes ( bytes. into_iter ( ) ) ?;
535- self . read ( addr, buffer)
553+ self . read_inner ( addr, buffer, false )
536554 }
537555
538556 pub fn transaction < ' a > (
539557 & mut self ,
540- addr : u8 ,
558+ addr : impl Into < Address > ,
541559 mut ops : impl Iterator < Item = Hal1Operation < ' a > > ,
542560 ) -> Result < ( ) , Error > {
561+ let addr = addr. into ( ) ;
543562 if let Some ( mut prev_op) = ops. next ( ) {
544563 // 1. Generate Start for operation
545564 match & prev_op {
546- Hal1Operation :: Read ( _) => self . prepare_read ( addr) ?,
565+ Hal1Operation :: Read ( _) => self . prepare_read ( addr, true ) ?,
547566 Hal1Operation :: Write ( _) => self . prepare_write ( addr) ?,
548567 } ;
549568
@@ -558,7 +577,9 @@ impl<I2C: Instance> I2c<I2C> {
558577 ( Hal1Operation :: Read ( _) , Hal1Operation :: Write ( _) ) => {
559578 self . prepare_write ( addr) ?
560579 }
561- ( Hal1Operation :: Write ( _) , Hal1Operation :: Read ( _) ) => self . prepare_read ( addr) ?,
580+ ( Hal1Operation :: Write ( _) , Hal1Operation :: Read ( _) ) => {
581+ self . prepare_read ( addr, false ) ?
582+ }
562583 _ => { } // No changes if operation have not changed
563584 }
564585
@@ -578,19 +599,21 @@ impl<I2C: Instance> I2c<I2C> {
578599
579600 pub fn transaction_slice (
580601 & mut self ,
581- addr : u8 ,
602+ addr : impl Into < Address > ,
582603 ops_slice : & mut [ Hal1Operation < ' _ > ] ,
583604 ) -> Result < ( ) , Error > {
605+ let addr = addr. into ( ) ;
584606 transaction_impl ! ( self , addr, ops_slice, Hal1Operation ) ;
585607 // Fallthrough is success
586608 Ok ( ( ) )
587609 }
588610
589611 fn transaction_slice_hal_02 (
590612 & mut self ,
591- addr : u8 ,
613+ addr : impl Into < Address > ,
592614 ops_slice : & mut [ Hal02Operation < ' _ > ] ,
593615 ) -> Result < ( ) , Error > {
616+ let addr = addr. into ( ) ;
594617 transaction_impl ! ( self , addr, ops_slice, Hal02Operation ) ;
595618 // Fallthrough is success
596619 Ok ( ( ) )
@@ -606,7 +629,7 @@ macro_rules! transaction_impl {
606629 if let Some ( mut prev_op) = ops. next( ) {
607630 // 1. Generate Start for operation
608631 match & prev_op {
609- $Operation:: Read ( _) => i2c. prepare_read( addr) ?,
632+ $Operation:: Read ( _) => i2c. prepare_read( addr, true ) ?,
610633 $Operation:: Write ( _) => i2c. prepare_write( addr) ?,
611634 } ;
612635
@@ -619,7 +642,7 @@ macro_rules! transaction_impl {
619642 // 3. If operation changes type we must generate new start
620643 match ( & prev_op, & op) {
621644 ( $Operation:: Read ( _) , $Operation:: Write ( _) ) => i2c. prepare_write( addr) ?,
622- ( $Operation:: Write ( _) , $Operation:: Read ( _) ) => i2c. prepare_read( addr) ?,
645+ ( $Operation:: Write ( _) , $Operation:: Read ( _) ) => i2c. prepare_read( addr, false ) ?,
623646 _ => { } // No changes if operation have not changed
624647 }
625648
@@ -635,6 +658,3 @@ macro_rules! transaction_impl {
635658 } ;
636659}
637660use transaction_impl;
638-
639- type Hal1Operation < ' a > = embedded_hal:: i2c:: Operation < ' a > ;
640- type Hal02Operation < ' a > = embedded_hal_02:: blocking:: i2c:: Operation < ' a > ;
0 commit comments