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.

I2C3 Not working under XDS100 JTAG debugger

Hello, I've got a custom board with TM4C1294NCPDT part running TI RTOS and trying to debug an issue with I2C3. For some reason, the I2C_transfer() call fails when running under the debugger and I see no data going out the pins. However, if I reboot outside the debugger I can see data clocking out to an EPROM I'm trying to communicate with. Any ideas? My read logic and I2C driver init code is listed below, but the device still doesn't seem to be responding when it runs outside the debugger even though I see data clocking out.  I'm new the I2C EPROM also and may not be addressing it properly with the RTOS I2C calls also.

Thanks,

Bob

 

int ReadSerialNumber(uint8_t ui8SerialNumber[16])

{

bool ret;

uint8_t txBuf[2];

I2C_Handle handle;

I2C_Params params;

I2C_Transaction i2cTransaction;

/* default invalid serial number is all FF's */

memset(ui8SerialNumber, 0xFF, sizeof(ui8SerialNumber));

I2C_Params_init(&params);

params.transferMode = I2C_MODE_BLOCKING;

params.transferCallbackFxn = NULL;

params.bitRate = I2C_100kHz;

handle = I2C_open(Board_I2C_AT24CS01, &params);

if (!handle) {

System_printf("I2C did not open\n");

System_flush();

return 0;

}

/* Note the Upper bit of the word address must be set

* in order to read the serial number. Thus 80H would

* set the starting address to zero prior to reading

* this sixteen bytes of serial number data.

*/

txBuf[0] = 0x80;

txBuf[1] = 0x00;

i2cTransaction.writeBuf = txBuf;

i2cTransaction.writeCount = 1;

i2cTransaction.readBuf = NULL;

i2cTransaction.readCount = 0;

i2cTransaction.slaveAddress = Board_AT24CS01_SERIAL_ADDR;

ret = I2C_transfer(handle, &i2cTransaction);

i2cTransaction.writeBuf = txBuf;

i2cTransaction.writeCount = 1;

i2cTransaction.readBuf = ui8SerialNumber;

i2cTransaction.readCount = 16;

i2cTransaction.slaveAddress = Board_AT24CS01_SERIAL_ADDR;

ret = I2C_transfer(handle, &i2cTransaction);

if (!ret)

{

System_printf("Unsuccessful I2C transfer\n");

System_flush();

}

I2C_close(handle);

return ret;

}

 

 

 

//// DRIVER INIT CODE ////////////////////////////////////////////////////

#include <ti/drivers/I2C.h>

#include <ti/drivers/i2c/I2CTiva.h>

/* I2C objects */

I2CTiva_Object i2cTivaObjects[PMX42_I2CCOUNT];

/* I2C configuration structure, describing which pins are to be used */

const I2CTiva_HWAttrs i2cTivaHWAttrs[PMX42_I2CCOUNT] = {

{I2C0_BASE, INT_I2C0},

{I2C1_BASE, INT_I2C1},

{I2C2_BASE, INT_I2C2},

{I2C3_BASE, INT_I2C3}

};

const I2C_Config I2C_config[] = {

{&I2CTiva_fxnTable, &i2cTivaObjects[0], &i2cTivaHWAttrs[0]},

{&I2CTiva_fxnTable, &i2cTivaObjects[1], &i2cTivaHWAttrs[1]},

{&I2CTiva_fxnTable, &i2cTivaObjects[2], &i2cTivaHWAttrs[2]},

{&I2CTiva_fxnTable, &i2cTivaObjects[3], &i2cTivaHWAttrs[3]},

{NULL, NULL, NULL}

};

/*

* ======== PMX42_initI2C ========

*/

void PMX42_initI2C(void)

