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 read Double

Genius 9880 points
Part Number: EK-TM4C1294XL

Hi Team,

Customer is trying to  communicate on an TI launchpad via i2c with a GPS Receiver and encountering issue with the i2c. Please see details below.

For the initialization and the communication aim using the TIVA ware Library. The TI Launchpad is the Master and the GPS receiver is the Slave. 

EK-TM4C129XL.txt
SYS_RESLT sys_I2cInitFunc(uint32_t g_ui32SysClock){

    SYS_RESLT eFault = SYS_RESLT__OK;

    //
    // Stop the Clock, Reset and Enable I2C Module
    // in Master Function
    //
    SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //
    // Wait for the I2C0 module to be ready.
    //
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0))
    {
    }
    //
    //Enable GPIO for Configuring the I2C Interface Pins
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Wait for the Peripheral to be ready for programming
    //
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB))
    {

    };
    //
    // Configure Pins for I2C2 Master Interface
    //
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    GPIOPinTypeI2C(GPIO_PORTB_AHB_BASE, GPIO_PIN_3);
    GPIOPinTypeI2CSCL(GPIO_PORTB_AHB_BASE, GPIO_PIN_2);

    //
    // Initialize Master
    //

    I2CMasterInitExpClk(I2C0_BASE,g_ui32SysClock, false);

    return eFault;}

the Parameter g_ui32SysClock is the System Clock frequency. 
Then I have a Function wich I use to read. 

    SYS_RESLT gps_readByteI2C(uint8_t *pbBytesRead, uint8_t bLen){

    SYS_RESLT eFault = SYS_RESLT__OK;
    uint8_t bAdd = GPS_I2C_ADD
    ;
    uint8_t bI = 0;// read only one byte
    if (bLen == 1){ // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // set i2c address and read
        I2CMasterSlaveAddrSet(I2C0_BASE, bAdd, true);
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // read on the bus
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
       
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // check fault
        if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
        {

            eFault = SYS_RESLT__I2C; // fault

        }
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // read data
        *pbBytesRead = I2CMasterDataGet(I2C0_BASE);

    }
    else // more then one byte to read
    {

        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // set i2c address and read
        I2CMasterSlaveAddrSet(I2C0_BASE, bAdd, true);
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // read on the bus first byte
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

        
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // check fault
        if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
        {
            //test = I2CMasterErr(I2C0_BASE);
            eFault = SYS_RESLT__I2C; // fault

        }
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // get data
        pbBytesRead[0] = I2CMasterDataGet(I2C0_BASE);

        

        // for all othe bytes
        for (bI = 0; bI < bLen - 2; bI++)
        {

            // wait
            while (I2CMasterBusy(I2C0_BASE))
            {

            }

            // set i2c address and read
            I2CMasterSlaveAddrSet(I2C0_BASE, bAdd, true);

            // wait
            while (I2CMasterBusy(I2C0_BASE))
            {

            }

            // read on the bus
            I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);

            // wait
            while (I2CMasterBusy(I2C0_BASE))
            {

            }

            // check fault
            if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
            {

                eFault = SYS_RESLT__I2C; // fault

            }
            while (I2CMasterBusy(I2C0_BASE))
            {

            }

            // get data
            pbBytesRead[bI + 1] = I2CMasterDataGet(I2C0_BASE);

            // break if new message
            if (pbBytesRead[bI + 1] == 0x24)
            {
                break;
            }

        }

        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // set i2c address and read
        I2CMasterSlaveAddrSet(I2C0_BASE, bAdd, true);
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // read on the bus last byte
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

        
        // wait
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // check fault
        if (I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
        {

            eFault = SYS_RESLT__I2C; // fault

        }
        while (I2CMasterBusy(I2C0_BASE))
        {

        }

        // get data
        pbBytesRead[bI + 1] = I2CMasterDataGet(I2C0_BASE);
        
    }

    return eFault;}

I Use a logic Analyzer to watch the i2c bus an there everything seams fine the message is correct and look like it should be. so I think the Problem is not the slave. the Problem is that in pbBytesRead are most of the bytes tow ore more times. for example the logic analyzer says on the bus was : 0x24 0x42 0x45 0x76 0x64. but the launchepad reads in pbBytesRead : 0x24 0x24 0x24 0x42 0x42 0x45 0x45 0x45 0x76 0x76 0x76 0x64 0x64 0x64. maybe something with the init is wrong? Has anybody some clue or hint for me ? if needed I can provide some more information.

Thanks.

Regards,
May

Thank you.

Regards,
May

  • Hi,

      Can you try for every place where you have I2CMasterBusy()

    replace:

    while (I2CMasterBusy(I2C0_BASE) == true); 

    with 

    while (!I2CMasterBusy(I2C0_BASE) == true);  // Add this line.  You can also add a short delay loop here instead of while (!I2CMasterBusy(I2C0_BASE) == true)

    while (I2CMasterBusy(I2C0_BASE) == true);   // Keep this line after the above line.

  • Hi Charles,

    Just received response from customer, please see details below.

    i tryed "while (I2CMasterBusy(I2C0_BASE) == true); " instead of "while (I2CMasterBusy(I2C0_BASE))
    {

    }". but is this not the same ?? This ist not working exact the same result.
    I tryed also with some Delays but there are also some bytes double or if the delay is to big some bytes are not in the array. the result of the logic Analyzer ( what I think is correct and is also what I expect) and what read by the board is attached.

    Some addition:

    with this line "while (!I2CMasterBusy(I2C0_BASE) == true)" I get in a forever loop. so this is not what I want. I checked also the combination : " SysCtlDelay(WAIT);
    while (I2CMasterBusy(I2C0_BASE) == true);"

    with #define WAIT 30
    this was also not the result I want

    Thank you.

    Regards,
    May

  • Hi May,

      Sorry, I think there is some confusion from my part. What I mean is in customer's code, everywhere you have the below line:

    Replace:

    while (I2CMasterBusy(I2C0_BASE))
            {

            }

     By:

    while (!I2CMasterBusy(I2C0_BASE) == true);  // Add this line.  

    while (I2CMasterBusy(I2C0_BASE))  // Keep this original line
            {

            }

    If the above suggestion does not work, I need to look at your code again to see what happens.