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.

Issues with TM4C/LM4F I2C 1 module



Hi,

I am using I2C 1 module of TM4C123H6PM to interface 24LC512 EEPROM. I am able to make I2C module work. However, the functionality is random and may times it fails to Write or Read data to/from external EEPROM. The addressing scheme is of 16bits to cover the full range of EEPROM.

The below code is not consistent. What am i missing??

Find below code:

void ConfigureI2C(void)
{
    //
    // Check the arguments.
    //
    ASSERT(I2CMasterBaseValid(I2C1_BASE));

    //
    // Enable Peripheral Clocks
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable pin PA7 for I2C1 I2C1SDA
    //
    MAP_GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    MAP_GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

    //
    // Enable pin PA6 for I2C1 I2C1SCL
    //
    MAP_GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    MAP_GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);    
}

unsigned char
I2CRegRead(unsigned long ulI2CBase, unsigned char ucSlaveAdress, _I2C_LOC_ADDR LocAddr)
{
	unsigned char ulRegValue = 0;

	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

    //
    // Tell the master module what address it will place on the bus when
    // writing to the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);

    //
    // Place the command to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_SEND);

    SysCtlDelay(1000);
    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
	// Place the command to be sent in the data register.
	//
	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);

	//
	// Initiate send of data from the master.
	//
	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_SEND);

	SysCtlDelay(1000);
	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

	//
	// Check for errors.
	//
	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
	{
		return 0;
	}

    //
    // Tell the master module what address it will place on the bus when
    // reading from the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 1);

    //
    // Tell the master to read data.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_RECEIVE);

//    SysCtlDelay(1000);

    //
    // Wait until master module is done receiving.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Read the data from the master.
    //
    ulRegValue = I2CMasterDataGet(ulI2CBase);

    //
    // Return the register value.
    //
    return ulRegValue;
}

unsigned long
I2CRegWrite(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
		_I2C_LOC_ADDR LocAddr, unsigned char ucValue)
{
	//
	// Check the arguments.
	//
	ASSERT(I2CMasterBaseValid(ulI2CBase));

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

    //
    // Tell the master module what address it will place on the bus when
    // writing to the slave.
    //
    I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);

    //
    // Place the command to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Place the value to be sent in the data register.
    //
    I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
	// Place the value to be sent in the data register.
	//
	I2CMasterDataPut(ulI2CBase, ucValue);

	//
	// Initiate send of data from the master.
	//
	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);

	//
	// Wait until master module is done transferring.
	//
	while(I2CMasterBusy(ulI2CBase))
	{
	};

	//
	// Check for errors.
	//
	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
	{
		return 0;
	}

    //
    // Initiate send of data from the master.
    //
    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_FINISH);

    //
    // Wait until master module is done transferring.
    //
    while(I2CMasterBusy(ulI2CBase))
    {
    };

    //
    // Check for errors.
    //
    if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }

    //
    // Return 1 if there is no error.
    //
    return 1;
}

void main(void )
{
    MAP_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    ConfigureI2C(I2C1_BASE, false);

    I2CLocAddr.val = 0x00;

    for(I2CLocAddr.val = 0; I2CLocAddr.val < 20; I2CLocAddr.val++)
    {
        I2CRegWrite(I2C1_BASE, 0x50, I2CLocAddr, 0xBB);
        _nop();
        SysCtlDelay(5000);
    }

    for(I2CLocAddr1.val = 0; I2CLocAddr1.val < 20; I2CLocAddr1.val++)
    {
        test1 = I2CRegRead(I2C1_BASE, 0x50, I2CLocAddr1);
        _nop();
        SysCtlDelay(5000);
    }
}



  • Hello Shrivardhan

    During Read command I am seeing that the transaction that is being generated are 2 independent write and 1 read instead of 2 write followed by a read with repeated start. Is this kind of transaction expected by the slave device?

    Please also do read the following I2C Application note to see what type of I2C transactions are produced for the different commands used in the I2CMasterControl API call.

    www.ti.com/.../spma073.pdf

    Regards
    Amit
  • Amit,
    Yes, that is the issue..

    I have I2C working code for addressing 8 bit registers map where as i need addressing for 16 bit register map..

    I tried to change and i am seeing this issue..

    I am interfacing 24LC512 EEPROM which has register address up to 64K.

    Any help of working code for 16 bit addressing???

    Regards,

    Shri
  • Amit,
    All example i could get shows only about 8 bit addressing and i am not ablew to make 16 bit addressing work without any issue..

    The i code i attached above writes to locations alternatively...

    Please help..

    Regards,

    Shri
  • Hello Shrivardhan,

    Please check the application note. The device being used also uses 16-bit address to access the FeRAM.

    Regards
    Amit
  • Amit,

    Any link to the application note???


    Regards,

    Shri

  • Amit,
    Thank you got the link.. However, i did not see any explanation regarding 16 bit in the pdf.
  • Thank you Amit.. It is working now...

    I am posting here the working code for 16 bit addressing.. It will be useful to developers like me..

    Your support appreciated...

    //*****************************************************************************
    //
    // I2C_Stellaris_API.c - Stellaris I2C Master Driver.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    // AUTHOR: JOERG QUINTEN
    // E2E-NICKNAME: aBUGSworstnightmare
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_gpio.h"
    #include "HardwareProfile.h"
    #include "inc/tm4c123gh6pz.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    
    #include "driverlib/timer.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/externfunction.h"
    #include "driverlib/i2c.h"
    #include "driverlib/debug.h"
    #include "HardwareProfile.h"
    #include "sysTimer.h"
    #include "drvPAN1026.h"
    #include "apiPAN1026.h"
    #include "drvBtUART.h"
    #include "pSystem.h"
    #include "apiStartup.h"
    #include "apiI2C.h"
    #include "drvI2C.h"
    
    //*****************************************************************************
    //
    //! \internal
    //! Checks a I2C master base address.
    //!
    //! \param ulI2CBase is the base address of the I2C Master module.
    //!
    //! This function determines if a I2C master module base address is valid.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Returns \b true if the base address is valid and \b false
    //! otherwise.
    //
    //*****************************************************************************
    #ifdef DEBUG
    static tBoolean
    I2CMasterBaseValid(unsigned long ulI2CBase)
    {
    	return(	(ulI2CBase == I2C0_MASTER_BASE) || (ulI2CBase == I2C1_MASTER_BASE) ||
    			(ulI2CBase == I2C2_MASTER_BASE) || (ulI2CBase == I2C3_MASTER_BASE));
    }
    #endif
    
    //*****************************************************************************
    //
    //! Initializes and enables the specified I2C block.
    //!
    //! \param ulI2CBase is the I2C peripheral to be used.
    //! \param ulI2CSpeed defines the normal (100kbps) or fast (400kbps) I2C mode.
    //!
    //! This function enables the specified I2C block and sets it up to run at
    //! the either 100kbps or 400kbps.  If the \e ulI2CSpeed is false, the I2C will
    //! run at 100kbps and if true, then the I2C will run at 400kbps.  The
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return None.
    //
    //*****************************************************************************
    void ConfigureI2C(unsigned long ulI2CBase, unsigned long ulI2CSpeed)
    {
        //
        // Check the arguments.
        //
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
        ASSERT((ulI2CSpeed == true) || (ulI2CSpeed == false));
    
        switch (ulI2CBase)
        {
    		// I2C_PERIPH_0
    		case  I2C0_BASE:
    		    //
    		    // I2C0 is used with PortB[3:2].  The actual port and
    		    // pins used may be different on your part, consult the data sheet for
    		    // more information.  GPIO port B needs to be enabled so these pins can
    		    // be used.
    		    //
    		    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
    		    //
    		    // Select the I2C function for these pins.  This function will also
    		    // configure the GPIO pins for I2C operation, setting them to
    		    // open-drain operation with weak pull-ups.  Consult the data sheet
    		    // to see which functions are allocated per pin.
    		    //
    		    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);	//	special I2CSCL treatment for M4F devices
    		    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
    		    //
    		    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    		    // This step is not necessary if your part does not support pin muxing.
    		    //
    		    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    		    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
    			//
    			// The I2C0 peripheral must be enabled before use.
    			//
    			SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    
    			//
    			// Enable and initialize the I2C0 master module.
    			//
    			I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed);
    			break;
    
    		// I2C_PERIPH_1
    		case  I2C1_BASE:
    //		    //
    //		    // I2C1 is used with PortA[7:6].  The actual port and
    //		    // pins used may be different on your part, consult the data sheet for
    //		    // more information.  GPIO port A needs to be enabled so these pins can
    //		    // be used.
    //		    //
    //		    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //
    //			//
    //			// The I2C1 peripheral must be enabled before use.
    //			//
    //			SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    //
    //		    //
    //		    // Select the I2C function for these pins.  This function will also
    //		    // configure the GPIO pins for I2C operation, setting them to
    //		    // open-drain operation with weak pull-ups.  Consult the data sheet
    //		    // to see which functions are allocated per pin.
    //		    //
    //		    GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);	//	special I2CSCL treatment for M4F devices
    //		    GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
    //
    //		    //
    //		    // Configure the pin muxing for I2C1 functions on port A6 and A7.
    //		    // This step is not necessary if your part does not support pin muxing.
    //		    //
    //		    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    //		    GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    //
    //			//
    //			// Enable and initialize the I2C1 master module.
    //			//
    //			I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
    
    			//
    			// Enable Peripheral Clocks
    			//
    			MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    			MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    			//
    			// Enable pin PA7 for I2C1 I2C1SDA
    			//
    			MAP_GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    			MAP_GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
    
    			//
    			// Enable pin PA6 for I2C1 I2C1SCL
    			//
    			MAP_GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    			MAP_GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    			I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
    			break;
    
    		// I2C_PERIPH_2
    		case  I2C2_BASE:
    		    //
    		    // I2C2 is used with PortE[5:4].  The actual port and
    		    // pins used may be different on your part, consult the data sheet for
    		    // more information.  GPIO port E needs to be enabled so these pins can
    		    // be used.
    		    //
    		    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    
    		    //
    		    // Select the I2C function for these pins.  This function will also
    		    // configure the GPIO pins for I2C operation, setting them to
    		    // open-drain operation with weak pull-ups.  Consult the data sheet
    		    // to see which functions are allocated per pin.
    		    //
    		    GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4);	//	special I2CSCL treatment for M4F devices
    		    GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5);
    
    		    //
    		    // Configure the pin muxing for I2C2 functions on port E4 and E5.
    		    // This step is not necessary if your part does not support pin muxing.
    		    //
    		    GPIOPinConfigure(GPIO_PE4_I2C2SCL);
    		    GPIOPinConfigure(GPIO_PE5_I2C2SDA);
    
    			//
    			// The I2C2 peripheral must be enabled before use.
    			//
    			SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
    
    			//
    			// Enable and initialize the I2C2 master module.
    			//
    			I2CMasterInitExpClk(I2C2_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed);
    			break;
    
    		// I2C_PERIPH_3
    		case  I2C3_BASE:
    		    //
    		    // I2C3 is used with PortD[1:0].  The actual port and
    		    // pins used may be different on your part, consult the data sheet for
    		    // more information.  GPIO port D needs to be enabled so these pins can
    		    // be used.
    		    //
    		    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    
    		    //
    		    // Select the I2C function for these pins.  This function will also
    		    // configure the GPIO pins for I2C operation, setting them to
    		    // open-drain operation with weak pull-ups.  Consult the data sheet
    		    // to see which functions are allocated per pin.
    		    //
    		    GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);	//	special I2CSCL treatment for M4F devices
    		    GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
    
    		    //
    		    // Configure the pin muxing for I2C2 functions on port D0 and D1.
    		    // This step is not necessary if your part does not support pin muxing.
    		    //
    		    GPIOPinConfigure(GPIO_PD0_I2C3SCL);
    		    GPIOPinConfigure(GPIO_PD1_I2C3SDA);
    
    			//
    			// The I2C3 peripheral must be enabled before use.
    			//
    			SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
    
    			//
    			// Enable and initialize the I2C3 master module.
    			//
    			I2CMasterInitExpClk(I2C3_MASTER_BASE, SysCtlClockGet(), ulI2CSpeed);
    			break;
    
        }
    }
    
    //*****************************************************************************
    //
    //! Reads the I2C slave register.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to read from.
    //!
    //! This function initiates a read from the slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Register value in an unsigned long format.  Note that 0 will be
    //! returned if there is ever an error, 1 if there was not.
    //
    //*****************************************************************************
    unsigned char
    I2CRegRead(unsigned long ulI2CBase, unsigned char ucSlaveAdress, _I2C_LOC_ADDR LocAddr)
    {
    	unsigned char ulRegValue = 0;
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
        //
        // Tell the master module what address it will place on the bus when
        // writing to the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
        //
        // Place the command to be sent in the data register.
        //
        I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
        SysCtlDelay(100);
        //
        // Wait until master module is done transferring.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    	SysCtlDelay(100);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
        //
        // Tell the master module what address it will place on the bus when
        // reading from the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 1);
    
        //
        // Tell the master to read data.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_RECEIVE);
        SysCtlDelay(100);
        //
        // Wait until master module is done receiving.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
        // Read the data from the master.
        //
        ulRegValue = I2CMasterDataGet(ulI2CBase);
    
        //
        // Return the register value.
        //
        return ulRegValue;
    }
    
    //*****************************************************************************
    //
    //! Writes to the specified I2C slave register.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to write data to.
    //! \param ucValue is the 8-bit data to be written.
    //!
    //! This function initiates a read from the I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Register value in an unsigned long format.  Note that 0 will be
    //! returned if there is ever an error, 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CRegWrite(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char ucValue)
    {
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// writing to the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, ucValue);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_FINISH);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }
    
    
    //*****************************************************************************
    //
    //! Reads one/multiple bytes of data from an I2C slave device.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to start reading from.
    //! \param cReadData is a pointer to the array to store the data.
    //! \param uiSize is the number of bytes to read from the slave.
    //!
    //! This function reads one/multiple bytes of data from an I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CReadData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char* cReadData, unsigned int uiSize)
    {
    	unsigned int uibytecount;		// local variable used for byte counting/state determination
    	int MasterOptionCommand;		// used to assign the commands for ROM_I2CMasterControl() function
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// writing to the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
        SysCtlDelay(1000);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//Extra
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	SysCtlDelay(1000);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// reading from the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, true);
    
    	//
    	// Start with BURST with more than one byte to write
    	//
    	MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_START;
    
    	for(uibytecount = 0; uibytecount < uiSize; uibytecount++)
    	{
    		//
    		// The second and intermittent byte has to be read with CONTINUE control word
    		//
    		if(uibytecount == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_CONT;
    
    		//
    		// The last byte has to be send with FINISH control word
    		//
    		if(uibytecount == uiSize - 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_FINISH;
    
    		//
    		// Re-configure to SINGLE if there is only one byte to read
    		//
    		if(uiSize == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_SINGLE_RECEIVE;
    
    		//
    		// Initiate read of data from the slave.
    		//
    		I2CMasterControl(ulI2CBase, MasterOptionCommand);
    
    		SysCtlDelay(1000);
    		//
    		// Wait until master module is done reading.
    		//
    		while(I2CMasterBusy(ulI2CBase))
    		{
    		};
    
    		//
            // Check for errors.
            //
            if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
            {
                return 0;
            }
    
            //
            // Move byte from register
            //
    		cReadData[uibytecount] = I2CMasterDataGet(ulI2CBase);
    	}
    
    	// send number of received bytes
    	return uibytecount;
    }
    
    //*****************************************************************************
    //
    //! Writes one/multiple bytes of data to an I2C slave device.
    //! Ensure to use auto-increment options on some devices
    //! (Control Registers, refer to data sheet).
    //! I.e. store related command in the first position of your data array.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to start writing to.
    //! \param cSendData is a pointer to the array to be send.
    //! \param uiSize is the number of bytes to send from array cSendData[].
    //!
    //! This function writes multiple bytes of data an I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CWriteData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char* cSendData, unsigned int uiSize)
    {
    	unsigned int uibytecount;		// local variable used for byte counting/state determination
    	int MasterOptionCommand;		// used to assign the commands for ROM_I2CMasterControl() function
    	unsigned char tmp;	//
    
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	SysCtlDelay(1000);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
        //
        // Tell the master module what address it will place on the bus when
        // writing to the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, false);
    
        //
        // Place the value to be sent in the data register.
        //
        I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
        SysCtlDelay(1000);
        //
        // Wait until master module is done transferring.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	SysCtlDelay(1000);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Start with CONT for more than one byte to write
    	//
    	MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;		//I2C_MASTER_CMD_BURST_SEND_CONT;
    
    	for(uibytecount = 0; uibytecount < uiSize; uibytecount++)
    	{
    		//
    		// The second and intermittent byte has to be send with CONTINUE control word
    		//
    		if(uibytecount == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;		//I2C_MASTER_CMD_BURST_SEND_CONT;
    
    		//
    		// The last byte has to be send with FINISH control word
    		//
    		if(uibytecount == uiSize - 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_FINISH;
    
    		//
    		// Re-configure to SINGLE if there is only one byte to write
    		//
    		if(uiSize == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_SINGLE_SEND;
    
    		tmp = cSendData[uibytecount];
    
    		//
    		// Send data byte
    		//
    		I2CMasterDataPut(ulI2CBase, cSendData[uibytecount]);
    
    		//
    		// Initiate send of data from the master.
    		//
    		I2CMasterControl(ulI2CBase, MasterOptionCommand);
    
    		SysCtlDelay(2000);
    		//
    		// Wait until master module is done transferring.
    		//
    		while(I2CMasterBusy(ulI2CBase))
    		{
    		};
    
    		//
            // Check for errors.
            //
            if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
            {
                return 0;
            }
    	}
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }
    
    //*****************************************************************************
    //
    //! Probes the selected I2C bus for available slave devices
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //!
    //! This function scans the selected I2C bus for available I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CBusScan(unsigned long ulI2CBase)
    {
    	unsigned char ucProbeAdress;
    	unsigned long ucerrorstate;
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// I2C Addresses are 7-bit values
    	// probe the address range of 0 to 127 to find I2C slave devices on the bus
    	//
    	for (ucProbeAdress = 0; ucProbeAdress < 127; ucProbeAdress++)
    	{
    	    //
    	    // Tell the master module what address it will place on the bus when
    	    // writing to the slave.
    	    //
    		I2CMasterSlaveAddrSet(ulI2CBase, ucProbeAdress, false);
    	    SysCtlDelay(50000);
    
    	    //
    	    // Place the command to be sent in the data register.
    	    //
    	    I2CMasterDataPut(ulI2CBase, 0x00);
    
    	    //
    	    // Initiate send of data from the master.
    	    //
    	    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
    	    //
    	    // Make some delay
    	    //
    	    SysCtlDelay(500000);
    
    	    //
    	    // Read the I2C Master Control/Status (I2CMCS) Register to a local
    	    // variable
    	    //
    	    ucerrorstate = I2CMasterErr(ulI2CBase);
    
    	    //
    	    // Examining the content I2C Master Control/Status (I2CMCS) Register
    	    // to see if the ADRACK-Bit (Acknowledge Address) is TRUE (1)
    	    // ( 1: The transmitted address was not acknowledged by the slave)
    	    //
    	    if(ucerrorstate & I2C_MASTER_ERR_ADDR_ACK)
    	    {
    	    	//
    	    	// device at selected address did not acknowledge --> there's no device
    	    	// with this address present on the I2C bus
    	    	//
    	        //
    	        // Print a message to Stdio
    	        //
    	    	//UARTprintf("Address not found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);
    		    //
    		    // Make some delay
    		    //
    	    	//ROM_SysCtlDelay(1500000);
    	    }
    
    	    //
    	    // ( 0: The transmitted address was acknowledged by the slave)
    	    //
    	    else
    	    {
    	    	//
    	    	// device at selected address acknowledged --> there is a device
    	    	// with this address present on the I2C bus
    	    	//
    	        //
    	        // Print a message to Stdio
    	        //
    //	    	UARTprintf("Address found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);
    
    		    //
    		    // Make some delay
    		    //
    	    	SysCtlDelay(1500000);
    	    }
    	}
    
    	//
    	// End transfer of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
        //
        // Print a message to Stdio
        //
    //	UARTprintf("I2C Bus-Scan done...\n");
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }

  • Posting final code:

    drvI2C.c

    //*****************************************************************************
    //
    // I2C_Stellaris_API.c - Stellaris I2C Master Driver.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    // AUTHOR: JOERG QUINTEN
    // E2E-NICKNAME: aBUGSworstnightmare
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_gpio.h"
    #include "HardwareProfile.h"
    #include "inc/tm4c123gh6pz.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    
    #include "driverlib/timer.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/uart.h"
    #include "driverlib/externfunction.h"
    #include "driverlib/i2c.h"
    #include "driverlib/debug.h"
    #include "HardwareProfile.h"
    #include "sysTimer.h"
    #include "drvPAN1026.h"
    #include "apiPAN1026.h"
    #include "drvBtUART.h"
    #include "pSystem.h"
    #include "apiStartup.h"
    #include "apiI2C.h"
    #include "drvI2C.h"
    
    //*****************************************************************************
    //
    //! \internal
    //! Checks a I2C master base address.
    //!
    //! \param ulI2CBase is the base address of the I2C Master module.
    //!
    //! This function determines if a I2C master module base address is valid.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Returns \b true if the base address is valid and \b false
    //! otherwise.
    //
    //*****************************************************************************
    #ifdef DEBUG
    static tBoolean
    I2CMasterBaseValid(unsigned long ulI2CBase)
    {
    	return(	(ulI2CBase == I2C0_MASTER_BASE) || (ulI2CBase == I2C1_MASTER_BASE) ||
    			(ulI2CBase == I2C2_MASTER_BASE) || (ulI2CBase == I2C3_MASTER_BASE));
    }
    #endif
    
    //*****************************************************************************
    //
    //! Initializes and enables the specified I2C block.
    //!
    //! \param ulI2CBase is the I2C peripheral to be used.
    //! \param ulI2CSpeed defines the normal (100kbps) or fast (400kbps) I2C mode.
    //!
    //! This function enables the specified I2C block and sets it up to run at
    //! the either 100kbps or 400kbps.  If the \e ulI2CSpeed is false, the I2C will
    //! run at 100kbps and if true, then the I2C will run at 400kbps.  The
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return None.
    //
    //*****************************************************************************
    void ConfigureI2C1(void)
    {
        //
        // Check the arguments.
        //
    	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    	MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    	//
    	// Enable pin PA7 for I2C1 I2C1SDA
    	//
    	MAP_GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    	MAP_GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
    
    	//
    	// Enable pin PA6 for I2C1 I2C1SCL
    	//
    	MAP_GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    	MAP_GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    	I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
    }
    
    //*****************************************************************************
    //
    //! Reads the I2C slave register.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to read from.
    //!
    //! This function initiates a read from the slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Register value in an unsigned long format.  Note that 0 will be
    //! returned if there is ever an error, 1 if there was not.
    //
    //*****************************************************************************
    unsigned char
    I2CRegRead(unsigned long ulI2CBase, unsigned char ucSlaveAdress, _I2C_LOC_ADDR LocAddr)
    {
    	unsigned char ulRegValue = 0;
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
        //
        // Tell the master module what address it will place on the bus when
        // writing to the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
        //
        // Place the command to be sent in the data register.
        //
        I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
        //
        // Wait until master module is done transferring.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
        //
        // Tell the master module what address it will place on the bus when
        // reading from the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 1);
    
        //
        // Tell the master to read data.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_SINGLE_RECEIVE);
        //
        // Wait until master module is done receiving.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
        // Read the data from the master.
        //
        ulRegValue = I2CMasterDataGet(ulI2CBase);
    
        //
        // Return the register value.
        //
        return ulRegValue;
    }
    
    //*****************************************************************************
    //
    //! Writes to the specified I2C slave register.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to write data to.
    //! \param ucValue is the 8-bit data to be written.
    //!
    //! This function initiates a read from the I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return Register value in an unsigned long format.  Note that 0 will be
    //! returned if there is ever an error, 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CRegWrite(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char ucValue)
    {
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// writing to the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, ucValue);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_FINISH);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }
    
    
    //*****************************************************************************
    //
    //! Reads one/multiple bytes of data from an I2C slave device.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to start reading from.
    //! \param cReadData is a pointer to the array to store the data.
    //! \param uiSize is the number of bytes to read from the slave.
    //!
    //! This function reads one/multiple bytes of data from an I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CReadData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char* cReadData, unsigned int uiSize)
    {
    	unsigned int uibytecount;		// local variable used for byte counting/state determination
    	int MasterOptionCommand;		// used to assign the commands for ROM_I2CMasterControl() function
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// writing to the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, 0);
    
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//Extra
    	//
    	// Place the command to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Tell the master module what address it will place on the bus when
    	// reading from the slave.
    	//
    	I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, true);
    
    	//
    	// Start with BURST with more than one byte to write
    	//
    	MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_START;
    
    	for(uibytecount = 0; uibytecount < uiSize; uibytecount++)
    	{
    		//
    		// The second and intermittent byte has to be read with CONTINUE control word
    		//
    		if(uibytecount == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_CONT;
    
    		//
    		// The last byte has to be send with FINISH control word
    		//
    		if(uibytecount == uiSize - 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_RECEIVE_FINISH;
    
    		//
    		// Re-configure to SINGLE if there is only one byte to read
    		//
    		if(uiSize == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_SINGLE_RECEIVE;
    
    		//
    		// Initiate read of data from the slave.
    		//
    		I2CMasterControl(ulI2CBase, MasterOptionCommand);
    
    		//
    		// Wait until master module is done reading.
    		//
    		while(I2CMasterBusy(ulI2CBase))
    		{
    		};
    
    		//
            // Check for errors.
            //
            if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
            {
                return 0;
            }
    
            //
            // Move byte from register
            //
    		cReadData[uibytecount] = I2CMasterDataGet(ulI2CBase);
    	}
    
    	// send number of received bytes
    	return uibytecount;
    }
    
    //*****************************************************************************
    //
    //! Writes one/multiple bytes of data to an I2C slave device.
    //! Ensure to use auto-increment options on some devices
    //! (Control Registers, refer to data sheet).
    //! I.e. store related command in the first position of your data array.
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //! \param ucSlaveAdress is the 7-bit address of the slave to be addressed.
    //! \param ucReg is the register to start writing to.
    //! \param cSendData is a pointer to the array to be send.
    //! \param uiSize is the number of bytes to send from array cSendData[].
    //!
    //! This function writes multiple bytes of data an I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CWriteData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char* cSendData, unsigned int uiSize)
    {
    	unsigned int uibytecount;		// local variable used for byte counting/state determination
    	int MasterOptionCommand;		// used to assign the commands for ROM_I2CMasterControl() function
    
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
        //
        // Tell the master module what address it will place on the bus when
        // writing to the slave.
        //
        I2CMasterSlaveAddrSet(ulI2CBase, ucSlaveAdress, false);
    
        //
        // Place the value to be sent in the data register.
        //
        I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.HIGHBYTE);
    
        //
        // Initiate send of data from the master.
        //
        I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
        //
        // Wait until master module is done transferring.
        //
        while(I2CMasterBusy(ulI2CBase))
        {
        };
    
        //
        // Check for errors.
        //
        if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
        {
            return 0;
        }
    
        //
    	// Place the value to be sent in the data register.
    	//
    	I2CMasterDataPut(ulI2CBase, LocAddr.SPLIT.LOWBYTE);
    
    	//
    	// Initiate send of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_CONT);
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// Check for errors.
    	//
    	if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
    	{
    		return 0;
    	}
    
    	//
    	// Start with CONT for more than one byte to write
    	//
    	MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;		//I2C_MASTER_CMD_BURST_SEND_CONT;
    
    	for(uibytecount = 0; uibytecount < uiSize; uibytecount++)
    	{
    		//
    		// The second and intermittent byte has to be send with CONTINUE control word
    		//
    		if(uibytecount == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_CONT;		//I2C_MASTER_CMD_BURST_SEND_CONT;
    
    		//
    		// The last byte has to be send with FINISH control word
    		//
    		if(uibytecount == uiSize - 1)
    			MasterOptionCommand = I2C_MASTER_CMD_BURST_SEND_FINISH;
    
    		//
    		// Re-configure to SINGLE if there is only one byte to write
    		//
    		if(uiSize == 1)
    			MasterOptionCommand = I2C_MASTER_CMD_SINGLE_SEND;
    
    		//
    		// Send data byte
    		//
    		I2CMasterDataPut(ulI2CBase, cSendData[uibytecount]);
    
    		//
    		// Initiate send of data from the master.
    		//
    		I2CMasterControl(ulI2CBase, MasterOptionCommand);
    
    		//
    		// Wait until master module is done transferring.
    		//
    		while(I2CMasterBusy(ulI2CBase))
    		{
    		};
    
    		//
            // Check for errors.
            //
            if(I2CMasterErr(ulI2CBase) != I2C_MASTER_ERR_NONE)
            {
                return 0;
            }
    	}
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }
    
    //*****************************************************************************
    //
    //! Probes the selected I2C bus for available slave devices
    //!
    //! \param ulI2CBase is the base for the I2C module.
    //!
    //! This function scans the selected I2C bus for available I2C slave device.
    //! The ulI2CBase parameter is the I2C modules master base address.
    //! \e ulI2CBase parameter can be one of the following values:
    //!
    //! - \b I2C0_MASTER_BASE
    //! - \b I2C1_MASTER_BASE
    //! - \b I2C2_MASTER_BASE
    //! - \b I2C3_MASTER_BASE
    //!
    //! \return 0 if there was an error or 1 if there was not.
    //
    //*****************************************************************************
    unsigned long
    I2CBusScan(unsigned long ulI2CBase)
    {
    	unsigned char ucProbeAdress;
    	unsigned long ucerrorstate;
    
    	//
    	// Check the arguments.
    	//
    	ASSERT(I2CMasterBaseValid(ulI2CBase));
    
    	//
    	// Wait until master module is done transferring.
    	//
    	while(I2CMasterBusy(ulI2CBase))
    	{
    	};
    
    	//
    	// I2C Addresses are 7-bit values
    	// probe the address range of 0 to 127 to find I2C slave devices on the bus
    	//
    	for (ucProbeAdress = 0; ucProbeAdress < 127; ucProbeAdress++)
    	{
    	    //
    	    // Tell the master module what address it will place on the bus when
    	    // writing to the slave.
    	    //
    		I2CMasterSlaveAddrSet(ulI2CBase, ucProbeAdress, false);
    	    SysCtlDelay(50000);
    
    	    //
    	    // Place the command to be sent in the data register.
    	    //
    	    I2CMasterDataPut(ulI2CBase, 0x00);
    
    	    //
    	    // Initiate send of data from the master.
    	    //
    	    I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_SEND_START);
    
    	    //
    	    // Make some delay
    	    //
    	    SysCtlDelay(500000);
    
    	    //
    	    // Read the I2C Master Control/Status (I2CMCS) Register to a local
    	    // variable
    	    //
    	    ucerrorstate = I2CMasterErr(ulI2CBase);
    
    	    //
    	    // Examining the content I2C Master Control/Status (I2CMCS) Register
    	    // to see if the ADRACK-Bit (Acknowledge Address) is TRUE (1)
    	    // ( 1: The transmitted address was not acknowledged by the slave)
    	    //
    	    if(ucerrorstate & I2C_MASTER_ERR_ADDR_ACK)
    	    {
    	    	//
    	    	// device at selected address did not acknowledge --> there's no device
    	    	// with this address present on the I2C bus
    	    	//
    	        //
    	        // Print a message to Stdio
    	        //
    	    	//UARTprintf("Address not found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);
    		    //
    		    // Make some delay
    		    //
    	    	//ROM_SysCtlDelay(1500000);
    	    }
    
    	    //
    	    // ( 0: The transmitted address was acknowledged by the slave)
    	    //
    	    else
    	    {
    	    	//
    	    	// device at selected address acknowledged --> there is a device
    	    	// with this address present on the I2C bus
    	    	//
    	        //
    	        // Print a message to Stdio
    	        //
    //	    	UARTprintf("Address found: 0x%2x - %3d\n",ucProbeAdress,ucProbeAdress);
    
    		    //
    		    // Make some delay
    		    //
    	    	SysCtlDelay(1500000);
    	    }
    	}
    
    	//
    	// End transfer of data from the master.
    	//
    	I2CMasterControl(ulI2CBase, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
        //
        // Print a message to Stdio
        //
    //	UARTprintf("I2C Bus-Scan done...\n");
    
        //
        // Return 1 if there is no error.
        //
        return 1;
    }

    drvI2C.h

    //*****************************************************************************
    //
    // I2C_Stellaris_API.h - Stellaris I2C Master Driver.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT, UNDER
    // ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    // AUTHOR: JOERG QUINTEN
    // E2E-NICKNAME: aBUGSworstnightmare
    //
    //*****************************************************************************
    
    #ifndef DRV_I2C_H
    #define DRV_I2C_H
    
    //*****************************************************************************
    //
    // Additional Defines for the API.
    //
    //*****************************************************************************
    
    typedef union
    {
        unsigned int val;
    
        struct //SPLIT
        {
        	unsigned char LOWBYTE;
        	unsigned char HIGHBYTE;
        }SPLIT;
    }_I2C_LOC_ADDR;
    
    typedef union
    {
        unsigned int val;
    
        struct //SPLIT
        {
        	unsigned char LOWBYTE;
        	unsigned char HIGHBYTE;
        }SPLIT;
    }_U16BIT;
    
    //*****************************************************************************
    //
    // Prototypes for the APIs.
    //
    //*****************************************************************************
    // setup code for all I2C modules present on the LM4F120E5QR
    extern void ConfigureI2C1(void);
    
    // functions for writing/reading single bytes of data
    extern unsigned char I2CRegRead(unsigned long ulI2CBase,
    								unsigned char ucSlaveAdress,
    								_I2C_LOC_ADDR LocAddr);
    
    extern unsigned long I2CRegWrite(unsigned long ulI2CBase,
    								unsigned char ucSlaveAdress,
    								_I2C_LOC_ADDR LocAddr,
                                    unsigned char ucValue);
    
    // functions for writing/reading multiple bytes of data
    extern unsigned long I2CReadData(unsigned long ulI2CBase, unsigned char ucSlaveAdress,
    		_I2C_LOC_ADDR LocAddr, unsigned char* cReadData, unsigned int uiSize);
    
    unsigned long I2CWriteData(unsigned long ulI2CBase,
    								unsigned char ucSlaveAdress,
    								_I2C_LOC_ADDR LocAddr,
    								unsigned char* cSendData,
    								unsigned int uiSize);
    
    unsigned long I2CBusScan(unsigned long ulI2CBase);
    
    #endif /* I2C_STELLARIS_API_H_ */
    

    main.c

    arry1[0] = 0xAA;
    	arry1[1] = 0x11;
    	arry1[2] = 0x89;
    	arry1[3] = 0xFE;
    	arry1[4] = 0x6A;
    	arry1[5] = 0xDC;
    
    	_nop();
    	I2CLocAddr.val = 0x10;
    	I2CWriteData(I2C1_BASE, 0x50, I2CLocAddr, arry1, 5);
    	_nop();
    
    	//Read
    	I2CLocAddr.val = 0x10;
    	I2CReadData(I2C1_BASE, 0x50, I2CLocAddr, arry2, 5);
    	_nop();
    	_nop();

  • Hello Shrivardhan,

    The application note path was given in the first post and if you go through the application code that is downloadable, it shows how to use 16-bit address. By the way in I2C terms there is nothing called 16 bit address. The 16 bit address that is used to access the external device is treated as a data by I2C.

    Regards
    Amit