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.

MSP430FR59941: Slave I2C does not ack device address following a restart

Part Number: MSP430FR59941

I'm trying to configure my msp430 as an I2C slave and I want it to work the same way you would read a register out of any other slave.  Usually by sending the device address, register address, issuing a restart, and then reading the data back.   So far I'm able to write the register address and receive it in the MSP430, but after my master issues a restart and again sends the device address as a read, I do not get an ack.

Do I have to switch modes somewhere in order to send bytes out?

Here's my setup code:

void setup_slave_i2c(void){
    // Configure GPIO
    P6SEL0 |= BIT4 | BIT5;
    P6SEL1 &= ~(BIT4 | BIT5);

    // Configure USCI_B2 for I2C mode
    UCB3CTLW0 = UCSWRST;                    // Software reset enabled
    UCB3CTLW0 |= UCMODE_3 | UCSYNC;         // I2C mode, sync mode
    UCB3I2COA0 = 0x38 | UCOAEN;             // own address is 0x48 + enable
    UCB3CTLW0 &= ~UCSWRST;                  // clear reset register
    UCB3IE |= UCRXIE | UCTXIE0 | UCSTPIE;            // transmit,stop interrupt enable
}

Here's my interrupt handler code:

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = EUSCI_B3_VECTOR
__interrupt void USCI_B3_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_B3_VECTOR))) USCI_B3_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCB3IV, USCI_I2C_UCBIT9IFG))
    {
        case USCI_NONE:          break;     // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;     // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG: break;     // Vector 4: NACKIFG
        case USCI_I2C_UCSTTIFG:
            UCB3IFG &= ~UCSTPIFG;
            /* Clear address and receive buffer */
            __bic_SR_register_on_exit(LPM0_bits);
            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
            UCB3IFG &= ~UCRXIFG;  //clear rx ifg
            //UCB3CTLW0 |= UCTXSTP;       // I2C stop condition
            //*RXData= UCB3RXBUF;
            *RXSlaveData = UCB3RXBUF;
            RXSlaveData++;
            //*RXData++;
            __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
            break;
        case USCI_I2C_UCTXIFG0:             // Vector 24: TXIFG0
            UCB2TXBUF = 0xAA;
            __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
            break;
        case USCI_I2C_UCBCNTIFG: break;     // Vector 26: BCNTIFG
        case USCI_I2C_UCCLTOIFG: break;     // Vector 28: clock low timeout
        case USCI_I2C_UCBIT9IFG: break;     // Vector 30: 9th bit
        default: break;
    }
}

What did I miss?  Any advice is always appreciated.

Thank you

  • Resolved, I had to clear the start IFG and then later I was using the wrong TXBUF.  Oddly there's no definition for UCSTTIFG that I could see.

  • Thanks for posting the solution Eric, glad to see that you were able to figured it out.  UCSTTIFG is defined as bit 2 of the UCB3IFG and is interrupt source 0x06 of the UCB3IV for eUSCI_B I2C operation.  It should set when the I2C module detects a START condition together with its own address.

    Ryan

**Attention** This is a public forum