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;
}