HI all I have run into a problem that I have been banging my head against the wall for a couple of week. I have using the MSP430F2274 and the i2c bus and getting mixed results. I have the SDA and SCL lines pulled up to VCC with 10k resistors.
I would say about 30% of the time everything works great and I get good data from the device that I am connecting to. The rest of the time I am getting hung up on the polling loop waiting for the TX Flag to be set in my I2C_write function. It seems that the UCTXSTT bit is not getting cleared out on the first byte TX. I have to power cycle to get things going again. Please provide some guidance if you can. Thank you for your time.
Attached is my code:
void I2C_init()
{
P3SEL |= 0x06; // Assign I2C pins to USCI_B0s P3.2 = SCL; P3.1 = SDA
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = CLK_DIVIDER; // fSCL = SMCLK/3 = ~333kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x68; // Set slave address 0x68
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume
}
void I2C_write(char reg_addr, char parameters)
{
while(UCB0STAT & UCBUSY);
UCB0CTL1 |= UCTXSTT + UCTR; //Start Condition sends address of slave
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = reg_addr; //Load register Address
while (!(IFG2 & UCB0TXIFG)); //<---LOCKS UP HERE
UCB0TXBUF = parameters; //Load register parameters
while (!(IFG2 & UCB0TXIFG));
UCB0CTL1 |= UCTXSTP; //Send stop message
while (UCB0CTL1 & UCTXSTP); //Wait until the stop message is sent
}
signed int I2C_read(char reg_addr)
{
signed int Data = 0;
while(UCB0STAT & UCBUSY); //Make sure bus in not busy
UCB0CTL1 |= UCTXSTT + UCTR; //Start Condition sends address of slave
while (!(IFG2 & UCB0TXIFG)); //Make sure data has been shifted out
UCB0TXBUF = reg_addr; //Load register address to read
while (UCB0CTL1 & UCTXSTT); //Wait until the ACK message has been RX
while(UCB0STAT & UCBUSY); //Make sure bus is not busy
UCB0CTL1 &= ~UCTR //Sets the master as a receiver
UCB0CTL1 |= UCTXSTT; //Start Condition sends address of slave
while ((UCB0CTL1 & UCTXSTT)); //Make sure start has been cleared
UCB0CTL1 |= UCTXSTP; //Send stop message
while (!(IFG2 & UCB0RXIFG)); //Make sure RXIFG is set
Data = UCB0RXBUF; //Save data to memory
while((UCB0CTL1 & UCTXSTP)); //Make sure stop has been sent
return Data;
}