2
2
//! [stm32h7xx-hal](https://github.com/stm32-rs/stm32h7xx-hal) implementation,
3
3
//! as of 2021-02-25.
4
4
5
- use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
6
5
use crate :: hal:: blocking:: i2c:: { Read , Write , WriteRead } ;
7
6
use crate :: pac:: { i2c1, I2C1 , I2C2 } ;
8
7
use crate :: rcc:: { Clocks , APB1R1 } ;
@@ -31,7 +30,7 @@ pub enum Error {
31
30
}
32
31
33
32
#[ doc( hidden) ]
34
- mod private {
33
+ pub ( self ) mod private {
35
34
pub trait Sealed { }
36
35
}
37
36
@@ -44,12 +43,12 @@ pub trait SdaPin<I2C>: private::Sealed {}
44
43
macro_rules! pins {
45
44
( $spi: ident, $af: ident, SCL : [ $( $scl: ident) ,* ] , SDA : [ $( $sda: ident) ,* ] ) => {
46
45
$(
47
- impl private:: Sealed for $scl<Alternate <$af, Output <OpenDrain >>> { }
48
- impl SclPin <$spi> for $scl<Alternate <$af, Output <OpenDrain >>> { }
46
+ impl super :: private:: Sealed for $scl<Alternate <$af, Output <OpenDrain >>> { }
47
+ impl super :: SclPin <$spi> for $scl<Alternate <$af, Output <OpenDrain >>> { }
49
48
) *
50
49
$(
51
- impl private:: Sealed for $sda<Alternate <$af, Output <OpenDrain >>> { }
52
- impl SdaPin <$spi> for $sda<Alternate <$af, Output <OpenDrain >>> { }
50
+ impl super :: private:: Sealed for $sda<Alternate <$af, Output <OpenDrain >>> { }
51
+ impl super :: SdaPin <$spi> for $sda<Alternate <$af, Output <OpenDrain >>> { }
53
52
) *
54
53
}
55
54
}
@@ -60,6 +59,8 @@ pub struct I2c<I2C, PINS> {
60
59
pins : PINS ,
61
60
}
62
61
62
+ // TODO review why StartCondition and State structs exists. Last
63
+ // update to them was november 2020
63
64
/// Start conditions that govern repeated sequential transfer
64
65
#[ derive( Debug , Clone ) ]
65
66
enum StartCondition {
@@ -119,48 +120,35 @@ impl State {
119
120
}
120
121
}
121
122
122
- impl < SCL , SDA > I2c < I2C1 , ( SCL , SDA ) > {
123
- pub fn i2c1 < F > ( i2c : I2C1 , pins : ( SCL , SDA ) , freq : F , clocks : Clocks , apb1 : & mut APB1R1 ) -> Self
124
- where
125
- F : Into < Hertz > ,
126
- SCL : SclPin < I2C1 > ,
127
- SDA : SdaPin < I2C1 > ,
128
- {
129
- apb1. enr ( ) . modify ( |_, w| w. i2c1en ( ) . set_bit ( ) ) ;
130
- apb1. rstr ( ) . modify ( |_, w| w. i2c1rst ( ) . set_bit ( ) ) ;
131
- apb1. rstr ( ) . modify ( |_, w| w. i2c1rst ( ) . clear_bit ( ) ) ;
132
- Self :: new ( i2c, pins, freq, clocks)
133
- }
123
+ macro_rules! hal {
124
+ ( $i2c_type: ident, $i2cX: ident, $i2cXen: ident, $i2cXrst: ident) => {
125
+ impl <SCL , SDA > I2c <$i2c_type, ( SCL , SDA ) > {
126
+ pub fn $i2cX<F >(
127
+ i2c: $i2c_type,
128
+ pins: ( SCL , SDA ) ,
129
+ freq: F ,
130
+ clocks: Clocks ,
131
+ apb1: & mut APB1R1 ,
132
+ ) -> Self
133
+ where
134
+ F : Into <Hertz >,
135
+ SCL : SclPin <$i2c_type>,
136
+ SDA : SdaPin <$i2c_type>,
137
+ {
138
+ apb1. enr( ) . modify( |_, w| w. $i2cXen( ) . set_bit( ) ) ;
139
+ apb1. rstr( ) . modify( |_, w| w. $i2cXrst( ) . set_bit( ) ) ;
140
+ apb1. rstr( ) . modify( |_, w| w. $i2cXrst( ) . clear_bit( ) ) ;
141
+ Self :: new( i2c, pins, freq, clocks)
142
+ }
143
+ }
144
+ } ;
134
145
}
135
146
136
- impl < SCL , SDA > I2c < I2C2 , ( SCL , SDA ) > {
137
- pub fn i2c2 < F > ( i2c : I2C2 , pins : ( SCL , SDA ) , freq : F , clocks : Clocks , apb1 : & mut APB1R1 ) -> Self
138
- where
139
- F : Into < Hertz > ,
140
- SCL : SclPin < I2C2 > ,
141
- SDA : SdaPin < I2C2 > ,
142
- {
143
- apb1. enr ( ) . modify ( |_, w| w. i2c2en ( ) . set_bit ( ) ) ;
144
- apb1. rstr ( ) . modify ( |_, w| w. i2c2rst ( ) . set_bit ( ) ) ;
145
- apb1. rstr ( ) . modify ( |_, w| w. i2c2rst ( ) . clear_bit ( ) ) ;
146
- Self :: new ( i2c, pins, freq, clocks)
147
- }
148
- }
147
+ hal ! ( I2C1 , i2c1, i2c1en, i2c1rst) ;
148
+ hal ! ( I2C2 , i2c2, i2c2en, i2c2rst) ;
149
149
150
150
#[ cfg( any( feature = "stm32l4x5" , feature = "stm32l4x6" ) ) ]
151
- impl < SCL , SDA > I2c < I2C3 , ( SCL , SDA ) > {
152
- pub fn i2c3 < F > ( i2c : I2C3 , pins : ( SCL , SDA ) , freq : F , clocks : Clocks , apb1 : & mut APB1R1 ) -> Self
153
- where
154
- F : Into < Hertz > ,
155
- SCL : SclPin < I2C3 > ,
156
- SDA : SdaPin < I2C3 > ,
157
- {
158
- apb1. enr ( ) . modify ( |_, w| w. i2c3en ( ) . set_bit ( ) ) ;
159
- apb1. rstr ( ) . modify ( |_, w| w. i2c3rst ( ) . set_bit ( ) ) ;
160
- apb1. rstr ( ) . modify ( |_, w| w. i2c3rst ( ) . clear_bit ( ) ) ;
161
- Self :: new ( i2c, pins, freq, clocks)
162
- }
163
- }
151
+ hal ! ( I2C3 , i2c3, i2c3en, i2c3rst) ;
164
152
165
153
impl < SCL , SDA , I2C > I2c < I2C , ( SCL , SDA ) >
166
154
where
@@ -225,14 +213,26 @@ where
225
213
( presc, scll, sclh, sdadel, scldel)
226
214
} ;
227
215
228
- let presc = u8 ( presc) . unwrap ( ) ;
216
+ macro_rules! u8_or_panic {
217
+ ( $value: expr, $message: literal) => {
218
+ match u8 ( $value) {
219
+ Ok ( value) => value,
220
+ Err ( _) => panic!( $message) ,
221
+ }
222
+ } ;
223
+ }
224
+
225
+ let presc = u8_or_panic ! ( presc, "I2C pres" ) ;
229
226
assert ! ( presc < 16 ) ;
230
- let scldel = u8 ( scldel) . unwrap ( ) ;
227
+
228
+ let scldel = u8_or_panic ! ( scldel, "I2C scldel" ) ;
231
229
assert ! ( scldel < 16 ) ;
232
- let sdadel = u8 ( sdadel) . unwrap ( ) ;
230
+
231
+ let sdadel = u8_or_panic ! ( sdadel, "I2C sdadel" ) ;
233
232
assert ! ( sdadel < 16 ) ;
234
- let sclh = u8 ( sclh) . unwrap ( ) ;
235
- let scll = u8 ( scll) . unwrap ( ) ;
233
+
234
+ let sclh = u8_or_panic ! ( sclh, "I2C sclh" ) ;
235
+ let scll = u8_or_panic ! ( scll, "I2C scll" ) ;
236
236
237
237
// Configure for "fast mode" (400 KHz)
238
238
i2c. timingr . write ( |w| {
@@ -472,43 +472,55 @@ where
472
472
}
473
473
}
474
474
475
- use crate :: gpio:: gpioa:: { PA10 , PA9 } ;
476
- use crate :: gpio:: gpiob:: { PB10 , PB11 , PB6 , PB7 } ;
477
-
478
- #[ cfg( any( feature = "stm32l4x3" , feature = "stm32l4x5" , feature = "stm32l4x6" ) ) ]
479
- use crate :: gpio:: gpioc:: { PC0 , PC1 } ;
480
-
481
- #[ cfg( any(
482
- feature = "stm32l4x1" ,
483
- feature = "stm32l4x2" ,
484
- feature = "stm32l4x3" ,
485
- feature = "stm32l4x6" ,
486
- ) ) ]
487
- use crate :: gpio:: gpiob:: PB8 ;
488
-
489
- #[ cfg( feature = "stm32l4x2" ) ]
490
- use crate :: gpio:: gpiob:: PB9 ;
475
+ // All parts have I2C1 on alternate function 4 of
476
+ // pins PA9/PB6 as SCL and PA10/PB7 as SDA, etc.
477
+ mod i2c_pins_default {
478
+ use super :: { I2C1 , I2C2 } ;
479
+ use crate :: gpio:: gpioa:: { PA10 , PA9 } ;
480
+ use crate :: gpio:: gpiob:: { PB10 , PB11 , PB6 , PB7 } ;
481
+ use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
491
482
492
- #[ cfg( any( feature = "stm32l4x1" , feature = "stm32l4x6" ) ) ]
493
- use crate :: gpio:: gpiob:: { PB13 , PB14 , PB9 } ;
483
+ pins ! ( I2C1 , AF4 ,
484
+ SCL : [ PA9 , PB6 ] ,
485
+ SDA : [ PA10 , PB7 ] ) ;
494
486
495
- pins ! ( I2C1 , AF4 ,
496
- SCL : [ PA9 , PB6 ] ,
497
- SDA : [ PA10 , PB7 ] ) ;
498
-
499
- pins ! ( I2C2 , AF4 , SCL : [ PB10 ] , SDA : [ PB11 ] ) ;
487
+ pins ! ( I2C2 , AF4 , SCL : [ PB10 ] , SDA : [ PB11 ] ) ;
488
+ }
500
489
501
490
#[ cfg( any( feature = "stm32l4x1" , feature = "stm32l4x2" , feature = "stm32l4x6" ) ) ]
502
- pins ! ( I2C1 , AF4 , SCL : [ PB8 ] , SDA : [ PB9 ] ) ;
491
+ mod i2c_pins_pb8_pb9 {
492
+ use super :: I2C1 ;
493
+ use crate :: gpio:: gpiob:: { PB8 , PB9 } ;
494
+ use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
495
+
496
+ pins ! ( I2C1 , AF4 , SCL : [ PB8 ] , SDA : [ PB9 ] ) ;
497
+ }
503
498
504
499
#[ cfg( any( feature = "stm32l4x1" , feature = "stm32l4x6" ) ) ]
505
- pins ! ( I2C2 , AF4 , SCL : [ PB13 ] , SDA : [ PB14 ] ) ;
500
+ mod i2c_pins_pb13_pb14 {
501
+ use super :: I2C2 ;
502
+ use crate :: gpio:: gpiob:: { PB13 , PB14 } ;
503
+ use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
506
504
507
- # [ cfg ( any ( feature = "stm32l4x5" , feature = "stm32l4x6" ) ) ]
508
- pins ! ( I2C3 , AF4 , SCL : [ PC0 ] , SDA : [ PC1 ] ) ;
505
+ pins ! ( I2C2 , AF4 , SCL : [ PB13 ] , SDA : [ PB14 ] ) ;
506
+ }
509
507
510
- #[ cfg( feature = "stm32l4x3" ) ]
511
- pins ! ( I2C1 , AF4 , SCL : [ PB8 ] , SDA : [ ] ) ;
508
+ #[ cfg( any( feature = "stm32l4x3" , feature = "stm32l4x5" , feature = "stm32l4x6" ) ) ]
509
+ mod i2c_pins_pbc0_pc1 {
510
+ use super :: I2C3 ;
511
+ use crate :: gpio:: gpioc:: { PC0 , PC1 } ;
512
+ use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
513
+
514
+ pins ! ( I2C3 , AF4 , SCL : [ PC0 ] , SDA : [ PC1 ] ) ;
515
+ }
512
516
513
517
#[ cfg( feature = "stm32l4x3" ) ]
514
- pins ! ( I2C2 , AF4 , SCL : [ PC0 ] , SDA : [ PC1 ] ) ;
518
+ mod i2c_pins_pa7_pb4 {
519
+ use super :: I2C3 ;
520
+ use crate :: gpio:: gpioa:: PA7 ;
521
+ use crate :: gpio:: gpiob:: PB4 ;
522
+ use crate :: gpio:: { Alternate , OpenDrain , Output , AF4 } ;
523
+
524
+ // These pins aren't as nicely consistent
525
+ pins ! ( I2C3 , AF4 , SCL : [ PA7 ] , SDA : [ PB4 ] ) ;
526
+ }
0 commit comments