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.

LP-MSP430FR2476: I2C only functions if same port LED is turned off

Part Number: LP-MSP430FR2476

Hi,

I've been using the launchpad to connect to an I2C device, using a modified I2C library provided by TI.

I have found, that the I2C module on port 1 pins 2 and 3 does not work if the LED on pin 1.0 is lit at the the same time. I was able to verify this after turning it on in different parts of my main. You can see the relevant part here

while(reg!=2)
{
    i2c_master_read(0x41, 0xe0, &reg, 1);
}
reg = 1;
i2c_master_write(0x41, 0xe0, &reg, 1);

P1OUT = BIT0;

while(reg != 65)
{
    i2c_master_read(0x41, 0xe0, &reg, 1);
}

whereever I put this, the program stops because the I2C unit is not working anymore and stays in LPM0.

Is there anything I am missing or are the LED and the low power mode somehow related? The interrupts that are needed for I2C to work are not triggering if the LED is lit.

For this you can see the i2c library I am using:

I2C_Mode i2c_master_read(uint8_t devAdd, uint8_t regAdd, uint8_t* readBuf, uint8_t count)
{
    rxComplete = 0;
    /* Initialize state machine */
    masterMode = TX_REG_ADDRESS_MODE;
    transmitRegAddr = regAdd;
    rxByteCtr = count;
    txByteCtr = 0;
    receiveIndex = 0;
    transmitIndex = 0;
    receiveBuffer = readBuf;

    /* Initialize slave address and interrupts */
    UCB0I2CSA = devAdd;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB0IE |= UCTXIE;                        // Enable TX interrupt

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

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

    return 0;

}

I2C_Mode i2c_master_write(uint8_t devAdd, uint8_t regAdd, const uint8_t* regData, uint8_t count)
{
    txComplete = 0;
    /* Initialize state machine */
    masterMode = TX_REG_ADDRESS_MODE;
    transmitRegAddr = regAdd;

    //Copy register data to TransmitBuffer
    transmitBuffer = regData;

    txByteCtr = count;
    rxByteCtr = 0;
    receiveIndex = 0;
    transmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB0I2CSA = devAdd;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB0IE |= UCTXIE;                        // Enable TX interrupt

    UCB0CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts

    return 0;
}

#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
{
  //Must read from UCB0RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
        rx_val = UCB0RXBUF;
        if (rxByteCtr)
        {
          receiveBuffer[receiveIndex++] = rx_val;
          rxByteCtr--;
        }

        if (rxByteCtr == 1)
        {
          UCB0CTLW0 |= UCTXSTP;
        }
        else if (rxByteCtr == 0)
        {
          UCB0IE &= ~UCRXIE;
          masterMode = IDLE_MODE;
          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
          P5OUT |= BIT1;
          P4OUT &= ~BIT7;
//          rxComplete = 1;
        }
        break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
        switch (masterMode)
        {
          case TX_REG_ADDRESS_MODE:
              UCB0TXBUF = transmitRegAddr;
              if (rxByteCtr)
                  masterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
              else
                  masterMode = TX_DATA_MODE;        // Continue to transmission with the data in Transmit Buffer
              break;

          case SWITCH_TO_RX_MODE:
              UCB0IE |= UCRXIE;              // Enable RX interrupt
              UCB0IE &= ~UCTXIE;             // Disable TX interrupt
              UCB0CTLW0 &= ~UCTR;            // Switch to receiver
              masterMode = RX_DATA_MODE;    // State state is to receive data
              UCB0CTLW0 |= UCTXSTT;          // Send repeated start
              if (rxByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB0CTLW0 & UCTXSTT));
                  UCB0CTLW0 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (txByteCtr)
              {
                  UCB0TXBUF = transmitBuffer[transmitIndex++];
                  txByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB0CTLW0 |= UCTXSTP;     // Send stop condition
                  masterMode = IDLE_MODE;
                  UCB0IE &= ~UCTXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
//                  txComplete = 1;
              }
              break;

          default:
              __no_operation();
              break;
        }
        break;
    default: break;
  }
}

  • I don't see where you configure your (P1) pins. What jumps out is:

    > P1OUT = BIT0;

    which sets all the pins in P1. In particular, if the library has engaged the P1REN pullups, this will change them to pulldowns.

    In any case, it's hazardous to change pins you don't know about. Try instead:

    > P1OUT |= BIT0; // P1.0 (only) high

  • oh thank you, the OR must have gone missing somewhere. Unfortunately after staring at it for hours it didn't occur to me what went missing.

**Attention** This is a public forum