summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/library/machine.I2C.rst4
-rw-r--r--docs/library/pyb.I2C.rst4
-rw-r--r--ports/stm32/i2c.c5
3 files changed, 11 insertions, 2 deletions
diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst
index 2a33b1da4..0eb1b67f5 100644
--- a/docs/library/machine.I2C.rst
+++ b/docs/library/machine.I2C.rst
@@ -91,6 +91,10 @@ General Methods
- *sda* is a pin object for the SDA line
- *freq* is the SCL clock rate
+ In the case of hardware I2C the actual clock frequency may be lower than the
+ requested frequency. This is dependant on the platform hardware. The actual
+ rate may be determined by printing the I2C object.
+
.. method:: I2C.deinit()
Turn off the I2C bus.
diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst
index 24b9cb8c3..2c526854a 100644
--- a/docs/library/pyb.I2C.rst
+++ b/docs/library/pyb.I2C.rst
@@ -96,6 +96,10 @@ Methods
that DMA transfers have more precise timing but currently do not handle bus
errors properly)
+ The actual clock frequency may be lower than the requested frequency.
+ This is dependant on the platform hardware. The actual rate may be determined
+ by printing the I2C object.
+
.. method:: I2C.is_ready(addr)
Check if an I2C device responds to the given address. Only valid when in controller mode.
diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c
index c63fe2162..a05a0954a 100644
--- a/ports/stm32/i2c.c
+++ b/ports/stm32/i2c.c
@@ -70,10 +70,11 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr
// SM: MAX(4, PCLK1 / (F * 2))
// FM, 16:9 duty: 0xc000 | MAX(1, (PCLK1 / (F * (16 + 9))))
+ // (the PCLK1-1 and +1 at the end is to round the division up)
if (freq <= 100000) {
- i2c->CCR = MAX(4, PCLK1 / (freq * 2));
+ i2c->CCR = MAX(4, ((PCLK1 - 1) / (freq * 2) + 1));
} else {
- i2c->CCR = 0xc000 | MAX(1, PCLK1 / (freq * 25));
+ i2c->CCR = 0xc000 | MAX(1, ((PCLK1 - 1) / (freq * 25) + 1));
}
// SM: 1000ns / (1/PCLK1) + 1 = PCLK1 * 1e-6 + 1