I have an I2C communication between MS430F5529(Launchpad) and MPU-9150. Everything was working but before a few days the MPU-9150 stop responding. I checked the status and it holds the SCL line low the entire time. Both lines are pulled up by 10k ohm resistors but when MPU is on it will automatically held SCL low. What is the solution?
I don't think the code will be important but I just posted a sample code that I first used to just read the WHO_AM_I register below.
#include <msp430.h>
void msDelay(unsigned int);
void init_I2C(void);
void transmit(void);
void receive(void);
unsigned int SLAVE_ADDRESS = 0x68;
volatile unsigned char WHO_AM_I = 0x00;
volatile unsigned char WHO_AM_I_ADDRESS = 0x75; //0x75;
int TXByteCtr,Rx;
int main(void) {
WDTCTL = WDTPW | WDTHOLD;
P4SEL |= BIT1 + BIT2; // Select I2C ports
init_I2C();
Rx = 0;
TXByteCtr = 1;
transmit();
msDelay(2);
//Receive process
Rx = 1;
receive();
while(1)
{
}
}
// USCI_B1 Data ISR
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
if(Rx)
{
WHO_AM_I = UCB1RXBUF; // Get RX data
Rx = 0;
UCB1IFG &= ~UCRXIFG;
UCB1IE &= ~UCRXIE;
UCB1CTL1 |= UCTXNACK;
UCB1CTL1 |= UCTXSTP;
}
else
{
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = WHO_AM_I_ADDRESS; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
UCB1IE &= ~UCTXIE;
UCB1IFG &= ~UCTXIFG;
}
}
}
void init_I2C(void)
{
UCB1CTL1 |= UCSWRST; // Enable software reset. Enabled. USCI logic held in reset state.
UCB1CTL0 |= UCMST + UCMODE_3 + UCSYNC; //I2C master synchronous mode
UCB1CTL1 |= UCSSEL_2 + UCSWRST; // Select SMCLK & keep on reset mode
UCB1BR0 = 12; // Baudrate control. Timer prescaler fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0x68; // Slave address only 7 bits is 0x68
UCB1CTL1 &= ~UCSWRST; // Release the USCI logic for operation
UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any flag present
}
void transmit(void)
{
UCB1IE &= ~UCRXIE;
UCB1IE |= UCTXIE; // +UCNACKIE Enable tx & rx interrupt
while(UCB1CTL1 & UCTXSTP); // Ensure that stop condition is sent (UCTXSTP is cleared automatically)
UCB1CTL1 |= UCTR + UCTXSTT; // I2C Tx + start condition
__bis_SR_register(GIE); // Enter LPM0 w/ interrupts
}
void receive(void)
{
UCB1IE &= ~UCTXIE;
UCB1IE |= UCRXIE;
while(UCB1CTL1 & UCTXSTP);
UCB1CTL1 &= ~UCTR; // I2C Rx mode
UCB1CTL1 |= UCTXSTT; // Send start condition
__bis_SR_register(GIE); // Enter LPM0 w/ interrupts
}
void msDelay(unsigned int msTime)
{
// Internal MCLK running at 1MHz
long counter;
for ( counter = 0; counter < msTime; counter++)
__delay_cycles( 1000 ); // 1 millisecond delay
}