This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529: i2c slave tx to master example code fails - MSP430F55xx_Uscib0_i2c_10.c

Part Number: MSP430F5529
Other Parts Discussed in Thread: MSP430G2553

I am working with code examples from  Resource Explorer - MSP430V3.60.00.10

Two files describe how to transmit a char array from the I2C slave to the I2C master.  

The file names are.

MSP430F55xx_uscib0_i2c_10.c      Slave transmits to the master

MSP430F55xx_uscib0_i2c_11.c      master receives transmission from the slave.

I am using code composure 6.0 to debug this code.   I have 2 devices connected through P3.0 and P3.1   Both pins have 10K resistors on it.

I actually got the master to transmit to the slave....That was a nightmare but my code works....Now I need to get the slave to transmit to the master.

The code examples are quite bad, as I determined from the experience using example code to create master to slave traansmission....but I cannot get this new code to work.

The issue is that both the slave and the master get stuck on the interrupt....nothing is happening.

Here is the 2 codes:....again straight from the example.   Why do they both the slave and the master get hung on the interrupt?

(Note I removed the copywrite header from this post to reduce the need to read all of it but it is TI code protected by their copywrite.)

SLAVE CODE -  Transmitting to a master

//******************************************************************************
//
// Slave code
// - slave transmits to master
//
// This is copied from MSP430F55xx_uscib0_i2c_11.c
//******************************************************************************
#include <msp430.h>

unsigned char *PTxData; // Pointer to TX data
const unsigned char TxData[] = // Table of data to transmit
{
0x11,
0x22,
0x33,
0x44,
0x55
};

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P3SEL |= 0x03; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0I2COA = 0x48; // Own Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE + UCSTPIE + UCSTTIE; // Enable STT and STP interrupt
// Enable TX interrupt

while (1)
{
PTxData = (unsigned char *)TxData; // Start of TX buffer

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until master
// finishes RX
__no_operation(); // Set breakpoint >>here<< and
} // read out the TXByteCtr counter
}

//------------------------------------------------------------------------------
// The USCI_B0 data ISR TX vector is used to move data from MSP430 memory to the
// I2C master. PTxData points to the next byte to be transmitted, and TXByteCtr
// keeps track of the number of bytes transmitted.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// The USCI_B0 state ISR TX vector is used to wake up the CPU from LPM0 in order
// to do processing in the main program after data has been transmitted. LPM0 is
// only exit in case of a (re-)start or stop condition when actual data
// was transmitted.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: // Vector 6: STTIFG
UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag
break;
case 8: // Vector 8: STPIFG
UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 if data was transmitted
break;
case 10: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
UCB0TXBUF = *PTxData++; // Transmit data at address PTxData
break;
default: break;
}
}

MASTER CODE

//******************************************************************************
//
// Master code
// - Master receives data from slave 
//
//
// This is copied from MSP430F55xx_uscib0_i2c_10.c
//
//******************************************************************************

#include <msp430.h>

unsigned char *PRxData; // Pointer to RX data
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[128]; // Allocate 128 byte of RAM

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P3SEL |= 0x03; // 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 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x48; // Slave Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCRXIE; // Enable RX interrupt

while (1)
{
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
RXByteCtr = 5; // Load RX byte counter
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT; // I2C start condition

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until all data
// is RX'd
__no_operation(); // Set breakpoint >>here<< and
} // read out the RxBuffer buffer
}

//-------------------------------------------------------------------------------
// 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
// any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
//-------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: // Vector 10: RXIFG
RXByteCtr--; // Decrement RX byte counter
if (RXByteCtr)
{
*PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
if (RXByteCtr == 1) // Only one byte left?
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
}
else
{
*PRxData = UCB0RXBUF; // Move final RX data to PRxData
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
}
break;
case 12: break; // Vector 12: TXIFG
default: break;
}
}

  • To insert code, use the "Insert Code" (</>) button.

    How exactly are the pins and the resistors connected?
  • The hardware is working fine as I am able to transmit a message from the master to the slave. I am having issue transmitting a message from the slave to the master. Again the example code is broken somehow.

    Hope this provides some additional clarity to the issue.
  • I never did get this code to work.

    The code was written by someone who did not read the programming manual and certainly did not test the code. The I2C code examples don't work. I am working with the MSP430F5529, MSP430G2553. The code is omitting a lot of setting required for proper operation. I ended up having to design and code the i2c from scratch.   I am now doing the same thing with the MSP430G2553.   Needless to say I am wasting time I did not budget for.   It is costing me.

    Thanks Texas Instruments !

    I2C examples need to be reviewed and rewritten.

**Attention** This is a public forum