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.

EK-TM4C1294XL: I2C master only generates interrupts when loopback is active

Part Number: EK-TM4C1294XL


Hello,

I've found an interesting behavior, and I'm wondering if anyone has an explanation for it.

I've been developing some I2C code on my EK-TM4C1294XL, and I have it mostly up and running. One weird behavior I noticed is that the I2C module doesn't generate any interrupts unless the loopback is enabled. When it's disabled, no interrupts are generated.

In both situations, I do not have the EK-TM4C1294XL connected to any external I2C devices. But I would still expect to get a start or stop interrupt, even if nothing is connected. Anybody know what's going on?

Here's some code to replicate the issue.


/**
 * main.c
 */
#include <stdint.h>
#include <stdbool.h>

#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/rom_map.h"
#include "driverlib/rom.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/interrupt.h"


uint32_t g_ui32SysClock;
static bool bInterruptPending;

void I2C_Int_Handler(void)
{
    uint32_t ui32IntStatus;

    ui32IntStatus = MAP_I2CMasterIntStatusEx(I2C2_BASE, true);
    MAP_I2CMasterIntClearEx(I2C2_BASE, ui32IntStatus);

    bInterruptPending = false;
}


int main(void)
{
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOL));
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C2));

    MAP_GPIOPinConfigure(GPIO_PL0_I2C2SDA);
    MAP_GPIOPinConfigure(GPIO_PL1_I2C2SCL);

    MAP_GPIOPinTypeI2C(GPIO_PORTL_BASE, GPIO_PIN_0);
    MAP_GPIOPinTypeI2CSCL(GPIO_PORTL_BASE, GPIO_PIN_1);

    MAP_I2CMasterInitExpClk(I2C2_BASE, g_ui32SysClock, false);
    MAP_I2CMasterIntEnableEx(I2C2_BASE, 0xFFF);

    I2CIntRegister(I2C2_BASE, I2C_Int_Handler);
    MAP_IntEnable(INT_I2C2);

    //if I2CLoopbackEnable is removed, the program hangs on while(bInterruptPending)
    //if I2CLoopbackEnable is kept, the program exits normally
    I2CLoopbackEnable(I2C2_BASE);


    MAP_I2CMasterSlaveAddrSet(I2C2_BASE, 0x03, false);
    bInterruptPending = true;
    MAP_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_QUICK_COMMAND);

     while(bInterruptPending);

	return 0;
}

  • Hello Adevries,

    In both situations, I do not have the EK-TM4C1294XL connected to any external I2C devices. But I would still expect to get a start or stop interrupt, even if nothing is connected. Anybody know what's going on?

    Do you have external pull-ups connected to the lines? If not you wouldn't get the interrupt because the voltage levels on the I/O would not change to reflect the stop condition.

    In loopback mode the signal isn't going to the I/O so that doesn't matter.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph,

    No, in both situations, I do not have any external pull-ups connected. In both situations, since there's no external pull-up, the voltage levels on the I/O wouldn't change, right? Why do they not matter when in loopback mode? Is there some kind of internal pull-up that's only active when looping back the signal? 

  • Hello Adevries,

    The external I2C bus works by pulling down the voltage from 3.3V so without the pull-up resistors, you won't have a signal to pull low and therefore the bus sees no transitions and cannot send start/stop conditions. So you are correct that voltage levels on the I/O wouldn't change, and that is why you aren't getting an interrupt.

    For the internal I2C with loopback I do believe they use the actual internal pull-ups, but not 100% sure. Regardless, when in loopback mode the signals don't reach the I/O but they are transitioning internally from high to low and therefore the start and stop conditions are seen and the latter will trigger the interrupt.

    In summary, you will need to add the external pull-ups if not using loopback mode to get any interrupts.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph,

    Okay, thanks for the advice! I was definitely planning on including pull-up resistors, but I will also make a note of what happens when they are not present haha.