i2c on kinetis

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

i2c on kinetis

3,519 Views
GerasinIvan
Contributor II

Hi all!

I'm trying to use sensors with I2C-interface. To understand i2c protoloc, i started with example from CW package (using MMA7660 accelerometer). And ti works great. Next, i started to write a code for communicating with MPL115A2 (barometer) and encountered a problem with reading from sensor. I tried different variation (i really don't know what's the problem) and it returns zeros, slave address, register address.

unsigned int j,i;

  unsigned char slaveID;

  /* Send Slave address */

  slaveID = (MPL115A << 1) | 0x00; //read from MPL115

  i2c_Start(); 

  i2c_write_byte(slaveID); //send address

  i2c_Wait();

  

  /* Send address of register */

  i2c_write_byte(0x04);

  i2c_Wait();

  

  /* swith to read mode */

  slaveID = (MPL115A << 1) | 0x01; //set slaveID for read

  i2c_RepeatedStart() //repeated start

  i2c_write_byte(slaveID);

  i2c_Wait();

  

   /* Put in Rx Mode */

  I2C0_C1 &= (~I2C_C1_TX_MASK);

   /* Turn off ACK */

  I2C0_C1 |= I2C_C1_TXAK_MASK;

  

  for(j = 0; j < 8; j++)

  {

  dataArray[j] = I2C0_D;

  i2c_Wait();

  }

i2c_stop();

Tags (2)
0 Kudos
11 Replies

1,481 Views
pavel_krenek
NXP Employee
NXP Employee

Hi Ivan,

Recently I was working on the implementation of the IIC for the sensors on the TOWER-SENSOR boards. I think that all of mentioned sensors are included into this implementation. You can try to look or use the source code for this solution (it is S08QE based).

Pavel

0 Kudos

1,481 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

The typical wait time is 3ms associated with each conversion type.

Another clue is please check the capacitor value for the capacitor of pin CAP. This capacitor is used as a decoupling capacitor for main internal regulator. Typical (recommended) value of this capacitor is 1uF, other values may cause a malfunction on the internal regulator and so, make the device to fail.

0 Kudos

1,481 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

In addition to Hui’s recommendation, make sure that both RST and SHDN pins are driven high.

0 Kudos

1,481 Views
GerasinIvan
Contributor II

I think i'm close to solution of problem. At this moment i have a 3 sensors:

MMA7660 accelometer

MPL115A barometer

SHT21 tempreture and humidity sensor.

I can work with accelerometer corretly. So I take a source code from i2c functions for MMA7660, and changed address to SHT21. From SHT21 i can read with 2 modes - hold master and no hold master.

     Hold master and No hold master:

In the  hold master mode, the SHT2x  pulls down the SCL line  while measuring  to force the master into a wait state. By releasing the SCL linethe sensor indicates that internal processing is terminated and that transmission may be continued.

In  no hold master mode, the MCU has to poll for the termination of the internal processing of the sensor. This is done by sending a Start condition followed by the I2C header (1000’0001) as shown in  Figure  14. If the internal processing is finished, the sensor acknowledges the poll of the MCU and data can be read by the MCU. If the measurement processing is not finished the sensor answers no ACK bit and the Start  condition must be issued once more.

source code:

unsigned char result;
  unsigned int j;

  /* Send Slave Address */
 
  /* send start signal */
  i2c_Start();

  /* send ID with W/R bit */
  i2c_write_byte((SHT21 << 1));
 
  i2c_Wait();

  /* Write Register Address */
  I2C0_D = u8RegisterAddress;
  i2c_Wait();

  /* Do a repeated start */
  I2C0_C1 |= I2C_C1_RSTA_MASK;

  /* Send Slave Address */
  I2C0_D = (SHT21 << 1) | 0x01; //read address
  i2c_Wait();

  /* Put in Rx Mode */
  I2C0_C1 &= (~I2C_C1_TX_MASK);

  /* Turn off ACK */
  I2C0_C1 |= I2C_C1_TXAK_MASK;

  /* Dummy read */
  result = I2C0_D;
  for (j=0; j<5000; j++){};
  i2c_Wait();
 
  /* Send stop */
  I2C0_C1  &= ~I2C_C1_MST_MASK;
  i2c_Stop();
  result = I2C0_D ;
  Pause();

  return result;

