AnsweredAssumed Answered

KE02x - I2C Read issue

Question asked by Rahul Natak on May 4, 2015
Latest reply on May 4, 2015 by Jorge_Gonzalez

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

 

 

}

Outcomes