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/MSP432P401R: msp432 unable to receive from slave.(i2c communication)

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Hi,

I'm working on i2c communication between 2 msp432p401r launchpad(red).

I'm using the code from driverlib "i2c_master_rw_repeated_start_single_byte-master_code" and "i2c_master_rw_repeated_start_single_byte-slave_code".

The issue I'm facing is that the master is not receiving the data from the slave.

The slave is working fine also there is no problem with the transmission from the master.

Could you please help me out.

Regards.

  • Can you confirm that you have not made any modifications to the example code, and the values of the pullup resistors?

    Thanks and Regards,
    Chris
  • Hi Chris,

    Thanks for the reply.

    I'm using 10k pullup resistors for both SCL and SDA lines.

    I've just commented out the lines-->

    //MAP_Interrupt_enableSleepOnIsrExit();--->both in master and slave

    //MAP_PCM_gotoLPM0InterruptSafe();-------->both in master and slave

    MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[0]);---------->change in the master code
    //MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, 0x55);----------->change in the master code

    That's all.

    Please go through the code attached.

    Thanks

    i2c_master_rw_repeated_start-slave_code.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    /* --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_B0 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 SLAVE 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 | 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/UCB0SDA|<-|----+->|P1.6/UCB0SDA |
    * | | | | |
    * | | | | |
    * | P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL |
    * | | | |
    *
    *****************************************************************************/
    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    /* Standard Defines */
    #include <stdint.h>
    #include <stdbool.h>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    2543.i2c_master_rw_repeated_start-master_code.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    /* --COPYRIGHT--,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_B0 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 | 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/UCB0SDA|<-|----+->|P1.6/UCB0SDA |
    * | | | | |
    * | | | | |
    * | P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL |
    * | | | |
    *
    *****************************************************************************/
    /* DriverLib Defines */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    /* Standard Defines */
    #include <stdint.h>
    #include <stdbool.h>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Please find the attached threads for reference.

    e2e.ti.com/.../2120033

    e2e.ti.com/.../2401720

    Regards,
    Chris
  • Hi Chris,

    Thanks for the reference but still introducing delay isn't working for me.
    Could there be any other mistake in my code?

    Regards,
    Vivek
  • You changed one other thing:
    < #define NUM_OF_REC_BYTES 10
    > #define NUM_OF_REC_BYTES 1

    With this setting, this test will never trigger:
    > if (xferIndex == NUM_OF_REC_BYTES - 2)
    and it won't stop (and will corrupt memory). With this program structure, you need to set this to at least 2 (the slave still thinks 10).

    These lines:
    > //MAP_Interrupt_enableSleepOnIsrExit();--->both in master and slave
    > //MAP_PCM_gotoLPM0InterruptSafe();-------->both in master and slave
    were there to make sure you don't start a new transaction before the previous one finishes.

    My guess is that right now you're encountering the second error, but as soon as you fix it you'll encounter the first error.
  • Hi Guys,
    Thanks for helping me out.
    Your guidance solved my issue. Now both master and slave are working fine.
    Here are my final codes for master and slave.
    I've made changes in the master code.

    // I2C MASTER CODE
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>

    /* Slave Address for I2C Slave */
    #define SLAVE_ADDRESS 0x48

    /* Statics */
    static uint8_t TXData = 0;
    static uint8_t TXByteCtr;
    static volatile uint32_t xferIndex;
    static volatile bool stopSent;
    static uint8_t RXData[10];
    static uint32_t numOfRecBytes;
    int flag,flag1,i;

    //![Simple I2C Config]
    /* 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_400KBPS, // Desired I2C Clock of 400khz
    0, // No byte counter threshold
    EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
    };
    //![Simple I2C Config]

    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,
    * (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
    */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
    GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

    //![Simple I2C Example]
    /* Initializing I2C Master to SMCLK at 400kbs with no autostop */
    MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);

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

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

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

    /* Enable and clear the interrupt flag */
    MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

    /* Enable master transmit interrupt */
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    //![Simple I2C Example]

    while (1)
    {
    /* Delay between Transmissions */
    for (ii = 0; ii < 10000; ii++);

    /* Load Byte Counter */
    TXByteCtr = 4;
    TXData = 0;

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

    /* Sending the initial start condition */
    MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData++);

    MAP_Interrupt_enableSleepOnIsrExit();
    MAP_PCM_gotoLPM0InterruptSafe();
    }
    }

    void EUSCIB0_IRQHandler(void)
    {
    uint_fast16_t status;

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

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
    MAP_I2C_masterSendStart(EUSCI_B0_BASE);
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
    /* Check the byte counter */
    if (TXByteCtr)
    {
    /* Send the next data and decrement the byte counter */
    MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData++);
    TXByteCtr--;
    } else
    {
    flag=1;
    MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
    MAP_Interrupt_disableSleepOnIsrExit();
    MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
    xferIndex = 0;
    MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    }
    }

    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
    if(xferIndex == 0)
    {
    RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
    numOfRecBytes = RXData[0];
    }
    else if (xferIndex == (numOfRecBytes - 2))
    {
    MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
    RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
    }
    else if (xferIndex == (numOfRecBytes - 1))
    {
    RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
    MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_STOP_INTERRUPT);
    MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    xferIndex = 0;
    stopSent = true;
    MAP_Interrupt_disableSleepOnIsrExit();

    }
    else
    {
    RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
    }
    }
    }
    ----------------------------------------------------------------------------------------------------------------------------------------------------
    ____________________________________________________________________________________________
    //I2C SLAVE CODE
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

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

    /* Application Defines */
    #define SLAVE_ADDRESS 0x48
    #define NUM_OF_RX_BYTES 4
    #define NUM_OF_TX_BYTES 10

    /* Application Variables */
    static volatile uint8_t RXData[NUM_OF_RX_BYTES];
    static volatile uint32_t xferIndex,kk;
    const uint32_t TXData[NUM_OF_TX_BYTES] =
    {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
    };

    int main(void)
    {
    /* Disabling the Watchdog */
    MAP_WDT_A_holdTimer();
    xferIndex = 0;

    /* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,
    * (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
    */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
    GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

    /* eUSCI I2C Slave Configuration */
    MAP_I2C_initSlave(EUSCI_B0_BASE, SLAVE_ADDRESS, EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
    EUSCI_B_I2C_OWN_ADDRESS_ENABLE);

    MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);

    /* Enable the module and enable interrupts */
    MAP_I2C_enableModule(EUSCI_B0_BASE);
    MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
    MAP_Interrupt_enableSleepOnIsrExit();
    MAP_Interrupt_enableMaster();

    while (1)
    {
    MAP_PCM_gotoLPM0();
    }
    }

    void EUSCIB0_IRQHandler(void)
    {
    uint_fast16_t status;

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

    /* RXIFG */
    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
    RXData[xferIndex++] = MAP_I2C_slaveGetData(EUSCI_B0_BASE);

    /* Resetting the index if we are at the end */
    if (xferIndex == NUM_OF_RX_BYTES)
    {
    xferIndex = 0;
    MAP_I2C_disableInterrupt(EUSCI_B0_BASE,
    EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    }

    }

    /* TXIFG */
    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
    MAP_I2C_slavePutData(EUSCI_B0_BASE, TXData[xferIndex++]);
    kk++; //just to check how many times the interrupt is triggered
    /* Resetting the index if we are at the end */
    if (xferIndex == NUM_OF_TX_BYTES)
    {
    xferIndex = 0;
    MAP_I2C_disableInterrupt(EUSCI_B0_BASE,
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
    EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    }
    }
    }

**Attention** This is a public forum