When i read in NO hold master i receive 0xff values. In hold master - all OK. I get a tempreture. So, may be here a problem with timing barometer? What can you advice?

And secod question:

Function above putted in while() cycle. So in ideal it will work permanently. But If i switch i2c_Stop() and result = I2C0_D ("result" before "stop") it will works only 1 time. What happens?

Thx for helping

0 Kudos

1,481 Views
chris_brown
NXP Employee
NXP Employee

Hi Ivan,

To answer your second question, it sounds like you might not be waiting for long enough between issuing the stop signal and issuing the start signal.  Have you tried increasing the amount of time you Pause() function waits?  If you have to wait for 1ms or longer then it's probably something else (and that's a conservative estimate).

Hope that helps,

0 Kudos

1,481 Views
GerasinIvan
Contributor II

I have tried to wait longer but it's not helps. It seems problem not here. I have no idea what's the problem(

0 Kudos

1,481 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Please refer below recommend I2C communication structure:

For “Start Pressure and Temperature Conversion, Read raw Pressure”:
Start -> 0x60+W -> ACK -> 0x12 -> ACK -> 0x01 -> Stop
*The typical delay is 3ms.
Start -> 0x60+W -> ACK -> 0x00 -> ACK ->
Restart -> 0x60+R -> ACK -> data from slave (0xMSB Pressure) -> ACK -> data from slave (0xLSB Pressure) -> data from slave (0xMSB Temperature) -> data from slave (0xLSB temperature) -> Stop

For Read Coefficients:
[Start], 0x60+[W], 0x04
[Restart], 0x60+[R], COEF1, COEF2, COEF3, COEF4, COEF5, COEF6, COEF7, COEF8, COEF9, COEF10, COEF11, COEF12, [Stop]

Note:
1> It need the 0x01 in the first line, since this is a pointer to the register and without it, it will never start the conversion.
2> We have a Start signal before the read, it must be a Restart signal, or should be in separate instructions, like:
Start -> 0x60+W -> ACK -> 0x00 -> ACK -> Stop
Start -> 0x60+R - > ACK - > data from slave - > ACK -> data from slave -> Stop
3> the typical wait time is 3ms

Wish it helps.

0 Kudos

1,481 Views
GerasinIvan
Contributor II

I'm just trying to read coefficients (source code in original post). I'm doing it just like you tell.May be there is a problems in i2c functions, but i'm not sure.

#define i2c_RepeatedStart()    I2C0_C1     |= 0x04;

#define i2c_Start()            I2C0_C1     |= 0x10;\

                               I2C0_C1     |= I2C_C1_MST_MASK

#define i2c_Stop()             I2C0_C1  &= ~I2C_C1_MST_MASK;\

                               I2C0_C1  &= ~I2C_C1_TX_MASK

#define i2c_EnterRxMode()      I2C0_C1   &= ~I2C_C1_TX_MASK;\

                               I2C0_C1   &= ~I2C_C1_TXAK_MASK

#define i2c_Wait()               while((I2C0_S & I2C_S_IICIF_MASK)==0) {} \

                                  I2C0_S |= I2C_S_IICIF_MASK;

#define i2c_write_byte(data)   I2C0_D = data

0 Kudos

1,481 Views
BlackNight
NXP Employee
NXP Employee

I recommend you check with a Logic Analyzer what is going on with the I2C bus.

Additionally, carefully check the errata of the device you are using. If you are using the KL25Z, then there is a known issue that the repeated start transaction is not correct on the bus:

KL25Z and I2C: Missing Repeated Start Condition | MCU on Eclipse

0 Kudos

1,481 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Ivan,

I find your code line 22 has error:

/* Turn off ACK */   

I2C0_C1 |= I2C_C1_TXAK_MASK;

The correct code is:

  /* Ensure TXAK bit is 0 */

  I2C0_C1 &= ~I2C_C1_TXAK_MASK;

Wish it helps.

0 Kudos

1,481 Views
GerasinIvan
Contributor II

Thx, i didn't see it. But it didn't help - nothing chanched.

Also - i put it in while() cycle, and it works only one time. It returns slave address in read mode (slaveID |= 0x01) in first array element and zeros in other elements.

0 Kudos