First of all, thank you in advance for the attention and the time dispensed understanding my problem.
So, I am developing a system that includes an MSP430F5529 communicating with an AD5933 via I2C. Previously, I did the same thing with an MSP430G2553 everything went smoothly and my code worked perfectly. I did check with an oscilloscope and every data was being sent. I started with that code for my new system and did all the necessary changes, ports, interrupts, registers, from G2553 to F5529.
No matter what, my code stop in verification loops. Especially this one:
while (UCB0STAT & UCBBUSY);
When I check the bus with an oscilloscope, the SCL is always high and SDA always low. So nothing happened on the bus.
I blink a LED during the code, and that works fine.
My code is bellow, please check it and let me know if you find something wrong, or if you have some idea for me to try out.
#include <msp430.h>
#define SLAVE_ADDRESS 0x0D /**< Address to AD5933. */
#define BAUD_RATE 0x12 /**< Baud Rate value. */
#define SDA_PIN BIT0 // msp430F5529 UCB0SDA pin
#define SCL_PIN BIT1 // msp430F5529 UCB0SCL pin
signed char byteCtr;
unsigned char *TI_transmit_field;
unsigned char *TI_receive_field;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
//LED configurations
P1DIR |= BIT1;
P1OUT |= BIT1;
P1OUT ^= (BIT1); //turn on LED
//MSP configurations to transmit
P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = BAUD_RATE; // set prescaler
UCB0BR1 = 0;
UCB0I2CSA = SLAVE_ADDRESS; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE = UCNACKIE;
UCB0IE |= UCTXIE; // Enable interrupts
P1OUT ^= (BIT1); //turn off LED
while (UCB0STAT & UCBBUSY) //wait for previous traffic to clear
;
//Configuration of the slave registers (SEND DATA)
unsigned char field[2] = { 0x80, 0xB1 };
TI_transmit_field = field;
byteCtr = 2;
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
while (UCB0STAT & UCBBUSY)
;
while (1)
;
}
//INTERRUPTS
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch (__even_in_range(UCB0IV, 12))
{
case 0:
break; // Vector 0: No interrupts
case 2:
break; // Vector 2: ALIFG
case 4:
UCB0CTL1 |= UCTXSTP;
UCB0IFG &= ~UCNACKIFG;
break; // Vector 4: NACKIFG
case 6:
break; // Vector 6: STTIFG
case 8:
break; // Vector 8: STPIFG
case 10: // Vector 10: RXIFG -- I am not using it yet (but I'll)
if (byteCtr == 0)
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
*TI_receive_field = UCB0RXBUF;
TI_receive_field++;
}
else
{
*TI_receive_field = UCB0RXBUF;
TI_receive_field++;
byteCtr--;
}
break;
case 12: // Vector 12: TXIFG
if (byteCtr == 0)
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI TX int flag
}
else
{
UCB0TXBUF = *TI_transmit_field;
TI_transmit_field++;
byteCtr--;
}
break;
default:
break;
}
}
Best Answer
The solution is to enable the global interrupts in the initialization. Using this line: