Stellaris LaunchPad working I2C code example

I tried using Stellaris LaunchPad evaluation board (EK-LM4F120XL) with I2C communication and I had a trouble. I'd like to show you a working I2C code example here to avoid wasting time.

The reason of the difficulty was that the Launch Pad I2C pins for booster pack were shared with other GPIO pins in the default configuration. Therefore you need to configure the pins in right way.

See the function SetupI2C() below.


#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_uart.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_i2c.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "driverlib/i2c.h"
#include "utils/ustdlib.h"
#include "utils/uartstdio.h"

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define I2C_SLAVE_ADDRESS       0x60

/*****************************************************************************/
/* This function returns:
 * I2C_MASTER_ERR_NONE, I2C_MASTER_ERR_ADDR_ACK, I2C_MASTER_ERR_DATA_ACK, or
 * I2C_MASTER_ERR_ARB_LOST.
 */
static unsigned long WaitI2CDone( unsigned int long ulBase){
    // Wait until done transmitting
    while( I2CMasterBusy(I2C3_MASTER_BASE));
    // Return I2C error code
    return I2CMasterErr( I2C3_MASTER_BASE);
}

static void SetupI2C(){
    /***
     * Shared Pin Setting
     */
    // You need to set the shared pins as input.
    GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    // Change the pad configuration to WPU
    GPIOPadConfigSet( GPIO_PORTB_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD_WPU);

    /***
     * I2C Setting
     */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0); //  special I2CSCL treatment for M4F devices
    GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);

    GPIOPinConfigure(GPIO_PD0_I2C3SCL);
    GPIOPinConfigure(GPIO_PD1_I2C3SDA);

    SysCtlPeripheralEnable( SYSCTL_PERIPH_I2C3);

    I2CMasterInitExpClk( I2C3_MASTER_BASE, SysCtlClockGet(), false);
    SysCtlDelay(10000);
}


int main(void) {
    uint8_t data = 0;
    int16_t i2c_err = I2C_MASTER_ERR_NONE;

    //
    // Setup the system clock to run at 50 Mhz from PLL with crystal reference
    //
    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|
                    SYSCTL_OSC_MAIN);
    SysCtlDelay(10000);

    SetupI2C();

    /** Send register address.
     */
    I2CMasterSlaveAddrSet( I2C3_MASTER_BASE, I2C_SLAVE_ADDRESS, false);   // false = write, true = read
    // Set register address of AK8963
    I2CMasterDataPut( I2C3_MASTER_BASE, 0x00);
    // Start sending data
    I2CMasterControl( I2C3_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    WaitI2CDone( I2C3_MASTER_BASE);

    /** Set read mode.
     */
    I2CMasterSlaveAddrSet( I2C3_MASTER_BASE, I2C_SLAVE_ADDRESS, true);   // false = write, true = read

    /** Single Read
     */
    I2CMasterControl( I2C3_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    if( (i2c_err = WaitI2CDone( I2C3_MASTER_BASE)))
        data = 0xff;
    else
        data = I2CMasterDataGet(I2C3_MASTER_BASE);

    return 0;
}


Raspberry Pi Power Monitor

Power Consumption Monitor using Raspberry Pi Sometimes I get tired of using test equipment to monitor the current and/or power...