I2C Pin Assignment Not Functioning

We’ve been working out some pin assignments on our board and have attempted to use the alternative pin configuration on I2C4 consisting of pins of 162 and 154. Using these pins did not produce outputs on pins 162 and 154. We did attempt to use the default pins and observed outputs on pins 55 and 63 which is correct. In other words, we observed that the assignment to pins 162 and 154 did not take and output was only on 55 and 63.

We are using library version: 2.1b4327-20180226

///
/// @file         I2c_Demo.c
/// @copyright    Copyright (c) 2015 Toradex AG
/// $Author: germano.kern $
/// $Rev: 4310 $
/// $Date: 2018-02-06 13:29:45 +0530 (Tue, 06 Feb 2018) $
/// @brief        Program to show how to use the I2C library
/// @target       Colibri VFxx Modules
/// @test         Tested on:  VFxx
/// @caveats      None

#include <windows.h>
//Uncomment the line below if you want to use TdxAllLibrariesDll.dll
//#define USE_DLL
#include "i2c_imx6.h"
#include "gpio.h"

//******************************************************************************
/// Scan I2C Bus for available devices.
/// @param[in]  i2c           HANDLE to I2C port, retrieved from I2c_Init()
void i2cScan(HANDLE i2c)
{
    int i, count = 0;
    BOOL Success;


    Success = I2c_Open(i2c);
    if (!Success)
    {
        printf("I2c_Open failed. Exit Scan", count);
        return;
    }


    printf("Scanning i2c bus...\r\n");
    for (i = 8; i < 0x78; i++) // First and last 8 addresses are reserved
    {
        BYTE tmpBuf;

        I2c_SetConfigInt(i2c, TEXT("SlaveAddr"), i, StoreVolatile);

        Success = (I2c_Read(i2c, &tmpBuf, 1) == (DWORD)-1) ? FALSE : TRUE;
        if (Success)
        {
            printf("- 0x%02x \n\r", i);
            count++;
        }
        //Sleep(1);
    }
    I2c_Close(i2c);

    printf("\r\n%d device(s) found.\r\n", count);
}

//*****************************************************************************
/// Main function
/// @param[in]  instance       Handle to program instance
/// @param[in]  prevInstance   Handle to previous program instance
/// @param[in]  cmdLine        Command line string pointer
/// @param[in]  cmdShow        Window state
/// @retval     1              Always returned
int wmain(int argc, wchar_t *argv[])
{
    DWORD i;
    DWORD returnValue;

    HANDLE i2c = NULL;
    BYTE data[8] = {0};

    // Initialize I2Cx, without affecting hardware registers
    i2c = I2c_Init(L"I2C3");
    if (i2c == NULL)
        printf("Error in I2c_Init()\r\n");


    // ====== BusScan ======
    i2cScan(i2c);

    // ====== RTC Read and Write Example ======

    //  Override the default io which is defined by the portName "I2C1"..."I2C4"
    //  Io configurations need to be done *before* calling I2c_Open() !
    { /* Need to include gpio.h for uIo structure */
      uIo ioScl = COLIBRI_PIN(162); /*Colibri Pin 74*/
      uIo ioSda = COLIBRI_PIN(154); /*Colibri Pin 50*/
    //          /*  or  */
    //  uIo ioScl;
    //  uIo ioSda;
    //  ioScl.GenericDefinition = IOCOLIBRIPIN(74);
    //  ioSda.GenericDefinition = IOCOLIBRIPIN(50);
      returnValue = I2c_SetConfigInt(i2c, L"ioScl", ioScl.GenericDefinition, StoreVolatile);
      returnValue = I2c_SetConfigInt(i2c, L"ioSda", ioSda.GenericDefinition, StoreVolatile);
    }

    // Open the i2c port
    I2c_Open(i2c);

    // Change configuration as required
    // Instead of calling this function, you can place default values in the registry
    //   [HKLM\SOFTWARE\Toradex\I2C1]
    //   BitRateHz        = dword:00061a80             ; = decimal 400000
    //   SlaveAddrSize    = dword:00000007             ; = decimal 7
    //   RegisterAddrSize = dword:00000000             ; = decimal 0
    I2c_SetConfigInt(i2c, L"BitRateHz",         100000,  StoreVolatile);  // Set I2C speed to 400KHz
    I2c_SetConfigInt(i2c, L"SlaveAddrSize",    7,       StoreVolatile);  // Set 7 bit Slave address
    I2c_SetConfigInt(i2c, L"RegisterAddrSize", 0,       StoreVolatile);  // No Register address to send

    // Set RTC address into handle, it will be valid for all future Read/Write calls
    // 0x68 is the 7 bit address of the RTC present on Colibri Evaluation Board
    I2c_SetConfigInt(i2c, L"SlaveAddr", 0x68, StoreVolatile);

    // I2C Read
    returnValue = I2c_Read(i2c, (DWORD*) data, 8);

    printf("\nReading the RTC: %s\r\n", (returnValue == I2C_RW_FAILURE ? "failed." : "successful."));

    // I2C Write
    for (i = 0; i < 8; i++)
        data[i] = 0;

    returnValue = I2c_Write(i2c, (DWORD*) data, 8);
    printf("\nResetting the RTC: %s\r\n", (returnValue == I2C_RW_FAILURE ? "failed." : "successful."));

    // Close and deinit I2C port
    I2c_Close(i2c);
    I2c_Deinit(i2c);

    // Finish demo application
    printf("\nPress enter to exit");
    fflush(stdin);
    getchar();

    return(TRUE);
}

