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.

TM4C1230D5PM: ROM_UpdateI2C locks up when I call it

Part Number: TM4C1230D5PM

Code to call ROM_UpdatreI2C

// disable watchdog timer
HWREG(SYSCTL_RCGCWD) = 0;

// turn off timer interrupts
TimerIntDisable(TIMER5_BASE, TIMER_TIMA_TIMEOUT);
IntMasterDisable();
// enable i2c0 master in addition to the already enabled slave
HWREG(I2C0_BASE + I2C_O_MCR) |= I2C_MCR_MFE;

ROM_UpdateI2C();

The on the I2C lines I send 

0x20 0x03 0x20 0x20  (I2C slave address is 0x10)

read 0x00 back

On the next attempt to write to chip, both I2C lines get pulled low.  The clock line, SCL, for 200 ms.  The SDA line does not release until I reset the chip

  • Hello Jeffrey,

    So the ROM_UpdateI2C function expects the I2C bus to be correctly configured already - I see you did one enabling there but to make it operational you also need to enable the Master clock / set the slave address as well. And I can't see how you configured the slave side either.

    I strongly suspect the issue is that something in the I2C peripheral is not fully configured.

    Here is the exact description from our User's Guide for clarity:

    This function assumes that the I2C0 interface has already been configured and is currently operational. The I2C0 slave is used for data transfer, and the I2C0 master is used to monitor bus busy conditions (therefore, both must be enabled).

    Best Regards,

    Ralph Jacobi

  • The application previously enables the I2C0 as a slave and it successfully communicates prior to the call to ROM_UpdateI2C.

    As a further experiment, I clock setup line after the enable.  This had no effect.

            // enable i2c0 master in addition to the already enabled slave
            HWREG(I2C0_BASE + I2C_O_MCR) |= I2C_MCR_MFE;
            HWREG(I2C0_BASE + I2C_O_MTPR) =  0x09;

  • Using the functions from i2c.c

    void setup_i2c_ez_slave(void)
    {
        // connect clock to i2c0
            //
        // Must enable the device before doing anything else.
        // first setup clock
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

        // Configure the pin muxing for I2C0 functions on port B2 and B3.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);

        //
        // Select the I2C function for these pins.  This function will also
        // configure the GPIO pins pins for I2C operation, setting them to
        // open-drain operation with weak pull-ups.  Consult the data sheet
        // to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

        //
        // Enable the I2C0 interrupt on the processor (NVIC).
        //
        //IntEnable(INT_I2C0);
        I2CIntRegister(I2C0_BASE, I2C0SlaveIntHandler);

        //
        // Configure and turn on the I2C0 slave interrupt.  The I2CSlaveIntEnableEx()
        // gives you the ability to only enable specific interrupts.  For this case
        // we are only interrupting when the slave device receives data or requests data.
        //
        I2CSlaveIntEnableEx(I2C0_BASE, I2C_SLAVE_INT_DATA);

        //
         // Enable the I2C0 slave module.
         //
        I2CSlaveEnable(I2C0_BASE);

        //
        // Set the slave address to SLAVE_ADDRESS
        //
        I2CSlaveInit(I2C0_BASE, 0x10);

  • Hello Jeffrey,

    The on the I2C lines I send 

    0x20 0x03 0x20 0x20  (I2C slave address is 0x10)

    read 0x00 back

    As I reviewed your posts again, I got to thinking about this more and I am not sure you are sending data properly to the boot loader.

    There is a specific packet format which needs to be used for all serial boot loaders (UARt/I2C/SPI).

    Section 5.1 of our Boot Loader User's Guide covers this clearly: https://www.ti.com/lit/pdf/spmu301

    Please have a read through that and let me know if you think that is applicable here. I wasn't entirely sure how to decode your packet but I don't think it has a data length or check sum included.

    Best Regards,

    Ralph Jacobi

  • From examining the sources in boot_loader, its now clear that I needed to read back 2 bytes, not one byte.

    Once I read back 2 bytes, everything is fine