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.

MSP430FR2433: I2C Bus is always busy

Part Number: MSP430FR2433
Other Parts Discussed in Thread: TCA9535

When I run the program below, it never gets past the first while loop that checks if the I2C bus is busy - why is that?

/* --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--*/
//******************************************************************************
//
//! This example shows how to configure the I2C module as a master for
//! multi byte transmission in interrupt driven mode. The address of the slave
//! module is set in this example.
//!
//!  Demo - EUSCI_B0 I2C Master TX multiple bytes to MSP430 Slave
//!
//!  Description: This demo connects two MSP430's via the I2C bus. The master
//!  transmits to the slave. This is the MASTER CODE. It cntinuously
//!  transmits an array of data and demonstrates how to implement an I2C
//!  master transmitter sending multiple bytes using the USCI_B0 TX interrupt.
//!  ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1MHz
//!
//!                                /|\  /|\
//!          MSP430FR2xx_4xx Board 10k  10k MSP430FR2xx_4xx Board
//!                   slave         |    |         master
//!             -----------------   |    |   -----------------
//!            |          UCB0SDA|<-|----+->|UCB0SDA          |
//!            |                 |  |       |                 |
//!            |                 |  |       |                 |
//!            |          UCB0SCL|<-+------>|UCB0SCL          |
//!            |                 |          |                 |
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - I2C peripheral
//! - GPIO Port peripheral (for I2C pins)
//! - SCL
//! - SDA
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_B0_VECTOR.
//
//******************************************************************************
#include "driverlib.h"
#include "Board.h"

//*****************************************************************************
//
//Set the address for slave module. This is a 7-bit address sent in the
//following format:
//[A6:A5:A4:A3:A2:A1:A0:RS]
//
//A zero in the "RS" position of the first byte means that the master
//transmits (sends) data to the selected slave, and a one in this position
//means that the master receives data from the slave.
//
//*****************************************************************************
#define SLAVE_ADDRESS 0x77

//*****************************************************************************
//
//Target frequency for SMCLK in kHz
//
//*****************************************************************************
#define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ   1000

//*****************************************************************************
//
//SMCLK/FLLRef Ratio
//
//*****************************************************************************
#define CS_SMCLK_FLLREF_RATIO   30

// Pointer to TX data
uint8_t TXData = 0;
uint8_t TXByteCtr;

void main(void)
{
    WDT_A_hold(WDT_A_BASE);

    //Set DCO FLL reference = REFO
    CS_initClockSignal(
            CS_FLLREF,
            CS_REFOCLK_SELECT,
            CS_CLOCK_DIVIDER_1
        );

    //Set Ratio and Desired MCLK Frequency and initialize DCO
    CS_initFLLSettle(
            CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ,
            CS_SMCLK_FLLREF_RATIO
            );

    //Set ACLK = VLO with frequency divider of 1
    CS_initClockSignal(
            CS_ACLK,
            CS_VLOCLK_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    //Set SMCLK = DCO with frequency divider of 1
    CS_initClockSignal(
            CS_SMCLK,
            CS_DCOCLKDIV_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    //Set MCLK = DCO with frequency divider of 1
    CS_initClockSignal(
            CS_MCLK,
            CS_DCOCLKDIV_SELECT,
            CS_CLOCK_DIVIDER_1
            );

    // Configure Pins for I2C
    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_UCB0SCL,
        GPIO_PIN_UCB0SCL,
        GPIO_FUNCTION_UCB0SCL
    );
    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_UCB0SDA,
        GPIO_PIN_UCB0SDA,
        GPIO_FUNCTION_UCB0SDA
    );

    /*
     * Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */
    PMM_unlockLPM5();

    EUSCI_B_I2C_initMasterParam param = {0};
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK();
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
    param.byteCounterThreshold = 0;
    param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);

    //Specify slave address
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
            SLAVE_ADDRESS
            );

    //Set Master in receive mode
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_MODE
            );

    //Enable I2C Module to start operations
    EUSCI_B_I2C_enable(EUSCI_B0_BASE);

    EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
            EUSCI_B_I2C_NAK_INTERRUPT
            );

    // Wait for I2C bus to be idle
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE));

    // Send the start condition
    EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, 0x06);

    // Wait for the start condition to be sent
    while (!(EUSCI_B_I2C_getInterruptStatus(EUSCI_B0_BASE, EUSCI_B_I2C_START_INTERRUPT)));

    // Clear the start condition flag
    EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_START_INTERRUPT);

    // send data byte
    EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, 0x00);


    while(1)
    {

    }
}

  • Hi Michael,

    IIC line need pull-up resisotr in SDA and SCL line, would you confirm your hardware connection is well?

    If issue insists, please check which register value is returned by the "EUSCI_B_I2C_isBusBusy", and then find the description of it in user's guide.

    B.R.

    Sal

  • Hi Sal,

    I am currently connected to the TCA9535, and I can confirm that the lines are being pulled high.

    When I run the unmodified example, everything works and I see data on the SDA line.

    With the modified example, I can confirm that the UCBBUSY register is a 1.

    Stepping through the code, it seems to become busy right after the I2C module get's enabled (line 178).

    What could be causing this?

  • Data sheet (SCPS201E) Table 7-2 shows the possible I2C addresses, and 0x77 is not one of them. How are pins A2-A0 configured?

    I would normally expect the NACK to show up later, but maybe if you run the program twice (since the target doesn't know that) you could see this result.

  • Bruce,

    I know that part all works because I can turn the LEDs on the TCA9535 ON/OFF. The address is indeed 0x77.

    When I do not have the correct address, I do see a NACK on the line (I am using a logic analyzer). I am using the EVM for the TCA9535.

    I also made a post about getting stuck polling the UCTXIFG - could these be related?

  • Hi Michael,

    According your description, I think the init code of IIC in unmodified example and modified example might have some difference. Please double check and the possible reason may relevant to this.

    By the way, what is the status of SDA and SCL line after you enable IIC?

    Also, the Master recieve mode process refers to following, you also can grasp the waveform of SDA and SCL, then find abnormal waveform:

    B.R.

    Sal

  • Sal,

    The code works some of the time, but when I go into a debug mode and step through the code, that's when problems start to occur.

    I have to do a full reset of the MSP430 (power down, wait a few minutes) for the exact same code to start working again.

  • Hi Michael,

    If it need a reset from 430, I assume that 430 device makes the IIC line busy.

    Can you share the difference of you code with unmodified code (IIC initialization parts)?

    Also, can you share your IIC waveform and it might help find more information:

    SCL+SDA line: free run with no error;

    SCL+SDA line: debug step, power reset -> inital IIC -> Busy

    B.R.

    Sal

  • I don't use the Driver library but a few observations:

    The setMode call is redundant since the start call sets this.

    Clearing the interrupt flags is also redundant as they are cleared in reset. Well, Figure 24-32 and Table 24-19 conflict on the state of TXIFG0 after reset.

    You don't finish the I2C transaction so a stop is never generated. UCBBUSY is set on a start condition and cleared on a stop.

**Attention** This is a public forum