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.

I2C: SCL held Low



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
}

  • In your ISR, you don't need your Rx flag. You can check the RXIFG/TXIFG bits. they tells you whether this was an RX or TX interrupt.

    Writing to TXBUF (ro reading from RXBUF) will clear the IFG bit automatically.

    Also, it makes no sense that you clear the TXIE bit on the first byte you send - it renders your TXByteCtr useless - the ISR won't be called twice, no matter how many bytes are to send.

    However, if you code worked and you didn't change it and now it is no longer working, the most likely explanation is a hardware problem. Bad soldering, a hair-crack on a PCB trace, whatever.

    BTW: " __bis_SR_register(GIE); // Enter LPM0 w/ interrupts"
    This won't enter LPM. When you change code functionality, you should also change the comments.

  • I forgot to edit the comment but when it comes to the functionality of the code, it has worked before and I was using another bigger size code that I thought was not necessary to post.

    Since I am using the Expansion board from Sparkfun for MPU-9150 there was no additional soldering that I have made and I have today tested the pin out of the expansion board and it seems fine. The clock is just low the whole time. Could it be that the chip is burnt? or is there any case in software that could do that? It goes down before I even start to run the code.

  • Maybe you killed the slave (or at least its port pins). I fear this problem is beyond my skills of remote diagnostics.

**Attention** This is a public forum