@@ -2,54 +2,67 @@ use core::ops::Deref;
22
33use crate :: gpio;
44use crate :: i2c:: { Error , NoAcknowledgeSource } ;
5- use crate :: pac:: { fmpi2c1, FMPI2C1 , RCC } ;
6- use crate :: rcc:: { Enable , Reset } ;
5+ use crate :: pac:: fmpi2c1 as i2c1;
6+ use crate :: pac:: { self , RCC } ;
7+ use crate :: rcc:: { BusClock , Enable , Reset } ;
78use fugit:: { HertzU32 as Hertz , RateExtU32 } ;
89
10+ // Old names
11+ pub use I2c as FmpI2c ;
12+ pub use Mode as FmpMode ;
13+
914mod hal_02;
1015mod hal_1;
1116
1217pub trait Instance :
1318 crate :: Sealed
14- + crate :: Ptr < RB = fmpi2c1 :: RegisterBlock >
19+ + crate :: Ptr < RB = i2c1 :: RegisterBlock >
1520 + Deref < Target = Self :: RB >
1621 + Enable
1722 + Reset
23+ + BusClock
1824 + gpio:: alt:: I2cCommon
1925{
2026 fn clock_hsi ( rcc : & crate :: pac:: rcc:: RegisterBlock ) ;
2127}
2228
23- impl Instance for FMPI2C1 {
24- fn clock_hsi ( rcc : & crate :: pac:: rcc:: RegisterBlock ) {
25- rcc. dckcfgr2 ( ) . modify ( |_, w| w. fmpi2c1sel ( ) . hsi ( ) ) ;
26- }
27- }
29+ macro_rules! i2c {
30+ ( $I2C: ty, $i2csel: ident, $I2Calias: ident) => {
31+ pub type $I2Calias = I2c <$I2C>;
2832
29- impl crate :: Ptr for FMPI2C1 {
30- type RB = fmpi2c1:: RegisterBlock ;
31- #[ inline( always) ]
32- fn ptr ( ) -> * const Self :: RB {
33- Self :: ptr ( )
34- }
33+ impl Instance for $I2C {
34+ fn clock_hsi( rcc: & crate :: pac:: rcc:: RegisterBlock ) {
35+ rcc. dckcfgr2( ) . modify( |_, w| w. $i2csel( ) . hsi( ) ) ;
36+ }
37+ }
38+
39+ impl crate :: Ptr for $I2C {
40+ type RB = i2c1:: RegisterBlock ;
41+ #[ inline( always) ]
42+ fn ptr( ) -> * const Self :: RB {
43+ Self :: ptr( )
44+ }
45+ }
46+ } ;
3547}
3648
49+ #[ cfg( feature = "fmpi2c1" ) ]
50+ i2c ! ( pac:: FMPI2C1 , fmpi2c1sel, FMPI2c1 ) ;
51+
3752/// I2C FastMode+ abstraction
38- pub struct FMPI2c < I2C : Instance > {
53+ pub struct I2c < I2C : Instance > {
3954 i2c : I2C ,
4055 pins : ( I2C :: Scl , I2C :: Sda ) ,
4156}
4257
43- pub type FMPI2c1 = FMPI2c < FMPI2C1 > ;
44-
45- #[ derive( Debug , PartialEq ) ]
46- pub enum FmpMode {
58+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
59+ pub enum Mode {
4760 Standard { frequency : Hertz } ,
4861 Fast { frequency : Hertz } ,
4962 FastPlus { frequency : Hertz } ,
5063}
5164
52- impl FmpMode {
65+ impl Mode {
5366 pub fn standard ( frequency : Hertz ) -> Self {
5467 Self :: Standard { frequency }
5568 }
@@ -71,7 +84,7 @@ impl FmpMode {
7184 }
7285}
7386
74- impl From < Hertz > for FmpMode {
87+ impl From < Hertz > for Mode {
7588 fn from ( frequency : Hertz ) -> Self {
7689 let k100: Hertz = 100 . kHz ( ) ;
7790 let k400: Hertz = 400 . kHz ( ) ;
@@ -85,26 +98,39 @@ impl From<Hertz> for FmpMode {
8598 }
8699}
87100
88- impl < I2C : Instance > FMPI2c < I2C > {
101+ pub trait I2cExt : Sized + Instance {
102+ fn i2c < ' a > (
103+ self ,
104+ pins : ( impl Into < Self :: Scl > , impl Into < Self :: Sda > ) ,
105+ mode : impl Into < Mode > ,
106+ ) -> I2c < Self > ;
107+ }
108+
109+ impl < I2C : Instance > I2cExt for I2C {
110+ fn i2c < ' a > (
111+ self ,
112+ pins : ( impl Into < Self :: Scl > , impl Into < Self :: Sda > ) ,
113+ mode : impl Into < Mode > ,
114+ ) -> I2c < Self > {
115+ I2c :: new ( self , pins, mode)
116+ }
117+ }
118+
119+ impl < I2C : Instance > I2c < I2C > {
89120 pub fn new (
90121 i2c : I2C ,
91122 pins : ( impl Into < I2C :: Scl > , impl Into < I2C :: Sda > ) ,
92- mode : impl Into < FmpMode > ,
123+ mode : impl Into < Mode > ,
93124 ) -> Self {
94125 unsafe {
95- // NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
96- let rcc = & ( * RCC :: ptr ( ) ) ;
97-
98126 // Enable and reset clock.
99- I2C :: enable ( rcc) ;
100- I2C :: reset ( rcc) ;
101-
102- I2C :: clock_hsi ( rcc) ;
127+ I2C :: enable_unchecked ( ) ;
128+ I2C :: reset_unchecked ( ) ;
103129 }
104130
105131 let pins = ( pins. 0 . into ( ) , pins. 1 . into ( ) ) ;
106132
107- let i2c = FMPI2c { i2c, pins } ;
133+ let i2c = I2c { i2c, pins } ;
108134 i2c. i2c_init ( mode) ;
109135 i2c
110136 }
@@ -114,14 +140,18 @@ impl<I2C: Instance> FMPI2c<I2C> {
114140 }
115141}
116142
117- impl < I2C : Instance > FMPI2c < I2C > {
118- fn i2c_init < M : Into < FmpMode > > ( & self , mode : M ) {
143+ impl < I2C : Instance > I2c < I2C > {
144+ fn i2c_init ( & self , mode : impl Into < Mode > ) {
119145 let mode = mode. into ( ) ;
120146 use core:: cmp;
121147
122148 // Make sure the I2C unit is disabled so we can configure it
123149 self . i2c . cr1 ( ) . modify ( |_, w| w. pe ( ) . clear_bit ( ) ) ;
124150
151+ // NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
152+ let rcc = unsafe { & ( * RCC :: ptr ( ) ) } ;
153+ I2C :: clock_hsi ( rcc) ;
154+
125155 // Calculate settings for I2C speed modes
126156 let presc;
127157 let scldel;
@@ -135,21 +165,21 @@ impl<I2C: Instance> FMPI2c<I2C> {
135165 // Normal I2C speeds use a different scaling than fast mode below and fast mode+ even more
136166 // below
137167 match mode {
138- FmpMode :: Standard { frequency } => {
168+ Mode :: Standard { frequency } => {
139169 presc = 3 ;
140170 scll = cmp:: max ( ( ( ( FREQ >> presc) >> 1 ) / frequency. raw ( ) ) - 1 , 255 ) as u8 ;
141171 sclh = scll - 4 ;
142172 sdadel = 2 ;
143173 scldel = 4 ;
144174 }
145- FmpMode :: Fast { frequency } => {
175+ Mode :: Fast { frequency } => {
146176 presc = 1 ;
147177 scll = cmp:: max ( ( ( ( FREQ >> presc) >> 1 ) / frequency. raw ( ) ) - 1 , 255 ) as u8 ;
148178 sclh = scll - 6 ;
149179 sdadel = 2 ;
150180 scldel = 3 ;
151181 }
152- FmpMode :: FastPlus { frequency } => {
182+ Mode :: FastPlus { frequency } => {
153183 presc = 0 ;
154184 scll = cmp:: max ( ( ( ( FREQ >> presc) >> 1 ) / frequency. raw ( ) ) - 4 , 255 ) as u8 ;
155185 sclh = scll - 2 ;
@@ -171,7 +201,8 @@ impl<I2C: Instance> FMPI2c<I2C> {
171201 self . i2c . cr1 ( ) . modify ( |_, w| w. pe ( ) . set_bit ( ) ) ;
172202 }
173203
174- fn check_and_clear_error_flags ( & self , isr : & fmpi2c1:: isr:: R ) -> Result < ( ) , Error > {
204+ #[ inline( always) ]
205+ fn check_and_clear_error_flags ( & self , isr : & i2c1:: isr:: R ) -> Result < ( ) , Error > {
175206 // If we received a NACK, then this is an error
176207 if isr. nackf ( ) . bit_is_set ( ) {
177208 self . i2c
@@ -183,6 +214,7 @@ impl<I2C: Instance> FMPI2c<I2C> {
183214 Ok ( ( ) )
184215 }
185216
217+ #[ inline( always) ]
186218 fn end_transaction ( & self ) -> Result < ( ) , Error > {
187219 // Check and clear flags if they somehow ended up set
188220 self . check_and_clear_error_flags ( & self . i2c . isr ( ) . read ( ) )
0 commit comments