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.

MSP432P401R: I2C code hangs at MAP_I2C_masterSendMultiByteStart

Part Number: MSP432P401R

I have built a new board and I am trying to get I2C functionality to work. My code is hanging whenever I call MAP_I2C_masterSendMultiByteStart. Specifically at this point in the driverlib function: 

    while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS))
        ;

I am using the example, updated for the SCL and SDA Pins I am using (P6.6 - UCB3SDA, AND P6.7 - UCB3SCL)

Attached is the code I have. What is causing it to hang?

When I look at my code from a logic analyzer, it shows that only SDA is sending data, and nothing is happening on SCL.

I fixed a hardware error (toombstoned termination resistor) on the SCL line, and now I get nothing on my logic analyzer at all. All connections on the bus seem to be intact, and there does not appear to be any more hardware errors. The termination resistors are 3.3K ohm.

/*
 * -------------------------------------------
 *    MSP432 DriverLib - v3_21_00_05 
 * -------------------------------------------
 *
 * --COPYRIGHT--,BSD,BSD
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
/******************************************************************************
 *  MSP432 I2C - EUSCI_B3_BASE I2C Master TX  bytes to MSP432 Slave - Repeated Start
 *
 *  Description: This demo connects two MSP432 's via the I2C bus. The master
 *  transmits to the slave. This is the MASTER CODE. It continuously
 *  transmits an array of data and demonstrates how to implement an I2C
 *  master transmitter sending multiple bytes followed by a repeated start,
 *  followed by a read of multiple bytes.  This is a common operation for
 *  reading register values from I2C slave devices such as sensors. The
 *  transaction for the I2C that is written looks as follows:
 *
 *  ________________________________________________________________
 *  |  Start   |      |      |  Start   |                   |       |
 *  | 0x48Addr | 0x04 | 0x00 | 0x48Addr |  <10 Byte Read>   | Stop  |
 *  |    W     |      |      |    R     |                   |       |
 *  |__________|______|______|__________|___________________|_______|
 *
 *  ACLK = n/a, MCLK = HSMCLK = SMCLK = BRCLK = default DCO = ~3.0MHz
 *
 *                                /|\  /|\
 *                MSP432P401      10k  10k      MSP432P401
 *                   slave         |    |         master
 *             -----------------   |    |   -----------------
 *            |     P1.6/UCB3SDA|<-|----+->|P1.6/UCB3SDA     |
 *            |                 |  |       |                 |
 *            |                 |  |       |                 |
 *            |     P1.7/UCB3SCL|<-+------>|P1.7/UCB3SCL     |
 *            |                 |          |                 |
 *
 * Author: Timothy Logan
 *****************************************************************************/
/* DriverLib Defines */
#include "driverlib.h"

/* Standard Defines */
#include <stdint.h>

#include <stdbool.h>
#include <string.h>

/* Slave Address for I2C Slave */
#define SLAVE_ADDRESS       0x55
#define NUM_OF_REC_BYTES    10

/* Variables */
const uint8_t TXData[2] = {0x04, 0x00};
static uint8_t RXData[NUM_OF_REC_BYTES];
static volatile uint32_t xferIndex;
static volatile bool stopSent;

/* I2C Master Configuration Parameter */
const eUSCI_I2C_MasterConfig i2cConfig =
{
        EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        3000000,                                // SMCLK = 3MHz
        EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 100khz
        0,                                      // No byte counter threshold
        EUSCI_B_I2C_NO_AUTO_STOP                // No Autostop
};

