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.

Unable to get i2c examples between 2 MSP430F5529 Launchpads working

Other Parts Discussed in Thread: MSP430F5529, MSP430WARE

I’m trying to test i2c between two MSP430F5529 LaunchPad Eval boards, using the examples published as part of the MSP430Ware at msp430\msp430ware_1_40_01_44\examples\devices\5xx_6xx\MSP430F55xx_Code_Examples\C\, specifically MSP430F55xx_uscib0_i2c_08.c (master) with MSP430F55xx_uscib0_i2c_09.c (slave).

Powering up the programmed boards, with CLK and SDA lines appropriately connected and pulled up, I see both SDA’s go high (and stay high), but never see any activity on the clock lines.

Debugging the master reveals hitting the master's ISR, case 12, once. I've never seen the slave ISR executed.

Any suggestions?


Thanks,

Steve

MASTER CODE:

/* --COPYRIGHT--,BSD_EX

 * Copyright (c) 2012, Texas Instruments Incorporated

 * All rights reserved.

 *

 * Redistribution and use in source and binary forms, with or without

 * modification, are permitted provided that the following conditions

 * are met:

 *

 * *  Redistributions of source code must retain the above copyright

 *    notice, this list of conditions and the following disclaimer.

 *

 * *  Redistributions in binary form must reproduce the above copyright

 *    notice, this list of conditions and the following disclaimer in the

 *    documentation and/or other materials provided with the distribution.

 *

 * *  Neither the name of Texas Instruments Incorporated nor the names of

 *    its contributors may be used to endorse or promote products derived

 *    from this software without specific prior written permission.

 *

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;

 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 *

 *******************************************************************************

 *

 *                       MSP430 CODE EXAMPLE DISCLAIMER

 *

 * MSP430 code examples are self-contained low-level programs that typically

 * demonstrate a single peripheral function or device feature in a highly

 * concise manner. For this the code may rely on the device's power-on default

 * register values and settings such as the clock configuration and care must

 * be taken when combining code from several examples to avoid potential side

 * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware

 * for an API functional library-approach to peripheral configuration.

 *

 * --/COPYRIGHT--*/

//******************************************************************************

//  MSP430F552x Demo - USCI_B0 I2C Master TX multiple bytes to MSP430 Slave

//

//  Description: This demo connects two MSP430's via the I2C bus. The master

//  transmits to the slave. This is the MASTER CODE. It cntinuously

//  transmits an array of data and demonstrates how to implement an I2C

//  master transmitter sending multiple bytes using the USCI_B0 TX interrupt.

//  ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz

//

// ***to be used with "MSP430F55xx_uscib0_i2c_09.c" ***

//

//                                /|\  /|\

//                MSP430F5529     10k  10k      MSP430F5529

//                   slave         |    |         master

//             -----------------   |    |   -----------------

//           -|XIN  P3.0/UCB0SDA|<-|----+->|P3.0/UCB0SDA  XIN|-

//            |                 |  |       |                 |

//           -|XOUT             |  |       |             XOUT|-

//            |     P3.1/UCB0SCL|<-+------>|P3.1/UCB0SCL     |

//            |                 |          |                 |

//

//   Bhargavi Nisarga

//   Texas Instruments Inc.

//   April 2009

//   Built with CCSv4 and IAR Embedded Workbench Version: 4.21

//******************************************************************************

 

#include <msp430.h>

unsigned char *PTxData;                     // Pointer to TX data

unsigned char TXByteCtr;

 

const unsigned char TxData[] =              // Table of data to transmit

{

  0xc1,

  0xc2,

  0xc3,

  0xc4,

  0xc5

};

 

int main(void)

{

  unsigned int i;

  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 |= UCTXIE;                         // Enable TX interrupt

 

  while (1)

  {

    for(i=0;i<10;i++);                      // Delay required between transaction

    PTxData = (unsigned char *)TxData;      // TX array start address

                                            // Place breakpoint here to see each

                                            // transmit operation.

    TXByteCtr = sizeof TxData;              // Load TX byte counter

    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

   

    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0, enable interrupts

    __no_operation();                       // Remain in LPM0 until all data

                                            // is TX'd

    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

  }

}

 

//------------------------------------------------------------------------------

// The USCIAB0TX_ISR is structured such that it can be used to transmit any

// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData

// points to the next byte to transmit.

//------------------------------------------------------------------------------

#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: break;                           // Vector  4: NACKIFG

  case  6: break;                           // Vector  6: STTIFG

  case  8: break;                           // Vector  8: STPIFG

  case 10: break;                           // Vector 10: RXIFG

  case 12:                                  // Vector 12: TXIFG 

    if (TXByteCtr)                          // Check TX byte counter

    {

      UCB0TXBUF = *PTxData++;               // Load TX buffer

      TXByteCtr--;                          // Decrement TX byte counter

    }

    else

    {

      UCB0CTL1 |= UCTXSTP;                  // I2C stop condition

      UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag

      __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0

    } 

  default: break;

  }

}

 

 

SLAVE CODE:

/* --COPYRIGHT--,BSD_EX

 * Copyright (c) 2012, Texas Instruments Incorporated

 * All rights reserved.

 *

 * Redistribution and use in source and binary forms, with or without

 * modification, are permitted provided that the following conditions

 * are met:

 *

 * *  Redistributions of source code must retain the above copyright

 *    notice, this list of conditions and the following disclaimer.

 *

 * *  Redistributions in binary form must reproduce the above copyright

 *    notice, this list of conditions and the following disclaimer in the

 *    documentation and/or other materials provided with the distribution.

 *

 * *  Neither the name of Texas Instruments Incorporated nor the names of

 *    its contributors may be used to endorse or promote products derived

 *    from this software without specific prior written permission.

 *

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;

 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 *

 *******************************************************************************

 *

 *                       MSP430 CODE EXAMPLE DISCLAIMER

 *

 * MSP430 code examples are self-contained low-level programs that typically

 * demonstrate a single peripheral function or device feature in a highly

 * concise manner. For this the code may rely on the device's power-on default

 * register values and settings such as the clock configuration and care must

 * be taken when combining code from several examples to avoid potential side

 * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware

 * for an API functional library-approach to peripheral configuration.

 *

 * --/COPYRIGHT--*/

//******************************************************************************

//  MSP430F552x Demo - USCI_B0 I2C Slave RX multiple bytes from MSP430 Master

//

//  Description: This demo connects two MSP430's via the I2C bus. The master

//  transmits to the slave. This is the slave code. The interrupt driven

//  data receiption is demonstrated using the USCI_B0 RX interrupt.

//  ACLK = n/a, MCLK = SMCLK = default DCO = ~1.045MHz

//

// ***to be used with "MSP430F55xx_uscib0_i2c_08.c" ***

//

//                                /|\  /|\

//                MSP430F5529     10k  10k     MSP430F5529

//                   slave         |    |         master

//             -----------------   |    |   -----------------

//           -|XIN  P3.0/UCB0SDA|<-|----+->|P3.0/UCB0SDA  XIN|-

//            |                 |  |       |                 |

//           -|XOUT             |  |       |             XOUT|-

//            |     P3.1/UCB0SCL|<-+------>|P3.1/UCB0SCL     |

//            |                 |          |                 |

//

//   Bhargavi Nisarga

//   Texas Instruments Inc.

//   April 2009

//   Built with CCSv4 and IAR Embedded Workbench Version: 4.21

//******************************************************************************

 

#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 = UCMODE_3 + UCSYNC;             // I2C Slave, synchronous mode

  UCB0I2COA = 0x48;                         // Own Address is 048h

  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

  UCB0IE |= UCSTPIE + UCSTTIE + UCRXIE;     // Enable STT, STP & RX interrupt

 

  while (1)

  {

    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer

    RXByteCtr = 0;                          // Clear RX byte count

    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0, enable interrupts

                                            // Remain in LPM0 until master

                                            // finishes TX

    __no_operation();                       // Set breakpoint >>here<< and read

  }                                         // read out the RxData buffer

}

 

//------------------------------------------------------------------------------

// The USCI_B0 data ISR RX vector is used to move received data from the I2C

// master to the MSP430 memory.

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

// The USCI_B0 state ISR TX vector is used to wake up the CPU from LPM0 in order

// to process the received data in the main program. LPM0 is only exit in case

// of a (re-)start or stop condition when actual data was received.

//------------------------------------------------------------------------------

#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: break;                           // Vector  4: NACKIFG

  case  6:                                  // Vector  6: STTIFG

    UCB0IFG &= ~UCSTTIFG;

    break;

  case  8:                                  // Vector  8: STPIFG

    UCB0IFG &= ~UCSTPIFG;

    if (RXByteCtr)                          // Check RX byte counter

      __bic_SR_register_on_exit(LPM0_bits);

    break;

  case 10:                                  // Vector 10: RXIFG

    *PRxData++ = UCB0RXBUF;                 // Get RX'd byte into buffer

    RXByteCtr++;

    break;

  case 12: break;                           // Vector 12: TXIFG 

  default: break;

  } 

}

  • Sorry, it’s a pain to read your code. Could you please edit your post and put it into a readable form, by using the code tool (the button on the bottom right of the edit window toolbar)?

    Is the code the unaltered demo code or did you change something? If so, you should highlight the libnes you changed (and write what you changed)

  • Sorry about the formatting. The code in my post is unchanged from the examples. Ultimately I gave up on the example code and returned to my implementation (essentially the example plus everything else I'm trying to do). Then I changed my i2c handling from ports 3.0/3.1/UCB0 to 4.1/4.2/UCB1 on both the master and slave. All works well now.

  • That’s, well, unexpected.

    Do you know why it didn’t work? If the port settings were okay for UCB0 and are (obviously) now for USB1, I don’t see a reason why it didn’t work on UCB0 but does on UCB1, as the code is the same, just using other register names. It could possibly mean that the register definitions for UCB0 are wrong in the header files or the addresses are wrong in the linker script. Which should be investigated further.

**Attention** This is a public forum