{

/* I2C0 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PB2_I2C0SCL);

GPIOPinConfigure(GPIO_PB3_I2C0SDA);

GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);

GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

/* I2C1 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PG0_I2C1SCL);

GPIOPinConfigure(GPIO_PG1_I2C1SDA);

GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);

GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);

/* I2C2 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PL1_I2C2SCL);

GPIOPinConfigure(GPIO_PL0_I2C2SDA);

GPIOPinTypeI2CSCL(GPIO_PORTL_BASE, GPIO_PIN_1);

GPIOPinTypeI2C(GPIO_PORTL_BASE, GPIO_PIN_0);

/* I2C3 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PK4_I2C3SCL);

GPIOPinConfigure(GPIO_PK5_I2C3SDA);

GPIOPinTypeI2CSCL(GPIO_PORTK_BASE, GPIO_PIN_4);

GPIOPinTypeI2C(GPIO_PORTK_BASE, GPIO_PIN_5);

I2C_init();

}

#include <ti/drivers/I2C.h>

#include <ti/drivers/i2c/I2CTiva.h>

/* I2C objects */

I2CTiva_Object i2cTivaObjects[PMX42_I2CCOUNT];

/* I2C configuration structure, describing which pins are to be used */

const I2CTiva_HWAttrs i2cTivaHWAttrs[PMX42_I2CCOUNT] = {

{I2C0_BASE, INT_I2C0},

{I2C1_BASE, INT_I2C1},

{I2C2_BASE, INT_I2C2},

{I2C3_BASE, INT_I2C3}

};

const I2C_Config I2C_config[] = {

{&I2CTiva_fxnTable, &i2cTivaObjects[0], &i2cTivaHWAttrs[0]},

{&I2CTiva_fxnTable, &i2cTivaObjects[1], &i2cTivaHWAttrs[1]},

{&I2CTiva_fxnTable, &i2cTivaObjects[2], &i2cTivaHWAttrs[2]},

{&I2CTiva_fxnTable, &i2cTivaObjects[3], &i2cTivaHWAttrs[3]},

{NULL, NULL, NULL}

};

/*

* ======== PMX42_initI2C ========

*/

void PMX42_initI2C(void)

{

/* I2C0 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PB2_I2C0SCL);

GPIOPinConfigure(GPIO_PB3_I2C0SDA);

GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);

GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

/* I2C1 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PG0_I2C1SCL);

GPIOPinConfigure(GPIO_PG1_I2C1SDA);

GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);

GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);

/* I2C2 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PL1_I2C2SCL);

GPIOPinConfigure(GPIO_PL0_I2C2SDA);

GPIOPinTypeI2CSCL(GPIO_PORTL_BASE, GPIO_PIN_1);

GPIOPinTypeI2C(GPIO_PORTL_BASE, GPIO_PIN_0);

/* I2C3 Init */

/* Enable the peripheral */

SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);

/* Configure the appropriate pins to be I2C instead of GPIO. */

GPIOPinConfigure(GPIO_PK4_I2C3SCL);

GPIOPinConfigure(GPIO_PK5_I2C3SDA);

GPIOPinTypeI2CSCL(GPIO_PORTK_BASE, GPIO_PIN_4);

GPIOPinTypeI2C(GPIO_PORTK_BASE, GPIO_PIN_5);

I2C_init();

}

  • Could you tell me what version of CCS and TIRTOS you are using?
  • Thanks for the reply, looks like CCS v6.1.0.00104 and TI RTOS v2.10.01.38.

    Bob

  • Just found in the interrupt handler I2CTiva_hwiFxn() that error 4 is occurring for some reason, think this is I2C_MASTER_ERR_ADDR_ACK. The part I'm trying to communicate with is an Atmel AT24CS01-STUM-T (5 pin SOT-23). I'm trying to read the unique serial number from this part. Think I have the correct device address 0xB0.
  • Just found the problem. For some reason they chose to shift the I2C address provided to the function I2CMasterSlaveAddrSet() left a bit prior to OR'ing in the R/W bit. My part wants 0xB0 for the address, so I had to change the address in my code to 0x40 prior to calling the transfer function. Maybe I missed this in the documentation somewhere, but live and learn I guess. This cost me several days of headaches and painful debugging. Time for a beer!

    Bob


    void
    I2CMasterSlaveAddrSet(uint32_t ui32Base, uint8_t ui8SlaveAddr,
                          bool bReceive)
    {
        //
        // Check the arguments.
        //
        ASSERT(_I2CBaseValid(ui32Base));
        ASSERT(!(ui8SlaveAddr & 0x80));

        //
        // Set the address of the slave with which the master will communicate.
        //
        HWREG(ui32Base + I2C_O_MSA) = (ui8SlaveAddr << 1) | bReceive;
    }