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