KE02x - I2C Read issue

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

KE02x - I2C Read issue

638 Views
rahulnatak
Contributor I

1) Hardware used  - MKE02x FRDM development board, EEPROM - ST24C16, Microchip 24C128, LED CAT9532

2) I2C Working conditions - MEK02x (Master) - EEPROM  (Slave) both read and write is working fine with FBE mode i.e direct crystal frequency 10Mhz (also tested with 5Mhz and 2.5Mhz).

3) I2C Not Working conditions - MEK02x (Master) - EEPROM  (Slave) both read and write not working with FEE mode i.e FLL Engaged external @ frequency 20Mhz, 10Mhz etc. Also same is the case with internal oscillator.

4) I2C with LED CAT9532 - Write operation - working fine, Read operation - Key detection working but sometime the driver get stucked or key is not detected and after this i want to reset the system.

5) KE02x I2C with LED CAT9532 sometimes it reads the input keys connected to LED CAT9532 but after 4-5 read operation and gets the I2C hang i see in the debugger it shows me MST bit is set but busy flag is bot busy.

6) Also it is hard to calculate baudspeed

I2C baudrate = I2C module clock speed(Hz)/(Mul x SCL Divider)

For I2C 100Kbps:

let I2C module clock speed(Hz) = 8Mhz

                                          Mul = 1      (Mul = I2C0_BAUDRATE_MULT)

                               SCL Divider = (8000000/100000)/Mul

  i will get SCL divider value and from this i want to get ICR value from refernce manual and this is going to put in the frequency divder resistor i.e ICR

I have question for some of SCL div value thier are 2-3 ICR values from this which is is to be selected from refrence manual

Is thier any auto calculation of baudspeed instead of looking this all manually.

5) Following is the sequence for read and write handle from application layer

            #if(I2C_TEST == ENABLED)

                                    switch (I2c_Slot)

                                    {

                                    case 0:

                                                if (I2c__GetStatus(I2C0, I2C_STATUS_STATE) == I2C_STATE_IDLE)

                                                {

                                                            I2c__Write(I2C0, 0x00, Rd_data, 2);

                                                            I2c_Slot++;

                                                }

                                                break;

                                    case 1:

                                                if (I2c__GetStatus(I2C0, I2C_STATUS_STATE) == I2C_STATE_IDLE)

                                                {

                                                            I2c__Write(I2C0, 0x00, Rd_data, 0);

                                                            I2c_Slot++;

                                                }

                                                break;

                                    case 2:

                                                if (I2c__GetStatus(I2C0, I2C_STATUS_STATE) == I2C_STATE_IDLE)

                                                {

                                                            I2c__RequestRead(I2C0, 2);

                                                            I2c_Slot++;

                                                            GPIO__PIN_TOGGLE(PORTH,1);

                                                }

                                                break;

                                    case 3:

                                                if (I2c__GetStatus(i2c_device, I2C_STATUS_STATE) == I2C_STATE_IDLE)

                                                {

                                                            I2c_Slot++;

                                                }

                                                break;

                                    case 4:

                                                if (I2c__GetStatus(i2c_device, I2C_STATUS_STATE) == I2C_STATE_IDLE)

                                                {

                                                            I2c__Read(i2c_device, &Rx_buf[str_data], 2);

                                                            str_data = str_data + 2;

                                                            I2c__Clear(i2c_device);

                                                            I2c__ResetBus(i2c_device);

                                                            I2c_Slot++;

                                                }

                                                break;

                                    default:

                                                I2c_Slot++;

                                                if (I2c_Slot == 40)

                                                {

                                                            I2c_Slot = 0;

                                                }

                                                break;

                                   

6) My I2C interrupt routine

void I2c0__InterruptHandler(void)

