none
Unable to set I2C2 in SLAVE MODE (IMX51 EVK + WCE700 BSP + iMX51_EVK_MOBILITY OSDesign ) Description: RRS feed

  • Question

  • We are using Freescale IMx51 EVK dev. kit and IMX51 EVK
    MOBILITY Software(WCE700 BSP and iMX51_EVK_Mobility
    OSDesign) provided by freescale.


    ---------------------------------------------------------------------------
    BACKGROUND AND THE HARDWARE SETUP
    ---------------------------------------------------------------------------
    Our product setup is as below:
    1. The iMX51 EVK is connected to a daughter board that has
    an Infenion XE164 microcontroller.
    2. The iMX processor and the XE164 uController,
    communicate over I2C Bus. We are using I2C2 module of the
    iMX.

    -------------------------------------
    PROBLEM
    -------------------------------------
    1. When the iMX is a Master and we send data to XE164,
    things are fine.
    2. But now, we want to have a multi-master I2C configuration,
    so that both the iMX and the XE164 can send data to each
    other.

    Here we are facing a problem. As to have multi-master setup,
    we need to put the iMX in slave mode when it has nothing to
    send. (Basically iMX should default to SLAVE mode).

    We are UNABLE to set the iMX I2C2 peripheral in slave mode
    using the I2CSDK.dll.

    Below is the code listing of what we have been trying to do:
            >       Initially we check whether iMX is in SLAVE or
    MASTER mode. We get to know that it is is MASTER MODE.
            >       Then we try to enable the slave mode by calling the
    "I2CEnableSlave()" API, which works fine.
            >       Then we call the "I2CSetSlaveMode()" API which
    FAILS.


    Am I going wrong somewhere? How can I setup the iMX in
    Slave Mode?

    Regards,

    Nicoal Thomas

    Monday, January 21, 2013 8:27 AM

Answers

  • I2CSDK.dll is a wrapper for the I2C driver and most calls are implemented as DeviceIoControl: calling GetLastError() may give you some more information about why I2CSetSlaveMode returns FALSE.

    By the way from the SDK documentation I read: "I2CSetSlaveMode [...] is for back compatibility. Use I2CEnableSlave instead"


    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com


    Monday, January 21, 2013 11:09 AM
  • Hi Luca, thanks for your suggestion. i have tried using I2CenableSlave function to set the module to slave mode. It says it has set successfully but when we try to set the self address to the module it won't get set.. this happens only when it is in master mode. I have disabled all other modules which were accessing I2C2. i will attach the code snippet to make it clear. 

    hLib =  LoadLibrary(TEXT("\\Windows\\i2csdk.dll") );
        if(hLib == NULL)
        {
            error = GetLastError();
            RETAILMSG(1, ( TEXT("LoadLibrary FAIL error = %d"), error ) );
        }
        else
            RETAILMSG(1, ( TEXT("handle to the library successfully created %d"), __LINE__ ) );
        
        hI2C = I2COpenHandle( _T("I2C2:") ); //opens the handle
        if( (hI2C == INVALID_HANDLE_VALUE) || (hI2C == NULL) )
        {
            RETAILMSG( TRUE, (_T("Failed to Open Handle to I2C2")));
            return -1;
        }
     retVal=I2CEnableSlave(hI2C);
        if(retVal==TRUE)
        {
            RETAILMSG(TRUE,(_T("I2C slave access is enabled")));
        }
    	else
    	{
            RETAILMSG(TRUE,(_T("I2C slave access is disabled")));
        }
    
        //Check whether the salve mode has been set or NOT
    	retVal = I2CIsSlave( hI2C, &isSlave );
        if( retVal  == FALSE )
        {
            RETAILMSG( TRUE, (_T("Failed to query Slave mode")));
            return -1;
        }
        if( isSlave == FALSE )
        {
            RETAILMSG( TRUE, (_T("Failed to Set Slave mode, read-back failed") ) );
            return -1;
        }
    	else
    	{
            RETAILMSG( TRUE, (_T("Slave mode set successfully") ) );
        }
    
    	//Set I2C frequency
        retVal = I2CSetFrequency( hI2C, (DWORD)I2C_ADAPTER_FREQUENCY );
        if( retVal  == FALSE )
        {
            ERRORMSG( TRUE, (_T("Failed to set I2C frequency") ));
            return -1;
        }
    	else if(retVal  == TRUE)
    	{
            RETAILMSG( TRUE, (_T("I2C frequency set to 100kbps") ));
        }
    retVal=I2CSetSelfAddr(hI2C,SELFADD);
    	if(retVal==TRUE)
        {
            RETAILMSG(TRUE,(_T("I2C SelfAddr is enabled")));
        }
    	else
    	{
            RETAILMSG(TRUE,(_T("I2C SelfAddr is failed to enable")));   
    	}
    	retVal=I2CGetSelfAddr(hI2C,&BySelfadd);
    	if(retVal==TRUE)
    	{
    		RETAILMSG(TRUE,(_T("I2C SelfAddr got successfully")));
    		RETAILMSG(TRUE,(_T("I2C SelfAddr is 0x%X",BySelfadd)));
    		
    	}
    	else
    	{
    		RETAILMSG(TRUE,(_T("Failed to get I2C SelfAddr")));
    	}

    I get all messages saying successful but i don't get the desired slave address value when i use I2CGetSelfAddr()... can u tell me why it is happening and one more question is there in  my mind.. should i use I2C packet and I2CTransfer function for slave read and write operation or not?

    Regards,

    Nicoal Thomas

    • Marked as answer by Nicoal Thomas Friday, January 3, 2014 11:03 AM
    Monday, January 21, 2013 12:30 PM

