Skip to content

Commit fdddcd2

Browse files
authored
I2C: Allow exact frequency matches (OpenDevicePartnership#504)
41f9d4d made a change to filter out configurations that had a duty cycle of exactly the target frequency in an attempt to add a little buffer so that jitter wouldn't cause overshoot of the target frequency. This works at a duty cycle of 50% where there exists a (high_clocks, low_clocks, clock_div) tuple that satisfies this due to rounding error, e.g. (9, 9, 7) => 380952. However, this had the unintended side-effect of causing any duty cycles that do not incur rounding error at any point to be rejected - i.e. it's impossible to configure a 40% duty cycle at 100kHz because the candidates all divide cleanly. This change reverts to allowing direct matches to enable these duty cycles. Clients that need strict compliance can use strict_mode: true to achieve it.
1 parent 4cd1854 commit fdddcd2

File tree

1 file changed

+1
-8
lines changed

1 file changed

+1
-8
lines changed

src/i2c/master.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,7 @@ impl SpeedRegisterSettings {
129129
(hi_clocks, lo_clocks, clock_div_multiplier)
130130
})
131131
.filter(|(hi_clocks, lo_clocks, clock_div_multiplier)| {
132-
// Require the resulting frequency to be strictly below `target_freq_hz`.
133-
//
134-
// This is necessary because hardware clock dividers and scalers can introduce
135-
// rounding errors or imprecisions, causing the actual I2C clock to slightly exceed
136-
// the calculated value. By enforcing a strict inequality, we ensure that the actual
137-
// I2C clock frequency will not exceed the requested maximum, which is important for
138-
// I2C compliance and to avoid violating timing requirements of connected devices.
139-
get_freq_hz(*hi_clocks, *lo_clocks, *clock_div_multiplier, CLOCK_SPEED_HZ) < target_freq_hz
132+
get_freq_hz(*hi_clocks, *lo_clocks, *clock_div_multiplier, CLOCK_SPEED_HZ) <= target_freq_hz
140133
})
141134
.min_by(|(hi_a, lo_a, div_a), (hi_b, lo_b, div_b)| {
142135
let freq_a = get_freq_hz(*hi_a, *lo_a, *div_a, CLOCK_SPEED_HZ);

0 commit comments

Comments
 (0)