I'm trying to figure out a weird little issue I've discovered while debugging another element of my code.

I've got a STM32F303K8 reading and writing to an I2C peripheral.

The I2C clock speed is configured to be 400 kHz in CubeMX, but that's not the actual clock speed when I look at it via a logic analyzer.

To make things more interesting/confusing, there seems to be an inverse relationship between the system clock speed and the actual I2C speed.

When I'm running at 8 MHz system clock (CubeMX config below):

8 MHz configuration in CubeMX

My I2C clock looks like this on a logic analyzer:

Logic analyzer trace showing I2C clock running at 333.33 kHz

Showing 333.33 kHz.

When I change the system clock up to 72 MHz (CubeMX below):

CubeMX at 72 MHz Configuration

Logic analyzer trace of the I2C clock looks like this:

Logic analyzer trace showing I2C clock speed of 46.79 kHz

Giving me only 46.79 kHz. No other settings were changed.

My I2C settings are below (configured in 72 MHz mode - the 8 MHz mode is the same, except for the timing register).

I2C Settings

I've been trying to root out the source of this all day, with not much luck. Does anybody know what's going on here, and what I can do to prevent this causing problems?

Thank you all so much for your help!

  • 4
    \$\begingroup\$ Are you sure the external crystal works? It almost matches a situation where the PLL can't use external crystal and the core actually runs at internal 8 MHz, not 72 MHz from PLL? \$\endgroup\$ – Justme Nov 12 '19 at 23:07
  • \$\begingroup\$ Thanks for the suggestion - I just checked the clock on an oscilloscope and got 8Mhz on the nose from the crystal. \$\endgroup\$ – pileunderflow Nov 12 '19 at 23:31
  • \$\begingroup\$ If the PLL is indeed working, double check that your tool is routing the clock to the I2C hardware that it thinks its routing. Actually checking hardware registers and comparing them against the datasheet, as tedious as it sounds, should tell you what's what. \$\endgroup\$ – TimWescott Nov 12 '19 at 23:55
  • 4
    \$\begingroup\$ I'm unfamiliar with cubemx but you should check that when you change the setting from 8 to 72 MHz you're changing the actual clock frequency and not just changing an assumed clock frequency that's used to calculate the I2C prescaler divider values. One way would be to flash an LED using a dumb NOP delay loop with a fixed number of iterations, note the approximate actual flash period, then change clock config and see if the flash period changes accordingly. \$\endgroup\$ – pericynthion Nov 12 '19 at 23:59
  • 1
    \$\begingroup\$ @pileunderflow Getting clock at the oscillator does not mean the clock was present or it has been stable since PLL was configured to use it. CSS will fall back to internal oscillator as soon as it detects clock failure. \$\endgroup\$ – Justme Nov 13 '19 at 1:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.