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: