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.

TM4C123GE6PM: MPU6050 is stuck at MPU6050Init

Part Number: TM4C123GE6PM
Other Parts Discussed in Thread: TM4C123GH6PM

Hello,

I'm trying to communicate between the TM4C123G Launchpad and a GY52 breakout board with an MPU6050.
The sensor's I2C SDA is connected to PE4 and the SCL to PE5.
The sensor is powered from the 5V pin of Launchpad (an LDO converts the 5V to 3.3V to power the MPU6050).
Please see the attached photo:

Blue wire: SDA
Black wire: SCL
Red wire: 5V VCC
Green wire: GND

I tested to see that the board's LDO functions correctly and I measured exactly 3.3V.
I use the following code and run it line by line using F6 in CCS.
It gets stuck on the line with the MPU6050Init 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"

////////////////////////////////////////////////////////////////////////////////////////////////////
// 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"
#include "sensorlib/hw_mpu6050.h"
#define DEBUG

////////////////////////////////////////////////////////////////////////////////////////////////////
#include "definitions_mpu6050.h"
tI2CMInstance g_sI2CInst; // I2C master driver structure. "tI2CMInstance" is defined in the i2cm_drv.h file.
tMPU6050 g_sMPU6050Inst; // MPU6050 sensor driver structure. "tMPU6050" is defined in the mpu6050.h file.
volatile unsigned long g_vui8DataFlag; // Data ready flag
volatile unsigned long g_vui8ErrorFlag; // Error flag

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

    // Configure the clock
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

////////////////////////////////////////////////////////////////////////////////////////////////////
// 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);

    float fAccel[3], fGyro[3];

    // USER_MPU6050Callback will modify the g_bMPU6050Done variable to true if MPU6050Init succeeds.
    g_bMPU6050Done = false;
    // Initialize the MPU6050 
    MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS, USER_MPU6050Callback, &g_sMPU6050Inst);


    while(!g_bMPU6050Done) { }

    // USER_MPU6050Callback will modify the g_bMPU6050Done variable to true if MPU6050ReadModifyWrite succeeds.
    g_bMPU6050Done = false;
    // Configure the MPU6050 for +/- 4 g accelerometer range.
    MPU6050ReadModifyWrite(&g_sMPU6050Inst, MPU6050_O_ACCEL_CONFIG, ~MPU6050_ACCEL_CONFIG_AFS_SEL_M, MPU6050_ACCEL_CONFIG_AFS_SEL_4G, USER_MPU6050Callback, 0);
    while(!g_bMPU6050Done) { }

    while(1)
    {
    }
}

  • Hello Shai,

    You will need to get an oscilloscope to see what I2C communication is occurring. Make sure the right data is being sent, and also check the wave forms to make sure they are clean. Have you checked that the board you are communicating with has properly installed pullup resistors?
  • Hi,

    The board does have pull-ups installed.

    I'll check the signals with an oscilloscope...

    What about the code?  Does it look proper ?

  • I checked with an oscilloscope:
    I set the trigger to normal and used F6 to run the code.
    There's absolutely no change to on the SDA and SCL pins...

    The voltage is a stable 3.3V
  • Hello Shai,

    If SDA and SCL aren't changing then something is causing a hang before I2C data is sent out. If you pause the code, where does it pause at?

    As far as your code looking proper, nothing really sticks out to me as being wrong in the software. I do see you have setup your own Callback function. Can you try using the Callback function that comes with sensorlib and see if you get activity on the I2C lines with that modification?
  • You mean the static MPU6050Callback from mpu6050.c ?
  • Hello Shai,

    Looked into the Callback API's more and what I was thinking of wasn't actually from sensorlib itself but the examples made by using sensorlib.

    Basically a Callback like this, but for your device and not the MPU9150:

    //*****************************************************************************
    //
    // MPU9150 Sensor callback function.  Called at the end of MPU9150 sensor
    // driver transactions. This is called from I2C interrupt context. Therefore,
    // we just set a flag and let main do the bulk of the computations and display.
    //
    //*****************************************************************************
    void
    MPU9150AppCallback(void *pvCallbackData, uint_fast8_t ui8Status)
    {
        //
        // If the transaction succeeded set the data flag to indicate to
        // application that this transaction is complete and data may be ready.
        //
        if(ui8Status == I2CM_STATUS_SUCCESS)
        {
            g_vui8I2CDoneFlag = 1;
        }
    
        //
        // Store the most recent status in case it was an error condition
        //
        g_vui8ErrorFlag = ui8Status;
    }

  • That's what I thought...
    My USER_MPU6050Callback is exactly the same...

    Meanwhile, I had some progress.
    Following your suggestion, I paused the code and found it to hang in the interrupt handler function.
    The thing is - I modified the pins from the lab originals from PORTD to PORTE (I2C module #2 instead of #3).
    All my modifications to the main.c code where correct - but I forgot to change tm4c123gh6pm_startup_ccs.c
    This file still had I2C module #3 as the target...

    I changed tm4c123gh6pm_startup_ccs.c to handle interrupts for module #2 (instead of #3 originally).
    Once I F6 over MPU6050Init it no longer hangs and I see correct data being sent over the I2C lines.

    I encountered a new problem afterwards - but lets leave it for another thread.

    Thanks a lot for your help!
  • Hello Shai,

    Ahhh that makes sense then, I did notice you changed ports but didn't think to call out the startup_ccs.c file as something else to check out. Glad you were able to debug it that far on your end. Agreed that a new topic should get a new thread.