@chronic788 ,

I guess, you called I2c_Init with “I2C4” portname.

i2c = I2c_Init(L"I2C4");

I2c_SetConfigInt for ioScl, ioSda parameters must be called before I2c_Open function. Please refer Compatible I2C Configurations section in Toradex_CE_Libraries.chm documentation for more information.

Let us know if it doesn’t solve the issue.

Thank you for getting back to us!

We reran the program with I2C set on L"I2C4" and got the same result. Also, we made sure that we call I2c_SetConfigInt for ioScl and ioSda parameters before I2c_open.

Here is our updated code:

///
/// @file         I2c_Demo.c
/// @copyright    Copyright (c) 2015 Toradex AG
/// $Author: germano.kern $
/// $Rev: 4310 $
/// $Date: 2018-02-06 13:29:45 +0530 (Tue, 06 Feb 2018) $
/// @brief        Program to show how to use the I2C library
/// @target       Colibri VFxx Modules
/// @test         Tested on:  VFxx
/// @caveats      None

#include <windows.h>
//Uncomment the line below if you want to use TdxAllLibrariesDll.dll
//#define USE_DLL
#include "i2c_imx6.h"
#include "gpio.h"

//******************************************************************************
/// Scan I2C Bus for available devices.
/// @param[in]  i2c           HANDLE to I2C port, retrieved from I2c_Init()
void i2cScan(HANDLE i2c)
{
    int i, count = 0;
    BOOL Success;


    Success = I2c_Open(i2c);
    if (!Success)
    {
        printf("I2c_Open failed. Exit Scan", count);
        return;
    }


    printf("Scanning i2c bus...\r\n");
    for (i = 8; i < 0x78; i++) // First and last 8 addresses are reserved
    {
        BYTE tmpBuf;

        I2c_SetConfigInt(i2c, TEXT("SlaveAddr"), i, StoreVolatile);

        Success = (I2c_Read(i2c, &tmpBuf, 1) == (DWORD)-1) ? FALSE : TRUE;
        if (Success)
        {
            printf("- 0x%02x \n\r", i);
            count++;
        }
        //Sleep(1);
    }
    I2c_Close(i2c);

    printf("\r\n%d device(s) found.\r\n", count);
}

