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.

MSP430F5340: MSP430F5340 hangs while checking UCTXSTT bit

Part Number: MSP430F5340

Hi 

i am facing an issue where MSP hangs while checking for UCTXSTT bit.

below is my code:

UCB1I2CSA = ucSlaveAddress;
UCB1CTL1 &= ~UCSWRST;

UCB1CTL1 |= UCTR | UCTXSTT; // I2C tx, start condition


while (((UCB1CTL1 & UCTXSTT) == 0) && (UCB1IFG & UCTXIFG));

if i remove ((UCB1CTL1 & UCTXSTT)  and monitor only IFG flag it works and later i am checking for NACK. code works fine without any NACK after start condition is generated. 

But why is it hanging when i am checking for  UCTXSTT bit. ?

Thanks

Rekha

  • Hi Rekha,

    Please refer to example code.

    Is it possible device hangs on a repeated START condition?

    1212.C.zip

    Thanks,

    Ling

  • Hi,

    device will not hang on repeated start i mean when MSP is switched from Transmit mode to receiver mode.

    initially start bit is sent and then i am polling for UCTXSTT bit to clear. but it never happens.

    i even referred example code but it has interrupt based approach. but my code follows polling method.

    attaching my file.

    i2c battry.txt
     //I2C function//
    
    uint8_t ucRxdata[2] = { };
        UCB1I2CSA = ucSlaveAddress;               // set Slave Address as 0x55
        UCB1CTL1 &= ~UCSWRST;
    
        UCB1CTL1 |= UCTR | UCTXSTT;             // I2C tx, start condition
    
        for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++)
        {
            if (((UCB1CTL1 & UCTXSTT) == 0) && (UCB1IFG & UCTXIFG))
           // if ((UCB1IFG & UCTXIFG))
            {
                break;
            }
        }
        if (g_uloopcount == LOOP_COUNT)
        {
            /* Stop the I2C transmission */
            UCB1CTL1 |= UCTXSTP;
            //send previous value
            return prev_value;
        }
        /* Check for NACK/ACK - after start+address byte */
        if (UCB1IFG & UCNACKIFG)
        {
            /* Stop the I2C transmission */
            UCB1CTL1 |= UCTXSTP;
    
            /* Clear the interrupt flag */
            UCB1IFG &= ~UCNACKIFG;
    
            //should reset MSP if Battery Percentage I2C is called first time and encounters I2C error
            if(one_time_flag == false)
            {
                one_time_flag = true;
                return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value);
            }
            else
            {
                //send previous value
                return prev_value;
            }
        }
        UCB1TXBUF = ucCmd;
        // wait until cmd got sent
        for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++)
        {
            if (UCB1IFG & UCTXIFG)
            {
                break;
            }
        }
        if (g_uloopcount == LOOP_COUNT)
        {
            /* Stop the I2C transmission */
            UCB1CTL1 |= UCTXSTP;
            //send previous value
            return prev_value;
        }
        UCB1CTL1 &= ~UCTR;
        UCB1CTL1 |= UCTXSTT;
        //wait till the start condition is cleared
        for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++)
        {
            if ((UCB1CTL1 & UCTXSTT) == 0)
            {
                break;
            }
        }
        if (g_uloopcount == LOOP_COUNT)
        {
            /* Stop the I2C transmission */
            UCB1CTL1 |= UCTXSTP;
            //send previous value
            return prev_value;
        }
    
        /* Check for ACK */
        if (UCB1IFG & UCNACKIFG)
        {
            /* Stop the I2C transmission */
            UCB1CTL1 |= UCTXSTP;
    
            /* Clear the interrupt flag */
            UCB1IFG &= ~UCNACKIFG;
            //should reset MSP if Battery Percentage I2C is called first time and encounters I2C error
            if (one_time_flag == false)
            {
                one_time_flag = true;
                return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value);
            }
            else
            {
                //send previous value
                return prev_value;
            }
        }
    
        unsigned int uiCounter = 0;
        unsigned int uiRxCounter = 2;
        while (uiRxCounter > 0)
        {
            for (g_uloopcount = 0; g_uloopcount < LOOP_COUNT; g_uloopcount++)
            {
                if (UCB1IFG & UCRXIFG)
                {
                    break;
                }
            }
            if (g_uloopcount == LOOP_COUNT)
            {
                /* Stop the I2C transmission */
                UCB1CTL1 |= UCTXSTP;
                //send previous value
                return prev_value;
            }
    
            /* Check for ACK */
            if (UCB1IFG & UCNACKIFG)
            {
                /* Stop the I2C transmission */
                UCB1CTL1 |= UCTXSTP;
    
                /* Clear the interrupt flag */
                UCB1IFG &= ~UCNACKIFG;
    
                if (one_time_flag == false)
                {
                    one_time_flag = true;
                    return BatteryFuelGuageI2CMasterReceive(ucSlaveAddress, ucCmd, ucDataLength, prev_value);
                }
                else
                {
                    //send previous value
                    return prev_value;
                }
    
            }
            ucRxdata[uiCounter] = UCB1RXBUF; // Receive data from fuel gauge
            if (uiCounter == 0)
            {
                //Send stop condition.
                UCB1CTL1 |= UCTXSTP;
            }
            uiCounter++;
            uiRxCounter--;
        }
    
        UCB1IFG &= ~UCRXIFG;
        /* Clear USCI_B1 TX int flag */
        UCB1IFG &= ~UCTXIFG;
    
        g_uBatteryInfo = (uint16_t) ucRxdata[0] << 8 | ucRxdata[1]; //Transmit received data byte by byte
    
        return g_uBatteryInfo;

    Thanks

    Rekha

  • As shown in User Guide (SLAU208Q) Fig 38-12, STT won't clear until you recognize TXIFG and put something into TXBUF. 

    So I can see how the if() in the code you attached can fail, but not how the while() you posted could hang (since there the sense of the test is reversed).

    In any case, go through that Figure and assure that your code follows the required steps.

  • Bruce McKenney47378 said:
    As shown in User Guide (SLAU208Q) Fig 38-12, STT won't clear until you recognize TXIFG and put something into TXBUF

    does this means my code is not checking for flags properly?

    also i did not understand which figure you are talking about!!!

  • Yes, the indicated if() should only be checking for TXIFG, since until you act upon that STT will always be 1.

    The Figure is the diagram in the F5 User Guide (Rev Q) p. 1006. There should be a link to this document on the Product page. I keep this (or equivalent) page open all the time when I'm trying to write I2C code.

  • thank you for your quick response.

    ok i modified my code to monitor IFG flag -> look for NACK -> if ACK is received -> confirms that STT is cleared and i continue with code flow.

    is my approach correct?

    Thanks

    Rekha

  • Sounds about right. (I don't have the diagram in front of me.)

    You didn't mention it, but in response to the TXIFG you must actually write to TXBUF in order to proceed. (The bus is stalled until you do that.)

    What does it do when you run it?

  • Hi,

    yes i am writing to TxBUF in response to IFG flag. 

    when we run it : slave's register address is written to TXBUF, once this command is executed we restart I2C by changing MSP to receiver mode to receive data from slave.

  • That sounds like what you set out to do. Good to hear.

  • Thank you very much for your constant support. i will go ahead and close this ticket.