{

  uint8 temp;

  temp = 0;

  #if (I2C0_FEATURE == ENABLED)

  I2C_0.I2C_S1.BIT.IICIF = 1;                                //Clear Interrupt Flag - No interrupt pending

  if(I2C_0.I2C_C1.BIT.MST == 1)                                                   //Check for Master Mode Select (1 - Master mode, 0 - Slave mode)

  {

  //Check for I2C0 Error

  if (((I2C_0.I2C_S1.BYTE) & (I2C_S_ARBL_MASK | I2C_S_RXAK_MASK)) != FALSE)

  {

      if (((I2C_0.I2C_S1.BYTE) & (I2C_S_ARBL_MASK)) != FALSE)

      {

      I2c0_Ack_Error = I2C_ERROR_BUS_LOCKED;                              //Set the error flag - Loss of Arbitration

     }

    else

    {

    I2C0_STOP();

    I2C0_Busy = I2C_STATE_IDLE;

    //I2c0_Ack_Error = I2C_ERROR_ACK;                                     //No ACK signal detected from Slave device

    }

  //I2C0_Busy = I2C_STATE_IDLE;

  //Clear the error to accommodate the new errors

  I2C_0.I2C_S1.BYTE = (0 << I2C_S_ARBL_SHIFT) | (0 << I2C_S_RXAK_SHIFT);

  }

  else

  {

  if ((I2C_0.I2C_C1.BIT.TX == TRUE))                                      //Tx bit = 1:Transmit Data to Slave device

  {

  if(I2c0_SlaveAddr & 0x01)                                             //Slave internal address from where the data is to be read

  {

  if (I2C_0.I2C_S1.BIT.RXAK == 0)                                 //Check ACK signal received from slave device for successful transmission of one byte data on the bus

  {

  I2C0_RxEnable();                                            //Enable I2C0 Receiver

  temp = I2C_0.I2C_D;                                         //Dummy Read - Copy received 1 byte data from Data I/O register

  I2c0_SlaveAddr = (I2c0_SlaveAddr & 0xFE);

  }

  }

  else

  {

  //I2C0 Write data to Slave device

  if(I2C_0.I2C_S1.BIT.RXAK == 0)                                  //Check ACK signal received from slave device for successful transmission of one byte data on the bus

  {

  if(I2C0_Flag == TRUE)

  {

  I2C_0.I2C_D = I2c0_InternalAddress;

  I2C0_Flag = FALSE;

  }

  else if (I2c0_TxPointer < I2c0_SizeWrite)

  {

  I2C_0.I2C_D = I2c0_Buffer_Out[I2c0_TxPointer];          //Transmit Data to Slave

  I2c0_TxPointer++;                                      //Increment Transmit pointer by 1

  }

  else

  {

  I2C0_STOP();                                        //Generate Stop signal for I2C_0 (bit MST = 0)

  I2C0_Busy = I2C_STATE_IDLE;

  }

  }

  }

  }

  else                                                                    //Tx bit = 0:Receive Data from Slave device

  {

  //I2C0 Read data from Slave device

  if (I2c0_RxPointer == I2c0_SizeRead -1)

  {

  I2C_0.I2C_C1.BIT.TXAK = 1;                                      //Send NACK to stop the communication

  I2c0_Buffer_In[I2c0_RxPointer] = I2C_0.I2C_D;                       //Read Received Data from Slave//Generate Stop signal for I2C_0 (bit MST = 0)

  I2c0_RxPointer++;

  }

  else

  {

  //Copy received data from Data I/O register to I2C0_Buffer_In array

  I2c0_Buffer_In[I2c0_RxPointer] = I2C_0.I2C_D;                       //Read Received Data from Slave

  I2C_0.I2C_C1.BIT.TXAK = 0;                                          //Send ACK to Slave device

  I2c0_RxPointer++;                                                   //Increment Receive pointer by 1

  }

  }

  }

  }

Thanks

Rahul

  #else

  //Disable the I2c Peripheral and its events

  I2C_0.I2C_C1.BYTE &= ~(I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK );

  #endif

}

0 Kudos
1 Reply

383 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Rahul Natak:

In most cases to debug I2C problems having a scope or logic analyzer becomes very handy. Have you observed the signals generated for cases (3), (4) and (5)?

- For cases (4) and (5), what do you mean by "input key" and "key detection"?

- About (6), unfortunately there is no pattern in the ICR values table, so you cannot have some kind of formula. Possible approach to automate ICR value selection is to have a lookup table matching the one in the Reference Manual and have your code search for the one that best fits your required baudrate.


Regards!,
Jorge Gonzalez

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

0 Kudos