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 RM48 I2C Driver Problems

Other Parts Discussed in Thread: HALCOGEN

Hercules RM48 - I2C Problems

Hello. 

We have the Hercules RM48 Reference Board. We are using HalCogen to autogenerate I2C drivers.  We tried running the "example_i2cInterrupt_Communication.c" under Halcogen examples for RM48. the I2C.c code goes into the endless loop in I2C.C (i2cSendByte function) after 8 bytes: i2cSendByte(i2cREG1,*t_buff++); in i2c.c HalcoGen Code.

1. To double check, what should the HalcoGen I2C driver be configured to under the I2C Global, Clocks and Ports sections in Halcogen UI for the TI Hercules RM48 reference board?

2. We have enabled the I2C under PINMUX in Halcogen, is there anything else here?

3. Under interrupts, I2C has been enabled, are there any other interrupts that need to be configured for this example to work?

The while loop in i2c.c i2cSendByte function:

/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)

{

} /* Wait */

Thank you

  • Tammy,

    Please open HALCoGen's help utility from within HALCoGen as "Help --> Help Topics".

    This opens a new HALCoGen help window. You can then choose the I2C communication example and follow the step-by-step instructions.

    Regards, Sunil

  • Hi Thank You.

      Yes, I have run this example thank you.  If you go back and reread my original post the problem is with the other I2C example that you can get to in HalcoGen via Help -> Examples. Windows Explorer then opens up to directory called C:\ti\Hercules\HALCoGen\v04.01.00\examples\RM48x

     The I2C with Interrupt Enables.

    In this directory from TI si a file called example_i2cInterrupt_Communication.c.

    This example with Interrupt and I2C is what I was asking about. File contents in example as follows:

    /** @example example_i2cCommunication.c
    *   This is an example which describes the steps to create an example I2C application which
    *   configures I2C to transfer a set of data. To emulate the transfer the internal loopback
    *   has been enabled. Verify RX_PACK array by the end of code execution.
    *
    *  
    *   @b Step @b 1:
    *
    *   Create a new project.
    *
    *   Navigate: -> File -> New -> Project (click)
    *
    *   @image html example_createProject.jpg "Figure: Create a new Project"
    *
    *   @b Step @b 2:
    *
    *   Configure driver code generation:
    *   - Enable I2C driver
    *   - Disable others
    *
    *
    *   Navigate: -> TMS570LSxx /RM4 -> Enable Drivers
    *
    *   @image html i2c_enabledriver.JPG "Figure: Enable I2C Driver"
    *
    *   @b Step @b 3:
    *
    *   Configure I2C:
    *   - Configure i2c as master transmitter with 10 bit address mode  with 8 bit wide transfer
    *     i.e., Bit Count --> 8 and Data Count --> 16
    *   Navigate: -> TMS570LSxx /RM4 -> I2C
    *
    *   @image html example_i2cCommunication4.jpg "Figure: I2C General Configuration"
    *
    *   Configure I2C Baudrate
    *   @image html example_i2cCommunication2.jpg "Figure: I2C Baudrate Configuration"
    *   
    *   Configure I2C Pins as functional
    *   @image html example_i2cCommunication3.jpg "Figure: I2C Pin Configuration"
    *
    *   @b Step @b 4:
    *
    *   Configure VIM:
    *   - Enable I2C Interrupt channel in VIM
    *
    *   Navigate: -> TMS570LSxx /RM4 -> VIM Channel 64-95
    *
    *   @image html example_i2cCommunication5.jpg "Figure: Enable I2C VIM channel"
    *
    *   @b Step @b 5:
    *
    *   Copy the source code below into your sys_main.c (or) replace sys_main.c with this file.
    *
    *   The example file can also be found in the examples folder: ../HALCoGen/examples
    *
    *   @note HALCoGen generates an empty main function in sys_main.c,
    *
    */

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

    /* Include Files */

    #include "sys_common.h"
    #include "system.h"

    /* USER CODE BEGIN (1) */
    #include "esm.h"
    #include "i2c.h"
    #include "sys_core.h"

    #define own_add 0x20
    #define slv_add 0x10
    #define bsize    16


    uint8  TX_PACK[bsize]={'H','E','R','C','U','L','E','S','M','I','C','R','O','-','T','I'};
    uint8  RX_PACK[bsize]={0};
    uint32 data;

    void i2cEnableLoopback(i2cBASE_t *i2c);
    /* USER CODE END */


    /** @fn void main(void)
    *   @brief Application main function
    *
    */

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


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

        uint32 buf_size = bsize;
        uint8  *t_buff = &TX_PACK[0];
        uint8  *r_buff = &RX_PACK[0];

     /* Enable CPU Interrupts - FIQ & IRQ */ 
        _enable_interrupt_();
       
        /* i2c initialization         */
        i2cInit();                      
       
        /* set i2c own address        */
        i2cSetOwnAdd(i2cREG1,own_add); 
       
        /* enable internal loopback   */
        i2cEnableLoopback(i2cREG1);    

     /* Initiate Receive data length & destination ptr */
        i2cReceive(i2cREG1, 16, r_buff);

        /* Initiate Start condition for Transmission  */
        i2cSetStart(i2cREG1);

        /* send data packets          */
        while(buf_size--)
        {
           i2cSendByte(i2cREG1,*t_buff++);      
        }
       
        /* Clear Stop Condition detect flag  */
        i2cClearSCD(i2cREG1);

        /* Disable RX ready Interrupt  */ 
        i2cDisableNotification(i2cREG1, I2C_RX_INT);
       
        /* wait for ever  */
        while(1);                       

    /* USER CODE END */   
    }

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

  • Sorry about that. I will ask for help from the team that put these examples together.

    Regards, Sunil

  • Hi Tammy,

    There was a bug in our documentation due to which this example didn't show up in the HALCoGen Help file. There's actually an attached image which shows that you need to enable the RXRDY interrupt as well.

    Once you do this, the example works. Also, in case you have an issue where you don't receive the last couple of characters, you need to add a delay before the i2cClearSCD(i2cREG1); statement.

    Thanks for pointing this out, we'll fix it in the next release.

    Regards,

    Chaitanya

  • Thank you. Added change in screen shot above and delay, and all bytes come through. Question -- when does PINMUX (in HalCoGen) for I2C need to be enabled? We did not enable this and sample code worked now with your recommended changes above. Under what circumstances should the PINMUX be enabled for I2C (or for any of the other drivers)?

  • Tammy,

    The I2C functions are multiplexed with other functions on the assigned terminals.

    MIBSPI3NCS[2]/I2C_SDA/N2HET1[27]

    MIBSPI3NCS[3]/I2C_SCL/N2HET1[29]

    If you want to output the I2C signals onto these terminals, the I/O multiplexing module must be configured. Inputs are generally broadcast to each module connected to the terminal. So if you have an I2C function that is used as an input only, then the system will still work even if no I/O multiplexing configuration is done.

    Note that no I/O multiplexing control is necessary if you are just testing the I2C in digital loop-back mode. In this mode, the connection between transmit and receive data is made internally.

    Regards, Sunil

  • Thank you. What happens if we enable PINMUX (the multiplexing) these drivers that are sharing assigned terminals via HalCoGen, and HalCoGen PINMUX menu shows a "conflict".i.e., we need both i.e., I2C and N2HET f(or PWM for example). When we went to enable PINMUX for the different drivers, there were several notifications of conflicts which is why we went back to the default of disabling. What does it mean when there is a conflict and what do we do about it if we need both functions assigned to the same terminals?  Thank you again.

  • Tammy,

    You cannot make use of both functions assigned to a single terminal, especially output functions. There are several other terminals assigned for N2HET channels as well.

    A conflict identified by HALCoGen just means that there are more than one functions selected for a given terminal, and that you should choose just one of them.

    Regards, Sunil