• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » I2C hangs on while (UCB0CTL1_bit.UCTXSTT == 1);
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    I2C hangs on while (UCB0CTL1_bit.UCTXSTT == 1);

    This question is answered
    Flavio Renga90296
    Posted by Flavio Renga90296
    on Apr 27 2012 18:12 PM
    Prodigy40 points

    I'm trying to communicate with an external sensor with I2C interface, using the MSP430G2553 peripheral in polling mode (no interrupt).

    The code hangs on the while (UCB0CTL1_bit.UCTXSTT == 1); polling line, just after the MSP sends the start command and then the slave address.

    I checked the signals with an oscilloscope: the clock remains low just after the last address bit.

    I know that after the UCTXSTT while loop I should also check the interrupt to verify if the slave has the acknowledged the address, but the main problem is that program doesn't exit the while loop.

    I also noticed that many MSP users have the same problem in using the I2C in a polling mode.

    Shouldn't be used in this way?

    Is there any solution?

    Hereafter the code:

    --------

    UCB0CTL1_bit.UCSWRST = 1; // USCI Software Reset

    UCB0CTL0_bit.UCSYNC = 1; // Syncronous Mode
    UCB0CTL0_bit.UCMODE0 = 1; // I2C Mode
    UCB0CTL0_bit.UCMODE1 = 1; // I2C Mode
    UCB0CTL0_bit.UCMST = 1; // Master Select
    UCB0CTL0_bit.UCMM = 0; // Single Master Environment
    UCB0CTL0_bit.UCSLA10 = 0; // 7 bit Slave Address
    UCB0CTL0_bit.UCA10 = 0; // 7 bit Own Address

    UCB0CTL1_bit.UCSSEL0 = 1; // SMCLCK Select
    UCB0CTL1_bit.UCSSEL1 = 1; // SMCLCK Select

    UCB0BR1 = 0;
    UCB0BR0 = 80;

    UCB0I2COA = 0x0000 + I2C_MSP430_ADDRESS; // 7 bit own address (1Bh = 27d) + General Call Disabled

    UCB0CTL1_bit.UCSWRST = 0; // USCI Software un-Reset


    ...


    int I2C_start_and_write (unsigned char argData, unsigned char argAddress) {
    // // wait for the end of any previous activity on the bus
    // while (UCB0CTL1_bit.UCTXSTP == 1);

    // Set the slave address
    UCB0I2CSA = argAddress;

    // set UCTR for transmitter mode
    UCB0CTL1_bit.UCTR = 1;

    // set UCTXSTT to generate a START condition
    // (the slave address is automatically sent after the START condition)
    UCB0CTL1_bit.UCTXSTT = 1;

    // wait for the end of any previous activity on the bus
    while (UCB0CTL1_bit.UCTXSTT == 1);

    // Write the data on the I2C bus
    UCB0TXBUF = argData;

    // Return true
    return (1);
    }

    MSP430 I2C polling hangs while UCTXSTT
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 30 2012 10:01 AM
      Verified Answer
      Verified by Flavio Renga90296
      Guru140295 points

      Flavio Renga90296
      I also noticed that many MSP users have the same problem in using the I2C in a polling mode.

      And I often answered to this:

      This is documented and intended unctionality. Look at the I2C diagram for master transmitter mode.
      After setting UCTXSTT, TXIFG gets set. And the USCI waits in the ACK cycle of teh start condition until either something is written to TXBUF (so it can continue) or UCTXSTT or UCTXSTP are set (so it will end the current transfer).

      In your code, you don't tell the USCI whether you want to continue with data sending or end the transfer, so it waits for you.

      If using interrupts, many people don't notice this as the intrrupt gets called immediately after setting UCTXSTT, stuffing something into TXBUF.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Flavio Renga90296
      Posted by Flavio Renga90296
      on Apr 30 2012 17:51 PM
      Prodigy40 points

      Thanks so much for the clarification.

      I've implemented some modification to the code according to your comments (see hereafter), but the program is still halting on the while loop:

              while (UCB0CTL1_bit.UCTXSTT == 1);

      Where am I wrong?

      Thanks again.

      Flavio

      int I2C_start_and_write (unsigned char argData, unsigned char argAddress) {
          // wait for the end of any previous activity on the bus
          while (UCB0CTL1_bit.UCTXSTP == 1);

          // Set the slave address
          UCB0I2CSA = argAddress;

          // set UCTR for transmitter mode
          UCB0CTL1_bit.UCTR = 1;

          // set UCTXSTT to generate a START condition
          // (the slave address is automatically sent after the START condition)
          UCB0CTL1_bit.UCTXSTT = 1;

          // wait until the START condition has been sent
          while (IFG2_bit.UCB0TXIFG == 0);                              // OPTIONAL?

          // immidiately write the data on the I2C bus
          UCB0TXBUF = argData;

          // wait for the end of any previous activity on the bus
          while (UCB0CTL1_bit.UCTXSTT == 1);                            // THE CODE LOOPS HERE

          // if not acknowledge
          if (UCB0STAT_bit.UCNACKIFG == 1) {
              // Generate stop condition
              UCB0CTL1_bit.UCTXSTP = 1;
              // Return false
              return (0);
          }

          // Return true
          return (1);
      }

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Flavio Renga90296
      Posted by Flavio Renga90296
      on May 02 2012 03:55 AM
      Prodigy40 points

      Thanks again for your suggestions.

      The code I posted is now working.

      For your information, the problem was in another part of the code, in particular there was a bug in the code I wrote to  release the I2C bus sending a stop condition. This caused the I2C peripheral to enter in an unknown state. The I2C peripheral remains in this hanged state even after a new flash downloading, causing the correct portion of the code to run abnormally.

      The only approaches I can use to exit  the I2C peripheral from the hanged state are:

      1. to remove the power from the microcontroller and run again the code (the code works once until the bug in my code)
      2. to manually set the I2C port  outputs first to 1 then to 0 (the code works once until the bug in my code)

      Did you ever noticed this kind of behavior?

      Thanks again.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on May 02 2012 13:27 PM
      Verified Answer
      Verified by Flavio Renga90296
      Guru140295 points

      Flavio Renga90296

      The only approaches I can use to exit  the I2C peripheral from the hanged state are:

      1. to remove the power from the microcontroller and run again the code (the code works once until the bug in my code)
      2. to manually set the I2C port  outputs first to 1 then to 0 (the code works once until the bug in my code)


      So it seems your bug was crashing the I2C slave, which was still 'busy' when receiving the new transmission and was holding the clock low.

      The USCIs itnernal state and behaviour is reset whenever you set the UCSWRST bit (which you should do before setting/changing the slave address, the baudrate, switching master/slave mode etc.)

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Joao Benevides
      Posted by Joao Benevides
      on Jul 19 2012 10:05 AM
      Prodigy20 points

      I'm having exactly the same problem.

      The weird thing is that it worked two times already while trying to write into the FRAM I'm working with.

      What did you do to solve this problem?

      I've tried to disconnect from the JTAG and then reset the computer and ... nothing.

      It worked two days ago(the last time I tried it) and no problems. This morning while I was trying to debug it again, it keeps hanging on the same UCTXSTT loop.

      Please help me out,

      Thank you so much!

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Jul 20 2012 07:35 AM
      Guru140295 points

      Joao Benevides
      It worked two days ago

      Code that worked once will continue working if there was no change. The only thing that might have changed is the hardware. Do you have proper pullups on the SDA and SCL lines? If not, this may slow down the I2C to a few 100Hz effective frequency (which may go through undetected as 'working' and then suddenly fail totally.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use