I2C read function issues

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

I2C read function issues

2,943 Views
kaslewis
Contributor III

Is there anyone at Freescale available to help with the I2C operation for the KEA-64. I am having issues reading back the response from an I2C device, There seems to be an issue having the KEA-64 provide the clock signal for the sensor device to replay with the requested data. This is the main issue preventing my proposed demo project from going live, any help would be very much appreciated.

Thanks

Kas

P.s. I have attached my code for a read from address 0x4B register 0x0B, there is just no clock for the devices response from that register.

#include "derivative.h" /* include peripheral declarations */

#define MWSR      0x00  /* Master write  */

#define MRSW      0x01  /* Master read */

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

                                          I2C0_C1     |= I2C_C1_MST_MASK

#define i2c_write_byte(data)   I2C0_D = data

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

                                 I2C0_S |= I2C_S_IICIF_MASK;

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

                               I2C0_C1  &= ~I2C_C1_TX_MASK

unsigned char MasterTransmission;

/*******************************************************************/

/*!

* Pause Routine

*/

void Pause(void){

    int n;

    for(n=1;n<50;n++) {

      asm("nop");

    }

}

/***********************************************************************************************

*

* @brief    Uart_SendChar - Send a single byte on Uart1

* @param    byte to send

* @return   none

*

************************************************************************************************/ 

void Uart_SendChar(uint8_t send)

{

  while((UART2_S1&UART_S1_TDRE_MASK)==0);

  (void)UART2_S1;

  UART2_D=send;

}

void writeRegister(unsigned char slaveID, unsigned char registerAddress, unsigned char data)

{

  MasterTransmission = MWSR;

  slaveID = slaveID << 1;

  slaveID |= MasterTransmission;

  i2c_Start();

  i2c_write_byte(slaveID);

  i2c_Wait();

  I2C0_D = registerAddress;

  i2c_Wait();

  I2C0_D = data;

  i2c_Wait();

  i2c_Stop();

}

void Clk_Init()

{

  ICS_C1|=ICS_C1_IRCLKEN_MASK; /* Enable the internal reference clock*/

  ICS_C3= 0x50; /* Reference clock frequency = 39.0625 KHz*/

  while(!(ICS_S & ICS_S_LOCK_MASK));   /* Wait for PLL lock, now running at 40 MHz (1024 * 39.0625Khz) */

    ICS_C2|=ICS_C2_BDIV(1)  ; /*BDIV=2, Bus clock = 20 MHz*/

  ICS_S |= ICS_S_LOCK_MASK ; /* Clear Loss of lock sticky bit */

}

void UART_Init()

{

  SIM_SCGC |=  SIM_SCGC_UART2_MASK;

  UART2_BDL= 128;

  UART2_C1 = 0;

  UART2_C2 |= UART_C2_TE_MASK;

  UART2_C2 |= UART_C2_RE_MASK;

  UART2_C2 |= UART_C2_RIE_MASK;

}

void i2cInit(){

  //I2C setup

  SIM_SCGC |= SIM_SCGC_I2C_MASK;

  SIM_PINSEL |= SIM_PINSEL_I2C0PS_MASK;

    I2C0_F = 0x00;

    I2C0_C1 = I2C_C1_IICEN_MASK | I2C_C1_MST_MASK | I2C_C1_IICIE_MASK;

}

int main(void)

{

  long int delay;

  unsigned char i;

  unsigned char replay;

  char string[] = "My name is Bob C. Marley \r\n\r\n";

  Clk_Init();

  UART_Init();

  SIM_SCGC |= SIM_SCGC_I2C_MASK;

  SIM_PINSEL |= SIM_PINSEL_I2C0PS_MASK;

  I2C0_F = 0x11;

  I2C0_C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_IICEN_MASK;

  I2C0_D = 0x96;

  while ((I2C0_S & I2C_S_IICIF_MASK) == 0){

  //Wait for data to transmit

  }

  I2C0_S |= I2C_S_IICIF_MASK;

  I2C0_D = 0x0B;

  while ((I2C0_S & I2C_S_IICIF_MASK) == 0){

  //Wait for data to transmit

  }

  I2C0_S |= I2C_S_IICIF_MASK;

  //Restart

  I2C0_C1 |= I2C_C1_RSTA_MASK;

  I2C0_D = 0x97;

  while ((I2C0_S & I2C_S_IICIF_MASK) == 0){

  //Wait for data to transmit

  }

  I2C0_S |= I2C_S_IICIF_MASK;

    I2C0_C1 &= !I2C_C1_TX_MASK;

  I2C0_C1 |= I2C_C1_TXAK_MASK;

  replay = I2C0_D;

  while ((I2C0_S & I2C_S_IICIF_MASK) == 0){

  //Wait for data to transmit

  }

  while(1) {  

    for (i = 0; string[i] != '\0'; i++){

    Uart_SendChar(string[i]);

    }

  

  

    for(delay = 0; delay < 99999; delay++);

  }

return 0;

}

Tags (2)
0 Kudos
10 Replies

1,390 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

KEA product is using the same I2C module with KE06 product.

Customer could download CodeWarrior MCU V10.6 software, there provides KE06 product I2C module application code at default installation path:

C:\Freescale\CW MCU v10.6\MCU\CodeWarrior_Examples\Kinetis_Examples\KE\build\cw\ke06\I2C_MasterInt_demo

I also attached KE06 I2C driver for your reference.


Wish it helps.
best regards
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,390 Views
kaslewis
Contributor III

I have looked through a few Freescale I2C demo code for the KEA or other Kinetis boards but none work. Some are just plainly wrong (do not seem to know how to read a register... ) and others just don't make sense. Any real help would be much appreciated, a tried, tested and know to be good demo would be helpful but so far what I have seems to be coded with no testing or any real thought.

Kas

0 Kudos

1,390 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Kas,

Which I2C device you are using?


Wish it helps.
best regards
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,390 Views
kaslewis
Contributor III

Hello Ma,

I am using a PmodTMP2 from Digilent that has a Analog Devices ADT7420 on board. I have added two 4.7k pull up resistors one to the SCL line and the other to the SDA line. I can see the KEA-64 sending data but when it comes to recive data from the ADT7420 the KEA-64 does not provide a clock source. I have tried a dummy read and a dummy write but neither seem to provide a clock source.

Kas

0 Kudos

1,390 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Kas,

Analog Devices ADT7420 with the same I2C process with MMA8451 chip.

ADT7420 register read process:

ADT7420.jpg

MMA8451 register read process:

MM8451.jpg

Customer could refer K60 100MHz i2c_demo from attached file, which shows how to read data from MMA8451 chip.

I just abstract the read register processing for your reference:

u8 hal_dev_mma8451_read_reg(u8 addr)

{

    u8 result;

    i2c_start(I2C0_B);

    i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_WRITE);

    i2c_wait(I2C0_B);

    i2c_get_ack(I2C0_B);

    i2c_write_byte(I2C0_B, addr);

    i2c_wait(I2C0_B);

    i2c_get_ack(I2C0_B);

    i2c_repeated_start(I2C0_B);

    i2c_write_byte(I2C0_B, I2C_ADDR_MMA8451 | I2C_READ);

    i2c_wait(I2C0_B);

    i2c_get_ack(I2C0_B);

    i2c_set_rx_mode(I2C0_B);

    i2c_give_nack(I2C0_B);

    result = i2c_read_byte(I2C0_B);

    i2c_wait(I2C0_B);

    i2c_stop(I2C0_B);

    result = i2c_read_byte(I2C0_B);

    pause();

    return result;

}

While K60_100MHz I2C module with a little different with KEA I2C module at I2Cx_FLT register.

Kinetis KE series product with the same I2C module with KEA product, there also with I2C read data from MM8451 example with Processor Expert project.

Customer could find related example from CW V10.6 installation path:

C:\Freescale\CW MCU v10.6\MCU\CodeWarrior_Examples\Processor_Expert\Kinetis\FRDM-KE06Z\I2C_PWM

I also attached that example at this thread for your reference.


Wish it helps.
best regards
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,390 Views
kaslewis
Contributor III

Hello Ma,

Can you please look over the code I have posted as it looks very similar, I just do not use macros I call everything explicitly. I have included output from the logic analyzer and as you can see the only thing missing is the clock needed for the device to replay to the KEA-64. I have looked at ALL the code you have provided but NOTHING seems to be working, therefore postinhg more code will NOT help, rather please look at what I have done and let me know what is wrong.

Thanks

2014-11-30 15_10_36-Saleae Logic 1.1.15 - [Connected] - [12 MHz, 1000 B Samples].jpg

0 Kudos

1,390 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Kas,

I checked your code with below error:

in main() function, when you want to change I2C module mode from write to read, the below code is incorrect:

I2C0_C1 &= !I2C_C1_TX_MASK;

The correct code is :

I2C0_C1 &= ~I2C_C1_TX_MASK;

And when you want to get the ADT7420 ID value, it need to read I2C0_D register twice, please refer below code:

    i2c_give_nack(I2C0_B);      //your code is I2C0_C1 |= I2C_C1_TXAK_MASK;

    result = i2c_read_byte(I2C0_B);   //your code is  replay = I2C0_D;

    i2c_wait(I2C0_B);    //your code is    while ((I2C0_S & I2C_S_IICIF_MASK) == 0){  //Wait for data to transmit  }

    i2c_stop(I2C0_B);    //your code need to add as   I2C0_C1  &= ~I2C_C1_MST_MASK;  I2C0_C1  &= ~I2C_C1_TX_MASK;

    result = i2c_read_byte(I2C0_B);  //your code need to add as   replay = I2C0_D;


Wish it helps.
best regards
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,390 Views
kaslewis
Contributor III

Hello Ma,

From what I can see your code and my code is the same. Where you call a macro I use what is inside the macro. For example, i2c_wait(I2C_B) is exactly the same as while ((I2C0_S & I2C_S_IICIF_MASK) == 0){  //Wait for data to transmit  } as this is defined in the header function, yet I am still having issues.

Can you please NOT use any macros an instead use the bare register in correcting what I have done wrong, because I still see nothing really different between what you and I have done.

Kas

0 Kudos

1,390 Views
vignesh_vb_7
Contributor IV

Hi Kas,

I am also struck up in the same kind of problem.Please send me the I2C working code if you have finished it.

0 Kudos

1,390 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Kas,

Your code with below error:

in main() function, when you want to change I2C module mode from write to read, the below code is incorrect:

I2C0_C1 &= !I2C_C1_TX_MASK;

The correct code is :

I2C0_C1 &= ~I2C_C1_TX_MASK;

And when you want to get the ADT7420 ID value, it need to read I2C0_D register twice.

Wish it helps.
best regards
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos