AnsweredAssumed Answered

Kinetis I2C - Strange Behaviour

Question asked by weblar on Oct 23, 2012
Latest reply on Jan 26, 2014 by Mark Sample

I have a very odd issue relating to I2C behaviour on a Kinetis K60 micro.

 

My source clock is 8MHz configured to give 120MHz on PLL0 and 48MHz on PLL1. I've set the CLKDIV1 divisors such that the bus clock is 60MHz, the FlexBus clock is 30MHz and the flash clock is 20MHz. This is all working great.

 

I'm using I2C0 to read a number of sensors for an AHRS system - an ADXL345 accelerometer, an HMC5883L magnetometer and an ITG-3200 rate gyro. Having mis-read the datasheet, I mistakenly set the I2C0_F "MULT" value to 4 (illegal value, 0 assumed) and "ICR" to 20 (assuming it was 4 x 20 = 80, i.e. 8MHz / 80 = 100kHz). When I run my code which includes the bare-metal I2C driver, all works well, but when investigating things using a scope, it appears that my actual I2C clock frequency is more like 750kHz - far too high for my sensors yet it still works.

 

Now, if I crank down the clock to about 400kHz - using correct settings from the datasheet -  things start to go a bit awry. Using the Freescale example of reading from an MMA7660 device, my code always hangs waiting for the I2C_S_IICIF flag to be set in the IC0_S register having just written the slave register address (not device address). I can reliably reproduce this and the problem goes away if I crank the clock back up to 750kHz.

 

The code looks like this...

 

  /* send data to slave */

  IIC_StartTransmission(SlaveID,MWSR);

  i2c_Wait();

  I2C0_D = u8RegisterAddress;

  i2c_Wait();                                   // <<- Here is where we freeze and never move on

  I2C0_D = u8Data;

  i2c_Wait();

  i2c_Stop();

  Pause();

 

 

I'm using 1K pull-ups on the SDA and SCL lines as suggested by the I2C spec (to give > 3mA sink current).

 

Any suggestions as to what I could try next?

Outcomes