This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28069: Issue with I2C ISR Not Updating Value When Reading EEPROM on TMS320F28069

Part Number: TMS320F28069

Tool/software:

Hello,

I am working with the TI C2000 TMS320F28069 microcontroller and I am using I2C to read from an EEPROM. I am encountering an issue where my I2C interrupt service routine (ISR) does not seem to update the value when reading from the EEPROM if the read operation is initiated within the Timer0 ISR. However, it works correctly when I perform the read operation in the main loop.

Here is my timero IRQ:

interrupt void TIM0_IRQn(void)
{
   EALLOW;
   AT24C02_Read(0x10);
   val1 = InData[0];
   AT24C02_Read(0x11);
   val2 = InData[0];
   PieCtrlRegs.PIEACK.bit.ACK1 = 1;
   EDIS;
}

The AT24C02_Read() is just a function use to communicate with the EEPROM. Running the code above, it seems that val1 is equal to val2, and it did read the value from the EEPROM in address 0x10 correctly but can't read the second address 0x11.

While perform the read operation in the main loop:

void main()

{

// Initialization code...

while(1)
    {
        DELAY_US(500);
        AT24C02_Read(0x10);
        val1 = InData[0];
        AT24C02_Read(0x11);
        val2 = InData[0]; }
}

In the main loop, both vol1 and vol2 are read out correctly.

This is my IIC configuration:

void I2CA_Init(void)
{
   // Initialize I2C
    I2caRegs.I2CSAR = 0x0050;       // Slave Address.
    I2caRegs.I2COAR = 0x002D;       //  address as Master.
    I2caRegs.I2CPSC.all = 6;        // Prescaler - need 7-12 Mhz on module clk
    I2caRegs.I2CCLKL = 10;          // NOTE: must be non zero
    I2caRegs.I2CCLKH = 5;           // NOTE: must be non zero
    I2caRegs.I2CIER.all = 0x2C;     // Enable SCD & ARDY interrupts

    I2caRegs.I2CMDR.bit.IRS = 1;    // Take I2C out of reset
                                    // Stop I2C when suspended

    I2caRegs.I2CFFTX.all = 0x6000;  // Enable FIFO mode and TXFIFO
//    I2caRegs.I2CFFRX.all = 0x2040;    // Enable RXFIFO, clear RXFFINT,
    return;
}

void I2CA_Write(Uint16 Addr, Uint16 data)
{
    I2caRegs.I2CCNT = 2;            // 3 Additional Bytes being tranferred.
    I2caRegs.I2CDXR = Addr;         // Send Register to be updated.
//    I2caRegs.I2CDXR = HIGH_BYTE(data);
    I2caRegs.I2CDXR = LOW_BYTE(data);
//    I2caRegs.I2CDXR = 0x10;

    I2caRegs.I2CMDR.all = 0x6E20;   // Set up the control register
}

void I2CA_Read(Uint16 Addr)
{
    I2cIndex = 0;
    I2caRegs.I2CCNT = 1;            // 1 Additional Byte being tranferred.
    I2caRegs.I2CDXR = Addr;     // Send Register to be updated.
    I2caRegs.I2CMDR.all = 0x6620;   // Set up the control register:

    DELAY_US(50);                   // Delay 50 usec

    I2caRegs.I2CCNT = 1;            // Set up receive of 2 bytes.
    I2caRegs.I2CMDR.all = 0x6C20;   // Send "repeated" Start with Read (TRX off)
                                        // and Stop.
}

void I2CA_Wait(void)
{
   // Wait until the STP bit is cleared from any previous master communication.
   // Clearing of this bit by the module is delayed until after the SCD bit is
   // set. If this bit is not checked prior to initiating a new message, the
   // I2C could get confused.

    while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.

    while (I2caRegs.I2CSTR.bit.BB == 1);  // Wait for Bus Busy to be zero.

}

The IIC ISR is:

interrupt void i2c_int1a_isr(void)     // I2C-A
{
    Uint16 IntSource;

   // Read interrupt source
    IntSource = I2caRegs.I2CISRC.bit.INTCODE & 0x7;

    switch(IntSource)
    {
        case I2C_NO_ISRC:   // =0
            break;

        case I2C_ARB_ISRC:  // =1
            break;

        case I2C_NACK_ISRC: // =2
            break;

        case I2C_ARDY_ISRC: // =3
            break;

        case I2C_RX_ISRC:   // =4
            InData[I2cIndex] = I2caRegs.I2CDRR;
            break;

        case I2C_TX_ISRC:   // =5
            break;

        case I2C_SCD_ISRC:  // =6
            break;

        case I2C_AAS_ISRC:  // =7
            break;

        default:
            asm("   ESTOP0"); // Halt on invalid number.
    }

   // Enable future I2C (PIE Group 8) interrupts
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}

I suspect there might be a conflict or timing issue between the Timer0 ISR and the I2C ISR, but I am not sure how to resolve this. Any advice or suggestions on how to fix this issue would be greatly appreciated.

Thank you!

  • Hi Xinghang,

    Assuming that the I2C is configured as controller receiver, what it looks like is happening is that the ARDY and RX and RX and SCD events (depending on what triggers the I2C ISR) are occurring at very similar times, if not the same time. You can try modifying the Timer period if that can be done and adding delays between reads within the ISR as the delay within the read routine may not be enough time. Note that the average EEPROM takes a maximum of 5ms to do a read or write.

    Best Regards,

    Aishwarya

  • Xinghang,

    Have you been able to resolve this issue? If there are no more questions, I will go ahead and close this thread. 

    Best Regards,

    Aishwarya