1
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
2
- use crate :: stm32:: { I2C1 , RCC } ;
1
+ use core:: ops:: Deref ;
3
2
4
3
use crate :: stm32;
5
4
use embedded_hal:: blocking:: i2c:: { Write , WriteRead } ;
@@ -65,32 +64,71 @@ i2c_pins! {
65
64
sda => [ gpiob:: PB14 <Alternate <AF5 >>, gpiof:: PF0 <Alternate <AF1 >>] ,
66
65
}
67
66
}
67
+ #[ cfg( any( feature = "stm32f030x8" , feature = "stm32f030xc" ) ) ]
68
+ i2c_pins ! {
69
+ I2C2 => {
70
+ scl => [ gpiob:: PB10 <Alternate <AF1 >>] ,
71
+ sda => [ gpiob:: PB11 <Alternate <AF1 >>] ,
72
+ }
73
+ }
74
+ #[ cfg( feature = "stm32f030xc" ) ]
75
+ i2c_pins ! {
76
+ I2C2 => {
77
+ scl => [ gpiob:: PB13 <Alternate <AF5 >>] ,
78
+ sda => [ gpiob:: PB14 <Alternate <AF5 >>] ,
79
+ }
80
+ }
68
81
69
82
#[ derive( Debug ) ]
70
83
pub enum Error {
71
84
OVERRUN ,
72
85
NACK ,
73
86
}
74
87
88
+ macro_rules! i2c {
89
+ ( $( $I2C: ident: ( $i2c: ident, $i2cXen: ident, $i2cXrst: ident, $apbenr: ident, $apbrstr: ident) , ) +) => {
90
+ $(
91
+ use crate :: stm32:: $I2C;
92
+ impl <SCLPIN , SDAPIN > I2c <$I2C, SCLPIN , SDAPIN > {
93
+ pub fn $i2c( i2c: $I2C, pins: ( SCLPIN , SDAPIN ) , speed: KiloHertz ) -> Self
94
+ where
95
+ SCLPIN : SclPin <$I2C>,
96
+ SDAPIN : SdaPin <$I2C>,
97
+ {
98
+ // NOTE(unsafe) This executes only during initialisation
99
+ let rcc = unsafe { & ( * stm32:: RCC :: ptr( ) ) } ;
100
+
101
+ /* Enable clock for I2C */
102
+ rcc. $apbenr. modify( |_, w| w. $i2cXen( ) . set_bit( ) ) ;
103
+
104
+ /* Reset I2C */
105
+ rcc. $apbrstr. modify( |_, w| w. $i2cXrst( ) . set_bit( ) ) ;
106
+ rcc. $apbrstr. modify( |_, w| w. $i2cXrst( ) . clear_bit( ) ) ;
107
+ I2c { i2c, pins } . i2c_init( speed)
108
+ }
109
+ }
110
+ ) +
111
+ }
112
+ }
75
113
#[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
76
- impl < SCLPIN , SDAPIN > I2c < I2C1 , SCLPIN , SDAPIN > {
77
- pub fn i2c1 ( i2c : I2C1 , pins : ( SCLPIN , SDAPIN ) , speed : KiloHertz ) -> Self
78
- where
79
- SCLPIN : SclPin < I2C1 > ,
80
- SDAPIN : SdaPin < I2C1 > ,
81
- {
82
- // NOTE(unsafe) This executes only during initialisation
83
- let rcc = unsafe { & ( * RCC :: ptr ( ) ) } ;
84
-
85
- /* Enable clock for I2C1 */
86
- rcc. apb1enr . modify ( |_, w| w. i2c1en ( ) . set_bit ( ) ) ;
87
-
88
- /* Reset I2C1 */
89
- rcc. apb1rstr . modify ( |_, w| w. i2c1rst ( ) . set_bit ( ) ) ;
90
- rcc. apb1rstr . modify ( |_, w| w. i2c1rst ( ) . clear_bit ( ) ) ;
114
+ i2c ! {
115
+ I2C1 : ( i2c1, i2c1en, i2c1rst, apb1enr, apb1rstr) ,
116
+ }
117
+ #[ cfg( any( feature = "stm32f030xc" , feature = "stm32f030xc" ) ) ]
118
+ i2c ! {
119
+ I2C2 : ( i2c2, i2c2en, i2c2rst, apb1enr, apb1rstr) ,
120
+ }
91
121
122
+ // It's s needed for the impls, but rustc doesn't recognize that
123
+ #[ allow( dead_code) ]
124
+ type I2cRegisterBlock = stm32:: i2c1:: RegisterBlock ;
125
+ impl < I2C , SCLPIN , SDAPIN > I2c < I2C , SCLPIN , SDAPIN >
126
+ where
127
+ I2C : Deref < Target = I2cRegisterBlock > ,
128
+ {
129
+ fn i2c_init ( self : Self , speed : KiloHertz ) -> Self {
92
130
/* Make sure the I2C unit is disabled so we can configure it */
93
- i2c. cr1 . modify ( |_, w| w. pe ( ) . clear_bit ( ) ) ;
131
+ self . i2c . cr1 . modify ( |_, w| w. pe ( ) . clear_bit ( ) ) ;
94
132
95
133
// Calculate settings for I2C speed modes
96
134
let presc;
@@ -118,7 +156,7 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
118
156
}
119
157
120
158
/* Enable I2C signal generator, and configure I2C for 400KHz full speed */
121
- i2c. timingr . write ( |w| {
159
+ self . i2c . timingr . write ( |w| {
122
160
w. presc ( )
123
161
. bits ( presc)
124
162
. scldel ( )
@@ -132,12 +170,12 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
132
170
} ) ;
133
171
134
172
/* Enable the I2C processing */
135
- i2c. cr1 . modify ( |_, w| w. pe ( ) . set_bit ( ) ) ;
173
+ self . i2c . cr1 . modify ( |_, w| w. pe ( ) . set_bit ( ) ) ;
136
174
137
- I2c { i2c , pins }
175
+ self
138
176
}
139
177
140
- pub fn release ( self ) -> ( I2C1 , ( SCLPIN , SDAPIN ) ) {
178
+ pub fn release ( self ) -> ( I2C , ( SCLPIN , SDAPIN ) ) {
141
179
( self . i2c , self . pins )
142
180
}
143
181
@@ -166,8 +204,10 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
166
204
}
167
205
}
168
206
169
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
170
- impl < SCLPIN , SDAPIN > WriteRead for I2c < I2C1 , SCLPIN , SDAPIN > {
207
+ impl < I2C , SCLPIN , SDAPIN > WriteRead for I2c < I2C , SCLPIN , SDAPIN >
208
+ where
209
+ I2C : Deref < Target = I2cRegisterBlock > ,
210
+ {
171
211
type Error = Error ;
172
212
173
213
fn write_read ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
@@ -244,8 +284,10 @@ impl<SCLPIN, SDAPIN> WriteRead for I2c<I2C1, SCLPIN, SDAPIN> {
244
284
}
245
285
}
246
286
247
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
248
- impl < SCLPIN , SDAPIN > Write for I2c < I2C1 , SCLPIN , SDAPIN > {
287
+ impl < I2C , SCLPIN , SDAPIN > Write for I2c < I2C , SCLPIN , SDAPIN >
288
+ where
289
+ I2C : Deref < Target = I2cRegisterBlock > ,
290
+ {
249
291
type Error = Error ;
250
292
251
293
fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
0 commit comments