//*****************************************************************************
/// Main function
/// @param[in]  instance       Handle to program instance
/// @param[in]  prevInstance   Handle to previous program instance
/// @param[in]  cmdLine        Command line string pointer
/// @param[in]  cmdShow        Window state
/// @retval     1              Always returned
int wmain(int argc, wchar_t *argv[])
{
    DWORD i;
    DWORD returnValue;

    HANDLE i2c = NULL;
    BYTE data[8] = {0};

    // Initialize I2Cx, without affecting hardware registers
    i2c = I2c_Init(L"I2C4");
    if (i2c == NULL)
        printf("Error in I2c_Init()\r\n");


    // ====== BusScan ======
    i2cScan(i2c);

    // ====== RTC Read and Write Example ======

    //  Override the default io which is defined by the portName "I2C1"..."I2C4"
    //  Io configurations need to be done *before* calling I2c_Open() !
    { /* Need to include gpio.h for uIo structure */
      uIo ioScl = COLIBRI_PIN(162); /*Colibri Pin 74*/
      uIo ioSda = COLIBRI_PIN(154); /*Colibri Pin 50*/
    //          /*  or  */
    //  uIo ioScl;
    //  uIo ioSda;
    //  ioScl.GenericDefinition = IOCOLIBRIPIN(74);
    //  ioSda.GenericDefinition = IOCOLIBRIPIN(50);
      returnValue = I2c_SetConfigInt(i2c, L"ioScl", ioScl.GenericDefinition, StoreVolatile);
      returnValue = I2c_SetConfigInt(i2c, L"ioSda", ioSda.GenericDefinition, StoreVolatile);
    }

    // Open the i2c port
    I2c_Open(i2c);

    // Change configuration as required
    // Instead of calling this function, you can place default values in the registry
    //   [HKLM\SOFTWARE\Toradex\I2C1]
    //   BitRateHz        = dword:00061a80             ; = decimal 400000
    //   SlaveAddrSize    = dword:00000007             ; = decimal 7
    //   RegisterAddrSize = dword:00000000             ; = decimal 0
    I2c_SetConfigInt(i2c, L"BitRateHz",         100000,  StoreVolatile);  // Set I2C speed to 400KHz
    I2c_SetConfigInt(i2c, L"SlaveAddrSize",    7,       StoreVolatile);  // Set 7 bit Slave address
    I2c_SetConfigInt(i2c, L"RegisterAddrSize", 0,       StoreVolatile);  // No Register address to send

    // Set RTC address into handle, it will be valid for all future Read/Write calls
    // 0x68 is the 7 bit address of the RTC present on Colibri Evaluation Board
    I2c_SetConfigInt(i2c, L"SlaveAddr", 0x68, StoreVolatile);

    // I2C Read
    returnValue = I2c_Read(i2c, (DWORD*) data, 8);

    printf("\nReading the RTC: %s\r\n", (returnValue == I2C_RW_FAILURE ? "failed." : "successful."));

    // I2C Write
    for (i = 0; i < 8; i++)
        data[i] = 0;

    returnValue = I2c_Write(i2c, (DWORD*) data, 8);
    printf("\nResetting the RTC: %s\r\n", (returnValue == I2C_RW_FAILURE ? "failed." : "successful."));

    // Close and deinit I2C port
    I2c_Close(i2c);
    I2c_Deinit(i2c);

    // Finish demo application
    printf("\nPress enter to exit");
    fflush(stdin);
    getchar();

    return(TRUE);
}

@chronic788 ,

Could you please comment i2cScan(i2c); and try. I2c_SetConfigInt for ioScl, ioSda parameters must be called before very first I2c_Open function. I2c pin alternate functionality will be set at very first I2c_Open and will be valid till calling I2c_Deinit. If you want to use different I2c pins of the same channel then call APIs below sequence

  • I2C-Init
  • Set ioScl, ioSda pins through I2c_SetConfigInt
  • I2c_open
  • Access I2C bus
  • I2c_Close
  • I2c-Deinit

Hi, whether you got the result?, since we are also facing the same issue

Hi @leninewinraja,

What is the problem you are facing?

Which port name you passed to the I2c_Init()?

Please check the I2C pin availability with the library help file (Toradex_CE_Libraries.chm) of the Toradex CE library version that you are using.

Also, please do check with the oscilloscope/logic analyzer whether you are getting any output waveform on the expected pin.