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.

MSP430F6779A: I2C not working properly

Part Number: MSP430F6779A

So, I have been trying to receive some digital inpits bits connected to the I/O expander using I2C. The code worked once few months ago, but now when I am trying again it isn't working. When I added a breakpoint in my interrupt vector table for NACK interrupt flag, I found the microcntroller is getting a NACK flag. I am 100% sure that the slave address is correct (0x19). I have enabled all the interrupts, but the code get stuck in a while loop when I try to recieve byte information. This shows that the connection between the master and slave is not established and it is causing the problem. I have tried everything to make it work, but it isn't working. Please help me out here. 

The part where I am getting stuck is below. When I try to recieve the byte in the mains while loop, the code get stuck in the EUSCI_B_I2C_masterReceiveSingle while loop. When I try to call the same function in the interrupt as shown in the code below, the controller doesn't reach that statement because RXIFG bit is not set.




uint8_t EUSCI_B_I2C_masterReceiveSingle(uint16_t baseAddress)
{
    //Polling RXIFG0 if RXIE is not enabled
    if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCRXIE0))
    {
        while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG0))           // the code get stuck here 
        {
            ;
        }
    }

    //Read a byte.
    return (HWREG16(baseAddress + OFS_UCBxRXBUF));
}


This is my whole code for receiving data through I2C


#define SLAVE_ADDRESS 0x19
#include "driverlib.h"
uint8_t RXData;
void main(void)
{
    //Stop WDT
    WDT_A_hold(WDT_A_BASE);

    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_P4,
        GPIO_PIN4 + GPIO_PIN5
        );

    EUSCI_B_I2C_initMasterParam param = {0};
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;            //Setting clock source to SMCLK
    param.i2cClk = UCS_getSMCLK();                                  
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;                 
    param.byteCounterThreshold = 1;                                     //Number of bytes to receive 
    param.autoSTOPGeneration =
        EUSCI_B_I2C_NO_AUTO_STOP;                                        //No auto stop. I can set it to stop if the desired bytes ( in this case - 1) is received. 
    EUSCI_B_I2C_initMaster(EUSCI_B1_BASE, &param);

   EUSCI_B_I2C_setSlaveAddress(EUSCI_B1_BASE,
                                SLAVE_ADDRESS
                                );

    //Set Master in receive mode
    EUSCI_B_I2C_setMode(EUSCI_B1_BASE,
                        EUSCI_B_I2C_RECEIVE_MODE
                        );

    UCB1IE = 0; 
    //Enable I2C Module to start operations
     EUSCI_B_I2C_enable(EUSCI_B1_BASE);

     EUSCI_B_I2C_clearInterrupt(EUSCI_B1_BASE,
     EUSCI_B_I2C_RECEIVE_INTERRUPT1 + 
     EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_NAK_INTERRUPT);              //Clearing all required interrupts 

 
    EUSCI_B_I2C_enableInterrupt(EUSCI_B1_BASE,
                                EUSCI_B_I2C_RECEIVE_INTERRUPT1 +
                               EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_NAK_INTERRUPT
                               );
    
    
   __enable_interrupt();
   //__bis_SR_register(GIE); 
    while(1)
    {
        __delay_cycles(2000);
        while(EUSCI_B_I2C_SENDING_STOP ==
              EUSCI_B_I2C_masterIsStopSent(EUSCI_B1_BASE))
        {
            ;
        }
        // I2C start condition
        EUSCI_B_I2C_masterReceiveStart(EUSCI_B1_BASE);
     } 
} 

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B1_VECTOR)))
#endif
void USCIB1_ISR(void)
{
    static uint8_t count = 0;
    switch(__even_in_range(UCB1IV,0x1E))
    {
    case 0x00: 
      break;       // Vector 0: No interrupts break;
    case 0x02: break;       // Vector 2: ALIFG break;
    case 0x04:
        EUSCI_B_I2C_masterReceiveStart(EUSCI_B1_BASE);              
        break;           // Vector 4: NACKIFG break;
    case 0x06: break;       // Vector 6: STT IFG break;
    case 0x08: break;       // Vector 8: STPIFG break;
    case 0x0a: break;       // Vector 10: RXIFG3 break;
    case 0x0c: break;       // Vector 14: TXIFG3 break;
    case 0x0e: break;       // Vector 16: RXIFG2 break;
    case 0x10: break;       // Vector 18: TXIFG2 break;
    case 0x12: 
      RXData = EUSCI_B_I2C_masterReceiveSingle(
            EUSCI_B1_BASE 
            );                                                               
      break;       // Vector 20: RXIFG1 break;
    case 0x14: break;       // Vector 22: TXIFG1 break;
    case 0x16:
        RXData = EUSCI_B_I2C_masterReceiveSingle(
            EUSCI_B1_BASE
            );                                                               // Get RX data

        break;           // Vector 24: RXIFG0 break;
    case 0x18: break;       // Vector 26: TXIFG0 break;
    case 0x1a:
        break;           // Vector 28: BCNTIFG break;
    case 0x1c: break;       // Vector 30: clock low timeout break;
    case 0x1e: break;       // Vector 32: 9th bit break;
    default: break;
    }
}



Please help me, I am ot sure what I am doing worng. I have spent weeks now trying to figure this out.Pls help. Thanks
  • If you're getting a NACK from the slave, you won't be able to do much of anything else. I suggest you focus on that.

    1) Check your wiring (again). Are you fairly certain the slave is powered up, and that the pullups are still connected? (Keep in mind that a NACK is just the absence of an ACK, so if the slave is "dead", that's what you'll see.)

    2) What slave device are you using? More to the point: What board is it mounted on? Some boards allow you to change the slave address using jumpers, and if you changed that (even accidentally) you'll get NACKs.

    3) If you have a scope, a trace of the transaction is often enlightening.

  • Hello Harsh,

    Have you made any more progress on this? 

    Do you have an LSA to look at the I2C bus?  

    Also, I usually recommend people start with the MSP430 I2C Standard master example which has some read_register and Write_register function examples:  

    Thanks,

    JD

**Attention** This is a public forum