diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst index 2a33b1da47..0eb1b67f58 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 24b9cb8c3a..2c526854aa 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 c63fe21624..a05a0954af 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