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.

HERCULES_SAFETY_MCU_DEMOS: Halcogen I2C Example Infinite Loop

Part Number: HERCULES_SAFETY_MCU_DEMOS

Hello, I am a beginner trying to get I2C to work on the TMS570LC43x Microcontroller and I am using the code provided in the "example_i2cMaster_TX_RX.c" file. I use the functions generated by HalCoGen and configure it as instructed in the example. I am getting stuck in an infinite loop (pictured below). I am not sure how to fix it.

/* Include Files */

#include "HL_sys_common.h"

/* USER CODE BEGIN (1) */
#include "HL_i2c.h"
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
#define DATA_COUNT  10

#define Master_Address 0x26
#define Slave_Address  0x40

uint8_t TX_Data_Master[10] = { 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
uint8_t RX_Data_Master[10] = { 0 };

uint8_t TX_Data_Slave[10] = { 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29};
uint8_t RX_Data_Slave[10] = { 0 };

/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */

    int repeat = 0; int delay =0;

///////////////////////////////////////////////////////////////
//        Master Transfer Functionality                      //
///////////////////////////////////////////////////////////////
    /* I2C Init as per GUI
     *  Mode = Master - Transmitter
     *  baud rate = 100KHz
     *  Count = 10
     *  Bit Count = 8bit
     */
    i2cInit();

    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, Slave_Address);

    /* Set direction to Transmitter */
    /* Note: Optional - It is done in Init */
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);


    for(repeat = 0; repeat < 2; repeat++)
    {
        /* Configure Data count */
        /* Note: Optional - It is done in Init, unless user want to change */
        i2cSetCount(i2cREG1, DATA_COUNT);

        /* Set mode as Master */
        i2cSetMode(i2cREG1, I2C_MASTER);

        /* Set Stop after programmed Count */
        i2cSetStop(i2cREG1);

        /* Transmit Start Condition */
        i2cSetStart(i2cREG1);

        /* Tranmit DATA_COUNT number of data in Polling mode */
        i2cSend(i2cREG1, DATA_COUNT, TX_Data_Master);

        /* Wait until Bus Busy is cleared */
        while(i2cIsBusBusy(i2cREG1) == true);

        /* Wait until Stop is detected */
        while(i2cIsStopDetected(i2cREG1) == 0);

        /* Clear the Stop condition */
        i2cClearSCD(i2cREG1);

        /* Simple Dealya before starting Next Block */
        /* Depends on how quick the Slave gets ready */
        for(delay=0;delay<1000000;delay++);

    }

    while(1);

/* USER CODE BEGIN (4) */
/* USER CODE END */

    return 0;
}

The loop which I get stuck in is in the i2cSend() function.

void i2cSend(i2cBASE_t *i2c, uint32 length, uint8 * data)
{
    uint32 index = i2c == i2cREG1 ? 0U : 1U;

/* USER CODE BEGIN (17) */
/* USER CODE END */

    if ((g_i2cTransfer_t[index].mode & (uint32)I2C_TX_INT) != 0U)
    {
        /* we are in interrupt mode */
        /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
        g_i2cTransfer_t[index].data   = data;

        /* start transmit by sending first byte */
        /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
        i2c->DXR = (uint32)*g_i2cTransfer_t[index].data;
        /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
        g_i2cTransfer_t[index].data++;
        /* Length -1 since one data is written already */
        g_i2cTransfer_t[index].length = (length - 1U);
        /* Enable Transmit Interrupt */
        i2c->IMR |= (uint32)I2C_TX_INT;
    }
    else
    {
        /* send the data */
        /*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
        while (length > 0U)
        {
            /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
            while ((i2c->STR & (uint32)I2C_TX_INT) == 0U) /* GETTING STUCK HERE */
            {
            } /* Wait */
            /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
            i2c->DXR = (uint32)*data;
            /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
            data++;
            length--;
        }
    }
/* USER CODE BEGIN (18) */
/* USER CODE END */
}

What can I do to fix this? 

  • Hello,

    1. Is pinmux configured for I2C correctly? I2C1 SDA and SCL are multiplexed with MibSPI signals, and those 2 pins are configured as MibSPI by default.

    2. Do you add pull-up resistors to I2C1 SDA and I2C1 SCL signals? They are open-drain signals, and need to be pulled up externally.