Part Number: MSP430G2533
Other Parts Discussed in Thread: MSP430G2553, RF430FRL152H
I'm trying to use the I2C protocol to communicate between the MSP-EXP430G2 evaluation board (having the MSP430G2533 micro-controller) and a photo-detector (slave).
I've connected 2.2 K Ohms pull external resistors from the SDA and SCL lines pulled-up to the VDD (3.4 volts).
The slave address is 0x2A.
The protocol to communicate with the slave requires the following sequence(shown in the figure below) that I've stored the TX_DATA[8] array.
The code I'm using is pasted here. The problem is that: I'm either getting no ACK signal from the slave (this happens 90% of the times with some random value of the pull up), or sometimes when I get the ACK signal apart from the address there is no other data being transmitted (this happens only 10% of the time).
When I single step in the code in CCS Studio, the code gets stuck in the I2C transmit interrupt : __bis_SR_register(CPUOFF + GIE); and does not come out.
Does anyone have any idea why it would be that way? or did anyone face any similar problem before? any help would be highly appreciated.
// Communicating with the I2C Slave for data transfer from the photo-detector
// TI Development starter kit board is used here
#include <msp430.h>
/*
* main.c
*/
void I2C_Initialise(void);
void I2C_Transmit(void);
void I2C_Receive(void);
int TransmitByteCtr = 8;
unsigned char PointerRxData; // Pointer to RX data
int Rx = 0;
unsigned char TX_DATA[8] = {0x2A, 0x00, 0x89, 0x2A, 0x00, 0x09, 0x2A, 0x03};
int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
//DISABLE_INT; // Disable all the interrupts
//ClockInitialise();
// Both are Port 1: Port 1.6 Port 1.7 Bits are set for I2C using the port registers, SDA = P1.7 SCL = P1.6 //
P1DIR |= 0xC0;
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 //
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
I2C_Initialise();
while(1)
{
//Transmit process
Rx = 0;
I2C_Transmit();
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
//Receive process
Rx = 1;
I2C_Receive();
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
}
}
//-------------------------------------------------------------------------------
// 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 = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if(Rx == 1)
{ // Master Recieve?
PointerRxData = UCB0RXBUF; // Get RX data
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
else
{ // Master Transmit
if (TransmitByteCtr<8) // Check TX byte counter
{
UCB0TXBUF = TX_DATA[TransmitByteCtr]; // Load TX buffer
TransmitByteCtr++; // Decrement TX byte counter
}
else
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}
void I2C_Initialise(void)
{
IE2 |= UCB0RXIE; //Enable RX interrupt
IE2 |= UCB0TXIE; // Enable TX interrupt
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
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 = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x2A; // Slave Address is 02Ah
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
void I2C_Transmit(void)
{
// while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
void I2C_Receive(void)
{
UCB0CTL1 &= ~UCTR ; // Clear UCTR
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT; // I2C start condition
while (UCB0CTL1 & UCTXSTT); // Start condition sent?
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
I
