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.

Tiva Launchpad communication over I2C

I"m trying to communicate with a unique serial number chip (Microchip Part # 24AA02UID) and not sure what I'm doing wrong.  I'm using the Tiva Launchpad as a Master and the chip as the slave.  The process for getting data is to initially write a memory address of where you want to start reading, then send a read request and it will send back data starting from the sent memory address.  A known address and value is the read only manufacturing code stored at 0XFA with a value of 0x29.

I not sure if I'm writing or reading incorrectly, or if I just addressing the slave wrong (default is B1010000).  Simplified code I'm using below.  Right now it's spitting out 0x00 for everything which is really nothing.

#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

void
PortFunctionInit(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    // Enable pin PB2 for I2C0 I2C0SCL
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);

    // Enable pin PB3 for I2C0 I2C0SDA
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    // Enable pin PA0 for UART0 U0RX
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);

    // Enable pin PA1 for UART0 U0TX
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1);
}


//*****************************************************************************
// Main code starts here
//*****************************************************************************
int main(void)
{
	// Set the clocking to run directly from the crystal.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    		SYSCTL_XTAL_16MHZ);

	// Initialize and setup the ports
    PortFunctionInit();
	UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    UARTStdioConfig(0, 115200, 16000000);

    UARTprintf("\r\nUART working...\r\n");

    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    I2CMasterSlaveAddrSet(I2C0_BASE, 0b1010000, false);
    while(I2CMasterBusBusy(I2C0_BASE)) {}
    I2CMasterDataPut(I2C0_BASE, 0xFA);
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

	I2CMasterSlaveAddrSet(I2C0_BASE, 0b1010000, true);
	while(I2CMasterBusBusy(I2C0_BASE)) {}
	uint32_t data = I2CMasterDataGet(I2C0_BASE);
	UARTprintf("0x%02X", data);

    // Loop forever while the timers run.
	while(1)
	{
	}
}

  • Hello Brandon,

    Look at the addressing part in the following application note

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

    Also the 2nd I2CMasterBusBusy is not correct. After you send the first data you need to put I2CMasterBusy. For the second transaction there is no command there for the I2C controller to process

    Regards
    Amit
  • I finally got everything working.  The trick was adding 1 kOhm pull up resistors from SCL and SDA to +3.3V and getting all the function calls included.  As usual, it makes sense now that it's working.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    // Slave address is binary 1010000 or hex 50.
    // Eigth bit is defined as part Tx or Rx
    #define SLAVE_ADDRESS 0B1010000
    
    //*****************************************************************************
    // Port initilization
    //*****************************************************************************
    void PortFunctionInit(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        // Enable pin PB2 for I2C0 I2C0SCL
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    
        // Enable pin PB3 for I2C0 I2C0SDA
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
        // Enable pin PA0 for UART0 U0RX
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);
    
        // Enable pin PA1 for UART0 U0TX
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1);
    }
    
    
    //*****************************************************************************
    // Main code starts here
    //*****************************************************************************
    int main(void)
    {
    	// Set the clocking to run directly from the crystal.
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
        		SYSCTL_XTAL_16MHZ);
    
    	// Initialize and setup the ports
        PortFunctionInit();
    	UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
        UARTStdioConfig(0, 115200, 16000000);
    
        UARTprintf("\r\nUART working...\r\n");
    
        I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    
        I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);
        I2CMasterDataPut(I2C0_BASE, 0xFA);
        I2CMasterControl(I2C0_BASE,I2C_MASTER_CMD_SINGLE_SEND);
        while(I2CMasterBusy(I2C0_BASE));
    
    	I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, true);
    	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
        while(I2CMasterBusy(I2C0_BASE));
    	uint32_t data = I2CMasterDataGet(I2C0_BASE);
    	UARTprintf("0x%02X", data);
    
        // Loop forever
    	while(1)
    	{
    	}
    }
    

  • Hello Brandon,

    Was the application note useful?

    Regards
    Amit
  • Yes, between that and more forum searches, everything works now.