All replies

  • I2CSDK.dll is a wrapper for the I2C driver and most calls are implemented as DeviceIoControl: calling GetLastError() may give you some more information about why I2CSetSlaveMode returns FALSE.

    By the way from the SDK documentation I read: "I2CSetSlaveMode [...] is for back compatibility. Use I2CEnableSlave instead"


    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com


    Monday, January 21, 2013 11:09 AM
  • Hi Luca, thanks for your suggestion. i have tried using I2CenableSlave function to set the module to slave mode. It says it has set successfully but when we try to set the self address to the module it won't get set.. this happens only when it is in master mode. I have disabled all other modules which were accessing I2C2. i will attach the code snippet to make it clear. 

    hLib =  LoadLibrary(TEXT("\\Windows\\i2csdk.dll") );
        if(hLib == NULL)
        {
            error = GetLastError();
            RETAILMSG(1, ( TEXT("LoadLibrary FAIL error = %d"), error ) );
        }
        else
            RETAILMSG(1, ( TEXT("handle to the library successfully created %d"), __LINE__ ) );
        
        hI2C = I2COpenHandle( _T("I2C2:") ); //opens the handle
        if( (hI2C == INVALID_HANDLE_VALUE) || (hI2C == NULL) )
        {
            RETAILMSG( TRUE, (_T("Failed to Open Handle to I2C2")));
            return -1;
        }
     retVal=I2CEnableSlave(hI2C);
        if(retVal==TRUE)
        {
            RETAILMSG(TRUE,(_T("I2C slave access is enabled")));
        }
    	else
    	{
            RETAILMSG(TRUE,(_T("I2C slave access is disabled")));
        }
    
        //Check whether the salve mode has been set or NOT
    	retVal = I2CIsSlave( hI2C, &isSlave );
        if( retVal  == FALSE )
        {
            RETAILMSG( TRUE, (_T("Failed to query Slave mode")));
            return -1;
        }
        if( isSlave == FALSE )
        {
            RETAILMSG( TRUE, (_T("Failed to Set Slave mode, read-back failed") ) );
            return -1;
        }
    	else
    	{
            RETAILMSG( TRUE, (_T("Slave mode set successfully") ) );
        }
    
    	//Set I2C frequency
        retVal = I2CSetFrequency( hI2C, (DWORD)I2C_ADAPTER_FREQUENCY );
        if( retVal  == FALSE )
        {
            ERRORMSG( TRUE, (_T("Failed to set I2C frequency") ));
            return -1;
        }
    	else if(retVal  == TRUE)
    	{
            RETAILMSG( TRUE, (_T("I2C frequency set to 100kbps") ));
        }
    retVal=I2CSetSelfAddr(hI2C,SELFADD);
    	if(retVal==TRUE)
        {
            RETAILMSG(TRUE,(_T("I2C SelfAddr is enabled")));
        }
    	else
    	{
            RETAILMSG(TRUE,(_T("I2C SelfAddr is failed to enable")));   
    	}
    	retVal=I2CGetSelfAddr(hI2C,&BySelfadd);
    	if(retVal==TRUE)
    	{
    		RETAILMSG(TRUE,(_T("I2C SelfAddr got successfully")));
    		RETAILMSG(TRUE,(_T("I2C SelfAddr is 0x%X",BySelfadd)));
    		
    	}
    	else
    	{
    		RETAILMSG(TRUE,(_T("Failed to get I2C SelfAddr")));
    	}

    I get all messages saying successful but i don't get the desired slave address value when i use I2CGetSelfAddr()... can u tell me why it is happening and one more question is there in  my mind.. should i use I2C packet and I2CTransfer function for slave read and write operation or not?

    Regards,

    Nicoal Thomas

    • Marked as answer by Nicoal Thomas Friday, January 3, 2014 11:03 AM
    Monday, January 21, 2013 12:30 PM