int main(void)
{
    volatile uint32_t ii;

    /* Disabling the Watchdog  */
    MAP_WDT_A_holdTimer();

    /* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,
     *   (UCB3SIMO/UCB3SDA, UCB3SOMI/UCB3SCL).
     */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,
            GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
    stopSent = false;
    memset(RXData, 0x00, NUM_OF_REC_BYTES);

    /* Initializing I2C Master to SMCLK at 100khz with no autostop */
    MAP_I2C_initMaster(EUSCI_B3_BASE, &i2cConfig);

    /* Specify slave address */
    MAP_I2C_setSlaveAddress(EUSCI_B3_BASE, SLAVE_ADDRESS);

    /* Set Master in transmit mode */
    MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_MODE);

    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(EUSCI_B3_BASE);

    /* Enable and clear the interrupt flag */
    MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    //Enable master Receive interrupt
    MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    MAP_Interrupt_enableSleepOnIsrExit();
    MAP_Interrupt_enableInterrupt(INT_EUSCIB3);

    while (1)
    {
        /* Making sure the last transaction has been completely sent out */
        while (MAP_I2C_masterIsStopSent(EUSCI_B3_BASE) == EUSCI_B_I2C_SENDING_STOP);

        /* Send start and the first byte of the transmit buffer. We have to send
         * two bytes to clean out whatever is in the buffer from a previous
         * send  */
        MAP_I2C_masterSendMultiByteStart(EUSCI_B3_BASE, TXData[0]);
        MAP_I2C_masterSendMultiByteNext(EUSCI_B3_BASE, TXData[0]);


        /* Enabling transfer interrupt after stop has been sent */
        MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

        /* While the stop condition hasn't been sent out... */
        while(!stopSent)
        {
            MAP_PCM_gotoLPM0InterruptSafe();
        }

        stopSent = false;
    }
}

/*******************************************************************************
 * eUSCIB3 ISR. The repeated start and transmit/receive operations happen
 * within this ISR.
 *******************************************************************************/
void EUSCIB3_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B3_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE, status);

    /* If we reached the transmit interrupt, it means we are at index 1 of
     * the transmit buffer. When doing a repeated start, before we reach the
     * last byte we will need to change the mode to receive mode, set the start
     * condition send bit, and then load the final byte into the TXBUF.
     */
    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        MAP_I2C_masterSendMultiByteNext(EUSCI_B3_BASE, TXData[1]);
        MAP_I2C_disableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
        MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_MODE);
        xferIndex = 0;
        MAP_I2C_masterReceiveStart(EUSCI_B3_BASE);
        MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

    }

    /* Receives bytes into the receive buffer. If we have received all bytes,
     * send a STOP condition */
    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        if(xferIndex == NUM_OF_REC_BYTES - 2)
        {
            MAP_I2C_masterReceiveMultiByteStop(EUSCI_B3_BASE);
            RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
        }
        else if(xferIndex == NUM_OF_REC_BYTES - 1)
        {
            RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
            MAP_I2C_disableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
            MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
            xferIndex = 0;
            stopSent = true;
            MAP_Interrupt_disableSleepOnIsrExit();
        }
        else
        {
            RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
        }

    }
}
    
/*
 * -------------------------------------------
 *    MSP432 DriverLib - v3_21_00_05 
 * -------------------------------------------
 *
 * --COPYRIGHT--,BSD,BSD
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
#include <stdint.h>

/* Forward declaration of the default fault handlers. */
static void resetISR(void);
static void nmiISR(void);
static void faultISR(void);
static void defaultISR(void);


/* External declaration for the reset handler that is to be called when the */
/* processor is started                                                     */
extern void _c_int00(void);

/* External declaration for system initialization function                  */
extern void SystemInit(void);

/* Linker variable that marks the top of the stack. */
extern unsigned long __STACK_END;


/* External declarations for the interrupt handlers used by the application. */
extern void EUSCIB3_IRQHandler (void);

/* Interrupt vector table.  Note that the proper constructs must be placed on this to  */
/* ensure that it ends up at physical address 0x0000.0000 or at the start of          */
/* the program if located at a start address other than 0.                            */
#pragma RETAIN(interruptVectors)
#pragma DATA_SECTION(interruptVectors, ".intvecs")
void (* const interruptVectors[])(void) =
{
    (void (*)(void))((uint32_t)&__STACK_END),
                                            /* The initial stack pointer */
    resetISR,                               /* The reset handler         */
    nmiISR,                                 /* The NMI handler           */
    faultISR,                               /* The hard fault handler    */
    defaultISR,                             /* The MPU fault handler     */
    defaultISR,                             /* The bus fault handler     */
    defaultISR,                             /* The usage fault handler   */
    0,                                      /* Reserved                  */
    0,                                      /* Reserved                  */
    0,                                      /* Reserved                  */
    0,                                      /* Reserved                  */
    defaultISR,                             /* SVCall handler            */
    defaultISR,                             /* Debug monitor handler     */
    0,                                      /* Reserved                  */
    defaultISR,                             /* The PendSV handler        */
    defaultISR,                             /* The SysTick handler       */
    defaultISR,                             /* PSS ISR                   */
    defaultISR,                             /* CS ISR                    */
    defaultISR,                             /* PCM ISR                   */
    defaultISR,                             /* WDT ISR                   */
    defaultISR,                             /* FPU ISR                   */
    defaultISR,                             /* FLCTL ISR                 */
    defaultISR,                             /* COMP0 ISR                 */
    defaultISR,                             /* COMP1 ISR                 */
    defaultISR,                             /* TA0_0 ISR                 */
    defaultISR,                             /* TA0_N ISR                 */
    defaultISR,                             /* TA1_0 ISR                 */
    defaultISR,                             /* TA1_N ISR                 */
    defaultISR,                             /* TA2_0 ISR                 */
    defaultISR,                             /* TA2_N ISR                 */
    defaultISR,                             /* TA3_0 ISR                 */
    defaultISR,                             /* TA3_N ISR                 */
    defaultISR,                             /* EUSCIA0 ISR               */
    defaultISR,                             /* EUSCIA1 ISR               */
    defaultISR,                             /* EUSCIA2 ISR               */
    defaultISR,                             /* EUSCIA3 ISR               */
    defaultISR,                     /* EUSCIB0 ISR               */
    defaultISR,                             /* EUSCIB1 ISR               */
    defaultISR,                             /* EUSCIB2 ISR               */
    EUSCIB3_IRQHandler,                             /* EUSCIB3 ISR               */
    defaultISR,                             /* ADC14 ISR                 */
    defaultISR,                             /* T32_INT1 ISR              */
    defaultISR,                             /* T32_INT2 ISR              */
    defaultISR,                             /* T32_INTC ISR              */
    defaultISR,                             /* AES ISR                   */
    defaultISR,                             /* RTC ISR                   */
    defaultISR,                             /* DMA_ERR ISR               */
    defaultISR,                             /* DMA_INT3 ISR              */
    defaultISR,                             /* DMA_INT2 ISR              */
    defaultISR,                             /* DMA_INT1 ISR              */
    defaultISR,                             /* DMA_INT0 ISR              */
    defaultISR,                             /* PORT1 ISR                 */
    defaultISR,                             /* PORT2 ISR                 */
    defaultISR,                             /* PORT3 ISR                 */
    defaultISR,                             /* PORT4 ISR                 */
    defaultISR,                             /* PORT5 ISR                 */
    defaultISR,                             /* PORT6 ISR                 */
    defaultISR,                             /* Reserved 41               */
    defaultISR,                             /* Reserved 42               */
    defaultISR,                             /* Reserved 43               */
    defaultISR,                             /* Reserved 44               */
    defaultISR,                             /* Reserved 45               */
    defaultISR,                             /* Reserved 46               */
    defaultISR,                             /* Reserved 47               */
    defaultISR,                             /* Reserved 48               */
    defaultISR,                             /* Reserved 49               */
    defaultISR,                             /* Reserved 50               */
    defaultISR,                             /* Reserved 51               */
    defaultISR,                             /* Reserved 52               */
    defaultISR,                             /* Reserved 53               */
    defaultISR,                             /* Reserved 54               */
    defaultISR,                             /* Reserved 55               */
    defaultISR,                             /* Reserved 56               */
    defaultISR,                             /* Reserved 57               */
    defaultISR,                             /* Reserved 58               */
    defaultISR,                             /* Reserved 59               */
    defaultISR,                             /* Reserved 60               */
    defaultISR,                             /* Reserved 61               */
    defaultISR,                             /* Reserved 62               */
    defaultISR                              /* Reserved 63               */
};


/* This is the code that gets called when the processor first starts execution */
/* following a reset event.  Only the absolutely necessary set is performed,   */
/* after which the application supplied entry() routine is called.  Any fancy  */
/* actions (such as making decisions based on the reset cause register, and    */
/* resetting the bits in that register) are left solely in the hands of the    */
/* application.                                                                */
void resetISR(void)
{
    SystemInit();

    /* Jump to the CCS C Initialization Routine. */
    __asm("    .global _c_int00\n"
          "    b.w     _c_int00");
}

/* This is the code that gets called when the processor receives a NMI.  This  */
/* simply enters an infinite loop, preserving the system state for examination */
/* by a debugger.                                                              */
static void nmiISR(void)
{
    /* Fault trap exempt from ULP advisor */
    #pragma diag_push
    #pragma CHECK_ULP("-2.1")

    /* Enter an infinite loop. */
    while(1)
    {
    }

    #pragma diag_pop
}


/* This is the code that gets called when the processor receives a fault        */
/* interrupt.  This simply enters an infinite loop, preserving the system state */
/* for examination by a debugger.                                               */
static void faultISR(void)
{
    /* Fault trap exempt from ULP advisor */
    #pragma diag_push
    #pragma CHECK_ULP("-2.1")

    /* Enter an infinite loop. */
    while(1)
    {
    }

    #pragma diag_pop
}


/* This is the code that gets called when the processor receives an unexpected  */
/* interrupt.  This simply enters an infinite loop, preserving the system state */
/* for examination by a debugger.                                               */
static void defaultISR(void)
{
    /* Fault trap exempt from ULP advisor */
    #pragma diag_push
    #pragma CHECK_ULP("-2.1")

    /* Enter an infinite loop. */
    while(1)
    {
    }

    #pragma diag_pop
}

  • Show the schematic of your circuit.
    What are the voltage levels of the I²C signals?
    Is this software the original example code, or did you change something?
  • The circuit schematic is attached. It works fine when jerry rigged to pins 1.6 and 1.7 as in the original example code.

    The uploaded code is not the original example. B0 has been changed to B3 and I have played with changing EUSCI_B_I2C_TRANSMIT_INTERRUPT0 to EUSCI_B_I2C_TRANSMIT_INTERRUPT3

    The code I have been working with is below, I am using the MSP432 SDK (driverlib)

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v4_00_00_11 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /******************************************************************************
     *  MSP432 I2C - EUSCI_B3_BASE I2C Master TX  bytes to MSP432 Slave - Repeated Start
     *
     *  Description: This demo connects two MSP432 's via the I2C bus. The master
     *  transmits to the slave. This is the MASTER CODE. It continuously
     *  transmits an array of data and demonstrates how to implement an I2C
     *  master transmitter sending multiple bytes followed by a repeated start,
     *  followed by a read of multiple bytes.  This is a common operation for
     *  reading register values from I2C slave devices such as sensors. The
     *  transaction for the I2C that is written looks as follows:
     *
     *  ________________________________________________________________
     *  |  Start   |      |      |  Start   |                   |       |
     *  | 0x48Addr | 0x04 | 0x00 | 0x48Addr |  <10 Byte Read>   | Stop  |
     *  |    W     |      |      |    R     |                   |       |
     *  |__________|______|______|__________|___________________|_______|
     *
     *  ACLK = n/a, MCLK = HSMCLK = SMCLK = BRCLK = default DCO = ~3.0MHz
     *
     *                                /|\  /|\
     *                MSP432P401      10k  10k      MSP432P401
     *                   slave         |    |         master
     *             -----------------   |    |   -----------------
     *            |     P1.6/UCB3SDA|<-|----+->|P1.6/UCB3SDA     |
     *            |                 |  |       |                 |
     *            |                 |  |       |                 |
     *            |     P1.7/UCB3SCL|<-+------>|P1.7/UCB3SCL     |
     *            |                 |          |                 |
     *
     * Author: Timothy Logan
     *****************************************************************************/
    /* DriverLib Defines */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Defines */
    #include <stdint.h>
    
    #include <stdbool.h>
    #include <string.h>
    
    /* Slave Address for I2C Slave */
    #define SLAVE_ADDRESS       0x48
    #define NUM_OF_REC_BYTES    10
    
    /* Variables */
    const uint8_t TXData[2] = {0x04, 0x00};
    static uint8_t RXData[NUM_OF_REC_BYTES];
    static volatile uint32_t xferIndex;
    static volatile bool stopSent;
    
    /* I2C Master Configuration Parameter */
    const eUSCI_I2C_MasterConfig i2cConfig =
    {
            EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
            3000000,                                // SMCLK = 3MHz
            EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 100khz
            0,                                      // No byte counter threshold
            EUSCI_B_I2C_NO_AUTO_STOP                // No Autostop
    };
    
    int main(void)
    {
        volatile uint32_t ii;
    
        /* Disabling the Watchdog  */
        MAP_WDT_A_holdTimer();
    
        /* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,
         *   (UCB3SIMO/UCB3SDA, UCB3SOMI/UCB3SCL).
         */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6,
                GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
        stopSent = false;
        memset(RXData, 0x00, NUM_OF_REC_BYTES);
    
        /* Initializing I2C Master to SMCLK at 100khz with no autostop */
        MAP_I2C_initMaster(EUSCI_B3_BASE, &i2cConfig);
    
        /* Specify slave address */
        MAP_I2C_setSlaveAddress(EUSCI_B3_BASE, SLAVE_ADDRESS);
    
        /* Set Master in transmit mode */
        MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    
        /* Enable I2C Module to start operations */
        MAP_I2C_enableModule(EUSCI_B3_BASE);
    
        /* Enable and clear the interrupt flag */
        MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE,
                EUSCI_B_I2C_TRANSMIT_INTERRUPT3 + EUSCI_B_I2C_RECEIVE_INTERRUPT3);
        //Enable master Receive interrupt
        MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT3);
        MAP_Interrupt_enableSleepOnIsrExit();
        MAP_Interrupt_enableInterrupt(INT_EUSCIB3);
    
        while (1)
        {
            /* Making sure the last transaction has been completely sent out */
            while (MAP_I2C_masterIsStopSent(EUSCI_B3_BASE) == EUSCI_B_I2C_SENDING_STOP);
    
            /* Send start and the first byte of the transmit buffer. We have to send
             * two bytes to clean out whatever is in the buffer from a previous
             * send  */
            MAP_I2C_masterSendMultiByteStart(EUSCI_B3_BASE, TXData[0]);
            MAP_I2C_masterSendMultiByteNext(EUSCI_B3_BASE, TXData[0]);
    
    
            /* Enabling transfer interrupt after stop has been sent */
            MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT3);
    
            /* While the stop condition hasn't been sent out... */
            while(!stopSent)
            {
                MAP_PCM_gotoLPM0InterruptSafe();
            }
    
            stopSent = false;
        }
    }
    
    /*******************************************************************************
     * eUSCIB3 ISR. The repeated start and transmit/receive operations happen
     * within this ISR.
     *******************************************************************************/
    void EUSCIB3_IRQHandler(void)
    {
        uint_fast16_t status;
    
        status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B3_BASE);
        MAP_I2C_clearInterruptFlag(EUSCI_B3_BASE, status);
    
        /* If we reached the transmit interrupt, it means we are at index 1 of
         * the transmit buffer. When doing a repeated start, before we reach the
         * last byte we will need to change the mode to receive mode, set the start
         * condition send bit, and then load the final byte into the TXBUF.
         */
        if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT3)
        {
            MAP_I2C_masterSendMultiByteNext(EUSCI_B3_BASE, TXData[1]);
            MAP_I2C_disableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT3);
            MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_MODE);
            xferIndex = 0;
            MAP_I2C_masterReceiveStart(EUSCI_B3_BASE);
            MAP_I2C_enableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT3);
    
        }
    
        /* Receives bytes into the receive buffer. If we have received all bytes,
         * send a STOP condition */
        if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT3)
        {
            if(xferIndex == NUM_OF_REC_BYTES - 2)
            {
                MAP_I2C_masterReceiveMultiByteStop(EUSCI_B3_BASE);
                RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
            }
            else if(xferIndex == NUM_OF_REC_BYTES - 1)
            {
                RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
                MAP_I2C_disableInterrupt(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT3);
                MAP_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
                xferIndex = 0;
                stopSent = true;
                MAP_Interrupt_disableSleepOnIsrExit();
            }
            else
            {
                RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE);
            }
    
        }
    }
        
    

  • The eUSCI module has four interrupts flags to be able to handle the four different slave addresses.

    In master mode, each module has only a single interrupt, so have to use EUSCI_B_I2C_TRANSMIT_INTERRUPT0. (Different modules have different interrupt vectors instead.)
  • I got it. I needed to set the pin to secondary not primary.

**Attention** This is a public forum