Other Parts Discussed in Thread: MSP430BT5190
I'm trying to use the example code (modified to work with my MSP430BT5190) for a read from an I2C slave with the MSP430 as the Master, but I'm having trouble understanding how the code works. Specifically What I'm wondering about most is in order to do an I2C read, the sequence for reading from my slave device (which seems fairly standard for I2C) is to send [START] > [SLAVE ADDRESS] > [R/W] receive an [ACK] from the slave, and then to send [DESIRED ADDRESS TO READ FROM] and then the slave will send back the data in that register/address followed by an [ACK] (and here you would decide to do a repeated start or send a STOP), but in the example code I don't see the desired address implemented anywhere so I'm not sure how I can do a read with it. I've included my modified code below and for understanding my I2C slave is connected to P9.2/UCB2SOMI/UCB2SCL and P9.1/UCB2SIMO/UCB2SDA for the SCL and SDA lines respectively.
#include <msp430.h>
int TXByteCtr;
unsigned char PRxData;
int Rx = 0;
char WHO_AM_I = 0x00;
char itgAddress = 0x1C;
void init_I2C(void);
void Transmit(void);
void Receive(void);
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P9SEL |= 0x06; // I2C pins
init_I2C();
while(1){
//Transmit process
Rx = 0;
TXByteCtr = 1;
Transmit();
//Receive process
Rx = 1;
Receive();
}
}
//-------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C slave
// to the MSP430 memory. It is structured such that it can be used to receive
//-------------------------------------------------------------------------------
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
{
if(Rx == 1){ // Master Recieve?
PRxData = UCB2RXBUF; // Get RX data
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
else{ // Master Transmit
if (TXByteCtr) // Check TX byte counter
{
UCB2TXBUF = WHO_AM_I; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB2CTL1 |= UCTXSTP; // I2C stop condition
UCB2IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}
void init_I2C(void) {
UCB2CTL1 |= UCSWRST; // Enable SW reset
UCB2CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB2CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB2BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB2BR1 = 0;
UCB2I2CSA = itgAddress; // Slave Address is 069h
UCB2CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB2IE |= UCRXIE + UCTXIE; //Enable RX and TX interrupt
}
void Transmit(void){
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB2CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
void Receive(void){
while (UCB2CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB2CTL1 &= ~UCTR ; // Clear UCTR
UCB2CTL1 |= UCTXSTT; // I2C start condition
while (UCB2CTL1 & UCTXSTT); // Start condition sent?
UCB2CTL1 |= UCTXSTP; // I2C stop condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}