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.

I2C on MSP 430F5529

Other Parts Discussed in Thread: BQ24272, MSP430F2274, MSP430WARE

I need to do I2C with a Bq24272 chip.  I was able to do it with an arduino and read the required registers. I need to do the same using MSP 430 F5529. Is there a modular library available for the same? Since communicating between the MSP and the Bq chip would require a lot of sending and receiving using I2C, I tried to use the sample codes available on TI's website first. I used the sample code for Master_send and Slave_receive available on the website to try to communicate between two MSP4305529s. But when I put the oscilloscope on the SCL line, I did not get any pulses. My board did not have the UCSIB0 pins available so I had changed the codes to implement I2C using the UCSIB1 pins. Was the error caused by this?

The changed code is as follows:

Master as Transmitter:


#include <msp430.h>

unsigned char TXData;
unsigned char TXByteCtr;

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P4SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0x48; // Slave Address is 048h
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt

TXData = 0x01; // Holds TX data

while (1)
{
TXByteCtr = 1; // Load TX byte counter

while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
__no_operation(); // Remain in LPM0 until all data
// is TX'd

TXData++; // Increment data byte
}
}

//------------------------------------------------------------------------------
// The USCIAB0_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count.
//------------------------------------------------------------------------------
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(__even_in_range(UCB1IV,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
{
UCB1TXBUF = TXData; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
break;
default: break;
}
}

Slave as Receiver:


#include <msp430.h>

volatile unsigned char RXData;

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P4SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB1I2COA = 0x48; // Own Address is 048h
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCRXIE; // Enable RX interrupt

while (1)
{
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
__no_operation(); // Set breakpoint >>here<< and read
} // RXData
}

// USCI_B0 Data ISR
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(__even_in_range(UCB1IV,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
RXData = UCB1RXBUF; // Get RX data
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
break;
case 12: break; // Vector 12: TXIFG
default: break;
}
}

  • Hi Sachin ,

             I have not found any modular library for the same I2C interfacing .But have referred TI's code for I2C Communication with an EEPROM (e.g. 24128) with MSP430F2274(slaa208a). You can find the code on TI's site.

    Thank you,

    Smita

  • You may want to take a look at the MSP430Ware DriverLib for F5xx-6xx. It has pre-written device drivers for doing I2C.

  • I tried that but I could not use the example project in that because it gave the following error:

    Then I tried using the code for  MasterTXSingle directly. The files I included in the code 

    #include "hw_memmap.h"
    #include "usci_b_i2c.h"
    #include "ucs.h"
    #include "wdt_a.h"
    #include "gpio.h"

    Still,  errors " __MSP430_BASEADDRESS_WDT_A not found ", " __MSP430_BASEADDRESS_UCSI_B0 not found " and " __MSP430_BASEADDRESS_UCS " not found appeared.

  • Dear,

    Did you ever resolve the issue?

    I'm at the same level with my code for USCI_B1 and no data gets sent out,  the USCI_B1_ISR is never entered so the startcondition (STTIFG) is never reached...

    Did you get above code working

    ANSWER:

    My problem was resolved when chaning the UCB1CTL1 register, setting the UCSSELx to SMCLK instead of UCLKI  (see 36.4.2 in the UserGuide)

    My ISR,

    /**************************************************************************//**
    *
    * USCIB1_ISR
    *
    * @brief   interrupt service routine for USCI B1
    *
    * @param   -
    *
    * @return  true - I2C bus is idle, otherwise false
    *
    ******************************************************************************/
    #pragma vector = USCI_B1_VECTOR 
    __interrupt void USCIB1_ISR(void)
    {  
      switch(__even_in_range(UCB1IV,0x0f))
      {
        case 0x00: break; // Vector 0: No interrupts break;
        case 0x02:        // Vector 2: ALIFG Arbitration Lost break;  
          E_TRACE_TEXT_LF("I2C Arbitration lost");
          break;          
        case 0x04:        // Vector 4: NACKIFG 
        {
          // set flag to indicate NACK
          nack_flag = true;
          // send stop signal
          UCB1CTLW0 |= UCTXSTP;
          break;
        }
        case 0x06:        // Vector 6: STTIFG break;
          E_TRACE_TEXT_LF("I2C Start Condition Received");
          break;          
        case 0x08:        // Vector 8: STPIFG , STOP Condition 
        {
          // wake-up CPU
          //__bic_SR_register_on_exit(LPM0_bits);
          TRACE_TEXT_LF("I2C Stop Condition");
          break;  
        }
        case 0x0a:  // Vector 10: RXIFG break;
        {
          // copy data into buffer
          *rx_data_p = UCB1RXBUF;
          if(num_of_rx_bytes)
          {
            // increment rx data pointer
            rx_data_p++;
            // decrement rx counter
            if(--num_of_rx_bytes == 0)
            {
              // send stop
              while(UCB1CTLW0 & UCTXSTP);
              UCB1CTLW0 |= UCTXSTP;
            }        
          }           
          break;
        }
        case 0x0c: // Vector $0c: TXIFG0 
        {
          // transmit as long as needed
          if(num_of_tx_bytes)
          {
            UCB1TXBUF = *tx_data_p;
            
            // increment pointer and decrement bytes to sent
            tx_data_p++;
            num_of_tx_bytes--;
          }
          else
          {
        	if(repeated_start == false)
        	{
              // send stop
              UCB1CTLW0 |= UCTXSTP;
        	}
        	else
        	{
        	  // send start byte
        	  UCB1CTLW0 = (UCB1CTLW0 & (~UCTR)) | UCTXSTT;
    
        	  if(num_of_rx_bytes == 0)
        	  {
       	    // wait until start is sent
        	    while(UCB1CTLW0 & UCTXSTT);
    
        	    // abort send stop after first byte
        	    while(UCB1CTLW0 & UCTXSTP);
        	    UCB1CTLW0 |= UCTXSTP;
        	  }
        	}
          }          
          break;
        }
        default: break;	
    	
      }	
    }

**Attention** This is a public forum