Kinetis I2C - Strange Behaviour

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Kinetis I2C - Strange Behaviour

2,079 Views
weblar
Contributor V

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?

Labels (1)
Tags (2)
0 Kudos
3 Replies

473 Views
mjbcswitzerland
Specialist V

Hi

Check that the I2C_S_IICIF is reset when the first transmission starts so that the first wait is performed (I use interrupt driver drivers where the IRQ always does this).

Before sending a new message check also that the bus is not busy (IIC_IBB). If a new message is started when the bus is not free it can cause a problem (eg. when the stop bit of a previous message hasn't completed).The slower the bus speed the more likely this state is encountered...

Otherwise I don't see the problem in the code above. I have used the I2C (interrupt driven but essentially based on the same status flag) between 50kHz and 400kHz on both channels without difficulties.

Regards

Mark

http://www.uTasker.com

473 Views
Mohsin455
Contributor IV

Hi,

     I am also getting similar behaviour. It works at high speeds (300KHz) but at low speeds (100KHz)  it hangs at same location as above. I also make sure I check the I2C goes to idle stage after sending STOP on completetion of either read or write.

Any help appreciated.

Thanks,

Mohsin

0 Kudos

473 Views
marks
Contributor IV

Hello, I too am seeing the same behavior. It occurs when I lower the baud rate to below 500Khz. It hangs between an I2C read followed by an I2C write. If I include a small delay between the two the problem goes away but I'm sure this is not the right fix. Could someone please reply with specific details on the right fix? I tried the recommend solutions above but they did not seem to have any effect.

Thanks,

Mark

0 Kudos