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.

Piccolo I2C Corruption with MPU-6050

Other Parts Discussed in Thread: TMS320F28027

Hi,

I am trying to communicate with MPU6050 through F28027 Piccolo.  I've read almost all I2C related topics in the forum but I could find answer to corruption problem which I stucked. I've set I2C and I imported MPU-6050 headers. Communication starts well but after a while it is being corrupted. 

SCL stays HIGH and SDA stays LOW. After that, even I restartted program or reload, I could not continue communication. Power off/on is restart it. 

Code is below. Any help would be very appreciated. 

Thanks

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "sensorlib/hw_mpu6050.h"

void   I2CA_Init(void);
uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData);
uint16_t I2CA_ReadData(uint16_t readReg, int ind);

__interrupt void timerRoutine(void);

int initGyro(void);
void initGPIOsSpecific(void);

#define I2C_SLAVE_ADDR        0x68
#define I2C_NUMBYTES          2

#define GYRO_INIT_DONE		  0x3001
#define GYRO_WRITE_DONE		  0x3002
#define GYRO_READ_DONE		  0x3003
#define XRDY_STAT			  0x3004
#define RRDY_STAT			  0x3005
#define ARDY_STAT		  	  0x3006
#define SCD_STAT			  0x3007

#define i2clooplim 			  5000

uint16_t I2C_STATS = 0;

uint16_t whoAmI;
uint16_t gyroData[3][2];
uint16_t accelData[3][2];


void main(void)
{

// WARNING: Always ensure you call memcpy before running any functions from RAM
// InitSysCtrl includes a call to a RAM based function and without a call to
// memcpy first, the processor will go "into the weeds"
   #ifdef _FLASH
	memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
   #endif


// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the f2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO:
// This example function is found in the f2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//   InitGpio();
// Setup only the GP I/O only for I2C functionality
   InitI2CGpio();


// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the f2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in f2802x_DefaultIsr.c.
// This function is found in f2802x_PieVect.c.
   InitPieVectTable();

   EALLOW;
   GpioCtrlRegs.GPADIR.bit.GPIO0 =1;
   GpioCtrlRegs.GPADIR.bit.GPIO1 =1;
   EDIS;

   /*
// Copy time critical code and Flash setup code to RAM
// This includes the following ISR functions InitFlash();
   memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

// Call Flash Initialization to setup flash waitstates this function must reside in RAM
   InitFlash();
   */


// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   //EALLOW;  // This is needed to write to EALLOW protected registers
   //PieVectTable.I2CINT1A = &i2c_int1a_isr;
   //EDIS;   // This is needed to disable write to EALLOW protected registers

   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.TINT0 = &timerRoutine;
   EDIS;


   InitCpuTimers();
   ConfigCpuTimer(&CpuTimer0, 60, 1000);  				// TINT0	// 1ms Timer	>> Includes main function
   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0


// Enable interrupts required for this example

// Enable I2C interrupt 1 in the PIE: Group 1 interrupt 1
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;          			// Enable the PIE block
   IER |= M_INT1;

   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;					// Enable TINT0 in the PIE: Group 1 interrupt 7


   // Step 4. Initialize all the Device Peripherals:
   // This function is found in f2802x_InitPeripherals.c
   // InitPeripherals(); // Not required for this example
   I2CA_Init();


   I2C_STATS = initGyro();
   DELAY_US(1000);


   EINT;   // Enable Global interrupt INTM
   ERTM;   // Enable Global realtime interrupt DBGM


   // Application loop
   for(;;)
   {

   }
}   // end of main

__interrupt void timerRoutine(void)
{
	CpuTimer0.InterruptCount++;

	if(CpuTimer0.InterruptCount%64 == 0){
		//GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;
		//GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1;

		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_XOUT_L, 1);
		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_XOUT_H, 2);
		/*
		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_YOUT_L, 3);
		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_YOUT_H, 4);
		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_ZOUT_L, 5);
		I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_ZOUT_H, 6);


		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_XOUT_L, 7);
		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_XOUT_H, 8);
		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_YOUT_L, 9);
		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_YOUT_H, 10);
		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_ZOUT_L, 11);
		I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_ZOUT_H, 12);
		*/
	}
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


