• 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 » Multi-Byte Receive Issues with MSP430F5529 USCI I2C
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 >
  • Multi-Byte Receive Issues with MSP430F5529 USCI I2C

    Multi-Byte Receive Issues with MSP430F5529 USCI I2C

    This question is not answered
    Rocky
    Posted by Rocky
    on Aug 10 2012 10:52 AM
    Prodigy20 points

    I have been working on setting up communication between an MSP430F5529 I2C Master and several peripheral slaves.  I've encountered some difficulty terminating multi-byte receives at higher clock speeds.  Below is the ISR I have been using from the MSP430F55xx C Samples provided by TI:

    //-------------------------------------------------------------------------------
    // The USCI_B0 data ISR is used to move received data from the I2C slave
    // to the MSP430 memory. It is structured such that it can be used to receive
    // any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
    //-------------------------------------------------------------------------------
    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    {
    switch(__even_in_range(UCB0IV,12))
    {
    case 0: break; // Vector 0: No interrupts
    case 2: break; // Vector 2: ALIFG
    case 4: // Vector 4: NACKIFG
      UCBOCTL1 |= UCTXSTP;
      UCB0STAT &= ~UCNACKIFG
      break;
    case 6: break; // Vector 6: STTIFG
    case 8: break; // Vector 8: STPIFG
    case 10: // Vector 10: RXIFG
      RXByteCtr--; // Decrement RX byte counter
      if (RXByteCtr)
      {
        *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData //CASE 1
        if (RXByteCtr == 1) // Only one byte left?
        UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
        //*PRxData++ = UCB0RXBUF; // Move RX data to address PRxData //CASE2
      } 
      else
      {
        *PRxData = UCB0RXBUF; // Move final RX data to PRxData
        //__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
      }
      break;
    case 12: break; // Vector 12: TXIFG
    default: break;
    }

    Note that I have removed the call to exit LPM0.  For debugging purposes I instead idle inside of a while( UCB0STAT & UCBBUSY) to verify that the transaction has truly finished.  I may return to making use of the LPM once this is working.  For clarity, it may be worth mentioning that RXByteCtr is initially set to the number of bytes I wish to receive, so handling the final byte will begin by decrementing RXByteCtr from 1 to 0.  Anyways, on to the problem.

    At low bus speeds (60 kHz) everything works.  At higher bus speeds (>100kHz) I observe the following, even when communicating with another MSP430F5529 set in slave mode which should be capable of much faster speeds: 

    CASE 1: When UCTXSTP is set AFTER reading the 2nd to last byte. Normally everything works, but occasionally I will observe 1 extra bytes on the bus, and the would-be final byte will NOT be transferred into PRxData.  EDIT I have also verified that the ISR is NOT getting called an extra time to account for the extra byte.  This is important, as it eliminates one very easy explanation to why the would-be-final byte was not showing up in PRxData. /EDIT

    CASE 2: When UCTXSTP is set BEFORE reading the 2nd to last byte.  Normally everything works, but occasionally I will observe the correct number of bytes on the bus and yet the 2nd-to-last byte will NOT be transferred into PRxData.

    Here is my theory on what is happening:

    CASE1: If UCTXSTP gets set BEFORE the UCSI module acks the final byte, everything's dandy.  However, if the USCI module manages to ACK the final byte in-between the MSP reading from UCRXBUF and setting UCTXSTP, then somehow the would-be final byte is lost. Presumably this lost byte gets over-written by the new final byte. 

    CASE2: I assume the USCI module will always have begun transmission of the final byte by the time the ISR for the reception of the 2nd-to-final byte begins.  So I suspect that once UCTXSTP gets set, it's a race between the MSP430 reading RXBUF to clear the 2nd-to-last byte and the USCI module finishing reception of the final byte and over-writing the RXBUF before the MSP430 has a chance to read it.

    In both cases, the fundamental problem seems to revolve setting UCTXSTP allowing the USCI modle to over-write the UCRXBUF before the msp has a chance to read it.  However, I have not read anything in the user's guide or elsewhere that explicitly confirms this behavior (the user's guide seems a little vague about the specifics of these transactions.  What happens when a stop condition gets set "immediately"?  I believe this is where it might be worth clarifying whether or not the UCRXBUF gets overwritten).

    I am looking for a way to circumvent this issue without slowing the bus. 

    Any suggestions or clarifications are appreciated, thanks a lot! 

    I2C USCI MSP430F5529 Receive ucrxbuf overwritten uctxstp
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Rocky
      Posted by Rocky
      on Aug 10 2012 14:26 PM
      Prodigy20 points

      After a bit of brainstorming I think I've hit upon a solution, although I'm not sure if this procedure will have subtle unintended effects on the USCI module's operation. 

      When I wish to set the UCTXSTP bit, I first wait for the USCI module to hold the SCL line low (which should be after reading the 7th bit of the final byte).  Once I have verified that the bus is stalled, I manually revert the SCL pin to a standard IO set to output low.  Then I am free to both set the UCTXSTP bit AND read from the UCRXBUF without the USCI module running off and receiving the rest of the last byte.  Once both of these are completed, I return control of the SCL line to the USCI module. 

      See the following code:

      if ( RXByteCtr == 1)
      {
          while( !(UCB0STAT & UCSCLLOW) );  //wait for master to hold clock low - are now mid-reception of final byte
          P3SEL &= ~SCL_PIN;                       //Hold SCL Low Manually
          *PRxData++ = UCB0RXBUF;             //Read Buffer of 2nd to last byte
          UCB0CTL1 |= UCTXSTP;                   //send stop after finishing this final byte
          P3SEL |= SCL_PIN;                          //Hand SCL control Back to USCI
      }

      This seems to work at all speeds without any delay on the bus except for a small pause when this extra code executes.  Can anyone verify that I am not taking excessive liberties with the USCI module here? 

      Thanks again for any help, 

      ~Rocky

      EDIT This solution may not be flawless.  The bus now hangs periodically (but not in the while loop in the ISR, much to my surprise).  I am beginning to suspect that I am bumping into USCI30, since after increasing the bus speed I can no longer reliably read the UCRXBUF before the USCI stalls the SCL line, and on the scope the length of time for which the line is stalled is not always greater than 3*tBitClock .  If that is indeed the case, the above solution may not be to blame.  

      There is most certainly a flaw in this solution.  I have caught on the scope an instance in which the bus gets held low briefly on reception of the 5th bit (instead of the 7th).  Once the SCL resumes, the slave sends the rest of the byte appropriately and the USCI module responds with a NACK. However, instead of following the NACK with a STOP bit, the USCI module continues to pulse the SCL line endlessly.  I am not sure of why the bus would have been stalled on the 5th bit, or why this would result in the USCI module failing to send a stop condition.

      I2C USCI MSP430F5529 SCL Receive
      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 Aug 13 2012 10:47 AM
      Guru139900 points

      Rocky
      I have caught on the scope an instance in which the bus gets held low briefly on reception of the 5th bit (instead of the 7th).

      Possibly your detection of 'USCI holds SCL low on the 7th bit' was not perfect. When the USCI pulls SCL high, there is a short window in which SCL seems to be still low (due to line capacitance etc.) while the USCI has already released it and SCLLOW is flagged.
      You'll have to ensure that SCLLOW is flagged for more than the clock pulses for 1/2 clock cycle to be sure that there is indeed a clock stretching situation.

      Also, you should set UCTXNACK along with UCTXSTP. No need to manually hold SCL low. Just set NACK and STP, then read RXBUF, wait for RXIFG and read the last byte.

      Yes, I2C on the USCI is still not perfect.

      If timing is not critical (and it doe snot disturb the high-level protocol of the client), you may just ignore all this. When you get the interrupt for the last byte you want, simple set UCTXNACK+UCTXSTP, read the byte and drop the surplus byte that may or may not follow (depending on how fast you responded to the interrupt).

      _____________________________________
      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.
    • Rocky
      Posted by Rocky
      on Sep 20 2012 15:46 PM
      Prodigy20 points

      Sorry I have let this thread sit for a while.  I kept telling myself I'd go back and put time into figuring things out, but once I got something working 'enough' it was hard not to move on.

      Anyways, at least with the F5529, setting UCTXNACK along side UCTXSTP seems to have no effect.  The user's guide even says that a NACK will be generated upon setting only UCTXSTP. 

      I did take your suggestion and monitor SCLLOW to ensure it stays set.  This seems to have taken care of my problems, and now my code has been working for quite a while.  

      My original question hasn't actually been answered though.  I still don't know why I was loosing the second to last byte of some transmissions.  I don't actually mind receiving surplus bytes and ignoring them (although I can think of situations where that would be extremely undesirable), but that still didn't allow me to reliably receive all the bytes of the transaction I did need. 

      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