@@ -184,8 +184,8 @@ macro_rules! i2c_timing {
184
184
// Fast-mode (Fm) or Fast-mode Plus (Fm+)
185
185
// here we pick SCLL + 1 = 2 * (SCLH + 1)
186
186
187
- // Prescaler, 384 ticks for sclh/scll. Round up then subtract 1
188
- let presc_reg = ( ( ratio - 1 ) / 384 ) as u8 ;
187
+ // Prescaler, 96 ticks for sclh/scll. Round up then subtract 1
188
+ let presc_reg = ( ( ratio - 1 ) / 96 ) as u8 ;
189
189
// ratio < 1200 by pclk 120MHz max., therefore presc < 16
190
190
191
191
// Actual precale value selected
@@ -206,8 +206,8 @@ macro_rules! i2c_timing {
206
206
// Fast-mode (Fm)
207
207
assert!( $i2cclk >= 8_000_000 ) ; // See table in datsheet
208
208
209
- let sdadel = $i2cclk / 4_000_000 / presc;
210
- let scldel = $i2cclk / 2_000_000 / presc - 1 ;
209
+ let sdadel = $i2cclk / 3_000_000 / presc;
210
+ let scldel = $i2cclk / 1_000_000 / presc - 1 ;
211
211
212
212
( sdadel, scldel)
213
213
} ;
@@ -224,10 +224,17 @@ macro_rules! i2c_timing {
224
224
// here we pick SCLL = SCLH
225
225
assert!( $i2cclk >= 2_000_000 ) ; // See table in datsheet
226
226
227
- // Prescaler, 512 ticks for sclh/scll. Round up then
227
+ // Prescaler, 128 or 256 ticks for sclh/scll. Round up then
228
228
// subtract 1
229
- let presc = ( ratio - 1 ) / 512 ;
230
- let presc_reg = cmp:: min( presc, 15 ) as u8 ;
229
+ let presc_reg = ( ratio - 1 )
230
+ / if $freq < 8000 {
231
+ 256
232
+ } else if $freq < 80_000 {
233
+ 128
234
+ } else {
235
+ 64
236
+ } ;
237
+ let presc_reg = cmp:: min( presc_reg, 15 ) as u8 ;
231
238
232
239
// Actual prescale value selected
233
240
let presc = ( presc_reg + 1 ) as u32 ;
@@ -257,9 +264,12 @@ macro_rules! i2c_timing {
257
264
assert!( presc_reg < 16 ) ;
258
265
259
266
// Keep values within reasonable limits for fast per_ck
260
- let sdadel = cmp:: max( sdadel, 2 ) ;
267
+ let sdadel = cmp:: max( sdadel, 1 ) ;
261
268
let scldel = cmp:: max( scldel, 4 ) ;
262
269
270
+ let sdadel = cmp:: min( sdadel, 15 ) ;
271
+ let scldel = cmp:: min( scldel, 15 ) ;
272
+
263
273
( presc_reg, scll, sclh, sdadel, scldel)
264
274
} } ;
265
275
}
@@ -811,8 +821,8 @@ mod tests {
811
821
) ;
812
822
813
823
// We must generate a bus frequency less than or equal to that
814
- // specified. Tolerate a 0.5 % error
815
- assert ! ( f_scl <= 1.005 * freq) ;
824
+ // specified. Tolerate a 2 % error
825
+ assert ! ( f_scl <= 1.02 * freq) ;
816
826
817
827
// But it should not be too much less than specified
818
828
assert ! ( f_scl > 0.8 * freq) ;
@@ -884,6 +894,7 @@ mod tests {
884
894
"T SDA DELAY {:.2e} MINIMUM {:.2e}" ,
885
895
t_sdadel, t_sdadel_minimim
886
896
) ;
897
+ assert ! ( sdadel <= 15 ) ;
887
898
assert ! ( t_sdadel >= t_sdadel_minimim) ;
888
899
} ) ;
889
900
}
@@ -917,6 +928,7 @@ mod tests {
917
928
"T SDA DELAY {:.2e} MAXIMUM {:.2e}" ,
918
929
t_sdadel, t_sdadel_maximum
919
930
) ;
931
+ assert ! ( sdadel <= 15 ) ;
920
932
assert ! ( t_sdadel <= t_sdadel_maximum) ;
921
933
} ) ;
922
934
}
@@ -957,6 +969,7 @@ mod tests {
957
969
"T SCL DELAY {:.2e} MINIMUM {:.2e}" ,
958
970
t_scldel, t_scldel_minimum
959
971
) ;
972
+ assert ! ( scldel <= 15 ) ;
960
973
assert ! ( t_scldel >= t_scldel_minimum) ;
961
974
} ) ;
962
975
}
0 commit comments