void I2CA_Init(void)
{
    // Initialize I2C
    I2caRegs.I2CMDR.bit.IRS  = 0;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR;        			// Slave address
    I2caRegs.I2CPSC.all = 5;       						// Prescaler - need 7-12 Mhz on module clk

    I2caRegs.I2CCLKL = 10;           					// NOTE: must be non zero
    I2caRegs.I2CCLKH = 5;            					// NOTE: must be non zero
    I2caRegs.I2CIER.all = 0x3E;      					//
    //I2caRegs.I2CIER.all = 0x00;

    I2caRegs.I2CMDR.bit.IRS = 1;	    				// Take I2C out of reset
                                    					// Stop I2C when suspended
    I2caRegs.I2CFFTX.all = 0x0000;   					// Disable TXFIFO
    I2caRegs.I2CFFRX.all = 0x0000;   					// Disable RXFIFO

    DELAY_US(50000);
    return;
}



int initGyro(void)
{
	//I2CA_WriteData(MPU6050_O_PWR_MGMT_1, 0x00);
	I2CA_WriteData(MPU6050_O_PWR_MGMT_1, MPU6050_PWR_MGMT_1_CLKSEL_XG);
	//I2CA_WriteData(MPU6050_O_SMPLRT_DIV, 0x07);
	//I2CA_WriteData(MPU6050_O_CONFIG, 0x06);
	I2CA_WriteData(MPU6050_O_GYRO_CONFIG,MPU6050_GYRO_CONFIG_FS_SEL_250);
	I2CA_WriteData(MPU6050_O_ACCEL_CONFIG,MPU6050_ACCEL_CONFIG_AFS_SEL_2G);
	I2CA_WriteData(MPU6050_O_PWR_MGMT_1, 0x00);
	I2CA_ReadData(MPU6050_O_WHO_AM_I,0);

	DELAY_US(5000);
    return GYRO_INIT_DONE;
}

uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData)
{
	uint16_t lim = 0;

	//I2caRegs.I2CMDR.bit.IRS = 1;

	I2caRegs.I2CSAR = I2C_SLAVE_ADDR; 					//Set slave address
	I2caRegs.I2CCNT = 2;
	I2caRegs.I2CDXR = writeReg;
	I2caRegs.I2CMDR.bit.TRX = 1; 						//Set to Transmit mode
	I2caRegs.I2CMDR.bit.MST = 1; 						//Set to Master mode
	I2caRegs.I2CMDR.bit.FREE = 1;						//Run in FREE mode
	I2caRegs.I2CMDR.bit.STP = 1; 						//Stop when internal counter becomes 0
	I2caRegs.I2CMDR.bit.STT = 1; 						//Send the start bit, transmission will follow


	while(I2caRegs.I2CSTR.bit.XRDY == 0){
		lim++;	   			if(lim>=i2clooplim) 		break;
	};
	if(lim>=i2clooplim)		I2C_STATS = XRDY_STAT;
	else					I2C_STATS = XRDY_STAT;

	I2caRegs.I2CDXR = writeData; 						//Send out the message


    return GYRO_WRITE_DONE;
}

