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.

CCS: Slave not responding in i2c

Tool/software: Code Composer Studio

Hi,


I am interfacing MAX30100(Pulse oximeter sensor) with MSP430 using I2C Communication. I am transmitting device ID address but not able to read its value. It is stucking in the received buffer. When we start I2C condition the NACKIFG is becoming always one.

#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
  if(Rx == 1){                              // Master Recieve?
      PRxData[0] = UCB0RXBUF;                       // Get RX data
      temp++;
      __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
     // UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
    //  Rx--;
                IFG2 &= ~UCB0RXIFG;
  }

  else{                                     // Master Transmit
      if (TXByteCtr)                            // Check TX byte counter
        {

          UCB0TXBUF = 0xFF;                     // Load TX buffer  address of register 0xFF
          TXByteCtr--;                            // Decrement TX byte counter
          flag--;
          UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
                    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
                    __delay_cycles(112505);
                    __bic_SR_register_on_exit(CPUOFF);
        }

 }

}
void init_I2C(void) {
      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 = itgAddress;                         // Slave Address is 069h
      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
      IE2 |= UCB0RXIE + UCB0TXIE;               //Enable RX and TX interrupt
}

void Transmit(void){
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    UCB0STAT &= ~UCNACKIFG;
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
}
void Receive(void){
        while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
        UCB0CTL1 &= ~UCTR ;                     // Clear UCTR
        UCB0CTL1 |= UCTXSTT;                    // I2C start condition
        UCB0STAT &= ~UCNACKIFG;
        while (UCB0CTL1 & UCTXSTT);             // Start condition sent?
        UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
}    - --------------------------->stopping here

Can anyone tell us what is the problem and how to resolve it. Thanks in advance.

  • Hi swathi,

    There are several possible reasons as to why you are receiving a NACK when trying to start a communication sequence:

    1. The SDA and SCL lines are not pulled up to Vcc through the proper resistor values (4.7 kOhm recommended) or connected to the correct MSP pins.
    2. Incorrect slave address (57h according to the MAX30100 datasheet).
    3. PxSEL registers are not initialized properly for I2C pin functionality (not shown in code excerpt above).
    4. USCI registers have not been initialized properly (refer to TI-provided examples).
    5. Slave device is not powered properly (1.7 to 2.0 V from MAX30100 datasheet) or I2C line voltage level mismatch.

    Please follow these suggestions, provide your MSP device derivative, and oscilloscope or logic analyzer screenshots of the issue. e2e.ti.com/.../msp-i2c-getting-started-guide

    Regards,
    Ryan
  • Hi Ryan,

    Thanks for replying.
    1.we tried using 4.7KOhm pull ups and also more than 1k resistor but we got struck in transmit function itself.so we are using 1k pull up and less than that then it is stucking in after receive function as mentioned before.
    2. we provided 57h only as address
    3.P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
    P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
    4. WDTCTL = WDTPW + WDTHOLD;
    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 = itgAddress; // Slave Address is 069h
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    IE2 |= UCB0RXIE + UCB0TXIE;
    5.we given 3.3 v as mentioned in datasheet 1.8 to 3.3v.

    Actually we are able to interface another sensor (bmp180) where we followed the same procedure.but while interfacing max30100 we are unable to receive anything(observed NACKIFG flag not getting cleared when compared to bmp180).
  • Hi swathi,

    Since you've proven that the USCI initialization is correct (through previous communication with the bmp180) and that the slave device is powered on and sometimes responding (validating the slave address), you should focus specifically on the hardware lines and use an oscilloscope or logic analyzer to verify that your receive sequence is as expected according to the MSP430 and MAX30100 datasheets.

    Regards,
    Ryan

**Attention** This is a public forum