6 years, 7 months ago.

How to change I2C frequency on the MAX32630FTHR

I tried calling the I2C.frequency() command for the MAX32630FTHR, but it seems to have no effect. The first i2c port (pins P3_4/P3_5) on the device seems to always run at 400kHz.

If I run the IMU_Hello_World example, probing the second i2c port (where the onboard MAX14690 and BMI160 are hooked up to) shows it running at 100kHz for a bit during initialization, but then 400kHz when the sensors are polled in the main loop. However, I can't find the actual frequency being set anywhere in the example application code, nor the BMI160 library itself.

Any tips or suggestions as to where I can investigate further is greatly appreciated!

1 Answer

6 years, 7 months ago.

Hi,

If you export the program and download to your local system, you can read actual source of mbed-os.
In the I2C.cpp, the constructor I2C::I2C sets frequency to 100000. (line 29)
Then in the i2c_api.c the function i2c_init set frequency to I2CM_SPEED_400KHZ.
So far, these are reasonable, but as you wrote when we call I2C->frequency with
frequency other than 400kHz, the i2c clock seems still remaining to be 400kHz.
As far as I could read, the clock is decided in the function I2CM_init in i2cm.c (line 159).
I would guess that there is/are something wrong between line 172 to line 184,
but being a novice of Maxim MCU, that was about all I could reach.

moto

Accepted Answer

Great, thanks for pointing me in the right direction. To the best of my understanding, I've managed to find the relevant parts of the source code on the github (which I assume are the same as the downloaded version as the library for this board hasn't been updated that much recently).

The way the I2C library is implemented by the MAX32630 target may be a bit misleading. The mbed I2C frequency function looks like we're passing in an integer in hz, but the Maximum library's init function is actually using a enum containing two possible definitions, I2CM_SPEED_100KHZ and I2CM_SPEED_400KHZ which are associated with integers 0 and 1. So they are the correct data type when passed as the "speed", but do not provide the intended result if you expected them in Hertz!

Within the lines you refer to in i2cm.c, specifically at 175 shows that the frequency can only be one of TWO possible values. The reason why I'm getting a functional bus is during init I'm setting the SDA/SCL lines which calls the init with a valid and default default struct value of 400, so the bus should be good to go after setting the pins. However if I then try to change the speed, it basically fails and returns E_NOT_SUPPORTED. But because I've already validly initialized it once, and the higher level functions don't check for errors (set frequency function returns void), we just end up silently with a functioning bus at 400kHz.

This is also confirmed in page 401, section 7.2.2 of the Max32630 datasheet where it states the I2C bus supports two rates, 100kHz and 400kHz fast rate. without reading further into it one would expect any arbitrary speeds to be not possible.

Thanks again!

posted by Johnty Wang 02 Oct 2017

Hi, Johnty-san,

Thank you very much for your analysis!

Because of usual mbed i2c interface, I was expecting I2CM_SPEED_100KHZ as 100000 and I2CM_SPEED_400KHZ as 400000.

I have just tested and confirmed that if I specify 0 Hz(?) for i2c frequency, it acts as 100kHz and 1 Hz(?) causes it acts as 400kHz. (^_^)V

moto

posted by Motoo Tanaka 03 Oct 2017