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.

MSP430F5244: I2C Implementation

Part Number: MSP430F5244

My team and I are currently trying to use our MCU to communicate with the BMP280 barometer via I2C. Right now when we run our code the data and clock line never are driven low. Are we missing something? Below is the code.


#include <msp430.h>

unsigned char TXData;
unsigned char TXByteCtr;

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P4SEL |= BIT1 + BIT2;
P4MAP1 = PM_UCB1SDA; 
P4MAP2 = PM_UCB1SCL;
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 = 0x77; // Slave Address is 77h
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; // I2C TX, start condition
UCB1CTL1 |= UCTXSTT; // Transmit start


__bis_SR_register(GIE); // Enter LPM0 w/ interrupts


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.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
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;
}
}

  • > P4MAP1 = PM_UCB1SDA; 
    > P4MAP2 = PM_UCB1SCL;

    You need to unlock the port-mapper before you can modify the registers. [Ref UG (SLAU367P) Sec 13.2.1] There's an example here:

    https://dev.ti.com/tirex/explore/node?node=AHMasaKpJCYVD23zCbmgWg__IOGqZri__LATEST

  • Based on the example that you provided I unlocked the port map as you suggested, and disabled the interrupts while I was doing so. Unfortunately, I am still unable to get the SCL and SDA lines to do anything. Below is the code that I changed. Do you see anything else that could be causing issues?

    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    __disable_interrupt();
    PMAPPWD = 0x02D52; //enable pmap write access
    P4MAP1 = PM_UCB1SDA; // Assign I2C pins to USCI_B0
    P4MAP2 = PM_UCB1SCL; //disbale pmap write access
    PMAPPWD = 0;
    __enable_interrupt();

    P4SEL |= BIT1 + BIT2;

  • I just ran this code on an F5529 Launchpad, and my scope sees plenty of activity. (I didn't have an I2C slave handy, so I used the internal pullups.)  Maybe something with your wiring?

    Unsolicited(1): Based on Data Sheet (SLAS897C) Table 9-7, your PMAP settings are already set that way at Reset, so that sequence isn't really necessary (unless you're just trying how the PMAP works).

    Unsolicited(2): 

    > __bis_SR_register(GIE); // Enter LPM0 w/ interrupts

    Since this doesn't wait, it has the effect of sending Start conditions as fast as it can, preventing any transactions from completing. I suggest you wait for completion with something like:

    > __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts

**Attention** This is a public forum