@@ -5,7 +5,7 @@ use core::convert::TryFrom;
5
5
use crate :: {
6
6
gpio:: { gpioa, gpiob, gpiof, AF4 } ,
7
7
hal:: blocking:: i2c:: { Read , Write , WriteRead } ,
8
- pac:: { I2C1 , I2C2 } ,
8
+ pac:: { I2C1 , I2C2 , RCC , rcc :: cfgr3 :: I2C1SW_A } ,
9
9
rcc:: { Clocks , APB1 } ,
10
10
time:: Hertz ,
11
11
} ;
@@ -83,7 +83,7 @@ macro_rules! busy_wait {
83
83
}
84
84
85
85
macro_rules! hal {
86
- ( $( $I2CX: ident: ( $i2cX: ident, $i2cXen: ident, $i2cXrst: ident) , ) +) => {
86
+ ( $( $I2CX: ident: ( $i2cX: ident, $i2cXen: ident, $i2cXrst: ident, $i2cXsw : ident ) , ) +) => {
87
87
$(
88
88
impl <SCL , SDA > I2c <$I2CX, ( SCL , SDA ) > {
89
89
/// Configures the I2C peripheral to work in master mode
@@ -106,6 +106,12 @@ macro_rules! hal {
106
106
107
107
assert!( freq <= 1_000_000 ) ;
108
108
109
+ // NOTE(unsafe) atomic read with no side effects
110
+ let i2cclk = match unsafe { ( * RCC :: ptr( ) ) . cfgr3. read( ) . $i2cXsw( ) . variant( ) } {
111
+ I2C1SW_A :: HSI => 8_000_000 ,
112
+ I2C1SW_A :: SYSCLK => clocks. sysclk( ) . 0 ,
113
+ } ;
114
+
109
115
// TODO review compliance with the timing requirements of I2C
110
116
// t_I2CCLK = 1 / PCLK1
111
117
// t_PRESC = (PRESC + 1) * t_I2CCLK
@@ -114,7 +120,6 @@ macro_rules! hal {
114
120
//
115
121
// t_SYNC1 + t_SYNC2 > 4 * t_I2CCLK
116
122
// t_SCL ~= t_SYNC1 + t_SYNC2 + t_SCLL + t_SCLH
117
- let i2cclk = clocks. pclk1( ) . 0 ;
118
123
let ratio = i2cclk / freq - 4 ;
119
124
let ( presc, scll, sclh, sdadel, scldel) = if freq >= 100_000 {
120
125
// fast-mode or fast-mode plus
@@ -427,11 +432,11 @@ macro_rules! hal {
427
432
feature = "stm32f398" ,
428
433
) ) ]
429
434
hal ! {
430
- I2C1 : ( i2c1, i2c1en, i2c1rst) ,
431
- I2C2 : ( i2c2, i2c2en, i2c2rst) ,
435
+ I2C1 : ( i2c1, i2c1en, i2c1rst, i2c1sw ) ,
436
+ I2C2 : ( i2c2, i2c2en, i2c2rst, i2c2sw ) ,
432
437
}
433
438
434
439
#[ cfg( feature = "stm32f334" ) ]
435
440
hal ! {
436
- I2C1 : ( i2c1, i2c1en, i2c1rst) ,
441
+ I2C1 : ( i2c1, i2c1en, i2c1rst, i2c1sw ) ,
437
442
}
0 commit comments