uint16_t I2CA_ReadData(uint16_t readReg, int ind)
{
	uint16_t lim = 0;

	//I2caRegs.I2CMDR.bit.IRS = 1;

	I2caRegs.I2CSAR = I2C_SLAVE_ADDR; 					//Set slave address
    I2caRegs.I2CCNT = 1; 								//Set count to 2 address bytes
    I2caRegs.I2CDXR = readReg;							//Register to be read
    I2caRegs.I2CMDR.bit.TRX = 1; 						//Set to Transmit mode
    I2caRegs.I2CMDR.bit.MST = 1; 						//Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1;						//Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 0; 						//Dont release the bus after Tx
    I2caRegs.I2CMDR.bit.STT = 1; 						//Send the start bit, transmission will follow

    while(I2caRegs.I2CSTR.bit.XRDY == 0){				//Do nothing till data is shifted out
    	lim++;			    	if(lim>=i2clooplim) break;
    };

    if(lim>=i2clooplim)     	I2C_STATS = XRDY_STAT;
    else					  	I2C_STATS = I2C_SUCCESS;

    lim = 0;

    I2caRegs.I2CCNT = 1;								//read 1 bytes from device
    I2caRegs.I2CMDR.bit.TRX = 0; 						//Set to Recieve mode
    I2caRegs.I2CMDR.bit.MST = 1; 						//Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1;						//Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 1; 						//Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; 						//Repeated start, Reception will follow


    while(I2caRegs.I2CSTR.bit.RRDY == 0){				//I2CDRR not ready to read?
    	lim++;
    	if(lim>=i2clooplim) break;
    }
    if(lim>=i2clooplim)
    	I2C_STATS = RRDY_STAT;
    else
    	I2C_STATS = I2C_SUCCESS;

    if(ind == 0)
    	whoAmI = I2caRegs.I2CDRR;

    switch (ind) {
    	case 1:  accelData[0][0] = I2caRegs.I2CDRR;	break;
    	case 2:  accelData[0][1] = I2caRegs.I2CDRR;  break;
    	case 3:  accelData[1][0] = I2caRegs.I2CDRR;	break;
		case 4:  accelData[1][1] = I2caRegs.I2CDRR;  break;
		case 5:  accelData[2][0] = I2caRegs.I2CDRR;	break;
		case 6:  accelData[2][1] = I2caRegs.I2CDRR;  break;
		case 7:  gyroData[0][0]  = I2caRegs.I2CDRR;	break;
		case 8:  gyroData[0][1]  = I2caRegs.I2CDRR;  break;
		case 9:  gyroData[1][0]  = I2caRegs.I2CDRR;	break;
		case 10: gyroData[1][1]  = I2caRegs.I2CDRR;  break;
		case 11: gyroData[2][0]  = I2caRegs.I2CDRR;	break;
		case 12: gyroData[2][1]  = I2caRegs.I2CDRR;  break;
		default: break;
    }

    I2C_STATS = I2C_SUCCESS;
    DELAY_US(100);
    /*
    for(i = 0; i < numBytes; i++) {
		while(I2caRegs.I2CSTR.bit.RRDY == 0){			//I2CDRR not ready to read?
			I2C_STATS = RRDY_STAT;
		};
		I2C_STATS = I2C_SUCCESS;
		RxdData[i] = I2caRegs.I2CDRR;
    }
    */

    return GYRO_READ_DONE;
}


  • Have you tried switching the order of lines 265-266?

    I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow

    If you write STP first, I think you get a stop condition followed by a normal start condition. Please let me know if that doesn't work and I'll investigate further.

    Thanks,
  • I think there is something different. Same code sometimes works sometimes not.
    For now, I could not get any reply, even "whoAmI" byte.

    I changed the order of bit settings but nothing has changed.
    If I set I2CMDR register as byte, would it better or not?

    I am using GPIO32 / GPIO33 which internal pullups are disabled and MPU6050 with breakout board which has 4.7k pullup resistors.
    It seems, Piccolo could not get SDA or SCL pins low when it is needed.
    Does it change to replace higher value resistors on pullups?

    Thank you
  • If the code sometimes works, I suspect there's no software problem. Can you please post an oscilloscope capture of the SDA and SCL signals during a transmission?

    Thanks,
  • Sorry for delayed reply.

    Problem has solved.
    I have 4.7k pullup resistors on SDA and SCL. When I looked at with oscilloscope, I saw, SCL could not be taken low. I increased to 10k pullup and it seems working.

    Thanks for your help

  • hi, im a student and i wanna read a mpu6050 with the library embedded coder from matlab/simulink


    i will make the program to read the mpu6050 in simulink and using the ccs 3.3 make the .c files and .h files


    can you write to me an email? i have some problems with i2c comunication, i will send you the code that generate the ccs

    alfregomezdelga@hotmail.com

    thank you very much 

  • actually i dont think its a good method to read mpu6050 through simulink.
    but i would try to help
  • Hi,
    i am trying to use your code with c2000 picolo tms320f28027 and the MPU 9150 (invensense, its MPU6050 with more utilities) but i have problems to send and recieve information. I have connected the SDA and SCLA to GPIO28 and GPIO29 and Vddto3v3 and gnd to gnd.
    I put breakpoints when the code is at the function writedataI2c... and my results are:
    uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData)
    {
    uint16_t lim = 0;

    //I2caRegs.I2CMDR.bit.IRS = 1;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
    I2caRegs.I2CCNT = 2;
    I2caRegs.I2CDXR = writeReg;
    I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
    I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow


    while(I2caRegs.I2CSTR.bit.XRDY == 0){ //-------->>>>Never XRDY bit is '1' , always '0' ,the information never pass to I2CXSR register
    lim++; if(lim>=i2clooplim) break;
    };
    if(lim>=i2clooplim) I2C_STATS = XRDY_STAT;//------->>>> Always go here
    else I2C_STATS = XRDY_STAT;

    I2caRegs.I2CDXR = writeData; //Send out the message


    return GYRO_WRITE_DONE;
    }

    i have trying with 0x68 and 0x69 addrees... but it is not work
    The NACK bit is always '1' because i think never is connected to MPU9150....
    PD: i dont have external pull up , i conected a wire between the conections
    Thanks in advance
  • Hi,
    i am trying to use your code with c2000 picolo tms320f28027 and the MPU 9150 (invensense, its MPU6050 with more utilities) but i have problems to send and recieve information. I have connected the SDA and SCLA to GPIO28 and GPIO29 and Vddto3v3 and gnd to gnd.
    I put breakpoints when the code is at the function writedataI2c... and my results are:
    uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData)
    {
    uint16_t lim = 0;

    //I2caRegs.I2CMDR.bit.IRS = 1;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
    I2caRegs.I2CCNT = 2;
    I2caRegs.I2CDXR = writeReg;
    I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
    I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow


    while(I2caRegs.I2CSTR.bit.XRDY == 0){ //-------->>>>Never XRDY bit is '1' , always '0' ,the information never pass to I2CXSR register
    lim++; if(lim>=i2clooplim) break;
    };
    if(lim>=i2clooplim) I2C_STATS = XRDY_STAT;//------->>>> Always go here
    else I2C_STATS = XRDY_STAT;

    I2caRegs.I2CDXR = writeData; //Send out the message


    return GYRO_WRITE_DONE;
    }

    i have trying with 0x68 and 0x69 addrees... but it is not work
    The NACK bit is always '1' because i think never is connected to MPU9150....
    PD: i have external pull up 2k2, i conected a wire between the conections
    Thanks in advance
  • Please try 10K pull-ups.

    Also firstly try to get reply to "Who Am I" byte

  • I changed the pull-ups, but it doesnt work... i thinks it is because i use mpu9150 and the code is for mpu6150... i haven´t recieved nothing at "who am i" byte and i dont know where is the trouble.... i have seen step by step the code and i havent found the trouble... please help me! :)
    I put the whole code but its the same code...

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    #include "DSP28x_Project.h" // Device Headerfile and Examples Include File
    #include "hw_mpu6050.h"

    void I2CA_Init(void);
    uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData);
    uint16_t I2CA_ReadData(uint16_t readReg, int ind);

    __interrupt void timerRoutine(void);

    int initGyro(void);
    void initGPIOsSpecific(void);



    #define I2C_SLAVE_ADDR 0x68
    #define I2C_NUMBYTES 2

    #define GYRO_INIT_DONE 0x3001
    #define GYRO_WRITE_DONE 0x3002
    #define GYRO_READ_DONE 0x3003
    #define XRDY_STAT 0x3004
    #define RRDY_STAT 0x3005
    #define ARDY_STAT 0x3006
    #define SCD_STAT 0x3007

    #define i2clooplim 5000

    uint16_t I2C_STATS = 0;

    uint16_t whoAmI;
    uint16_t gyroData[3][2];
    uint16_t accelData[3][2];


    void main(void)
    {

    // WARNING: Always ensure you call memcpy before running any functions from RAM
    // InitSysCtrl includes a call to a RAM based function and without a call to
    // memcpy first, the processor will go "into the weeds"
    #ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif



    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the f2802x_SysCtrl.c file.
    InitSysCtrl();

    // Step 2. Initalize GPIO:
    // This example function is found in the f2802x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();
    // Setup only the GP I/O only for I2C functionality
    InitI2CGpio();


    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    DINT;

    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the f2802x_PieCtrl.c file.
    InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in f2802x_DefaultIsr.c.
    // This function is found in f2802x_PieVect.c.
    InitPieVectTable();

    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO0 =1;
    GpioCtrlRegs.GPADIR.bit.GPIO1 =1;
    EDIS;

    /*
    // Copy time critical code and Flash setup code to RAM
    // This includes the following ISR functions InitFlash();
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

    // Call Flash Initialization to setup flash waitstates this function must reside in RAM
    InitFlash();
    */


    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //EALLOW; // This is needed to write to EALLOW protected registers
    //PieVectTable.I2CINT1A = &i2c_int1a_isr;
    //EDIS; // This is needed to disable write to EALLOW protected registers

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.TINT0 = &timerRoutine;
    EDIS;


    InitCpuTimers();
    ConfigCpuTimer(&CpuTimer0, 60, 1000); // TINT0 // 1ms Timer >> Includes main function
    CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0


    // Enable interrupts required for this example

    // Enable I2C interrupt 1 in the PIE: Group 1 interrupt 1
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    IER |= M_INT1;

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE: Group 1 interrupt 7


    // Step 4. Initialize all the Device Peripherals:
    // This function is found in f2802x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
    I2CA_Init();


    I2C_STATS = initGyro();
    DELAY_US(1000);


    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM


    // Application loop
    for(;;)
    {

    }
    } // end of main

    __interrupt void timerRoutine(void)
    {
    CpuTimer0.InterruptCount++;

    if(CpuTimer0.InterruptCount%64 == 0){
    //GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;
    //GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1;

    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_XOUT_L, 1);
    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_XOUT_H, 2);
    /*
    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_YOUT_L, 3);
    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_YOUT_H, 4);
    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_ZOUT_L, 5);
    I2C_STATS = I2CA_ReadData(MPU6050_O_ACCEL_ZOUT_H, 6);


    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_XOUT_L, 7);
    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_XOUT_H, 8);
    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_YOUT_L, 9);
    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_YOUT_H, 10);
    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_ZOUT_L, 11);
    I2C_STATS = I2CA_ReadData(MPU6050_O_GYRO_ZOUT_H, 12);
    */
    }
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }


    void I2CA_Init(void)
    {
    // Initialize I2C
    I2caRegs.I2CMDR.bit.IRS = 0;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR; // Slave address
    I2caRegs.I2CPSC.all = 5; // Prescaler - need 7-12 Mhz on module clk

    I2caRegs.I2CCLKL = 60; // NOTE: must be non zero
    I2caRegs.I2CCLKH = 30; // NOTE: must be non zero
    I2caRegs.I2CIER.all = 0x3E; //
    //I2caRegs.I2CIER.all = 0x00;

    I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset
    // Stop I2C when suspended
    I2caRegs.I2CFFTX.all = 0x0000; // Disable TXFIFO
    I2caRegs.I2CFFRX.all = 0x0000; // Disable RXFIFO

    DELAY_US(50000);
    return;
    }



    int initGyro(void)
    {
    //I2CA_WriteData(MPU6050_O_PWR_MGMT_1, 0x00);
    I2CA_WriteData(MPU6050_O_PWR_MGMT_1, MPU6050_PWR_MGMT_1_CLKSEL_XG);
    //I2CA_WriteData(MPU6050_O_SMPLRT_DIV, 0x07);
    //I2CA_WriteData(MPU6050_O_CONFIG, 0x06);
    I2CA_WriteData(MPU6050_O_GYRO_CONFIG,MPU6050_GYRO_CONFIG_FS_SEL_250);
    I2CA_WriteData(MPU6050_O_ACCEL_CONFIG,MPU6050_ACCEL_CONFIG_AFS_SEL_2G);
    I2CA_WriteData(MPU6050_O_PWR_MGMT_1, 0x00);
    I2CA_ReadData(MPU6050_O_WHO_AM_I,0);

    DELAY_US(5000);
    return GYRO_INIT_DONE;
    }

    uint16_t I2CA_WriteData(uint16_t writeReg, uint16_t writeData)
    {
    uint16_t lim = 0;

    //I2caRegs.I2CMDR.bit.IRS = 1;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
    I2caRegs.I2CCNT = 2;
    I2caRegs.I2CDXR = writeReg;
    I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
    I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow


    while(I2caRegs.I2CSTR.bit.XRDY == 0){
    lim++; if(lim>=i2clooplim) break;
    };
    if(lim>=i2clooplim) I2C_STATS = XRDY_STAT;
    else I2C_STATS = XRDY_STAT;

    I2caRegs.I2CDXR = writeData; //Send out the message


    return GYRO_WRITE_DONE;
    }

    uint16_t I2CA_ReadData(uint16_t readReg, int ind)
    {
    uint16_t lim = 0;

    //I2caRegs.I2CMDR.bit.IRS = 1;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
    I2caRegs.I2CCNT = 1; //Set count to 2 address bytes
    I2caRegs.I2CDXR = readReg; //Register to be read
    I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
    I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
    I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow

    while(I2caRegs.I2CSTR.bit.XRDY == 0){ //Do nothing till data is shifted out
    lim++; if(lim>=i2clooplim) break;
    };

    if(lim>=i2clooplim) I2C_STATS = XRDY_STAT;
    else I2C_STATS = I2C_SUCCESS;

    lim = 0;

    I2caRegs.I2CCNT = 1; //read 1 bytes from device
    I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
    I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
    I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
    I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
    I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow


    while(I2caRegs.I2CSTR.bit.RRDY == 0){ //I2CDRR not ready to read?
    lim++;
    if(lim>=i2clooplim) break;
    }
    if(lim>=i2clooplim)
    I2C_STATS = RRDY_STAT;
    else
    I2C_STATS = I2C_SUCCESS;

    if(ind == 0)
    whoAmI = I2caRegs.I2CDRR;

    switch (ind) {
    case 1: accelData[0][0] = I2caRegs.I2CDRR; break;
    case 2: accelData[0][1] = I2caRegs.I2CDRR; break;
    case 3: accelData[1][0] = I2caRegs.I2CDRR; break;
    case 4: accelData[1][1] = I2caRegs.I2CDRR; break;
    case 5: accelData[2][0] = I2caRegs.I2CDRR; break;
    case 6: accelData[2][1] = I2caRegs.I2CDRR; break;
    case 7: gyroData[0][0] = I2caRegs.I2CDRR; break;
    case 8: gyroData[0][1] = I2caRegs.I2CDRR; break;
    case 9: gyroData[1][0] = I2caRegs.I2CDRR; break;
    case 10: gyroData[1][1] = I2caRegs.I2CDRR; break;
    case 11: gyroData[2][0] = I2caRegs.I2CDRR; break;
    case 12: gyroData[2][1] = I2caRegs.I2CDRR; break;
    default: break;
    }

    I2C_STATS = I2C_SUCCESS;
    DELAY_US(100);
    /*
    for(i = 0; i < numBytes; i++) {
    while(I2caRegs.I2CSTR.bit.RRDY == 0){ //I2CDRR not ready to read?
    I2C_STATS = RRDY_STAT;
    };
    I2C_STATS = I2C_SUCCESS;
    RxdData[i] = I2caRegs.I2CDRR;
    }
    */

    return GYRO_READ_DONE;
    }
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Thanks in advance , Rodrigo
  • change #define I2C_SLAVE_ADDR 0x68


    to #define I2C_SLAVE_ADDR 0x69

    the slave addres change if the pin AD0 is conected in Vcc or in GND, for default that pin are in GND and the address is 0x69


    i use pullups of 10k

  • Hi! i proved with both values... but when i try to send data, i always recieve a NACK... my register I2CSTR is 0001010000000110... i believe that it means that The slave is unable to accept the data. No such slave, command not understood, or unable to accept any more data...

    I also chage this lines of code:

    void I2CA_Init(void)
    {
        // Initialize I2C
        I2caRegs.I2CMDR.bit.IRS  = 0;

        I2caRegs.I2CSAR = I2C_SLAVE_ADDR;                   // Slave address
        I2caRegs.I2CPSC.all = 5;                            // Prescaler - need 7-12 Mhz on module clk

        I2caRegs.I2CCLKL = 10;                              // NOTE: must be non zero
        I2caRegs.I2CCLKH = 5;                               // NOTE: must be non zero
        I2caRegs.I2CIER.all = 0x3E;                         //
        //I2caRegs.I2CIER.all = 0x00;

        I2caRegs.I2CMDR.bit.IRS = 1;                        // Take I2C out of reset
                                                            // Stop I2C when suspended
        I2caRegs.I2CFFTX.all = 0x0000;                      // Disable TXFIFO
        I2caRegs.I2CFFRX.all = 0x0000;                      // Disable RXFIFO

        DELAY_US(50000);
        return;
    }

    Please help!!

    Thanks in advance, Rodrigo

  • Thanks to everyone!! I found my troubles, the firts one it´s that gpi28,29 doesn´t work in i2c mode... i change to gpi32,33... and the second one is the slave address is wrong in the data sheet..... the address with int-->gnd is 0x69 and not 0x68 like said the datasheet...

    Now i have a new problem.. i connected to mpu9150 but the device only send my zeros... i dont know why because i prove with arduino code and arduino device and all its ok(it is not a problem of device)... i think it is a code problem...Can help me?? What do you think about it?? Someone with this problem??

    Thanks in advance, Rodrigo

  • Hi


    In my case i use simulink to make i2c communication, that mean that i write and the i2c registers in dec... in your case is the same but the registers you write in hex


    i suggest to write in the register 127 to reset the MPU and write 0 ( 127 in dec, you need use hex ej: 0X7F (register) and write 0x0) to reset the values of your mpu


    i suppose that you use i2c.write or something like that. you need:

    -Reset
    -Configure the scale of the acc and gyro (if you dont do, will work with the default values)

    -say to the mpu to give you datas (in my case is write to the register 59 in dec, in your case is 0x3B)

    -read the values, i think that you will use i2c.read 0x3B or something like that, they will give you the values in order ACCEL_XOUT_H, ACCEL_XOUT_L, ACCEL_yOUT_H, etc... in order, so if you read the arduino code they combine the _H with _L moving 8 bits

    wirte to me if you need help, or see my threats, i ask a lot about mpu in this forum

  • Hi Rodrigo,

    Your post has been quite helpful for me, but there's something that has been troubling my mind. How did you wire the MPU5060 to your TI board? I've connected the SDA and SCL pins from the MPU6050 to my F28377S board, but I don't know where to connect the INT or the AD0 pins?

    Thanks in advance,

    Julián

  • Hello,

    If you still have a question, please consider creating a new post as old posts are generally closed and no longer tracked. You can provide the necessary information regarding your issue in the new post and include a link to this post if you'd like.

    Thanks,
    Elizabeth