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.

Compiler/TM4C1231H6PM: Compilation fails due to "unresolved symbol I2CMInit"

Part Number: TM4C1231H6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Tool/software: TI C/C++ Compiler

Hello,

The code below compiled well until I added the "I2CMInit" function:

////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#include <stdint.h>
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"

#define PWM_FREQUENCY 55

////////////////////////////////////////////////////////////////////////////////////////////////////
// My I2C defines & includes
#include "driverlib/i2c.h"
#include "driverlib/interrupt.h"
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
#include "sensorlib/i2cm_drv.h"
#include "sensorlib/mpu6050.h"
#define DEBUG
#define I2C_ADDRESS 0x68

tI2CMInstance g_sI2CInst; // I2C master driver structure

////////////////////////////////////////////////////////////////////////////////////////////////////
// My UART defines & includes
#include "driverlib/uart.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{

////////////////////////////////////////////////////////////////////////////////////////////////////
// My I2C initialization code

    // Enable GPIO peripheral that contains I2C 2
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    // Enable I2C module 2
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);

    // Configure the pin muxing for I2C2 functions on port E4 and E5.
    GPIOPinConfigure(GPIO_PE4_I2C2SCL);
    GPIOPinConfigure(GPIO_PE5_I2C2SDA);

    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4);
    GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5);

    IntMasterEnable();

    I2CMInit(&g_sI2CInst, I2C2_BASE, INT_I2C2, 0xFF, 0xFF, SysCtlClockGet());
    SysCtlDelay(SysCtlClockGet() / 3);

////////////////////////////////////////////////////////////////////////////////////////////////////
// My UART initialization code
    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    UARTCharPut(UART0_BASE, 'U');
    UARTCharPut(UART0_BASE, 'A');
    UARTCharPut(UART0_BASE, 'R');
    UARTCharPut(UART0_BASE, 'T');
    UARTCharPut(UART0_BASE, ' ');
    UARTCharPut(UART0_BASE, 'W');
    UARTCharPut(UART0_BASE, 'o');
    UARTCharPut(UART0_BASE, 'r');
    UARTCharPut(UART0_BASE, 'k');
    UARTCharPut(UART0_BASE, 's');

////////////////////////////////////////////////////////////////////////////////////////////////////

    volatile uint32_t ui32Load;
    volatile uint32_t ui32PWMClock;
    volatile uint8_t ui8Adjust;
    ui8Adjust = 83;

//  This command is already used for setting the UART and is therefore omitted.
//  SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

    SysCtlPWMClockSet(SYSCTL_PWMDIV_64);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinConfigure(GPIO_PD0_M1PWM0);

    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
    GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN);
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

    ui32PWMClock = SysCtlClockGet() / 64;
    ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
    PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);

    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
    PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
    PWMGenEnable(PWM1_BASE, PWM_GEN_0);

    while(1)
    {
// A bunch of lies...
    }

}

Now, it fails with the following error:

unresolved symbol I2CMInit, first referenced in ./main.obj PID C/C++ Problem

I searched the forum for the error and found this post - suggesting to install an older version of the compiler:

Before I do that - is there something I can change in the code to make it work with my current version ?

I'm using CCS Version: 7.1.0.00016 and TivaWare 2.1.4.178

  • Hi,

     Did you have a chance to look at the TivaWare I2C example in <TivaWare_Installation>/examples/peripherals/i2c folder? Below is the snippet of code to initialize the I2C0 for loopback mode.

        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    
        //
        // For this example 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.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        //
        // 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.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
        //
        // Select the I2C function for these pins.  This function will also
        // configure the GPIO pins 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.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
        //
        // Enable loopback mode.  Loopback mode is a built in feature that is
        // useful for debugging I2C operations.  It internally connects the I2C
        // master and slave terminals, which effectively let's you send data as
        // a master and receive data as a slave.
        // NOTE: For external I2C operation you will need to use external pullups
        // that are stronger than the internal pullups.  Refer to the datasheet for
        // more information.
        //
        I2CLoopbackEnable(I2C0_BASE);
    
        //
        // Enable and initialize the I2C0 master module.  Use the system clock for
        // the I2C0 module.  The last parameter sets the I2C data transfer rate.
        // If false the data rate is set to 100kbps and if true the data rate will
        // be set to 400kbps.  For this example we will use a data rate of 100kbps.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        I2CMasterInitExpClk(I2C0_BASE, ui32SysClock, false);
    #else
        I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    #endif
    
        //
        // Enable the I2C0 slave module. This module is enabled only for testing
        // purposes.  It does not need to be enabled for proper operation of the
        // I2Cx master module.
        //
        I2CSlaveEnable(I2C0_BASE);
    
        //
        // Set the slave address to SLAVE_ADDRESS.  In loopback mode, it's an
        // arbitrary 7-bit number (set in a macro above) that is sent to the
        // I2CMasterSlaveAddrSet function.
        //
        I2CSlaveInit(I2C0_BASE, SLAVE_ADDRESS);
    
        //
        // Tell the master module what address it will place on the bus when
        // communicating with the slave.  Set the address to SLAVE_ADDRESS
        // (as set in the slave module).  The receive parameter is set to false
        // which indicates the I2C Master is initiating a writes to the slave.  If
        // true, that would indicate that the I2C Master is initiating reads from
        // the slave.
        //
        I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);

  • If you want to use I2CMInit which is part of the sensorlib you need to link the library. See below.

  • Why wasn't this step necessary for "driverlib.lib" ?
    I use it it too...
  • The driverlib.lib is normally included already in the linker include search path. For sensorlib it is not included in the searchpath by default. You need to include it if you want to use it.
  • Thanks for helping.
    Where can I see what's included and what's not ?
  • If you start off with a simple TivaWare example such as hello or any examples under <TivaWare_Installation>/examples/boards/ek-tm4c123gxl then these projects are built to only include driverlib.lib but not other libraries as there is no need for these examples to reference other libraries but the driverlib.lib. Let's say you are creating a new project that needs to make use of the graphical library, you will need include the <TivaWare_Installation>/grlib/ccs/Debug/grlib.lib in the Linker's search path. If you were to reference the graphic examples projects in <TivaWare_Installation>/examples/boards//ek-tm4c123gxl -boostxl-kentec-s1 then you would have noticed that the grlib.lib is already specified in the search path. Likewise, if you were to try out the examples under <TivaWare_Installation>/examples/ek-tm4c123gxl-boostxl-senshub then you will see that the sensorlib.lib is specified in the Linker search path in the projects as these projects use the sensorlib.lib.
  •  I added the search path and it compiles - but now I get this warning:

    warning #10247-D: creating output section "i.I2CMInit" without a SECTIONS specification""

  • Please refer to the image I attached before. You need both the driverlib.lib and the sensorlib.lib. You are missing the driverlib.lib. Fix this issue first.