STM32: machine.freq unsupported on F0, L0, L4 and WB
When I set pyb.freq(30000000) it occurs an error that I can't change the frequency. How should I do?
stm32/i2c: Fix I2C frequency is faster than specified one.
This PR fixes following issue.
The actual I2C frequency is faster than specified one and it may exceededs I2C's specification for Fast mode.
Also, machine.I2C initialize with freq=400000 (I2C Fast mode) by default but actual frequency of SCL is faster than 400KHz.
The frequency of SCL should be less than or equal to 400KHz in Fast mode.
How to reproduce
Execute this code
>>> i2c=machine.I2C(1)
>>> i2c
I2C(1, scl=B8, sda=B9, freq=420000)
>>> i2c = machine.I2C(1, freq=350000)
>>> i2c
I2C(1, scl=B8, sda=B9, freq=420000)
MicroPython Version
v1.19.1
Environment
NUCLEO-F446RE
Detail of changes
To set frequency, I2Cx_CCR is set at
https://github.com/micropython/micropython/blob/0e8c2204da377e95b5000a3c708891d98cdeb69c/ports/stm32/i2c.c#L73-L77
but SCL may be faster than expected frequency if PCLK1 is not multiple of 10.
For example, PCLK1 of NUCLEO-F446RE is 42MHz. To get 400KHz or less, CCR should be 5 but actually CCR was set to 4 by the above formula.
pyb.I2C has the same issue, but I think it is a bug of STM32CubeF4.
It was fixed at least STM32CubeF4 v1.24.1, so I also fixed it at this PR:https://github.com/micropython/stm32lib/pull/22.
I also add that the actual frequency may be lower than the specified frequency to the document like SPI.
STM32CubeF4 also fix for Standard mode, so I also fix machine.I2C for standard mode.
After applying this PR, the frequency of SCL is less than 400KHz.
>>> i2c=machine.I2C(1)
>>> i2c
I2C(1, scl=B8, sda=B9, freq=336000)
>>> i2c = machine.I2C(1, freq=350000)
>>> i2c
I2C(1, scl=B8, sda=B9, freq=336000)