I'm trying to get my MSP430g2553 to talk to a sensor via I2C. If anyone can spot-check the hardware in the picture below and see if there's a problem there, I'd be grateful. The resistors are connected to the red rail. Right now they're 2.2k, but I've also tried 8k and 10k.
Picture: http://imgur.com/OTwArXa
The slave device is a PMU-6050 if you're interested.
Code is included.
#include <msp430g2553.h> //#include "MPU6050.h" #define MPU6050_RA_WHO_AM_I 0x75 #define MPU6050_DEFAULT_ADDRESS 0xD0 void init_I2C(void); int i2c_notready(void); char Receive(char); void Transmit(char, char); // Pin 1.6 is SCL // Pin 1.7 is SDA // Slave address for MPU6050 is 0x68 int main(void) { volatile char who_am_i; char gotit=0; WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1Mhz DCOCTL = CALDCO_1MHZ; P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2 |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 init_I2C(); // initialize i2c __delay_cycles(10000); while ( i2c_notready() ); // wait for bus to be free __delay_cycles(10000); who_am_i = Receive(MPU6050_RA_WHO_AM_I); if (who_am_i != 0x00) gotit=who_am_i; while(1){ } } void init_I2C(void) { UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = 1Mhz/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = MPU6050_DEFAULT_ADDRESS; UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCB0RXIE + UCB0TXIE; // Enable RX and TX interrupt } int i2c_notready(){ if(UCB0STAT & UCBBUSY) return 1; else return 0; } char Receive(char registerAddr){ char receivedByte; while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent (UCTXSTP auto clears after STOP is sent) UCB0CTL1 |= UCTR + UCTXSTT; // I2C start condition with UCTR flag for transmit while((IFG2 & UCB0TXIFG) == 0); //UCB0TXIFG is set immidiately (UCB0TXIFG is set to indicate TXBUF is ready for more data) UCB0TXBUF = registerAddr; //write registerAddr in TX buffer __delay_cycles(1000); /*********************** if (UCB0STAT & UCNACKIFG) { UCB0CTL1 |= UCTR + UCTXSTT; // I2C start condition with UCTR flag for transmit while((IFG2 & UCB0TXIFG) == 0); UCB0TXBUF = registerAddr; //write registerAddr in TX buffer __delay_cycles(1000); } ************/ while((IFG2 & UCB0TXIFG) == 0); // STUCK HERE wait until TX buffer is empty and transmitted UCB0CTL1 &= ~UCTR; // Clear I2C TX flag for receive UCB0CTL1 |= UCTXSTT + UCTXNACK; // I2C start condition with NACK for single byte reading while (UCB0CTL1 & UCTXSTT); // Start condition sent? RXBuffer full? receivedByte = UCB0RXBUF; UCB0CTL1 |= UCTXSTP; // I2C stop condition return receivedByte; } void Transmit(char registerAddr, char data){ while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTR + UCTXSTT; // I2C start condition with UCTR flag for transmit while((IFG2 & UCB0TXIFG) == 0); //UCB0TXIFG is set immidiately UCB0TXBUF = registerAddr; //write registerAddr in TX buffer while((IFG2 & UCB0TXIFG) == 0); // wait until TX buffer is empty and transmitted UCB0TXBUF = data; //Write data in register while((IFG2 & UCB0TXIFG) == 0); // wait until TX buffer is empty and transmitted UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear TX interrupt flag }
And the code keeps getting snagged at the line indicated below. Pretty sure the slave isn't sending back an acknowledge signal: