STM32 I2C Fast Mode

I’d like to use the STM32’s I2C peripheral in the 400Khz fast mode. I’m using a Olimex STM32-H107, which is running at 72Mhz. The PCLK1 is at 36Mhz. I am confused by what the reference manual says (RM0008) in the section about the I2C_CCR:

To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral input clock) must be a multiple of 10 MHz.

Should I take this to mean that I can’t use I2C in fast mode on this board, since my PCLK1 is at 36Mhz, which isn’t a multiple of 10Mhz?

Has anybody tried I2C fast 400KHz mode with the STM32?

Thanks,

~Luke

You might be able to set the frequency of PCLK1 in your software, to get whatever value you need. Otherwise, just change the crystal.

I wrote a simple script to iterate over every possible permutation of the allowable PLL multipliers, clock PREDIV’s, and AHB/ABP1 dividers, as well as bunch of standard crystal frequencies (4, 8, 10, 12, 16, 20, 24, 25Mhz). From all possible combinations, the only solution I found that will result in ABP1 being a multiple of 10Mhz requires the system clock (SYSCLK) to be 60Mhz. This means it is running at 12Mhz less than the published max clock rate of 72.0 Mhz.

It seems weird that just to use I2C in fast mode, you would have to run the system clock significantly slower. Unless I’ve made a mistake or overlooked something I don’t see any other solutions besides

  1. running slower and decreasing performance

  2. overclocking (e.g., SYSCLK = 80Mhz has lots of ways to make APB1 a multiple of 10MHz)

  3. ignoring their warning and just using the peripheral clocked at 36Mhz even though this isn’t a multiple of 10Mhz.

I tried #3 above and it actually seems to work fine, and I have seen other people do this but it seems risky and I wonder how reliable it will be. #1 will certainly work, but it would be nice to not have to decrease the system clock just because of the I2C peripheral. I have seen some posts about overclocking the STM32, but this also seems risky and might have undesirable side effects on other peripherals or flash memory access that would probably manifest as very mysterious behavior.

The data sheet doesn’t provide any reason for why the APB1 clock needs to be a multiple of 10MHz, can anybody think of reason why this must be so?

It’s so much easier to guess than to actually test, so that’s what I’ll do :slight_smile:

I’m guessing maybe the datasheet is a tiny bit misleading, or a tiny bit incomplete here. If you choose Fast Mode Duty Cycle flag = 1, then

T.high = 9 * CCR * T.pclk1

T.low = 16 * CCR * T.pclk1

so

T.total = 25 * CCR * T.pclk1

In this case, to get the I2C clock freq to be exactly 400KHz, you need pclk1 to be a multiple of 25 * 400KHz

But if the Fast Mode Duty Cycle flag = 0,

T.high = 1 * CCR * T.pclk1

T.low = 2 * CCR * T.pclk1

T.total = 3 * CCR * T.pclk1

In this case, to get the I2C clock freq to be exactly 400KHz, you need pclk1 to be a multiple of 1.2MHz.

I’m guessing the comments about multiple of 10 MHz really apply only when the flag = 1. Only guessing!

There was a detailed discussion of this topic over at the ST forums:

https://my.st.com/public/STe2ecommuniti … tviews=105